jberry      2003/02/22 20:41:26

  Modified:    c/src/xercesc/util/Platforms/MacOS MacOSPlatformUtils.cpp
                        MacOSPlatformUtils.hpp
  Added:       c/src/xercesc/util/Platforms/MacOS MacAbstractFile.hpp
                        MacCarbonFile.cpp MacCarbonFile.hpp
                        MacPosixFile.cpp MacPosixFile.hpp
  Log:
  Improvements to Mac OS port:
   - Refactor Mac OS file handling into distinct files per file type.
   - Add Posix file handling to use posix file apis directly where possible.
   - Carbon file access is now used only where posix files aren't available.
   - Tweaks to FSSpec/FSRef routines to handle directories better.
  
  Revision  Changes    Path
  1.11      +124 -402  
xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacOSPlatformUtils.cpp
  
  Index: MacOSPlatformUtils.cpp
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacOSPlatformUtils.cpp,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- MacOSPlatformUtils.cpp    6 Dec 2002 16:41:10 -0000       1.10
  +++ MacOSPlatformUtils.cpp    23 Feb 2003 04:41:26 -0000      1.11
  @@ -93,6 +93,8 @@
   #include <xercesc/util/XMLUni.hpp>
   #include <xercesc/util/XMLString.hpp>
   #include <xercesc/util/Platforms/MacOS/MacOSPlatformUtils.hpp>
  +#include <xercesc/util/Platforms/MacOS/MacCarbonFile.hpp>
  +#include <xercesc/util/Platforms/MacOS/MacPosixFile.hpp>
   
   #if (defined(XML_USE_INMEMORY_MSGLOADER) || defined(XML_USE_INMEM_MESSAGELOADER))
      #include <xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
  @@ -116,11 +118,6 @@
   
   XERCES_CPP_NAMESPACE_BEGIN
   
  -//----------------------------------------------------------------------------
  -//   Local Constants
  -//----------------------------------------------------------------------------
  -const std::size_t kMaxStaticPathChars = 512;         // Size of our statically 
allocated path buffers
  -
   
   //----------------------------------------------------------------------------
   // Function Prototypes
  @@ -136,9 +133,6 @@
   bool XMLParsePathToFSRef_Classic(const XMLCh* const pathName, FSRef& ref);
   bool XMLParsePathToFSSpec_Classic(const XMLCh* const pathName, FSSpec& spec);
   
  -std::size_t TranscodeUniCharsToUTF8(UniChar* src, char* dst, std::size_t srcCnt, 
std::size_t maxChars);
  -std::size_t TranscodeUTF8ToUniChars(char* src, UniChar* dst, std::size_t maxChars);
  -
   
   //----------------------------------------------------------------------------
   //  Local Data
  @@ -171,336 +165,18 @@
   //
   // gHasMPAPIs
   //    True if the Multiprocessing APIs are available.
  +//
  +// gUsePosixFiles
  +//   True if we're using XMLMacPosixFile rather than XMLMacCarbonFile.
   //----------------------------------------------------------------------------
  -static bool gFileSystemCompatible    = false;
  -static bool gHasFSSpecAPIs                   = false;
  -static bool gHasFS2TBAPIs                    = false;
  -static bool gHasHFSPlusAPIs                  = false;
  -static bool gHasFSPathAPIs                   = false;
  -static bool gPathAPIsUsePosixPaths   = false;
  -static bool gHasMPAPIs                               = false;
  -
  -
  -//----------------------------------------------------------------------------
  -// XMLMacFile methods
  -//----------------------------------------------------------------------------
  -
  -unsigned int
  -XMLMacFile::currPos()
  -{
  -    OSErr err = noErr;
  -    unsigned int pos = 0;
  -
  -    if (!mFileValid)
  -        ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  -
  -    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;
  -    }
  -
  -    if (err != noErr)
  -        ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  -
  -    return pos;
  -}
  -
  -
  -void
  -XMLMacFile::close()
  -{
  -    OSErr err = noErr;
  -    if (!mFileValid)
  -        ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  -
  -    if (gHasHFSPlusAPIs)
  -        err = FSCloseFork(mFileRefNum);
  -    else
  -        err = FSClose(mFileRefNum);
  -
  -    mFileValid = false;
  -
  -    if (err != noErr)
  -        ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  -}
  -
  -
  -unsigned int
  -XMLMacFile::size()
  -{
  -    OSErr err = noErr;
  -    unsigned int len = 0;
  -
  -    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);
  -
  -    return len;
  -}
  -
  -
  -void
  -XMLMacFile::openWithPermission(const XMLCh* const fileName, int macPermission)
  -{
  -    OSErr err = noErr;
  -
  -    if (mFileValid)
  -        ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, 
fileName);
  -
  -    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, 
macPermission, &mFileRefNum);
  -    }
  -    else
  -    {
  -        FSSpec spec;
  -        if (!XMLParsePathToFSSpec(fileName, spec))
  -            err = fnfErr;
  -
  -        if (err == noErr)
  -            err = FSpOpenDF(&spec, macPermission, &mFileRefNum);
  -    }
  -
  -    if (err != noErr)
  -        ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, 
