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]