MacCarbonFile.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:12k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Id: MacCarbonFile.cpp,v 1.1 2003/02/23 04:41:26 jberry Exp $
  58.  */
  59.  
  60. #include <xercesc/util/XercesDefs.hpp>
  61. #include <xercesc/util/XMLString.hpp>
  62. #include <xercesc/util/Janitor.hpp>
  63. #include <xercesc/util/Platforms/MacOS/MacCarbonFile.hpp>
  64. #if defined(__APPLE__)
  65.     // Include from Frameworks Headers under ProjectBuilder
  66.     #include <Carbon/Carbon.h>
  67. #else
  68.     // Classic include styles
  69.     #include <Files.h>
  70.     #include <TextUtils.h>
  71. #endif
  72. XERCES_CPP_NAMESPACE_BEGIN
  73. //----------------------------------------------------------------------------
  74. // XMLMacCarbonFile methods
  75. //----------------------------------------------------------------------------
  76. unsigned int
  77. XMLMacCarbonFile::currPos()
  78. {
  79.     OSErr err = noErr;
  80.     unsigned int pos = 0;
  81.     if (!mFileValid)
  82.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  83.     if (gHasHFSPlusAPIs)
  84.     {
  85.         SInt64 bigPos = 0;
  86.         err = FSGetForkPosition(mFileRefNum, &bigPos);
  87.         if (err == noErr)
  88.             pos = bigPos;
  89.     }
  90.     else
  91.     {
  92.         long longPos;
  93.         err = GetFPos(mFileRefNum, &longPos);
  94.         if (err == noErr)
  95.             pos = longPos;
  96.     }
  97.     if (err != noErr)
  98.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  99.     return pos;
  100. }
  101. void
  102. XMLMacCarbonFile::close()
  103. {
  104.     OSErr err = noErr;
  105.     if (!mFileValid)
  106.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  107.     if (gHasHFSPlusAPIs)
  108.         err = FSCloseFork(mFileRefNum);
  109.     else
  110.         err = FSClose(mFileRefNum);
  111.     mFileValid = false;
  112.     if (err != noErr)
  113.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  114. }
  115. unsigned int
  116. XMLMacCarbonFile::size()
  117. {
  118.     OSErr err = noErr;
  119.     unsigned int len = 0;
  120.     if (!mFileValid)
  121.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize);
  122.     if (gHasHFSPlusAPIs)
  123.     {
  124.         SInt64 bigLen = 0;
  125.         err = FSGetForkSize(mFileRefNum, &bigLen);
  126.         if (err == noErr)
  127.             len = bigLen;
  128.     }
  129.     else
  130.     {
  131.         long longLen;
  132.         err = GetEOF(mFileRefNum, &longLen);
  133.         if (err == noErr)
  134.             len = longLen;
  135.     }
  136.     if (err != noErr)
  137.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize);
  138.     return len;
  139. }
  140. bool
  141. XMLMacCarbonFile::openWithPermission(const XMLCh* const fileName, int macPermission)
  142. {
  143.     OSErr err = noErr;
  144.     if (mFileValid)
  145.         ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, fileName);
  146.     if (gHasHFSPlusAPIs)
  147.     {
  148.         FSRef ref;
  149.         if (!XMLParsePathToFSRef(fileName, ref))
  150.             err = fnfErr;
  151.         HFSUniStr255 forkName;
  152.         if (err == noErr)
  153.             err = FSGetDataForkName(&forkName);
  154.         if (err == noErr)
  155.             err = FSOpenFork(&ref, forkName.length, forkName.unicode, macPermission, &mFileRefNum);
  156.     }
  157.     else
  158.     {
  159.         FSSpec spec;
  160.         if (!XMLParsePathToFSSpec(fileName, spec))
  161.             err = fnfErr;
  162.         if (err == noErr)
  163.             err = FSpOpenDF(&spec, macPermission, &mFileRefNum);
  164.     }
  165.     if (err != noErr)
  166.         ThrowXML1(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile, fileName);
  167.     mFileValid = true;
  168. return mFileValid;
  169. }
  170. void
  171. XMLMacCarbonFile::create(const XMLCh* const filePath)
  172. {
  173.     OSErr err = noErr;
  174.     // Split path into directory and filename components
  175.     int posSlash = XMLString::lastIndexOf(filePath, '/', XMLString::stringLen(filePath) - 1);
  176.     int posName = (posSlash == -1) ? 0 : posSlash+1;
  177.     const XMLCh* namePtr = filePath + posName;
  178.     int nameLen = XMLString::stringLen(namePtr);
  179.     // Make a temporary string of the directory
  180.     ArrayJanitor<XMLCh> dirPath(new XMLCh[namePtr - filePath + 1]);
  181.     XMLString::subString(dirPath.get(), filePath, 0, posName);
  182.     // Create the file as appropriate for API set
  183.     if (gHasHFSPlusAPIs)
  184.     {
  185.      // HFS+
  186.         FSRef ref;
  187.         // If we find an existing file, delete it
  188.         if (XMLParsePathToFSRef(filePath, ref))
  189.             FSDeleteObject(&ref);
  190.         // Get a ref to the parent directory
  191.         if (!XMLParsePathToFSRef(dirPath.get(), ref))
  192.             err = fnfErr;
  193.         // Create a new file using the unicode name
  194.         if (err == noErr)
  195.         {
  196.             UniChar uniName[256];
  197.             err = FSCreateFileUnicode(
  198.                     &ref,
  199.                     nameLen, CopyXMLChsToUniChars(namePtr, uniName, nameLen, sizeof(uniName)),
  200.                     0, NULL, NULL, NULL);
  201.         }
  202.     }
  203.     else
  204.     {
  205.      // HFS
  206.         FSSpec spec;
  207.         // If we find an existing file, delete it
  208.         if (XMLParsePathToFSSpec(filePath, spec))
  209.             FSpDelete(&spec);
  210.         // Get a spec to the parent directory
  211.         if (!XMLParsePathToFSSpec(dirPath.get(), spec))
  212.             err = fnfErr;
  213.         // Check that the new name is not too long for HFS
  214.         if (err == noErr && nameLen > 31)
  215.             err = errFSNameTooLong;
  216.         if (err == noErr)
  217.         {
  218.             // Transcode the unicode name to native encoding
  219.             ArrayJanitor<const char> nativeName(XMLString::transcode(namePtr));
  220.             // Make a partial pathname from our current spec (parent directory) to the new file
  221.             unsigned char name[31 * 2 + 1 * 2 + 1];
  222.             unsigned char* partial = &name[1];
  223.             *partial++ = ':';        // Partial leads with :
  224.             const unsigned char* specName = spec.name; // Copy in spec name
  225.             for (int specCnt = *specName++; specCnt > 0; --specCnt)
  226.                 *partial++ = *specName++;
  227.             *partial++ = ':';        // Path component separator
  228.             char c;
  229.             for (const char* p = nativeName.get(); (c = *p++) != 0; ) // Copy in new element
  230.                 *partial++ = (c == ':') ? '/' : c; // Convert : to /
  231.             name[0] = partial - &name[1];   // Set the pascal string name length
  232.             // Update the spec: this will probably return fnfErr
  233.             //  (since we just deleted any existing file)
  234.             err = FSMakeFSSpec(spec.vRefNum, spec.parID, name, &spec);
  235.             // Create the file from the spec
  236.             err = FSpCreate(&spec, '????', 'TEXT', smSystemScript);
  237.         }
  238.     }
  239.     // Fail if we didn't create the file
  240.     if (err != noErr)
  241.     {
  242.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  243.         //ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  244.     }
  245. }
  246. bool
  247. XMLMacCarbonFile::open(const XMLCh* const path, bool toWrite)
  248. {
  249. bool success = false;
  250. if (toWrite)
  251. {
  252. create(path);
  253. success = openWithPermission(path, fsRdWrPerm);
  254. }
  255. else
  256. {
  257. success = openWithPermission(path, fsRdPerm);
  258. }
  259. return success;
  260. }
  261. bool
  262. XMLMacCarbonFile::open(const char* fileName, bool toWrite)
  263. {
  264. // Transcode the input filename from UTF8 into UTF16
  265. UniChar uniBuf[kMaxMacStaticPathChars];
  266. std::size_t pathLen = TranscodeUTF8ToUniChars(fileName, uniBuf, kMaxMacStaticPathChars-1);
  267. uniBuf[pathLen++] = 0;
  268. // Call through to the unicode open routine
  269. return open(uniBuf, toWrite);
  270. }
  271. unsigned int
  272. XMLMacCarbonFile::read(const unsigned int toRead, XMLByte* const toFill)
  273. {
  274.     unsigned int bytesRead = 0;
  275.     OSErr err = noErr;
  276.     if (!mFileValid)
  277.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  278.     if (gHasHFSPlusAPIs)
  279.     {
  280.         ByteCount actualCount;
  281.         err = FSReadFork(mFileRefNum, fsFromMark, 0, toRead, toFill, &actualCount);
  282.         bytesRead = actualCount;
  283.     }
  284.     else
  285.     {
  286.         long byteCount = toRead;
  287.         err = FSRead(mFileRefNum, &byteCount, toFill);
  288.         bytesRead = byteCount;
  289.     }
  290.     if (err != noErr && err != eofErr)
  291.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  292.     return bytesRead;
  293. }
  294. void
  295. XMLMacCarbonFile::write(const long byteCount, const XMLByte* const buffer)
  296. {
  297.     long bytesWritten = 0;
  298.     OSErr err = noErr;
  299.     if (byteCount <= 0 || buffer == NULL)
  300.         return;
  301.     if (!mFileValid)
  302.     {
  303.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  304.     }
  305.     if (gHasHFSPlusAPIs)
  306.     {
  307.         ByteCount actualCount;
  308.         err = FSWriteFork(mFileRefNum, fsFromMark, 0, byteCount, buffer, &actualCount);
  309.         bytesWritten = actualCount;
  310.     }
  311.     else
  312.     {
  313.         long count = byteCount;
  314.         err = FSWrite(mFileRefNum, &count, buffer);
  315.         bytesWritten = count;
  316.     }
  317.     if ((err != noErr && err != eofErr) || (bytesWritten != byteCount))
  318.     {
  319.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  320.     }
  321. }
  322. void
  323. XMLMacCarbonFile::reset()
  324. {
  325.     OSErr err = noErr;
  326.     if (!mFileValid)
  327.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
  328.     if (gHasHFSPlusAPIs)
  329.         err = FSSetForkPosition(mFileRefNum, fsFromStart, 0);
  330.     else
  331.         err = SetFPos(mFileRefNum, fsFromStart, 0);
  332.     if (err != noErr)
  333.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
  334. }
  335. XMLMacCarbonFile::~XMLMacCarbonFile()
  336. {
  337.     if (mFileValid)
  338.         close();
  339. }
  340. XERCES_CPP_NAMESPACE_END