fileName);
  -
  -    mFileValid = true;
  -}
  -
  -
  -void
  -XMLMacFile::create(const XMLCh* const filePath)
  -{
  -    OSErr err = noErr;
  -
  -    //       Split path into directory and filename components
  -    int posSlash = XMLString::lastIndexOf(filePath, '/', 
XMLString::stringLen(filePath) - 1);
  -    int posName = (posSlash == -1) ? 0 : posSlash+1;
  -
  -    const XMLCh* namePtr = filePath + posName;
  -    int nameLen = XMLString::stringLen(namePtr);
  -
  -    //       Make a temporary string of the directory
  -    ArrayJanitor<XMLCh> dirPath(new XMLCh[namePtr - filePath + 1]);
  -    XMLString::subString(dirPath.get(), filePath, 0, posName);
  -
  -    //       Create the file as appropriate for API set
  -    if (gHasHFSPlusAPIs)
  -    {
  -     //      HFS+
  -        FSRef ref;
  -
  -        //   If we find an existing file, delete it
  -        if (XMLParsePathToFSRef(filePath, ref))
  -            FSDeleteObject(&ref);
  -
  -        //   Get a ref to the parent directory
  -        if (!XMLParsePathToFSRef(dirPath.get(), ref))
  -            err = fnfErr;
  -
  -        //   Create a new file using the unicode name
  -        if (err == noErr)
  -        {
  -            UniChar uniName[256];
  -            err = FSCreateFileUnicode(
  -                    &ref,
  -                    nameLen, CopyXMLChsToUniChars(namePtr, uniName, nameLen, 
sizeof(uniName)),
  -                    0, NULL, NULL, NULL);
  -        }
  -    }
  -    else
  -    {
  -     //      HFS
  -        FSSpec spec;
  -
  -        //   If we find an existing file, delete it
  -        if (XMLParsePathToFSSpec(filePath, spec))
  -            FSpDelete(&spec);
  -
  -        //   Get a spec to the parent directory
  -        if (!XMLParsePathToFSSpec(dirPath.get(), spec))
  -            err = fnfErr;
  -
  -        //   Check that the new name is not too long for HFS
  -        if (err == noErr && nameLen > 31)
  -            err = errFSNameTooLong;
  -
  -        if (err == noErr)
  -        {
  -            //       Transcode the unicode name to native encoding
  -            ArrayJanitor<const char> nativeName(XMLString::transcode(namePtr));
  -
  -            // Make a partial pathname from our current spec (parent directory) to 
the new file
  -            unsigned char name[31 * 2 + 1 * 2 + 1];
  -            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++ = ':';                         // Path component separator
  -            char c;
  -            for (const char* p = nativeName.get(); (c = *p++) != 0; ) // Copy in 
new element
  -                *partial++ = (c == ':') ? '/' : c;           // Convert : to /
  -
  -            name[0] = partial - &name[1];   // Set the pascal string name length
  -
  -            //       Update the spec: this will probably return fnfErr
  -            //                                        (since we just deleted any 
existing file)
  -            err = FSMakeFSSpec(spec.vRefNum, spec.parID, name, &spec);
  -
  -            //       Create the file from the spec
  -            err = FSpCreate(&spec, '??\??', 'TEXT', smSystemScript);
  -        }
  -    }
  -
  -    //       Fail if we didn't create the file
  -    if (err != noErr)
  -    {
  -        ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  -        //ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  -    }
  -}
  -
  -
  -void
  -XMLMacFile::open(const XMLCh* const fileName)
  -{
  -    openWithPermission(fileName, fsRdPerm);
  -}
  -
  -
  -void
  -XMLMacFile::openFileToWrite(const XMLCh* const fileName)
  -{
  -    create(fileName);
  -    openWithPermission(fileName, fsRdWrPerm);
  -}
  -
  -
  -unsigned int
  -XMLMacFile::read(const unsigned int toRead, XMLByte* const toFill)
  -{
  -    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;
  -}
  -
  -
  -void
  -XMLMacFile::write(const long byteCount, const XMLByte* const buffer)
  -{
  -    long bytesWritten = 0;
  -    OSErr err = noErr;
  -
  -    if (byteCount <= 0 || buffer == NULL)
  -        return;
  -
  -    if (!mFileValid)
  -    {
  -        ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  -    }
  -
  -    if (gHasHFSPlusAPIs)
  -    {
  -        ByteCount actualCount;
  -        err = FSWriteFork(mFileRefNum, fsFromMark, 0, byteCount, buffer, 
&actualCount);
  -        bytesWritten = actualCount;
  -    }
  -    else
  -    {
  -        long count = byteCount;
  -        err = FSWrite(mFileRefNum, &count, buffer);
  -        bytesWritten = count;
  -    }
  -
  -    if ((err != noErr && err != eofErr) || (bytesWritten != byteCount))
  -    {
  -        ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  -    }
  -}
  -
  -
  -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);
  -}
  -
  -
  -XMLMacFile::~XMLMacFile()
  -{
  -    if (mFileValid)
  -        close();
  -}
  +bool gFileSystemCompatible   = false;
  +bool gHasFSSpecAPIs                  = false;
  +bool gHasFS2TBAPIs                   = false;
  +bool gHasHFSPlusAPIs         = false;
  +bool gHasFSPathAPIs                  = false;
  +bool gPathAPIsUsePosixPaths  = false;
  +bool gHasMPAPIs                              = false;
  +bool gUsePosixFiles                  = false;
   
   
   // ---------------------------------------------------------------------------
  @@ -580,8 +256,13 @@
   FileHandle
   XMLPlatformUtils::openFile(const char* const fileName)
   {
  -    ArrayJanitor<const XMLCh> xmlPath(XMLString::transcode(fileName));
  -    return openFile(xmlPath.get());
  +    // Check to make sure the file system is in a state where we can use it
  +    if (!gFileSystemCompatible)
  +        ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, 
fileName);
  +
  +    Janitor<XMLMacAbstractFile> file(XMLMakeMacFile());
  +    
  +    return (file->open(fileName, false)) ? file.release() : NULL;
   }
   
   
  @@ -592,18 +273,22 @@
       if (!gFileSystemCompatible)
           ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, 
