You are viewing a plain text version of this content. The canonical link for it is here.
Posted to c-dev@xerces.apache.org by James Berry <jb...@criticalpath.com> on 2000/07/15 01:27:27 UTC

Contributing Mac OS port of Xerces

I'm contributing the following Mac OS port of Xerces.

The port currently in the repository is quite out of date with respect to the current Xerces source. This new port, in addition to syncing back up with
the source, adds the following:

 - A new native transcoder for the Macintosh which sits on the built-in Macintosh Unicode Converter software.
 - Compatibility with Macintosh Carbon APIs as well as older Classic APIs.
 - Rewritten platform support featuring big file support and long unicode file names support.

I'm not at this time contributing project files for Codewarrior or Project Builder, though I've got them. I'll contribute those once things solidify with
the upcoming Mac OS X public beta. To avoid problems with monolithic binary project files, I may submit exported XML versions of such--any comment? If
anyone needs project files in the mean time, please contact me.

Please read the readme for more information.

Could someone please check these changes into CVS?

Thanks!

-jdb

a. Apply the diffs below
b. remove file c/Projects/MacOS/CWPrjFilesForMacOS.sea.hqx    [outdated]
c. add file c/Projects/MacOS/ShortenFiles.pl                                    [new file--attached]
d. add file c/src/util/Compilers/CodeWarriorDefs.cpp                      [new file--attached]
e. add file c/src/util/Platforms/MacOS/MacOSPlatformUtils.hpp     [new file--attached]
f. create directory c/src/util/Transcoders/MacOSUnicodeConverter  [new directory]
g. add file c/src/util/Transcoders/MacOSUnicodeConverter/MacOSUnicodeConverter.hpp  [new file--attached]
h. add file c/src/util/Transcoders/MacOSUnicodeConverter/MacOSUnicodeConverter.cpp   [new file--attached]

Here are the diffs:

? Projects/MacOS/CodeWarrior
? Projects/MacOS/ProjectBuilder
? Projects/MacOS/ShortenFiles.pl
? src/util/Compilers/CodeWarriorDefs.cpp
? src/util/Platforms/MacOS/MacOSPlatformUtils.hpp
? src/util/Transcoders/MacOSUnicodeConverter
Index: Projects/MacOS/ReadmeForMacOS.txt
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/Projects/MacOS/ReadmeForMacOS.txt,v
retrieving revision 1.1.1.1
diff -r1.1.1.1 ReadmeForMacOS.txt
1c1
< Disclaimer:
---
> State of Xerces Mac OS Port. 7/14/00 by James Berry, Critical Path Software, Inc.
3,71c3,72
<     XML4C is not officially supported under MacOS. These instructions
<     were provided by one of the contributers/users of XML4C and have
<     been included in the XML4C distribution just for convenience and
<     benefit of other users. XML4C team, will not be able to maintain
<     these files, but will be very willing to accept changes as
<     submitted by the users. All such changes may be sent to
<     xml4c@us.ibm.com.
<
<
< The directions in this file cover installing and building XML4C and
< ICU under the MacOS using CodeWarrior.
<
< 1.  Create a folder that will contain the XML4C and ICU distributions.
<       For future reference I will refer to this folder as "src drop".
<
< 2.  Download and uncompress the ICU 1.2.5 source distribution and the
<       XML4C 2.3.1 source distribution.  You might also want to download
<       the binary distributions because they may contain documentation
<       not present in the source distribution.  This will create two additional
<       folders: "xml4csrc2_3_1" and "icu".  Move these two folders into the
<       "src drop" folder.
<
< 3.  Drag the xml4csrc2_3_1 folder and drop it on to the "rename files" application
<       located in the same folder as this readme.  This is a MacPerl
<       script that renames files with names too long to fit in the HFS/HFS+
<       filesystem.  It also searches through all of the source code and
<       changes the #include statements to refer to the new file names.
<
< 4.  Move all the files from the "XML4C MacOS Drop:icu changes:common:" folder
<       to the "src drop:icu:source:common:" folder, replacing the existing files
<       in the icu source drop.
<
< 5.  Move the file from the "XML4C MacOS Drop:icu changes:extra:ustdio:" folder
<       to the "src drop:icu:source:extra:ustdio:" folder, replacing the existing file
<       in the icu source drop.
<
< 6.  Move the MacOS folder (in the Projects folder) to "src drop:xml4csrc2_3_1:Projects".
<
< 7.  You should be able to open the CodeWarrior project file
<        "src drop:xml4c2:Projects:MacOS:xml4c:xml4c" and build the xml4c library.
<
< 8.  You should also be able to open the CodeWarrior project file
<        "src drop:xml4c2_3_1:Projects:MacOS:icu:icu" and build the ICU library.
<
< 9.  If you wish you can create projects for and build the rest of
<        the tools and test suites.  They are not needed if you just want to
<        use xml4c.  I suggest that you use the binary data files distributed
<        with the binary distribution of ICU instead of creating your own from
<        the text data files in the ICE source distribution.
<
< There are some things to be aware of when creating your own projects using
< xml4c.
<
< 1.  You will need to link against both the ICU and XML4C libraries.
<
< 2.  The options "Always search user paths" and "Interpret DOS and Unix Paths"
<        are very useful.  Some of the code won't compile without them set.
<
< 3.  Most of the tools and test code will require slight modification to compile
<        and run correctly (typecasts, command line parameters, etc), but it is
<        possible to get them working correctly.
<
< 4.  You will most likely have to set up the Access Paths.  The access paths in the
<        xml4c projects should serve as a good example.
<
< If you are having problems getting xml4c working feel free to email
< me at jbellardo@alumni.calpoly.edu.  I may or may not be able to help
< (depending on things out of my control like work/class schedules) but I will
< try.
---
> This readme attempts to document the state of Mac OS support for Xerces. I suspect that this code has been ported to the Mac on a number of occasions.
My work on Xerces is derived in small part from a previous port by jbellardo@calpoly.edu.
>
> This port aims to bring Xerces to Mac OS, and to use Mac OS services as appropriate.
>
> Key work in these areas is:
>
>  - Development of a transcoder that relies on Mac OS's Unicode Converter. [MacOSUnicodeConverter].
>
>  - Near-complete rewrite of Mac OS Platform utilities [MacOSPlatformUtils] to support Mac OS
>    constructs and the latest changes in Xerces. All file access is done directly on top of the
>    Mac OS file system and in fact uses the new FSRef calls and long unicode names
>    whereever possible.
>
>  - Code supports both Carbon and Classic APIs.
>
>  - Detection of and support for Codewarrior and Project Builder.
>
> Key omissions include:
>
>  - Neither Codewarrior nor Project Builder project files are yet provided, though I've built
>    both. My Codewarrior projects are built under the new IDE 4.1 which has not yet been
>    publicly released. I'll release Project Builder projects after the Mac OS X public beta
>    is released. If you want them now...just email me.
>
>  - There is no NetAccessor support yet for Mac OS. This could/should probably be written
>    atop URL Access, and probably isn't that hard, but I haven't gotten around to it yet.
>    Other possibilities might include using libwww or the existing Xerces NetSocket accessor
>    if you're under Mac OS X.
>
> Usage Notes:
>
>  - A major hassle in porting this code to the Mac, and in keeping it up to date, is the
>    existance of a number of files with file names greater than 31 characters. Xalan is worse.
>    I've written a perl script "ShortenNames.pl" which will (1) copy source to a MacSrc directory
>    (2) shorten file names using appropriate hints, and (3) update internal usage of these
>    names (includes). To use this:
>
>    - Check out the code somewhere where you've got long names [unix system?]
>    - Move ShortenNames.pl into the "c" directory, at the same level as the
>      "src" directory.
>    - Invoke the script using perl ShortenNames.pl.
>    - This (should) create a new directory called MacSrc which is a duplicate of
>      the "src" directory but with names shortened appropriately. This has been
>      tested on Mac OS and Mac OS X, but in no other environments. YMMV.
>
>    Note that I'll ascribe most of the blame for the problem to Apple and other Mac tools
>    vendors. HFS+ fully supports long file names: it's too bad that Apple (Finder),
>    Aladdin (StuffIt), Metrowerks (CodeWarrior) and others (MacCVS) haven't chosen to support
>    long names within their products. I actually spent several days on the MacCVS end of this
>    task before deciding it was too hard given the timeframe with OS X almost here.
>    The situation under Mac OS X is much better.
>
>  - The Mac OS Platform utilities expect that pathnames will be in unix-form with '/' separators.
>    There is no support for Mac OS style pathnames with colons. Routines are provided to
>    convert back and forth between this style of name and FSRefs or FSSpecs. See
>    [MacOSPlatformUtils.hpp]. The choice to use unix-paths only was based on the idea that
>    any XML that has external references is likely to have them in unix form, so we have to
>    be able to support unix paths. To also support mac paths seems superfluous.
>
>  - I have not brought forward the previous port's rather bizzare support for file sources
>    that read from resources. If you want to read from a resource just read it into memory,
>    lock it down, and set up a memory based stream to parse through it.
>
>  - If you're building this code, make sure you include the MemoryBased messaged loader.
>    There is no Mac specific message loader for now.
>
>
> James Berry
> Critical Path Software, Inc.
> jberry@criticalpath.com
\ No newline at end of file
Index: src/util/AutoSense.hpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/util/AutoSense.hpp,v
retrieving revision 1.12
diff -r1.12 AutoSense.hpp
156d155
<
165d163
<
167a166,167
> #elif defined(MACOSX)
>     #define XML_MACOSX
Index: src/util/XercesDefs.hpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/util/XercesDefs.hpp,v
retrieving revision 1.2
diff -r1.2 XercesDefs.hpp
188,189c188,189
< #if defined(XML_MACOS)
< #include <util/Platforms/MaxOS/MacOSDefs.hpp>
---
> #if defined(XML_MACOS) || defined(XML_MACOSX)
> #include <util/Platforms/MacOS/MacOSDefs.hpp>
190a191
>
Index: src/util/Compilers/CodeWarriorDefs.hpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/util/Compilers/CodeWarriorDefs.hpp,v
retrieving revision 1.5
diff -r1.5 CodeWarriorDefs.hpp
107c107,109
< //  Define our version of the XMLCh.
---
> //  Define our version of the XMLCh. XMLCh should be mapped to the native
> //  wide char type (whatever wchar_t is.) On Mac, wchar_t is not an
> //  intrinsic type and is just mapped to unsigned short.
109c111,119
< typedef unsigned short XMLCh;
---
> typedef unsigned short  XMLCh;
> typedef unsigned short  UTF16Ch;
>
>
> // ---------------------------------------------------------------------------
> //  Define unsigned 16 and 32 bits integers
> // ---------------------------------------------------------------------------
> typedef unsigned short  XMLUInt16;
> typedef unsigned int    XMLUInt32;
115,117c125,127
< //#ifdef _DEBUG
< //#define XERCES_DEBUG
< //#endif
---
> #ifdef _DEBUG
> #define XERCES_DEBUG
> #endif
118a129,133
> // ---------------------------------------------------------------------------
> //  Provide some common string ops that are different/notavail for CodeWarrior.
> // ---------------------------------------------------------------------------
> int stricmp(const char* const str1, const char* const  str2);
> int strnicmp(const char* const str1, const char* const  str2, const unsigned int count);
Index: src/util/Compilers/GCCDefs.cpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/util/Compilers/GCCDefs.cpp,v
retrieving revision 1.3
diff -r1.3 GCCDefs.cpp
81c81
< #include <strings.h>
---
> #include <string.h>
Index: src/util/Platforms/MacOS/MacOSDefs.hpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/util/Platforms/MacOS/MacOSDefs.hpp,v
retrieving revision 1.3
diff -r1.3 MacOSDefs.hpp
89,147d88
< #include <resources.h>
<
< class XMLMacAbstractFile
< {
<     public:
<         XMLMacAbstractFile() {}
<         virtual ~XMLMacAbstractFile() {}
<
<         virtual unsigned int currPos() = 0;
<         virtual void close() = 0;
<         virtual unsigned int size() = 0;
<         virtual void open(const char* const) = 0;
<         virtual unsigned int read(const unsigned int, XMLByte* const) = 0;
<         virtual void reset() = 0;
< };
<
< class XMLMacFile : public XMLMacAbstractFile
< {
<     public:
<         XMLMacFile() : valid(0), fileRef(0) {}
<         virtual ~XMLMacFile();
<
<         unsigned int currPos();
<         void close();
<         unsigned int size();
<         void open(const char* const);
<         unsigned int read(const unsigned int, XMLByte* const);
<         void reset();
<
<     protected:
<         short fileRef;
<         short valid;
<         unsigned char pStr[300];
< };
<
< class XMLResFile : public XMLMacAbstractFile
< {
<     public:
<         XMLResFile() : valid(0), type(0), id(0), pos(0), len(0) {}
<         virtual ~XMLResFile();
<
<         unsigned int currPos();
<         void close();
<         unsigned int size();
<         void open(const char* const);
<         unsigned int read(const unsigned int, XMLByte* const);
<         void reset();
<
<     protected:
<         short valid;
<         unsigned long type;
<         short id;
<         unsigned char name[300];
<         Handle data;
<         long pos;
<         long len;
< };
<
<
156a98
> class XMLMacAbstractFile;
159,162d100
<
< int stricmp(const char *s1, const char *s2);
< int strnicmp(const char *s1, const char *s2, int n);
<
163a102
>
Index: src/util/Platforms/MacOS/MacOSPlatformUtils.cpp
===================================================================
RCS file: /home/cvspublic/xml-xerces/c/src/util/Platforms/MacOS/MacOSPlatformUtils.cpp,v
retrieving revision 1.4
diff -r1.4 MacOSPlatformUtils.cpp
94d93
< #include <util/String.hpp>
96,102c95,100
< #include <util/MacOSDefs.hpp>
< #include <iostream.h>
< #include <files.h>
< #include <gestalt.h>
< #include <traps.h>
< #include <lowmem.h>
< #include <Multiprocessing.h>
---
> #include <util/XMLString.hpp>
> #include <util/Platforms/MacOS/MacOSDefs.hpp>
> #include <util/Platforms/MacOS/MacOSPlatformUtils.hpp>
> #include <util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
> #include <util/Transcoders/MacOSUnicodeConverter/MacOSUnicodeConverter.hpp>
>
104a103,112
> #include <stdio.h>
> #include <ctype.h>
> #include <memory>
>
> #include <Files.h>
> #include <Gestalt.h>
> #include <Traps.h>
> #include <TextUtils.h>
> #include <Multiprocessing.h>
> #include <DriverSynchronization.h>
106a115,120
> //----------------------------------------------------------------------------
> // Function Prototypes
> //----------------------------------------------------------------------------
> #if !TARGET_API_MAC_CARBON
> static bool  TrapAvailable(UInt16 trapWord);
> #endif
111,115d124
< //  gFileSystemReady
< //    This flag indicates if the file system is ready to be used.  The only
< //    thing that might stop us is the absence of FSspec file manipulation
< //    routines in the OS.
< //
118a128,144
> //
> //  gFileSystemCompatible
> //    This flag indicates whether the file system APIs meet our minimum
> //   requirements.
> //
> // gHasFSSpecAPIs
> //   True if the FSSpecAPIs are available. These are required.
> //
> // gHasF2TBAPIs
> //   True if the FS supports 2 terrabyte calls. These are required for
> //   use under Carbon.
> //
> // gHasHFSPlusAPIs
> //   True if the FS supports HFSPlus APIs. If this is true, then the
> //   new Fork calls are used, and all file name and path handling
> //   uses long unicode names. Note that once a file is opened with
> //   the fork calls, only fork calls may be used to access it.
120,123c146,150
< static const char *resBaseStr = "/Access The Resource Fork Instead of the data fork?";
< static bool gFileSystemReady = false;
< static bool gGestaltAvail = false;
< static MPCriticalRegionID gCriticalRegion;
---
> static bool gGestaltAvail   = false;
> static bool gFileSystemCompatible = false;
> static bool gHasFSSpecAPIs   = false;
> static bool gHasFS2TBAPIs   = false;
> static bool gHasHFSPlusAPIs   = false;
127c154
< // XMLResFile methods
---
> // XMLMacFile methods
129,130d155
< XMLResFile::XMLResFile();
<
132c157
< void XMLResFile::open(const char* const resInfo)
---
> unsigned int XMLMacFile::currPos()
134,217c159,160
<     char option[32], value[32], command[70];
<     int cmdEnd = 0, cmdStart = 0;
<     int optEnd = 0, sep;
<     int mode = -1;
<     int typeValid = 0;
<
<     if (!strchr(&resInfo[cmdStart], '/'))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Malformed resource locater");
<
<     while(resInfo[cmdEnd] != '/')
<     {
<         if (strchr(&resInfo[cmdStart], '&') < strchr(&resInfo[cmdStart], '/') && strchr(&resInfo[cmdStart], '&') != 0)
<             cmdEnd = strchr(&resInfo[cmdStart], '&') - resInfo - 1;
<         else
<             cmdEnd = strchr(&resInfo[cmdStart], '/') - resInfo - 1;
<
<         if (cmdEnd - cmdStart > 68)
<             throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- resource option too long (>68 chars)");
<
<         memcpy(command, &resInfo[cmdStart], cmdEnd - cmdStart + 1);
<         command[cmdEnd - cmdStart + 1] = 0;
<         if (!strchr(command, '='))
<             throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Malformed resource locater");
<
<         sep = strchr(command, '=') - command;
<         memcpy(option, command, sep);
<         option[sep] = 0;
<         memcpy(value, &command[sep+1], strlen(command) - sep);
<
<         if (!strcmp(option, "mode"))
<         {
<             if (!strcmp(value, "by_id"))
<                 mode = 1;
<             else if (!strcmp(value, "by_id1"))
<                 mode = 2;
<             else if (!strcmp(value, "by_name"))
<                 mode = 3;
<             else if (!strcmp(value, "by_name1"))
<                 mode = 4;
<             else
<                 throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- 'mode' has to be 'by_id' or 'by_id1' or 'by_name' or 'by_name1'");
<         }
<         if (!strcmp(option, "type"))
<         {
<             if (strlen(value) != 4)
<                 throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- 'type' has to be four characters long");
<             typeValid = 1;
<             type = 0;
<             type += value[0] << 24;
<             type += value[1] << 16;
<             type += value[2] << 8;
<             type += value[3];
<         }
<
<         cmdStart = cmdEnd + 2;
<         cmdEnd++;
<     }
<
<     if (mode == 0)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Malformed resource locater requires a 'mode'");
<     if (typeValid == 0)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Malformed resource locater requires a 'type'");
<
<     switch(mode)
<     {
<         case 1: case 2:
<             id = atol(&resInfo[cmdEnd+1]);
<             if (mode == 1)
<                 data = GetResource(type, id);
<             else
<                 data = Get1Resource(type, id);
<             break;
<
<         case 3: case 4:
<             if (strlen(&resInfo[cmdEnd]) >= 255)
<                 throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Resource names have to be 255 characters or less");
<             strcpy((char*)name, &resInfo[cmdEnd]);
<             name[0] = strlen((char*)&name[1]);
<             if (mode == 3)
<                 data = GetNamedResource(type, name);
<             else
<                 data = Get1NamedResource(type, name);
<             break;
<     }
---
>  OSErr err = noErr;
>     unsigned int pos = 0;
219,228c162,163
<     if (ResError() != noErr)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Error opening resource");
<
<     GetResInfo(data, &id, &type, name);
<     len = GetResourceSizeOnDisk(data);
<     if (ResError() != noErr)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Error loading resource info");
<
<     valid = 1;
< }
---
>     if (!mFileValid)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
230,240c165,178
< unsigned int XMLResFile::read(const unsigned int buffLen, XMLByte* const buff)
< {
<     unsigned int totAvail = len - pos;
<     unsigned int numRead = (buffLen >= totAvail) ? totAvail : buffLen;
<
<     HLock(data);
<     memcpy(buff, *data, numRead);
<     HUnlock(data);
<     pos += numRead;
<     return numRead;
< }
---
>  if (gHasHFSPlusAPIs)
>  {
>   SInt64 bigPos = 0;
>   err = FSGetForkPosition(mFileRefNum, &bigPos);
>   if (err == noErr)
>    pos = bigPos;
>  }
>  else
>  {
>   long longPos;
>   err = GetFPos(mFileRefNum, &longPos);
>   if (err == noErr)
>    pos = longPos;
>  }
242,255c180,181
< void XMLResFile::close()
< {
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::curFilePos -- Not a valid file");
<     ReleaseResource(data);
<     valid = 0;
< }
<
< unsigned int XMLResFile::currPos()
< {
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::curFilePos -- Not a valid file");
<     return pos;
< }
---
>     if (err != noErr)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
257,261c183
< void XMLResFile::reset()
< {
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::resetFile -- Not a valid file");
<     pos = 0;
---
>     return pos;
264,269d185
< unsigned int XMLResFile::size()
< {
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize -- Not a valid file");
<     return len;
< }
271c187
< XMLResFile::~XMLResFile()
---
> void XMLMacFile::close()
273,275c189,196
<     if (valid)
<         close();
< }
---
>  OSErr err = noErr;
>     if (!mFileValid)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
>
>  if (gHasHFSPlusAPIs)
>   err = FSCloseFork(mFileRefNum);
>  else
>   err = FSClose(mFileRefNum);
277,279c198
< //----------------------------------------------------------------------------
< // XMLMacFile methods
< //----------------------------------------------------------------------------
---
>     mFileValid = false;
281,288c200,201
< unsigned int XMLMacFile::currPos()
< {
<     long len;
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::curFilePos -- Not a valid file");
<     if (noErr != GetFPos(fileRef, &len))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::curFilePos -- Error getting file position");
<     return len;
---
>     if (err != noErr)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
291,298d203
< void XMLMacFile::close()
< {
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::closeFile -- Not a valid file");
<     if (noErr != FSClose(fileRef))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::closeFile -- Error closing file");
<     valid = 0;
< }
300c205,206
< unsigned int XMLMacFile::size()
---
> unsigned int
> XMLMacFile::size()
302c208,209
<     long len;
---
>  OSErr err = noErr;
>     unsigned int len = 0;
304,307c211,231
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize -- Not a valid file");
<     if (noErr != GetEOF(fileRef, &len))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize -- Error closing file");
---
>     if (!mFileValid)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize);
>
>  if (gHasHFSPlusAPIs)
>  {
>   SInt64 bigLen = 0;
>   err = FSGetForkSize(mFileRefNum, &bigLen);
>   if (err == noErr)
>    len = bigLen;
>  }
>  else
>  {
>   long longLen;
>   err = GetEOF(mFileRefNum, &longLen);
>   if (err == noErr)
>    len = longLen;
>  }
>
>     if (err != noErr)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize);
>
311c235,236
< void XMLMacFile::open(const char* const fileName)
---
>
> void XMLMacFile::open(const XMLCh* const fileName)
313c238
<     OSErr myErr;
---
>     OSErr err = noErr;
315,336c240,256
<     if (valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Can't open the same file twice");
<     if (strlen(fileName) > 255)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile(const char* const) -- File name too long (>255 chars)");
<
<     if (fileName[0] == '/')
<     {
<         strcpy((char*)&pStr[1], &fileName[1]);
<         pStr[0] = strlen(fileName) - 1;
<         pStr[strlen(fileName)] = 0;
<     } else {
<         strcpy((char*)&pStr[1], fileName);
<         pStr[0] = strlen(fileName);
<         pStr[strlen(fileName) + 1] = 0;
<     }
<
<     for(int i = 1; i <= pStr[0]; i++)
<         if (pStr[i] == '/')
<             pStr[i] = ':';
<
<     myErr = HOpenDF(0, 0, pStr, fsRdWrPerm, &fileRef);
<     if (myErr != noErr)
---
>     if (mFileValid)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile);
>
>     if (gHasHFSPlusAPIs)
>     {
>   FSRef ref;
>   if (!XMLParsePathToFSRef(fileName, ref))
>        err = fnfErr;
>
>   HFSUniStr255 forkName;
>   if (err == noErr)
>    err = FSGetDataForkName(&forkName);
>
>   if (err == noErr)
>    err = FSOpenFork(&ref, forkName.length, forkName.unicode, fsRdWrPerm, &mFileRefNum);
>     }
>     else
338,339c258,263
<         cerr << myErr << endl;
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile(const char* const) -- Failed to open file.");
---
>   FSSpec spec;
>   if (!XMLParsePathToFSSpec(fileName, spec))
>        err = fnfErr;
>
>   if (err == noErr)
>    err = FSpOpenDF(&spec, fsRdWrPerm, &mFileRefNum);
340a265,267
>
>     if (err != noErr)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile);
342c269
<     valid = 1;
---
>     mFileValid = true;
347,353c274,296
<     long bytesRead = toRead;
<
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::readFileBuff -- Not a valid file");
<     if (noErr != FSRead(fileRef, &bytesRead, toFill))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::readFileBuffer - Read failed");
<     return (unsigned int)bytesRead;
---
>  unsigned int bytesRead = 0;
>  OSErr err = noErr;
>
>     if (!mFileValid)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
>
>  if (gHasHFSPlusAPIs)
>  {
>   ByteCount actualCount;
>   err = FSReadFork(mFileRefNum, fsFromMark, 0, toRead, toFill, &actualCount);
>   bytesRead = actualCount;
>  }
>  else
>  {
>      long byteCount = toRead;
>     err = FSRead(mFileRefNum, &byteCount, toFill);
>     bytesRead = byteCount;
>    }
>
>     if (err != noErr && err != eofErr)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
>
>     return bytesRead;
357,362c300,314
< void XMLMacFile::reset()
< {
<     if (!valid)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::resetFile -- Not a valid file");
<     if (noErr != SetFPos(fileRef, fsFromStart, 0))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize -- Error closing file");
---
> void
> XMLMacFile::reset()
> {
>  OSErr err = noErr;
>
>     if (!mFileValid)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
>
>  if (gHasHFSPlusAPIs)
>   err = FSSetForkPosition(mFileRefNum, fsFromStart, 0);
>  else
>   err = SetFPos(mFileRefNum, fsFromStart, 0);
>
>     if (err != noErr)
>       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
364a317
>
367c320
<     if (valid)
---
>     if (mFileValid)
370a324
>
372c326
< //  Local methods
---
> //  XMLPlatformUtils: The panic method
374,388c328
< static void WriteCharStrStdErr(const char* const toWrite)
< {
<     // Just print the data out the the MetroWerks standard error.
<     cerr << toWrite;
< }
<
<
< static void WriteCharStrStdOut(const char* const toWrite)
< {
<     // Just print the data out the the MetroWerks standard error.
<     cout << toWrite;
< }
<
<
< static void WriteUStrStdErr(const XMLCh* const toWrite)
---
> void XMLPlatformUtils::panic(const PanicReasons reason)
390,395c330,346
<     // Oh well, got to do it the hard way
<     char* tmpVal = XMLString::transcode(toWrite);
<     ArrayJanitor<char> janTmp(tmpVal);
<     WriteCharStrStdErr(tmpVal);
< }
<
---
>     const char* reasonStr = "Unknown reason";
>     if (reason == Panic_NoTransService)
>         reasonStr = "Could not load a transcoding service";
>     else if (reason == Panic_NoDefTranscoder)
>         reasonStr = "Could not load a local code page transcoder";
>     else if (reason == Panic_CantFindLib)
>         reasonStr = "Could not find the xerces-c DLL";
>     else if (reason == Panic_UnknownMsgDomain)
>         reasonStr = "Unknown message domain";
>     else if (reason == Panic_CantLoadMsgDomain)
>         reasonStr = "Cannot load message domain";
>     else if (reason == Panic_SynchronizationErr)
>         reasonStr = "A system synchronization error occured";
>     else if (reason == Panic_SystemInit)
>         reasonStr = "Failed to complete platform dependent initialization";
>     else
>      reasonStr = "Unknown error source";
397,402c348,359
< static void WriteUStrStdOut(const XMLCh* const toWrite)
< {
<     // Oh well, got to do it the hard way
<     char* tmpVal = XMLString::transcode(toWrite);
<     ArrayJanitor<char> janTmp(tmpVal);
<     WriteCharStrStdOut(tmpVal);
---
>     //
>     //  This isn't real friendly and should be cleaned up.
>     // Replace this code to do whatever you need to do.
>     //
>     char text[200];
>     sprintf(text, "Xerces Panic Error: %s", reasonStr);
>
>     Str255 pasText;
>     CopyCStringToPascal(text, pasText);
>     DebugStr(pasText);
>
>     exit(-1);
406d362
<
424a381
>
427,451c384,386
<      FileHandle file = 0;
<      int isRes = 0;
<
<     // Check to make sure the file system is in a state where we can use it
<      if (!gFileSystemReady)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile(const char* const) -- File system not ready."
<                   "  Maybe missing gestalt or no support for FSSpec's.");
<
<     if (strlen(fileName) >= strlen(resBaseStr))
<         if (strstr(fileName, resBaseStr) == fileName)
<             isRes = 1;
<
<     if (isRes == 0)
<     {
<         file = new XMLMacFile();
<         file->open(fileName);
<     }
<     else
<     {
<         file = new XMLResFile();
<         file->open(&fileName[strlen(resBaseStr)]);
<     }
<     if (file == 0)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::openFile(const char* const) -- Failed to allocate file object.");
<     return file;
---
>  const XMLCh* xmlPath = XMLString::transcode(fileName);
>  ArrayJanitor<const XMLCh> jan(xmlPath);
>  return openFile(xmlPath);
453a389
>
456,460c392,401
<     char* tmpName = XMLString::transcode(fileName);
<     FileHandle retVal = openFile(tmpName);
<     delete [] tmpName;
<
<     return retVal;
---
>     // Check to make sure the file system is in a state where we can use it
>     if (!gFileSystemCompatible)
>         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile);
>
>     XMLMacFile* file = new XMLMacFile();
>     Janitor<XMLMacAbstractFile> janFile(file);
>     file->open(fileName);
>     janFile.orphan();
>
>     return file;
466,467c407,408
<     throw XMLPlatformUtilsException("XMLPlatformUtils::openStdInHandle -- Standard input not supported on MacOS");
<     return NULL;//(void*)&cin;
---
>  ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile);
>  return NULL;
476c417
<     return theFile->read(toRead, toFill);
---
>  return theFile->read(toRead, toFill);
482c423
<     theFile->reset();
---
>  theFile->reset();
484a426
>
486c428
< //  XMLPlatformUtils: File Methods
---
> //  XMLPlatformUtils: File system methods
488c430
< void XMLPlatformUtils::writeToStdErr(const XMLCh* const toWrite)
---
> XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath)
490c432,447
<     WriteUStrStdErr(toWrite);
---
>  XMLCh* path = NULL;
>
>     if (gHasHFSPlusAPIs)
>     {
>      FSRef ref;
>      if (!XMLParsePathToFSRef(srcPath, ref) || (path = XMLCreateFullPathFromRef(ref)) == NULL)
>       path = XMLString::replicate(srcPath);
>     }
>     else
>     {
>      FSSpec spec;
>      if (!XMLParsePathToFSSpec(srcPath, spec) || (path = XMLCreateFullPathFromSpec(spec)) == NULL)
>       path = XMLString::replicate(srcPath);
>     }
>
>     return path;
493,496d449
< void XMLPlatformUtils::writeToStdErr(const char* const toWrite)
< {
<     WriteCharStrStdErr(toWrite);
< }
498c451
< void XMLPlatformUtils::writeToStdOut(const XMLCh* const toWrite)
---
> bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
500c453
<     WriteUStrStdOut(toWrite);
---
>  return (toCheck[0] != L'/');
503,506d455
< void XMLPlatformUtils::writeToStdOut(const char* const toWrite)
< {
<     WriteCharStrStdOut(toWrite);
< }
508a458,459
> XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
>                                     , const XMLCh* const    relativePath)
510,513d460
< // ---------------------------------------------------------------------------
< //  XMLPlatformUtils: Platform methods
< // ---------------------------------------------------------------------------
< XMLCh* XMLPlatformUtils::getBasePath(const XMLCh* const srcPath)
515,532c462,485
<     char* workingPath = XMLString::transcode(srcPath);
<     XMLCh *result;
<     char dirSep = '/', *lastSep = 0;
<
<     for(int i = 0; workingPath && workingPath[i]; i++)
<         if (workingPath[i] == dirSep)
<             lastSep = &workingPath[i];
<
<     if (lastSep == 0)
<         return XMLString::transcode("");
<
<     lastSep++;
<     dirSep = *lastSep;
<     *lastSep = 0;
< //    cout << "Returning base path: " << workingPath << endl;
<     result = XMLString::transcode(workingPath);
<     *lastSep = dirSep;
<     delete [] workingPath;
---
>  // Code from Windows largely unmodified for the Macintosh,
>  // with the exception of removing support for '\' path
>  // separator.
>  //
>  // Note that there is no support currently for Macintosh
>  // path separators ':'.
>
>     // Create a buffer as large as both parts and empty it
>     XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
>                               + XMLString::stringLen(relativePath)
>                               + 2];
>     ArrayJanitor<XMLCh> janBuf(tmpBuf);
>     *tmpBuf = 0;
>
>     //
>     //  If we have no base path, then just take the relative path as
>     //  is.
>     //
>     if (!basePath)
>     {
>         XMLString::copyString(tmpBuf, relativePath);
>         janBuf.orphan();
>         return tmpBuf;
>     }
534,535c487,492
<     return result;
< }
---
>     if (!*basePath)
>     {
>         XMLString::copyString(tmpBuf, relativePath);
>         janBuf.orphan();
>         return tmpBuf;
>     }
537,563c494,495
< bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
< {
<     char* workingPath = XMLString::transcode(toCheck);
<     char dirSep = '/', *sep;
<     short refNum;
<     long freeSpace;
<     unsigned char volName[260];
<
<     if (!*workingPath)
<         return false;
<
<     if (strstr(workingPath, ":"))
<         dirSep = ':';
<
<     if ( dirSep == '/' && workingPath[0] == '/')
<         return false;
<     if ( dirSep == '/' && workingPath[0] != '/')
<         return true;
<
<     sep = strstr(workingPath, ":");
<     if (sep == 0)
<         return true;
<
<     dirSep = *sep;
<     *sep = 0;
<
<     for(short i = 0; i < 7; i++)
---
>     const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
>     if (*basePtr != chForwardSlash)
565,580c497,498
<         if ( noErr == GetVInfo(i, volName, &refNum, &freeSpace))
<         {
<             if (strlen(workingPath) != volName[0])
<                 continue;
<
<             for(int j = 0, refNum = 0; j < volName[0]; j++)
<                 if (workingPath[j] != volName[j+1])
<                     refNum = 1;
<
<             if (!refNum)
<             {
<                 *sep = dirSep;
<                 delete [] workingPath;
<                 return false;
<             }
<         }
---
>         while ((basePtr >= basePath) && (*basePtr != chForwardSlash))
>             basePtr--;
582,585d499
<     *sep = dirSep;
<     delete [] workingPath;
<     return true;
< }
586a501,507
>     // There is no relevant base path, so just take the relative part
>     if (basePtr < basePath)
>     {
>         XMLString::copyString(tmpBuf, relativePath);
>         janBuf.orphan();
>         return tmpBuf;
>     }
589c510,563
< // ---------------------------------------------------------------------------
---
>     //  We have some path part, so we need to check to see if we have to
>     //  weave any of the parts together.
>     const XMLCh* pathPtr = relativePath;
>
>     while (true)
>     {
>         // If it does not start with some period, then we are done
>         if (*pathPtr != chPeriod)
>             break;
>
>         unsigned int periodCount = 1;
>         pathPtr++;
>         if (*pathPtr == chPeriod)
>         {
>             pathPtr++;
>             periodCount++;
>         }
>
>         // Has to be followed by a / or the null to mean anything
>         if ((*pathPtr != chForwardSlash) &&  *pathPtr)
>             break;
>
>         if (*pathPtr)
>             pathPtr++;
>
>         // If it's one period, just eat it, else move backwards in the base
>         if (periodCount == 2)
>         {
>             basePtr--;
>             while ((basePtr >= basePath) && (*basePtr != chForwardSlash))
>                 basePtr--;
>
>             // The base cannot provide enough levels, so it's in error/
>             if (basePtr < basePath)
>                 ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_BasePathUnderflow);
>         }
>     }
>
>     // Copy the base part up to the base pointer
>     XMLCh* bufPtr = tmpBuf;
>     const XMLCh* tmpPtr = basePath;
>     while (tmpPtr <= basePtr)
>         *bufPtr++ = *tmpPtr++;
>
>     // And then copy on the rest of our path
>     XMLString::copyString(bufPtr, pathPtr);
>
>     // Orphan the buffer and return it
>     janBuf.orphan();
>     return tmpBuf;
> }
>
>
> // ---------------------------------------------------------------------------
594c568
<     return TickCount()*10;
---
>     return TickCount() * 100 / 6;
600a575,597
> //
> // There are a number of choices for multi-threading on Mac OS. Traditionally
> // there was the Thread Manager, which provided cooperative multitasking on
> // 68K and PPC platforms, and preemptive multitasking on 68K platforms only.
> // The primary threading model supported under Carbon is the Multiprocessing
> // library, which as of version 2.0 provides a nice set of primitives. Under
> // Mac OS X, the Multiprocessing library is a thin veneer over pthreads.
> //
> // For lack of any really good solutions, I've implemented these mutexes
> // atop the Multiprocessing library. The critical regions employed here
> // support recursive behavior, which is required by Xerces.
> //
> // Please note that, despite this implementation, there are probably other
> // MacOS barriers to actually using Xerces in a multi-threaded environment.
> // Many other parts of your system and/or development environment may not
> // support pre-emption, even under Mac OS X. Examples may include the memory
> // allocator, the Unicode Converter or Utilities, and perhaps the file
> // system (though the FS is better with Multiprocessing as of System 9.0).
> //
> // These routines are provided somewhat speculatively, and with the philosphy
> // that this code, at least, shouldn't be the reason why multithreading
> // doesn't work. Compatibility of this library wrt the other areas described
> // above will be resolved in time.
602,605d598
< void XMLPlatformUtils::closeMutex(void* const mtxHandle)
< {
<     if (!MPLibraryIsLoaded())
<         throw XMLPlatformUtilsException("XMLPlatformUtils::makeMutex -- Multiprocessing library not installed correctly.  Please Install");
607,611c600,604
<     MPSemaphoreID *sema = (MPSemaphoreID*)mtxHandle;
<     if (!sema) return;
<
<     if (noErr != MPDeleteSemaphore(*sema))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::closeMutex -- Error deleting semaphore");
---
> void* XMLPlatformUtils::makeMutex()
> {
>  MPCriticalRegionID criticalRegion = NULL;
>  OSStatus status = MPCreateCriticalRegion(&criticalRegion);
>  return (status == noErr) ? static_cast<void*>(criticalRegion) : NULL;
615c608
< void XMLPlatformUtils::lockMutex(void* const mtxHandle)
---
> void XMLPlatformUtils::closeMutex(void* const mtxHandle)
617,624c610,611
<     if (!MPLibraryIsLoaded())
<         throw XMLPlatformUtilsException("XMLPlatformUtils::makeMutex -- Multiprocessing library not installed correctly.  Please Install");
<
<     MPSemaphoreID *sema = (MPSemaphoreID*)mtxHandle;
<     if (!sema) return;
<
<     if (noErr != MPWaitOnSemaphore(*sema, -1))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::lockMutex -- Error locking semaphore");
---
>  MPCriticalRegionID criticalRegion = reinterpret_cast<MPCriticalRegionID>(mtxHandle);
>  OSStatus status = MPDeleteCriticalRegion(criticalRegion);
628c615
< void* XMLPlatformUtils::makeMutex()
---
> void XMLPlatformUtils::lockMutex(void* const mtxHandle)
630,640c617,618
<     if (!MPLibraryIsLoaded())
<         throw XMLPlatformUtilsException("XMLPlatformUtils::makeMutex -- Multiprocessing library not installed correctly.  Please Install");
<
<     MPSemaphoreID *result = new MPSemaphoreID;
<     if (!result)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::makeMutex -- Error allocating memory for a semaphore");
<
<     if (noErr != MPCreateBinarySemaphore(result))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::makeMutex -- Error Creating semaphore");
<
<     return (void*)result;
---
>  MPCriticalRegionID criticalRegion = reinterpret_cast<MPCriticalRegionID>(mtxHandle);
>  OSStatus status = MPEnterCriticalRegion(criticalRegion, kDurationForever);
646,653c624,625
<     if (!MPLibraryIsLoaded())
<         throw XMLPlatformUtilsException("XMLPlatformUtils::makeMutex -- Multiprocessing library not installed correctly.  Please Install");
<
<     MPSemaphoreID *sema = (MPSemaphoreID*)mtxHandle;
<     if (!sema) return;
<
<     if (noErr != MPSignalSemaphore(*sema))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::unlockMutex -- Error unlocking semaphore");
---
>  MPCriticalRegionID criticalRegion = reinterpret_cast<MPCriticalRegionID>(mtxHandle);
>  OSStatus status = MPExitCriticalRegion(criticalRegion);
658a631,635
> //
> // Atomic manipulation is implemented atop routines that were traditionally
> // part of DriverServices, but are now apparently a part of Carbon. If this
> // selection proves to be invalid, similar routines in OpenTransport could
> // be used instead.
659a637
>
665,673c643,651
<     // Note -- I'm note sure what this method is supposed to do.  I just copied
<     // the code from the linux utils.
<
<     void *retVal = *toFill;
<     if (*toFill == toCompare)
<               *toFill = (void *)newValue;
<     return retVal;
<
<     throw XMLPlatformUtilsException("XMLPlatformUtils::compareAndSwap -- Not Implemented Yet.");
---
>  // Replace *toFill with newValue iff *toFill == toCompare,
>  // returning previous value of *toFill
>
>  Boolean success = CompareAndSwap(
>       reinterpret_cast<UInt32>(toCompare),
>       reinterpret_cast<UInt32>(newValue),
>       reinterpret_cast<UInt32*>(toFill));
>
>     return (success) ? const_cast<void*>(toCompare) : *toFill;
679,690c657
< /*    if (!MPLibraryIsLoaded())
<         throw XMLPlatformUtilsException("XMLPlatformUtils::platformInit -- Multiprocessing library not installed correctly.  Please Install");
<
<     if (noErr != MPEnterCriticalRegion(gCriticalRegion, -1))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::atomicIncrement -- Failed to enter the critical region.");*/
<
<     int result = location++;
<
< /*    if (noErr != MPExitCriticalRegion(gCriticalRegion))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::atomicIncrement -- Failed to exit the critical region.");*/
<
<     return result;
---
>  return IncrementAtomic(reinterpret_cast<long*>(&location));
696,697c663,669
< /*    if (!MPLibraryIsLoaded())
<         throw XMLPlatformUtilsException("XMLPlatformUtils::platformInit -- Multiprocessing library not installed correctly.  Please Install");
---
>  return DecrementAtomic(reinterpret_cast<long*>(&location));
> }
>
>
> // ---------------------------------------------------------------------------
> //  XMLPlatformUtils: Private Static Methods
> // ---------------------------------------------------------------------------
699,700c671,676
<     if (noErr != MPEnterCriticalRegion(gCriticalRegion, -1))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::atomicIncrement -- Failed to enter the critical region.");*/
---
> //
> //  This method handles the MacOS basic init functions.
> //
> void XMLPlatformUtils::platformInit()
> {
>     long value;
702c678,685
<     int result = location--;
---
>     // Figure out if we have the gestalt manager
>     // --we better have by now...this is a pre-system 7 feature!
>     gGestaltAvail =
> #if TARGET_API_MAC_CARBON
>         true;
> #else
>         TrapAvailable(_Gestalt);
> #endif
704,707c687,736
< /*    if (noErr != MPExitCriticalRegion(gCriticalRegion))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::atomicIncrement -- Failed to exit the critical region.");*/
<
<     return result;
---
>     // Figure out which functions we have available
>     if (gGestaltAvail)
>     {
>         if (Gestalt(gestaltFSAttr, &value) == noErr)
>         {
>          gHasFSSpecAPIs = (value & gestaltHasFSSpecCalls) != 0;
>          gHasFS2TBAPIs = (value & gestaltFSSupports2TBVols) != 0;
>          gHasHFSPlusAPIs = (value & gestaltHasHFSPlusAPIs) != 0;
>         }
>     }
>
>     gFileSystemCompatible = gHasFSSpecAPIs;
> }
>
>
> //
> //  This method handles the MacOS basic termination functions.
> //
> void XMLPlatformUtils::platformTerm()
> {
> }
>
>
> // ---------------------------------------------------------------------------
> //  XMLPlatformUtils: Private Static Methods
> // ---------------------------------------------------------------------------
>
> //
> //  This method is called by the platform independent part of this class
> //  during initialization. We have to create the type of net accessor that
> //  we want to use. If none, then just return zero.
> //
> XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
> {
>  // No net accessor on the Mac for now.
>  //
>  // We could:
>  //  Use URLAccess under Carbon and >= 8.6
>  //  Use libwww on Mac OS X
>     return 0;
> }
>
>
> //
> //  This method is called by the platform independent part of this class
> //  when client code asks to have one of the supported message sets loaded.
> //
> XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
> {
>     return new InMemMsgLoader(msgDomain);
709a739,755
>
> //
> //  This method is called very early in the bootstrapping process. This guy
> //  must create a transcoding service and return it. It cannot use any string
> //  methods, any transcoding services, throw any exceptions, etc... It just
> //  makes a transcoding service and returns it, or returns zero on failure.
> //
> XMLTransService* XMLPlatformUtils::makeTransService()
> {
>     return new MacOSUnicodeConverter;
> }
>
>
> //---------------------------------------------------
> // Utility Functions
> //---------------------------------------------------
>
711c757,759
< static bool MySWRoutineAvailable (int trapWord)
---
> #if !TARGET_API_MAC_CARBON
> static bool
> TrapAvailable (UInt16 trapWord)
728a777
> #endif
730,732d778
< // ---------------------------------------------------------------------------
< //  XMLPlatformUtils: Private Static Methods
< // ---------------------------------------------------------------------------
734,737c780,781
< //
< //  This method handles the MacOS basic init functions.
< //
< void XMLPlatformUtils::platformInit()
---
> bool
> XMLParsePathToFSRef(const XMLCh* const pathName, FSRef& ref)
739,752c783,893
<     OSErr myErr;
<     long feature;
<
<     // Figure out if we have the gestalt manager
<     gGestaltAvail = MySWRoutineAvailable(_Gestalt);
<
<     // Figure out if we have the FSspec function to use
<     if (gGestaltAvail)
<     {
<         myErr = Gestalt(gestaltFSAttr, &feature);
<         if (myErr == noErr)
<         {
<             if (feature & gestaltHasFSSpecCalls)
<                 gFileSystemReady = true;
---
>  const XMLCh* p = pathName;
>  const XMLCh* pEnd;
>
>  OSErr err = noErr;
>
>  if (*p == L'/')
>  {
>   // Absolute name: grab the first component as volume name
>
>   // Find the end of the path segment
>   for (pEnd = ++p; *pEnd && *pEnd != L'/'; ++pEnd) ;
>   size_t segLen = pEnd - p;
>
>   // Try to find a volume that matches this name
>   for (ItemCount volIndex = 1; err == noErr; ++volIndex)
>   {
>    HFSUniStr255 hfsStr;
>    hfsStr.length = 0;
>
>    // Get the volume name
>    err = FSGetVolumeInfo(
>       0,
>       volIndex,
>       static_cast<FSVolumeRefNum*>(NULL),
>       0,
>       static_cast<FSVolumeInfo*>(NULL),
>       &hfsStr,
>       &ref
>       );
>
>    // Compare against our path segment
>    if (err == noErr && segLen == hfsStr.length)
>    {
>     const UniChar* a = hfsStr.unicode;
>     const XMLCh* b = p;
>     while (b != pEnd && *a == *b)
>     {
>      ++a;
>      ++b;
>     }
>
>     if (b == pEnd)
>      break;  // we found our volume
>    }
>   }
>
>   p = pEnd;
>  }
>  else
>  {
>   // Relative name, so get the default directory as parent ref
>   FSSpec spec;
>   err = FSMakeFSSpec(0, 0, NULL, &spec);
>   if (err == noErr)
>    err = FSpMakeFSRef(&spec, &ref);
>  }
>
>  // ref now refers to the a parent directory: parse the rest of the path
>  while (err == noErr && *p)
>  {
>   switch (*p)
>   {
>    case L'/':   // Just skip any number of path separators
>     ++p;
>     break;
>
>    case L'.':   // Potentially "current directory" or "parent directory"
>     if (p[1] == L'/' || p[1] == 0)       // "current directory"
>     {
>      ++p;
>      break;
>     }
>     else if (p[1] == L'.' && (p[2] == L'/' || p[2] == 0)) // "parent directory"
>     {
>      p += 2;  // Get the parent of our parent
>
>      FSCatalogInfo catalogInfo;
>      err = FSGetCatalogInfo(
>         &ref,
>                              kFSCatInfoParentDirID,
>                              &catalogInfo,
>                              static_cast<HFSUniStr255*>(NULL),
>                              static_cast<FSSpec*>(NULL),
>                              &ref
>                              );
>
>                     // Check that we didn't go too far
>                  if (err != noErr || catalogInfo.parentDirID == fsRtParID)
>                   return false;
>
>                  break;
>     }
>     else // some other sequence of periods...fall through and treat as segment
>      ;
>
>    default:
>     // Find the end of the path segment
>     for (pEnd = p; *pEnd && *pEnd != L'/'; ++pEnd) ;
>
>     // pEnd now points either to '/' or NUL
>     // Create a new ref using this path segment
>     err = FSMakeFSRefUnicode(
>        &ref,
>        pEnd - p,
>                             reinterpret_cast<UniChar*>(const_cast<XMLCh*>(p)),
>                             kTextEncodingUnknown,
>                             &ref
>                             );
>
>                 p = pEnd;
>                 break;
753a895,1258
>  }
>
>  return err == noErr;
> }
>
>
> bool
> XMLParsePathToFSSpec(const XMLCh* const pathName, FSSpec& spec)
> {
>  // Transcode the path into ascii
>  const char* p = XMLString::transcode(pathName);
>  ArrayJanitor<const char> janPath(p);
>  const char* pEnd;
>
>  OSErr err = noErr;
>  Str255 name;  // Must be long enough for a partial pathname consisting of two segments (64 bytes)
>
>  if (*p == '/')
>  {
>   // Absolute name: grab the first component as volume name
>
>   // Find the end of the path segment
>   for (pEnd = ++p; *pEnd && *pEnd != '/'; ++pEnd) ;
>   size_t segLen = pEnd - p;
>
>   // Try to find a volume that matches this name
>   for (ItemCount volIndex = 1; err == noErr; ++volIndex)
>   {
>    FSVolumeRefNum volRefNum;
>
>    if (gHasFS2TBAPIs)
>    {
>     XVolumeParam xVolParam;
>     name[0] = 0;
>     xVolParam.ioNamePtr  = name;
>     xVolParam.ioVRefNum  = 0;
>     xVolParam.ioXVersion = 0;
>     xVolParam.ioVolIndex = volIndex;
>     err = PBXGetVolInfoSync(&xVolParam);
>     volRefNum = xVolParam.ioVRefNum;
>    }
>    else
>    {
> #if !TARGET_API_MAC_CARBON
>     HParamBlockRec hfsParams;
>     name[0] = 0;
>     hfsParams.volumeParam.ioNamePtr  = name;
>     hfsParams.volumeParam.ioVRefNum  = 0;
>     hfsParams.volumeParam.ioVolIndex = volIndex;
>     err = PBHGetVInfoSync(&hfsParams);
>     volRefNum = hfsParams.volumeParam.ioVRefNum;
> #else
>     err = nsvErr;
> #endif
>    }
>
>    // Compare against our path segment
>    if (err == noErr && segLen == StrLength(name))
>    {
>     ConstStringPtr a = name + 1;
>     const char* b = p;
>     while (b != pEnd && (*a == *b))
>     {
>      ++a;
>      ++b;
>     }
>
>     if (b == pEnd)
>     {
>      // we found our volume: fill in the spec
>      err = FSMakeFSSpec(volRefNum, fsRtDirID, NULL, &spec);
>      break;
>     }
>    }
>   }
>
>   p = pEnd;
>  }
>  else
>  {
>   // Relative name, so get the default directory as parent spec
>   err = FSMakeFSSpec(0, 0, NULL, &spec);
>  }
>
>  // We now have a parent directory in the spec.
>  while (err == noErr && *p)
>  {
>   switch (*p)
>   {
>    case '/':   // Just skip any number of path separators
>     ++p;
>     break;
>
>    case L'.':   // Potentially "current directory" or "parent directory"
>     if (p[1] == '/' || p[1] == 0)      // "current directory"
>     {
>      ++p;
>      break;
>     }
>     else if (p[1] == '.' && (p[2] == '/' || p[2] == 0)) // "parent directory"
>     {
>      p += 2;  // Get the parent of our parent
>
>      CInfoPBRec catInfo;
>      catInfo.dirInfo.ioNamePtr = NULL;
>      catInfo.dirInfo.ioVRefNum = spec.vRefNum;
>      catInfo.dirInfo.ioFDirIndex = -1;
>      catInfo.dirInfo.ioDrDirID = spec.parID;
>      err = PBGetCatInfoSync(&catInfo);
>
>                     // Check that we didn't go too far
>                  if (err != noErr || catInfo.dirInfo.ioDrParID == fsRtParID)
>                   return false;
>
>                  // Update our spec
>                  if (err == noErr)
>                   err = FSMakeFSSpec(spec.vRefNum, catInfo.dirInfo.ioDrParID, NULL, &spec);
>
>                  break;
>     }
>     else // some other sequence of periods...fall through and treat as segment
>      ;
>
>    default:
>     {
>      // Find the end of the path segment
>      for (pEnd = p; *pEnd && *pEnd != '/'; ++pEnd) ;
>
>      // Check for name length overflow
>      if (pEnd - p > 31)
>       return false;
>
>      // Make a partial pathname from our current spec to the new object
>      unsigned char* partial = &name[1];
>
>      *partial++ = ':';       // Partial leads with :
>      const unsigned char* specName = spec.name; // Copy in spec name
>      for (int specCnt = *specName++; specCnt > 0; --specCnt)
>       *partial++ = *specName++;
>
>      *partial++ = ':';       // Separator
>      while (p != pEnd)       // Copy in new element
>       *partial++ = *p++;
>
>      name[0] = partial - &name[1];    // Set the name length
>
>      // Update the spec
>      err = FSMakeFSSpec(spec.vRefNum, spec.parID, name, &spec);
>     }
>     break;
>   }
>  }
>
>  return err == noErr;
> }
>
>
> XMLCh*
> XMLCreateFullPathFromRef(const FSRef& startingRef)
> {
>  OSErr err = noErr;
>  FSCatalogInfo catalogInfo;
>  HFSUniStr255 name;
>  FSRef ref = startingRef;
>
>  const size_t kBufSize = 512;
>  XMLCh buf[kBufSize];
>  size_t bufPos   = kBufSize;
>  size_t bufCnt   = 0;
>
>  XMLCh* result = NULL;
>  size_t resultLen = 0;
>
>  buf[--bufPos] = L'\0';
>  ++bufCnt;
>
>  try  // help in cleaning up since ArrayJanitor doesn't handle assignment ;(
>  {
>   do
>   {
>    err = FSGetCatalogInfo(
>       &ref,
>       kFSCatInfoParentDirID,
>       &catalogInfo,
>       &name,
>       static_cast<FSSpec*>(NULL),
>       &ref
>       );
>
>    if (err == noErr)
>    {
>     // If there's not room in our static buffer for the new
>     // name plus separator, dump it to the dynamic result buffer.
>     if (bufPos < name.length + 1)
>     {
>      XMLCh* temp = new XMLCh[bufCnt + resultLen];
>
>      // Copy in the static buffer
>      memcpy(temp, &buf[bufPos], bufCnt * sizeof(XMLCh));
>
>      // Copy in the old buffer
>      if (resultLen > 0)
>       memcpy(temp + bufCnt, result, resultLen);
>
>      delete [] result;
>      result = temp;
>      resultLen += bufCnt;
>
>      bufPos = kBufSize;
>      bufCnt = 0;
>     }
>
>     // Prepend our new name and a '/'
>     bufPos -= name.length;
>     memcpy(&buf[bufPos], name.unicode, name.length * sizeof(UniChar));
>     buf[--bufPos] = L'/';
>     bufCnt += (name.length + 1);
>    }
>   }
>   while (err == noErr && catalogInfo.parentDirID != fsRtParID);
>
>   // Composite existing buffer with any previous result buffer
>   XMLCh* temp = new XMLCh[bufCnt + resultLen];
>
>   // Copy in the static buffer
>   memcpy(temp, &buf[bufPos], bufCnt * sizeof(XMLCh));
>
>   // Copy in the old buffer
>   if (resultLen > 0)
>    memcpy(temp + bufCnt, result, resultLen * sizeof(XMLCh));
>
>   delete [] result;
>   result = temp;
>  }
>  catch (...)
>  {
>   delete [] result;
>   throw;
>  }
>
>  return result;
> }
>
>
> XMLCh*
> XMLCreateFullPathFromSpec(const FSSpec& startingSpec)
> {
>  OSErr err = noErr;
>  FSSpec spec = startingSpec;
>
>  const size_t kBufSize = 512;
>  char buf[kBufSize];
>  size_t bufPos   = kBufSize;
>  size_t bufCnt   = 0;
>
>  char* result = NULL;
>  size_t resultLen = 0;
>
>  buf[--bufPos] = '\0';
>  ++bufCnt;
>
>  try  // help in cleanup since array janitor can't handle assignment ;(
>  {
>   short index = 0;
>   do
>   {
>    CInfoPBRec catInfo;
>    catInfo.dirInfo.ioNamePtr = spec.name;
>    catInfo.dirInfo.ioVRefNum = spec.vRefNum;
>    catInfo.dirInfo.ioFDirIndex = index;
>    catInfo.dirInfo.ioDrDirID = spec.parID;
>    err = PBGetCatInfoSync(&catInfo);
>
>    if (err == noErr)
>    {
>     size_t nameLen = StrLength(spec.name);
>
>     // If there's not room in our static buffer for the new
>     // name plus separator, dump it to the dynamic result buffer.
>     if (bufPos < nameLen + 1)
>     {
>      char* temp = new char[bufCnt + resultLen];
>
>      // Copy in the static buffer
>      memcpy(temp, &buf[bufPos], bufCnt);
>
>      // Copy in the old buffer
>      if (resultLen > 0)
>       memcpy(temp + bufCnt, result, resultLen);
>
>      delete [] result;
>      result = temp;
>      resultLen += bufCnt;
>
>      bufPos = kBufSize;
>      bufCnt = 0;
>     }
>
>     // Prepend our new name and a '/'
>     bufPos -= nameLen;
>     memcpy(&buf[bufPos], &spec.name[1], nameLen);
>     buf[--bufPos] = '/';
>     bufCnt += (nameLen + 1);
>
>     // From here on out, ignore the input file name
>     index = -1;
>
>     // Move up to the parent
>     spec.parID = catInfo.dirInfo.ioDrParID;
>    }
>   }
>   while (err == noErr && spec.parID != fsRtParID);
>
>   // Composite existing buffer with any previous result buffer
>   char* temp = new char[bufCnt + resultLen];
>
>   // Copy in the static buffer
>   memcpy(temp, &buf[bufPos], bufCnt);
>
>   // Copy in the old buffer
>   if (resultLen > 0)
>    memcpy(temp + bufCnt, result, resultLen);
>
>   delete [] result;
>   result = temp;
>   resultLen += bufCnt;
>  }
>  catch (...)
>  {
>   delete [] result;
>   throw;
>  }
>
>  // Cleanup and transcode to unicode
>  ArrayJanitor<char> jan(result);
>  return XMLString::transcode(result);
> }
>
>
> /*
>  XMLResFile is pretty twisted and not currently used.
>
> static const char *resBaseStr = "/Access The Resource Fork Instead of the data fork?";
>
>
> FileHandle XMLPlatformUtils::openFile(const char* const fileName)
> {
>      FileHandle file = 0;
>      int isRes = 0;
>
>     // Check to make sure the file system is in a state where we can use it
>      if (!gFileSystemReady)
>       ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile(const char* const) -- File system not ready."
>         //          "  Maybe missing gestalt or no support for FSSpec's.");
>
>     if (strlen(fileName) >= strlen(resBaseStr))
>         if (strstr(fileName, resBaseStr) == fileName)
>             isRes = 1;
>
>     if (isRes == 0)
>     {
>         file = new XMLMacFile();
>         file->open(fileName);
754a1260,1270
>     else
>     {
>         file = new XMLResFile();
>         file->open(&fileName[strlen(resBaseStr)]);
>     }
>     if (file == 0)
>       ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile(const char* const) -- Failed to allocate file object.");
>     return file;
> }
>
756,757c1272,1275
< /*    if (!MPLibraryIsLoaded())
<         throw XMLPlatformUtilsException("XMLPlatformUtils::platformInit -- Multiprocessing library not installed correctly.  Please Install");
---
> //----------------------------------------------------------------------------
> // XMLResFile methods
> //----------------------------------------------------------------------------
> XMLResFile::XMLResFile();
759,761d1276
<     if (noErr != MPCreateCriticalRegion(&gCriticalRegion))
<         throw XMLPlatformUtilsException("XMLPlatformUtils::platformInit -- Error creating critical section");*/
< }
763,770c1278
< //
< //  This is the first thing called during init. Each platform needs to set
< //  up the path to the Internationalization code.
< //
< //  NOTE:   It CANNOT use an String class methods, because that class has not
< //          be set up yet.
< //
< void XMLPlatformUtils::setupIntlPath()
---
> void XMLResFile::open(const char* const resInfo)
772,779c1280,1284
< //    fgIntlPath = "Macintosh HD:Desktop Folder:xml4csrc2_2_0:intlFiles:data:locales:";
<     short fileRef;
<     unsigned char pStr[300];
<     OSErr myErr;
<     OSType textCode = 'TEXT';
< //    StandardFileReply result;
< //    FInfo fileInfo;
<     long feature;
---
>     char option[32], value[32], command[70];
>     int cmdEnd = 0, cmdStart = 0;
>     int optEnd = 0, sep;
>     int mode = -1;
>     int typeValid = 0;
781,782c1286,1287
<     if (fgIntlPath != 0)
<         return;
---
>     if (!strchr(&resInfo[cmdStart], '/'))
>         ThrowXML(XMLPlatformUtilsException, XML4CExcepts::URL_MalformedURL);
784,788c1289
<     // Figure out if we have the gestalt manager
<     gGestaltAvail = MySWRoutineAvailable(_Gestalt);
<
<     // Figure out if we have the FSspec function to use
<     if (gGestaltAvail)
---
>     while(resInfo[cmdEnd] != '/')
790,791c1291,1326
<         myErr = Gestalt(gestaltFSAttr, &feature);
<         if (myErr == noErr)
---
>         if (strchr(&resInfo[cmdStart], '&') < strchr(&resInfo[cmdStart], '/') && strchr(&resInfo[cmdStart], '&') != 0)
>             cmdEnd = strchr(&resInfo[cmdStart], '&') - resInfo - 1;
>         else
>             cmdEnd = strchr(&resInfo[cmdStart], '/') - resInfo - 1;
>
>         if (cmdEnd - cmdStart > 68)
>          ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>           //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- resource option too long (>68 chars)");
>
>         memcpy(command, &resInfo[cmdStart], cmdEnd - cmdStart + 1);
>         command[cmdEnd - cmdStart + 1] = 0;
>         if (!strchr(command, '='))
>          ThrowXML(XMLPlatformUtilsException, XML4CExcepts::URL_MalformedURL);
>             //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Malformed resource locater");
>
>         sep = strchr(command, '=') - command;
>         memcpy(option, command, sep);
>         option[sep] = 0;
>         memcpy(value, &command[sep+1], strlen(command) - sep);
>
>         if (!strcmp(option, "mode"))
>         {
>             if (!strcmp(value, "by_id"))
>                 mode = 1;
>             else if (!strcmp(value, "by_id1"))
>                 mode = 2;
>             else if (!strcmp(value, "by_name"))
>                 mode = 3;
>             else if (!strcmp(value, "by_name1"))
>                 mode = 4;
>             else
>           ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>                 //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- 'mode' has to be 'by_id' or 'by_id1' or 'by_name' or 'by_name1'");
>
>         }
>         if (!strcmp(option, "type"))
793,794c1328,1336
<             if (feature & gestaltHasFSSpecCalls)
<                 gFileSystemReady = true;
---
>             if (strlen(value) != 4)
>           ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>                 //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- 'type' has to be four characters long");
>             typeValid = 1;
>             type = 0;
>             type += value[0] << 24;
>             type += value[1] << 16;
>             type += value[2] << 8;
>             type += value[3];
795a1338,1340
>
>         cmdStart = cmdEnd + 2;
>         cmdEnd++;
797,803c1342,1350
<
<     // Check to make sure the file system is in a state where we can use it
<     if (!gFileSystemReady)
<         throw XMLPlatformUtilsException("XMLPlatformUtils::setupIntlPath -- File system not ready."
<                   "  Maybe missing gestalt or no support for FSSpec's.");
<
<     if (noErr == HOpenDF(0, 0, "\p:locales:convrtrs.txt", fsRdWrPerm, &fileRef))
---
>
>     if (mode == 0)
>         ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Malformed resource locater requires a 'mode'");
>     if (typeValid == 0)
>         ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Malformed resource locater requires a 'type'");
>
>     switch(mode)
805,806c1352,1358
<         if (noErr != FSClose(fileRef))
<             throw XMLPlatformUtilsException("XMLPlatformUtils::setupIntlPath -- ERROR");
---
>         case 1: case 2:
>             id = atol(&resInfo[cmdEnd+1]);
>             if (mode == 1)
>                 data = GetResource(type, id);
>             else
>                 data = Get1Resource(type, id);
>             break;
808,809c1360,1370
<         fgIntlPath = ":locales:";
<         return;
---
>         case 3: case 4:
>             if (strlen(&resInfo[cmdEnd]) >= 255)
>           ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>                //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Resource names have to be 255 characters or less");
>             strcpy((char*)name, &resInfo[cmdEnd]);
>             name[0] = strlen((char*)&name[1]);
>             if (mode == 3)
>                 data = GetNamedResource(type, name);
>             else
>                 data = Get1NamedResource(type, name);
>             break;
812,823c1373,1383
<     throw XMLPlatformUtilsException("XMLPlatformUtils::setupIntlPath -- Couldn't find data files");
< /*    if (noErr != StandardGetFile("\pPlease locate the convrtrs.txt file in the locales directory:", 0, 1, &textCode, &result))
<             throw XMLPlatformUtilsException("XMLPlatformUtils::setupIntlPath -- StandardGetFile failed");
<
<     if (result.sfGood == 0)
<             throw XMLPlatformUtilsException("XMLPlatformUtils::setupIntlPath -- failed to locate locale files");
<
<     fgIntlPath = new char[result.sfFile.[0]+1];
<     fgIntlPath[result.sfFile.[0]] = 0;
<     memcpy(fgIntlPath, result.sfFile., result.sfFile.[0]);
<     cout << fgIntlPath << endl;*/
<             //throw XMLPlatformUtilsException("XMLPlatformUtils::setupIntlPath -- failed to load file info");
---
>     if (ResError() != noErr)
>       ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Error opening resource");
>
>     GetResInfo(data, &id, &type, name);
>     len = GetResourceSizeOnDisk(data);
>     if (ResError() != noErr)
>       ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotOpenFile);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::openFile -- Error loading resource info");
>
>     valid = 1;
826,829c1386
< // These functions are needed because MacOS doesn't define them
< // even though they are used.
< // Compare lexigraphically two strings
< static char tolower(char c)
---
> unsigned int XMLResFile::read(const unsigned int buffLen, XMLByte* const buff)
831,833c1388,1395
<     if (c >= 'A' && c <= 'Z')
<         return c + 'a' - 'A';
<     return c;
---
>     unsigned int totAvail = len - pos;
>     unsigned int numRead = (buffLen >= totAvail) ? totAvail : buffLen;
>
>     HLock(data);
>     memcpy(buff, *data, numRead);
>     HUnlock(data);
>     pos += numRead;
>     return numRead;
836c1398
< int stricmp(const char *s1, const char *s2)
---
> void XMLResFile::close()
838,846c1400,1412
<     char c1, c2;
<     while (1)
<     {
<         c1 = tolower(*s1++);
<         c2 = tolower(*s2++);
<         if (c1 < c2) return -1;
<         if (c1 > c2) return 1;
<         if (c1 == 0) return 0;
<     }
---
>     if (!valid)
>       ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotCloseFile);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::curFilePos -- Not a valid file");
>     ReleaseResource(data);
>     valid = 0;
> }
>
> unsigned int XMLResFile::currPos()
> {
>     if (!valid)
>       ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotGetCurPos);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::curFilePos -- Not a valid file");
>     return pos;
849c1415,1421
< // Compare lexigraphically two strings up to a max length
---
> void XMLResFile::reset()
> {
>     if (!valid)
>       ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotResetFile);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::resetFile -- Not a valid file");
>     pos = 0;
> }
851c1423
< int strnicmp(const char *s1, const char *s2, int n)
---
> unsigned int XMLResFile::size()
853,863c1425,1428
<     int i;
<     char c1, c2;
<     for (i=0; i<n; i++)
<     {
<         c1 = tolower(*s1++);
<         c2 = tolower(*s2++);
<         if (c1 < c2) return -1;
<         if (c1 > c2) return 1;
<         if (!c1) return 0;
<     }
<     return 0;
---
>     if (!valid)
>       ThrowXML(XMLPlatformUtilsException, XML4CExcepts::File_CouldNotGetSize);
>         //throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize -- Not a valid file");
>     return len;
866c1431
< void XMLPlatformUtils::platformTerm()
---
> XMLResFile::~XMLResFile()
868c1433,1434
<     // We don't have any termination requirements at this time
---
>     if (valid)
>         close();
869a1436,1438
> */
>
>


RE: Contributing Mac OS port of Xerces

Posted by Daniel Schroeder <da...@mozquito.com>.
> I'm contributing the following Mac OS port of Xerces.

I think our Mac developer is going to love you for this!

Many, many thanks!

  Daniel

-- ------------------------------
Daniel Schroder (daniel@mozquito.com)
Senior Software Engineer
Stack Overflow AG