fileName);
   
  -    Janitor<XMLMacAbstractFile> file(new XMLMacFile());
  -    file->open(fileName);
  +    Janitor<XMLMacAbstractFile> file(XMLMakeMacFile());
   
  -    return file.release();
  +    return (file->open(fileName, false)) ? file.release() : NULL;
   }
   
   
   FileHandle
   XMLPlatformUtils::openFileToWrite(const char* const fileName)
   {
  -    ArrayJanitor<const XMLCh> xmlPath(XMLString::transcode(fileName));
  -    return openFileToWrite(xmlPath.get());
  +    // Check to make sure the file system is in a state where we can use it
  +    if (!gFileSystemCompatible)
  +        ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, 
fileName);
  +
  +    Janitor<XMLMacAbstractFile> file(XMLMakeMacFile());
  +
  +    return (file->open(fileName, true)) ? file.release() : NULL;
   }
   
   
  @@ -614,10 +299,9 @@
       if (!gFileSystemCompatible)
           ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, 
fileName);
   
  -    Janitor<XMLMacAbstractFile> file(new XMLMacFile());
  -    file->openFileToWrite(fileName);
  +    Janitor<XMLMacAbstractFile> file(XMLMakeMacFile());
   
  -    return file.release();
  +    return (file->open(fileName, true)) ? file.release() : NULL;
   }
   
   
  @@ -815,21 +499,13 @@
   // 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
  +// For lack of any really universal 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.
  +// Please note that, despite this implementation, there may be other barriers
  +// to using Xerces in a multithreaded environment. The memory allocator
  +// under Mac OS 9, for instance, is not thread safe.
   // ---------------------------------------------------------------------------
   
   void*
  @@ -892,9 +568,7 @@
   //  Miscellaneous synchronization methods
   //
   // 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.
  +// part of DriverServices, but are now a part of Carbon.
   // ---------------------------------------------------------------------------
   
   void*
  @@ -949,7 +623,7 @@
        long value = 0;
   
        //      Detect available functions
  -
  +     
       //       Look for file system services
       if (noErr == Gestalt(gestaltFSAttr, &value))
       {
  @@ -963,14 +637,26 @@
           gHasFSPathAPIs               = false;
           #endif
   
  -        gPathAPIsUsePosixPaths = gHasFSPathAPIs && (value & (1 << 
gestaltFSUsesPOSIXPathsForConversion));
  +        gPathAPIsUsePosixPaths = gHasFSPathAPIs
  +                                                              && (value & (1 << 
gestaltFSUsesPOSIXPathsForConversion));
       }
   
  -    //       Look for MP
  -     gHasMPAPIs                              = MPLibraryIsLoaded();
  -
        //      We require FSSpecs at a minimum
       gFileSystemCompatible    = gHasFSSpecAPIs;
  +
  +     //      Determine which file system to use (posix or carbon file access)
  +     //      If we're using Metrowerks MSL, we surely don't want posix paths,
  +     //      as MSL doesn't use them.
  +     #if __MSL__ && (__MSL__ < 0x08000 || _MSL_CARBON_FILE_APIS)
  +     gUsePosixFiles                  = false;
  +     #else
  +     gUsePosixFiles                  = noErr == Gestalt(gestaltSystemVersion, 
&value)
  +                                                       && value >= 0x00001000
  +                                                       ;
  +     #endif
  +
  +    //       Look for MP
  +     gHasMPAPIs                              = MPLibraryIsLoaded();
   }
   
   
  @@ -1149,6 +835,22 @@
   }
   
   
  +//   Factory method to make an appropriate subclass of XMLMacAbstractFile
  +//   for our use
  +XMLMacAbstractFile*
  +XMLMakeMacFile(void)
  +{
  +     XMLMacAbstractFile* result = NULL;
  +     
  +     if (gUsePosixFiles)
  +             result = new XMLMacPosixFile;
  +     else
  +             result = new XMLMacCarbonFile;
  +             
  +     return result;
  +}
  +
  +
   bool
   XMLParsePathToFSRef(const XMLCh* const pathName, FSRef& ref)
   {
  @@ -1188,12 +890,12 @@
        std::size_t pathLen = XMLString::stringLen(pathName);
   
       //       Transcode XMLCh into UniChar
  -     UniChar uniBuf[kMaxStaticPathChars];
  -     CopyXMLChsToUniChars(pathName, uniBuf, pathLen, kMaxStaticPathChars);
  +     UniChar uniBuf[kMaxMacStaticPathChars];
  +     CopyXMLChsToUniChars(pathName, uniBuf, pathLen, kMaxMacStaticPathChars);
        
        //      Transcode Unicode to UTF-8
  -     char utf8Buf[kMaxStaticPathChars];
  -     pathLen = TranscodeUniCharsToUTF8(uniBuf, utf8Buf, pathLen, 
kMaxStaticPathChars-1);
  +     char utf8Buf[kMaxMacStaticPathChars];
  +     pathLen = TranscodeUniCharsToUTF8(uniBuf, utf8Buf, pathLen, 
kMaxMacStaticPathChars-1);
        
        //      Terminate the path
        char* p = utf8Buf;
  @@ -1204,7 +906,7 @@
        if (*p != '/')
        {
                //      Right justify the user path to make room for the pre-pended 
path
  -             std::memmove(p + kMaxStaticPathChars - pathLen, p, pathLen);
  +             std::memmove(p + kMaxMacStaticPathChars - pathLen, p, pathLen);
                                
                //      Get the current directory
           FSSpec spec;
  @@ -1215,14 +917,14 @@
                
                //      Get pathname to the current directory
                if (err == noErr)
  -                     err = FSRefMakePath(&ref, reinterpret_cast<UInt8*>(p), 
kMaxStaticPathChars - pathLen - 1);      // leave room for one '/'
  +                     err = FSRefMakePath(&ref, reinterpret_cast<UInt8*>(p), 
kMaxMacStaticPathChars - pathLen - 1);   // leave room for one '/'
                std::size_t prefixLen = std::strlen(p);
                        
                //      Now munge the two paths back together
                if (err == noErr)
                {
                        p[prefixLen++] = '/';
  -                     std::memmove(p + prefixLen, p + kMaxStaticPathChars - pathLen, 
pathLen);
  +                     std::memmove(p + prefixLen, p + kMaxMacStaticPathChars - 
pathLen, pathLen);
                }
                
                //      We now have a path from an absolute starting point
  @@ -1598,19 +1300,19 @@
        OSStatus err = noErr;
        
        //      Make the path in utf8 form
  -     char utf8Buf[kMaxStaticPathChars];
  +     char utf8Buf[kMaxMacStaticPathChars];
        utf8Buf[0] = '\0';
        
        if (err == noErr)
  -             err = FSRefMakePath(&startingRef, reinterpret_cast<UInt8*>(utf8Buf), 
kMaxStaticPathChars);
  +             err = FSRefMakePath(&startingRef, reinterpret_cast<UInt8*>(utf8Buf), 
kMaxMacStaticPathChars);
                
        //      Bail if path conversion failed
        if (err != noErr)
                return NULL;
        
        //      Transcode into UniChars
  -     UniChar uniBuf[kMaxStaticPathChars];
  -     std::size_t pathLen = TranscodeUTF8ToUniChars(utf8Buf, uniBuf, 
kMaxStaticPathChars-1);
  +     UniChar uniBuf[kMaxMacStaticPathChars];
  +     std::size_t pathLen = TranscodeUTF8ToUniChars(utf8Buf, uniBuf, 
kMaxMacStaticPathChars-1);
        uniBuf[pathLen++] = 0;
        
        //      Transcode into a dynamically allocated buffer of XMLChs
  @@ -1631,8 +1333,8 @@
       HFSUniStr255 name;
       FSRef ref = startingRef;
   
  -    XMLCh buf[kMaxStaticPathChars];
  -    std::size_t bufPos   = kMaxStaticPathChars;
  +    XMLCh buf[kMaxMacStaticPathChars];
  +    std::size_t bufPos   = kMaxMacStaticPathChars;
       std::size_t bufCnt   = 0;
   
       ArrayJanitor<XMLCh> result(NULL);
  @@ -1645,7 +1347,7 @@
        {
                err = FSGetCatalogInfo(
                        &ref,
  -                     kFSCatInfoParentDirID,
  +                     kFSCatInfoNodeFlags | kFSCatInfoParentDirID,
                        &catalogInfo,
                        &name,
                        static_cast<FSSpec*>(NULL),
  @@ -1670,28 +1372,39 @@
                                result.reset(temp.release());
                                resultLen += bufCnt;
                                
  -                             bufPos = kMaxStaticPathChars;
  +                             bufPos = kMaxMacStaticPathChars;
                                bufCnt = 0;
                        }
                        
  -                     // Prepend our new name and a '/'
  +                     // Prepend a slash if this was a directory
  +                     if (catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)
  +                     {
  +                             buf[--bufPos] = L'/';
  +                             ++bufCnt;
  +                     }
  +                     
  +                     // Prepend our new name
                        bufPos -= name.length;
  -                     ConvertSlashToColon(CopyUniCharsToXMLChs(name.unicode, 
&buf[bufPos], name.length, name.length), name.length);
  -                     buf[--bufPos] = L'/';
  -                     bufCnt += (name.length + 1);
  +                     ConvertSlashToColon(
  +                             CopyUniCharsToXMLChs(name.unicode, &buf[bufPos], 
name.length, name.length),
  +                             name.length);
  +                     bufCnt += name.length;
                }
        }
        while (err == noErr && catalogInfo.parentDirID != fsRtParID);
        
  -     // Composite existing buffer with any previous result buffer
  -     ArrayJanitor<XMLCh> final(new XMLCh[bufCnt + resultLen]);
  +     // Composite '/' + existing buffer + any previous result buffer
  +     ArrayJanitor<XMLCh> final(new XMLCh[1 + bufCnt + resultLen]);
  +     
  +     // Full pathnames always start with a leading /
  +     final.get()[0] = '/';
        
        // Copy in the static buffer
  -     std::memcpy(final.get(), &buf[bufPos], bufCnt * sizeof(XMLCh));
  +     std::memcpy(final.get() + 1, &buf[bufPos], bufCnt * sizeof(XMLCh));
        
        // Copy in the old buffer
        if (resultLen > 0)
  -             std::memcpy(final.get() + bufCnt, result.get(), resultLen * 
sizeof(XMLCh));
  +             std::memcpy(final.get() + 1 + bufCnt, result.get(), resultLen * 
sizeof(XMLCh));
        
       return final.release();
   }
  @@ -1735,8 +1448,8 @@
       OSStatus err = noErr;
       FSSpec spec = startingSpec;
   
  -    char buf[kMaxStaticPathChars];
  -    std::size_t bufPos   = kMaxStaticPathChars;
  +    char buf[kMaxMacStaticPathChars];
  +    std::size_t bufPos   = kMaxMacStaticPathChars;
       std::size_t bufCnt   = 0;
   
       ArrayJanitor<char> result(NULL);
  @@ -1775,15 +1488,21 @@
                                result.reset(temp.release());
                                resultLen += bufCnt;
                                
  -                             bufPos = kMaxStaticPathChars;
  +                             bufPos = kMaxMacStaticPathChars;
                                bufCnt = 0;
                        }
                        
  -                     // Prepend our new name and a '/'
  +                     // Prepend a slash if this was a directory
  +                     if (catInfo.dirInfo.ioFlAttrib & kioFlAttribDirMask)
  +                     {
  +                             buf[--bufPos] = '/';
  +                             ++bufCnt;
  +                     }
  +
  +                     // Prepend our new name
                        bufPos -= nameLen;
                        ConvertSlashToColon((char*)std::memcpy(&buf[bufPos], 
&spec.name[1], nameLen), nameLen);
  -                     buf[--bufPos] = '/';
  -                     bufCnt += (nameLen + 1);
  +                     bufCnt += nameLen;
                        
                        // From here on out, ignore the input file name
                        index = -1;
  @@ -1795,14 +1514,17 @@
        while (err == noErr && spec.parID != fsRtParID);
        
        // Composite existing buffer with any previous result buffer
  -     ArrayJanitor<char> final(new char[bufCnt + resultLen]);
  +     ArrayJanitor<char> final(new char[1 + bufCnt + resultLen]);
  +     
  +     // Full pathnames always start with a leading /
  +     final.get()[0] = '/';
        
        // Copy in the static buffer
  -     std::memcpy(final.get(), &buf[bufPos], bufCnt);
  +     std::memcpy(final.get() + 1, &buf[bufPos], bufCnt);
        
        // Copy in the old buffer
        if (resultLen > 0)
  -             std::memcpy(final.get() + bufCnt, result.get(), resultLen);
  +             std::memcpy(final.get() + 1 + bufCnt, result.get(), resultLen);
   
       // Cleanup and transcode to unicode
       return XMLString::transcode(final.get());
  @@ -1810,7 +1532,7 @@
   
   
   std::size_t
  -TranscodeUniCharsToUTF8(UniChar* src, char* dst, std::size_t srcCnt, std::size_t 
maxChars)
  +TranscodeUniCharsToUTF8(const UniChar* src, char* dst, std::size_t srcCnt, 
std::size_t maxChars)
   {
        std::size_t result = 0;
        
  @@ -1853,7 +1575,7 @@
   
   
   std::size_t
  -TranscodeUTF8ToUniChars(char* src, UniChar* dst, std::size_t maxChars)
  +TranscodeUTF8ToUniChars(const char* src, UniChar* dst, std::size_t maxChars)
   {
        std::size_t result = 0;
        
  
  
  
  1.7       +28 -44    
xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacOSPlatformUtils.hpp
  
  Index: MacOSPlatformUtils.hpp
  ===================================================================
  RCS file: 
/home/cvs/xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacOSPlatformUtils.hpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- MacOSPlatformUtils.hpp    13 Nov 2002 17:37:36 -0000      1.6
  +++ MacOSPlatformUtils.hpp    23 Feb 2003 04:41:26 -0000      1.7
  @@ -62,6 +62,9 @@
   
   #include <cstdlib>
   #include <xercesc/util/XercesDefs.hpp>
  +#include <xercesc/util/PlatformUtils.hpp>
  +#include <xercesc/util/Platforms/MacOS/MacAbstractFile.hpp>
  +
   
   #if defined(__APPLE__)
       //       Framework includes from ProjectBuilder
  @@ -73,49 +76,6 @@
   
   XERCES_CPP_NAMESPACE_BEGIN
   
  -//   Abstract class for files. This could be used to allow multiple file paradigms.
  -class XMLMacAbstractFile
  -{
  -    public:
  -        XMLMacAbstractFile() {}
  -        virtual ~XMLMacAbstractFile() {}
  -
  -        virtual unsigned int currPos() = 0;
  -        virtual void close() = 0;
  -        virtual unsigned int size() = 0;
  -        virtual void open(const XMLCh* const) = 0;
  -        virtual void openFileToWrite(const XMLCh* const) = 0;
  -        virtual unsigned int read(const unsigned int, XMLByte* const) = 0;
  -        virtual void write(const long byteCount, const XMLByte* const buffer) = 0;
  -        virtual void reset() = 0;
  -};
  -
  -
  -//   Concrete file class implemented using raw Carbon file system calls.
  -class XMLMacFile : public XMLMacAbstractFile
  -{
  -    public:
  -        XMLMacFile() : mFileRefNum(0), mFileValid(false) {}
  -        virtual ~XMLMacFile();
  -
  -        unsigned int currPos();
  -        void close();
  -        unsigned int size();
  -        void open(const XMLCh* const);
  -        void openFileToWrite(const XMLCh* const);
  -        unsigned int read(const unsigned int, XMLByte* const);
  -        void write(const long byteCount, const XMLByte* const buffer);
  -        void reset();
  -
  -    protected:
  -        void create(const XMLCh* const);
  -        void openWithPermission(const XMLCh* const, int macPermission);
  -
  -        short        mFileRefNum;
  -        bool mFileValid;
  -};
  -
  -
   //
   //   Support for customized panic handling:
   //  The default handling of panics is not very friendly.
  @@ -141,6 +101,10 @@
   //   While the port itself never creates such paths, it does use these same 
routines to
   //   parse them.
   
  +//   Factory method to create an appropriate concrete object
  +//   descended from XMLMacAbstractFile.
  +XMLUTIL_EXPORT XMLMacAbstractFile* XMLMakeMacFile(void);
  +
   //   Convert fom FSRef/FSSpec to a Unicode character string path.
   //   Note that you'll need to delete [] that string after you're done with it!
   XMLUTIL_EXPORT XMLCh*        XMLCreateFullPathFromFSRef(const FSRef& startingRef);
  @@ -160,6 +124,26 @@
   CopyUniCharsToXMLChs(const UniChar* src, XMLCh* dst, std::size_t charCount, 
std::size_t maxChars);
   XMLUTIL_EXPORT UniChar*
   CopyXMLChsToUniChars(const XMLCh* src, UniChar* dst, std::size_t charCount, 
std::size_t maxChars);
  +
  +//   UTF8/UniChar transcoding utilities
  +XMLUTIL_EXPORT std::size_t
  +TranscodeUniCharsToUTF8(const UniChar* src, char* dst, std::size_t srcCnt, 
std::size_t maxChars);
  +XMLUTIL_EXPORT std::size_t
  +TranscodeUTF8ToUniChars(const char* src, UniChar* dst, std::size_t maxChars);
  +
  +// Size of our statically allocated path buffers
  +const std::size_t kMaxMacStaticPathChars = 512;
  +
  +//   Global variables set in platformInit()
  +extern bool gFileSystemCompatible;
  +extern bool gHasFSSpecAPIs;
  +extern bool gHasFS2TBAPIs;
  +extern bool gHasHFSPlusAPIs;
  +extern bool gHasFSPathAPIs;
  +extern bool gPathAPIsUsePosixPaths;
  +extern bool gHasMPAPIs;
  +extern bool gMacOSX;
  +extern bool gUsePosixFiles;
   
   XERCES_CPP_NAMESPACE_END
   
  
  
  
  1.1                  
xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacAbstractFile.hpp
  
  Index: MacAbstractFile.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Id: MacAbstractFile.hpp,v 1.1 2003/02/23 04:41:26 jberry Exp $
   */
  
  #pragma once
  
  #include <xercesc/util/XercesDefs.hpp>
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  //    Abstract class for files. This could be used to allow multiple file paradigms.
  class XMLMacAbstractFile
  {
      public:
          XMLMacAbstractFile() {}
          virtual ~XMLMacAbstractFile() {}
  
          virtual unsigned int currPos() = 0;
          virtual void close() = 0;
          virtual unsigned int size() = 0;
          virtual bool open(const XMLCh* path, bool toWrite = false) = 0;
          virtual bool open(const char* path, bool toWrite = false) = 0;
          virtual unsigned int read(unsigned int byteCount, XMLByte* buffer) = 0;
          virtual void write(long byteCount, const XMLByte* buffer) = 0;
          virtual void reset() = 0;
  };
  
  XERCES_CPP_NAMESPACE_END
  
  
  
  1.1                  xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacCarbonFile.cpp
  
  Index: MacCarbonFile.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Id: MacCarbonFile.cpp,v 1.1 2003/02/23 04:41:26 jberry Exp $
   */
   
  #include <xercesc/util/XercesDefs.hpp>
  #include <xercesc/util/XMLString.hpp>
  #include <xercesc/util/Janitor.hpp>
  
  #include <xercesc/util/Platforms/MacOS/MacCarbonFile.hpp>
  
  
  #if defined(__APPLE__)
      //        Include from Frameworks Headers under ProjectBuilder
      #include <Carbon/Carbon.h>
  #else
      //        Classic include styles
      #include <Files.h>
      #include <TextUtils.h>
  #endif
  
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  //----------------------------------------------------------------------------
  // XMLMacCarbonFile methods
  //----------------------------------------------------------------------------
  
  unsigned int
  XMLMacCarbonFile::currPos()
  {
      OSErr err = noErr;
      unsigned int pos = 0;
  
      if (!mFileValid)
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  
      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;
      }
  
      if (err != noErr)
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  
      return pos;
  }
  
  
  void
  XMLMacCarbonFile::close()
  {
      OSErr err = noErr;
      if (!mFileValid)
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  
      if (gHasHFSPlusAPIs)
          err = FSCloseFork(mFileRefNum);
      else
          err = FSClose(mFileRefNum);
  
      mFileValid = false;
  
      if (err != noErr)
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  }
  
  
  unsigned int
  XMLMacCarbonFile::size()
  {
      OSErr err = noErr;
      unsigned int len = 0;
  
      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);
  
      return len;
  }
  
  
  bool
  XMLMacCarbonFile::openWithPermission(const XMLCh* const fileName, int macPermission)
  {
      OSErr err = noErr;
  
      if (mFileValid)
          ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, 
fileName);
  
      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, macPermission, 
&mFileRefNum);
      }
      else
      {
          FSSpec spec;
          if (!XMLParsePathToFSSpec(fileName, spec))
              err = fnfErr;
  
          if (err == noErr)
              err = FSpOpenDF(&spec, macPermission, &mFileRefNum);
      }
  
      if (err != noErr)
          ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, 
fileName);
  
      mFileValid = true;
        return mFileValid;
  }
  
  
  void
  XMLMacCarbonFile::create(const XMLCh* const filePath)
  {
      OSErr err = noErr;
  
      //        Split path into directory and filename components
      int posSlash = XMLString::lastIndexOf(filePath, '/', 
XMLString::stringLen(filePath) - 1);
      int posName = (posSlash == -1) ? 0 : posSlash+1;
  
      const XMLCh* namePtr = filePath + posName;
      int nameLen = XMLString::stringLen(namePtr);
  
      //        Make a temporary string of the directory
      ArrayJanitor<XMLCh> dirPath(new XMLCh[namePtr - filePath + 1]);
      XMLString::subString(dirPath.get(), filePath, 0, posName);
  
      //        Create the file as appropriate for API set
      if (gHasHFSPlusAPIs)
      {
        //      HFS+
          FSRef ref;
  
          //    If we find an existing file, delete it
          if (XMLParsePathToFSRef(filePath, ref))
              FSDeleteObject(&ref);
  
          //    Get a ref to the parent directory
          if (!XMLParsePathToFSRef(dirPath.get(), ref))
              err = fnfErr;
  
          //    Create a new file using the unicode name
          if (err == noErr)
          {
              UniChar uniName[256];
              err = FSCreateFileUnicode(
                      &ref,
                      nameLen, CopyXMLChsToUniChars(namePtr, uniName, nameLen, 
sizeof(uniName)),
                      0, NULL, NULL, NULL);
          }
      }
      else
      {
        //      HFS
          FSSpec spec;
  
          //    If we find an existing file, delete it
          if (XMLParsePathToFSSpec(filePath, spec))
              FSpDelete(&spec);
  
          //    Get a spec to the parent directory
          if (!XMLParsePathToFSSpec(dirPath.get(), spec))
              err = fnfErr;
  
          //    Check that the new name is not too long for HFS
          if (err == noErr && nameLen > 31)
              err = errFSNameTooLong;
  
          if (err == noErr)
          {
              //        Transcode the unicode name to native encoding
              ArrayJanitor<const char> nativeName(XMLString::transcode(namePtr));
  
              // Make a partial pathname from our current spec (parent directory) to 
the new file
              unsigned char name[31 * 2 + 1 * 2 + 1];
              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++ = ':';                          // Path component separator
              char c;
              for (const char* p = nativeName.get(); (c = *p++) != 0; ) // Copy in new 
element
                  *partial++ = (c == ':') ? '/' : c;            // Convert : to /
  
              name[0] = partial - &name[1];   // Set the pascal string name length
  
              //        Update the spec: this will probably return fnfErr
              //                                         (since we just deleted any 
existing file)
              err = FSMakeFSSpec(spec.vRefNum, spec.parID, name, &spec);
  
              //        Create the file from the spec
              err = FSpCreate(&spec, '??\??', 'TEXT', smSystemScript);
          }
      }
  
      //        Fail if we didn't create the file
      if (err != noErr)
      {
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
          //ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
      }
  }
  
  
  bool
  XMLMacCarbonFile::open(const XMLCh* const path, bool toWrite)
  {
        bool success = false;
        
        if (toWrite)
        {
                create(path);
                success = openWithPermission(path, fsRdWrPerm);
        }
        else
        {
                success = openWithPermission(path, fsRdPerm);
        }
        
        return success;
  }
  
  
  bool
  XMLMacCarbonFile::open(const char* fileName, bool toWrite)
  {
        //      Transcode the input filename from UTF8 into UTF16
        UniChar uniBuf[kMaxMacStaticPathChars];
        std::size_t pathLen = TranscodeUTF8ToUniChars(fileName, uniBuf, 
kMaxMacStaticPathChars-1);
        uniBuf[pathLen++] = 0;
        
        //      Call through to the unicode open routine
        return open(uniBuf, toWrite);
  }
  
  
  unsigned int
  XMLMacCarbonFile::read(const unsigned int toRead, XMLByte* const toFill)
  {
      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;
  }
  
  
  void
  XMLMacCarbonFile::write(const long byteCount, const XMLByte* const buffer)
  {
      long bytesWritten = 0;
      OSErr err = noErr;
  
      if (byteCount <= 0 || buffer == NULL)
          return;
  
      if (!mFileValid)
      {
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
      }
  
      if (gHasHFSPlusAPIs)
      {
          ByteCount actualCount;
          err = FSWriteFork(mFileRefNum, fsFromMark, 0, byteCount, buffer, 
&actualCount);
          bytesWritten = actualCount;
      }
      else
      {
          long count = byteCount;
          err = FSWrite(mFileRefNum, &count, buffer);
          bytesWritten = count;
      }
  
      if ((err != noErr && err != eofErr) || (bytesWritten != byteCount))
      {
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
      }
  }
  
  
  void
  XMLMacCarbonFile::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);
  }
  
  
  XMLMacCarbonFile::~XMLMacCarbonFile()
  {
      if (mFileValid)
          close();
  }
  
  XERCES_CPP_NAMESPACE_END
  
  
  
  1.1                  xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacCarbonFile.hpp
  
  Index: MacCarbonFile.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Id: MacCarbonFile.hpp,v 1.1 2003/02/23 04:41:26 jberry Exp $
   */
  
  #pragma once
  
  #include <xercesc/util/XercesDefs.hpp>
  #include <xercesc/util/Platforms/MacOS/MacOSPlatformUtils.hpp>
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  //    Concrete file class implemented using raw Carbon file system calls.
  class XMLMacCarbonFile : public XMLMacAbstractFile
  {
      public:
          XMLMacCarbonFile() : mFileRefNum(0), mFileValid(false) {}
          virtual ~XMLMacCarbonFile();
  
          unsigned int currPos();
          void close();
          unsigned int size();
          bool open(const XMLCh* path, bool toWrite);
          bool open(const char* path, bool toWrite);
          unsigned int read(unsigned int byteCount, XMLByte* buffer);
          void write(long byteCount, const XMLByte* buffer);
          void reset();
  
      protected:
          void create(const XMLCh* const);
          bool openWithPermission(const XMLCh* const, int macPermission);
  
          short mFileRefNum;
          bool  mFileValid;
  };
  
  XERCES_CPP_NAMESPACE_END
  
  
  
  1.1                  xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacPosixFile.cpp
  
  Index: MacPosixFile.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Id: MacPosixFile.cpp,v 1.1 2003/02/23 04:41:26 jberry Exp $
   */
  
  #include <xercesc/util/XercesDefs.hpp>
  #include <xercesc/util/XMLString.hpp>
  #include <xercesc/util/Janitor.hpp>
  
  #include <limits.h>
  #include <stdio.h>
  
  #include <xercesc/util/Platforms/MacOS/MacPosixFile.hpp>
  
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  //----------------------------------------------------------------------------
  // XMLMacPosixFile methods
  //----------------------------------------------------------------------------
  
  XMLMacPosixFile::XMLMacPosixFile()
    : mFile(NULL)
  {
  }
  
  
  XMLMacPosixFile::~XMLMacPosixFile()
  {
        if (mFile)
                close();
  }
  
  
  unsigned int
  XMLMacPosixFile::currPos()
  {
      if (!mFile)
                ThrowXML(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero);
                 
      long curPos = ftell(mFile);
        
      if (curPos == -1)
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize);
  
      return (unsigned int)curPos;
  }
  
  
  void
  XMLMacPosixFile::close()
  {
      if (!mFile)
                ThrowXML(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero);
                
      if (fclose(mFile))
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
                
        mFile = NULL;
  }
  
  
  unsigned int
  XMLMacPosixFile::size()
  {
      if (mFile == NULL)
                ThrowXML(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero);
                
      // Get the current position
      long curPos = ftell(mFile);
      if (curPos == -1)
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  
      // Seek to the end and save that value for return
      if (fseek(mFile, 0, SEEK_END))
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
  
      long retVal = ftell(mFile);
      if (retVal == -1)
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
  
      // And put the pointer back
      if (fseek(mFile, curPos, SEEK_SET))
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToPos);
  
      return (unsigned int)retVal;
  }
  
  
  bool
  XMLMacPosixFile::open(const XMLCh* const path, bool toWrite)
  {
      if (!path)
                ThrowXML(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero);
  
        //      Transcode the unicode path to UTF8, which is what the Mac posix 
routines want
        char tmpPath[kMaxMacStaticPathChars];
        std::size_t len = TranscodeUniCharsToUTF8(path, tmpPath, 
XMLString::stringLen(path), kMaxMacStaticPathChars-1);
        tmpPath[len] = 0;
        
        //      Call through to the char version to do the work
        return open(tmpPath, toWrite);
  }
  
  
  bool
  XMLMacPosixFile::open(const char* const path, bool toWrite)
  {
      if (!path)
                ThrowXML(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero);
  
        const char* perms = (toWrite) ? "w" : "r+";
        mFile = fopen(path, perms);
        
        return (mFile != NULL);
  }
  
  
  unsigned int
  XMLMacPosixFile::read(const unsigned int byteCount, XMLByte* const buffer)
  {
      if (!mFile || !buffer)
                ThrowXML(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero);
                
      size_t bytesRead = 0;
        if (byteCount > 0)
        {
        bytesRead = fread((void*)buffer, 1, byteCount, mFile);
  
                if (ferror(mFile))
                        ThrowXML(XMLPlatformUtilsException, 
XMLExcepts::File_CouldNotReadFromFile);
        }
        
      return (unsigned int)bytesRead;
  }
  
  
  void
  XMLMacPosixFile::write(long byteCount, const XMLByte* buffer)
  {
      if (!mFile || !buffer)
                ThrowXML(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero);
  
      while (byteCount > 0)
      {
          size_t bytesWritten = fwrite(buffer, sizeof(XMLByte), byteCount, mFile);
  
          if (ferror(mFile))
                        ThrowXML(XMLPlatformUtilsException, 
XMLExcepts::File_CouldNotWriteToFile);
  
                buffer          += bytesWritten;
                byteCount       -= bytesWritten;
      }
  }
  
  
  void
  XMLMacPosixFile::reset()
  {
      if (!mFile)
                ThrowXML(XMLPlatformUtilsException, XMLExcepts::CPtr_PointerIsZero);
                
      // Seek to the start of the file
      if (fseek(mFile, 0, SEEK_SET))
          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
  }
  
  
  XERCES_CPP_NAMESPACE_END
  
  
  
  1.1                  xml-xerces/c/src/xercesc/util/Platforms/MacOS/MacPosixFile.hpp
  
  Index: MacPosixFile.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
   * reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   *
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   *
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in
   *    the documentation and/or other materials provided with the
   *    distribution.
   *
   * 3. The end-user documentation included with the redistribution,
   *    if any, must include the following acknowledgment:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowledgment may appear in the software itself,
   *    if and wherever such third-party acknowledgments normally appear.
   *
   * 4. The names "Xerces" and "Apache Software Foundation" must
   *    not be used to endorse or promote products derived from this
   *    software without prior written permission. For written
   *    permission, please contact [EMAIL PROTECTED]
   *
   * 5. Products derived from this software may not be called "Apache",
   *    nor may "Apache" appear in their name, without prior written
   *    permission of the Apache Software Foundation.
   *
   * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
   * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
   * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
   * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
   * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
   * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
   * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
   * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
   * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation, and was
   * originally based on software copyright (c) 1999, International
   * Business Machines, Inc., http://www.ibm.com .  For more information
   * on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  /*
   * $Id: MacPosixFile.hpp,v 1.1 2003/02/23 04:41:26 jberry Exp $
   */
  
  #pragma once
  
  #include <xercesc/util/XercesDefs.hpp>
  #include <xercesc/util/Platforms/MacOS/MacOSPlatformUtils.hpp>
  
  #include <stdio.h>
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  //    Concrete file class implemented using raw Carbon file system calls.
  class XMLMacPosixFile : public XMLMacAbstractFile
  {
      public:
          XMLMacPosixFile();
          virtual ~XMLMacPosixFile();
  
          unsigned int currPos();
          void close();
          unsigned int size();
          bool open(const XMLCh* path, bool toWrite = false);
          bool open(const char* path, bool toWrite = false);
          unsigned int read(unsigned int byteCount, XMLByte* buffer);
          void write(long byteCount, const XMLByte* buffer);
          void reset();
  
      protected:
          FILE* mFile;
  };
  
  XERCES_CPP_NAMESPACE_END
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to