os390platformutils.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,122 行 · 第 1/3 页

CPP
1,122
字号
    char* extStart = strrchr( tmpFileName, '.' );    if ( extStart != NULL ) {        tmpPos = extStart + 1;        while( *tmpPos != '\0' ) {                *datasetPos++ = *tmpPos++;        }        *datasetPos++ = '(';    }    // Now we copy in the filename.    tmpPos = pathEnd + 1;    while( *tmpPos != '\0' && ((extStart == NULL) || (tmpPos < extStart)) ) {        *datasetPos++ = *tmpPos++;    }    // Finally cap off the filename with optional ")" and "'", plus a null    if( extStart != NULL ) *datasetPos++ = ')';    if( *tmpFileName == '/' ) *datasetPos++ = '\'';    *datasetPos = '\0';    fileHandle = fopen( datasetName , optionBuffer);    retVal->setHandle(fileHandle);    }    // fix for file:// protocol    // the tmpFileName has a prefix of //absolute path    // for example, file:////u/.... instead of file:///u/....    // the fopen() on OS/390 cannot open a //u/... POSIX file    if ((fileHandle == NULL) && (pathobj.getPathType() == PATH390_OTHER))    {       if ((tmpFileName[0] == '/') && (tmpFileName[1] == '/'))        {            char *srcName = tmpFileName + 1; // points past the first '/'            fileHandle = fopen(srcName , optionBuffer);            retVal->setHandle(fileHandle);            // temp fix for HFS files with type=record specified            // close the file and re-open it without the fopen options            // since they don't work too well with HFS files.            if (pathobj.isRecordType())            {               int fldata_rc = 0;               fldata_t fileinfo;               fldata_rc = fldata(fileHandle, srcName, &fileinfo);               if (fldata_rc)                 ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile, manager);               if (fileinfo.__dsorgHFS)               {                  if (fclose(fileHandle))                     ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile, manager);                  fileHandle=fopen(srcName, "rb");                  retVal->setHandle(fileHandle);                  retVal->setRecordType(_FHI_NOT_TYPE_RECORD);               }            }            // End temp fix ......   }    }    // If the fopen failed we have a pointer to the FileHandleImpl class but    // inside that class a file handle of NULL. In this case we need to delete    // the class and return a NULL to the caller since they should be checking    // for a NULL returned as a file open failed indicator.    if (fileHandle == NULL)    {       delete retVal;       retVal = 0;    }    return retVal;}static FileHandleImpl* openWrite(char* tmpFileName                                 , MemoryManager* const manager){    FileHandleImpl* retVal;    FILE* fileHandle = 0;    Path390 pathobj;    pathobj.setPath(tmpFileName);    fldata_t fileinfo;    int fldata_rc = 0;    int optionBufferSize = strlen("wb,");    int fileLrecl = 0;    bool isTypeRecord = _FHI_NOT_TYPE_RECORD;    // Check if we have fopen options specified in addition to a    // filename. If we do then we need to build a buffer that has    // "wb," followed by the options. Otherwise we just pass "wb"    // in as the options.    if (pathobj.getfopenParms())       optionBufferSize += (strlen(pathobj.getfopenParms()) + 1);    char* optionBuffer = (char*) manager->allocate((optionBufferSize) * sizeof(char));//new char[optionBufferSize];    ArrayJanitor<char> janText((char*)optionBuffer, manager);    strcpy(optionBuffer,"wb");    // Build the options buffer    if (pathobj.getfopenParms())    {       strcpy(optionBuffer + 2, ",");       strcpy(optionBuffer + 3, pathobj.getfopenParms());    }    // FileHandleImpl class. The constructor will allocate our staging    // buffer if it is a "type=record" open.    fileHandle = fopen(pathobj.getfopenPath(),optionBuffer);    // If this is a "type=record" open then we need to determine the    // LRECL of the file. The fldata info will have this in it.    // We save this in the FileHandleImpl class for use on subsequent    // writes to the file.    if (pathobj.isRecordType())    {       isTypeRecord = _FHI_TYPE_RECORD;       fldata_rc = fldata(fileHandle, pathobj.getfopenPath(), &fileinfo);       if (fldata_rc)          ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile, manager);       fileLrecl = fileinfo.__maxreclen;       // temp fix for HFS files       // close the file and re-open it without the fopen options       // since they don't work too well with HFS files.       if (fileinfo.__dsorgHFS)       {          if (fclose(fileHandle))            ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile, manager);          fileHandle=fopen(pathobj.getfopenPath(), "wb");       }      // end temp fix    }    // If the fopen failed we won't need to create an instance of the    // FileHandleImpl class .... just return a NULL wich the caller recognizes    // as a failure. If we have a valid file handle then we'll build create    // an instance of the class and return that to the caller.    if (fileHandle == NULL)       retVal = 0;    else       retVal = new (manager) FileHandleImpl(fileHandle, _FHI_WRITE, isTypeRecord,fileLrecl, manager);    return retVal;}// ---------------------------------------------------------------------------//  XMLPlatformUtils: File Methods// ---------------------------------------------------------------------------unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile                                          , MemoryManager* const manager){    // Get the current position    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;    FILE* fileHandle = (FILE*)fhiPtr->getHandle();    int curPos = ftell(fileHandle);    if (curPos == -1)       ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize, manager);    return (unsigned int)curPos;}void XMLPlatformUtils::closeFile(FileHandle theFile                                 , MemoryManager* const manager){    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;    FILE* fileHandle = (FILE*)fhiPtr->getHandle();    // We need to handle a close differently if this was a    // "type=record" open. In that case we may have data sitting in    // the staging buffer that is waiting to be written to the file.    // In this case write that data to the file before we actually    // close it.    if ( (fhiPtr->getOpenType() == _FHI_WRITE) &&         (fhiPtr->isRecordType())  &&         (fhiPtr->getNextByte()) )    {        XMLByte* tmpFlush = fhiPtr->getStgBufferPtr();        size_t bytesToWrite = fhiPtr->getNextByte();        emptyBuffer(tmpFlush, bytesToWrite, fhiPtr, manager);    }    // Do the regular close stuff ....    if (fclose(fileHandle))       ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile, manager);    // Delete the instance of the FileHandleImpl class (this will free the    // staging buffer for us)    delete fhiPtr;}unsigned int XMLPlatformUtils::fileSize(FileHandle theFile                                        , MemoryManager* const manager){    // Get the current position    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;    FILE* fileHandle = (FILE*)fhiPtr->getHandle();    long  int curPos = ftell(fileHandle);    if (curPos == -1)       ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos, manager);    // Seek to the end and save that value for return    if (fseek(fileHandle, 0, SEEK_END))       ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd, manager);    long int retVal = ftell(fileHandle);    if (retVal == -1)       ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd, manager);    // And put the pointer back    if (fseek(fileHandle, curPos, SEEK_SET) )       ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToPos, manager);    return (unsigned int)retVal;}FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName                                      , MemoryManager* const manager){    char* tmpFileName = XMLString::transcode(fileName, manager);    ArrayJanitor<char> janText((char*)tmpFileName, manager);    return openRead(tmpFileName, manager);}FileHandle XMLPlatformUtils::openFile(const char* const fileName                                      , MemoryManager* const manager){    char* tmpFileName = (char*) manager->allocate    (        (strlen(fileName) + 1) * sizeof(char)    );//new char[strlen(fileName) + 1];    ArrayJanitor<char> janText((char*)tmpFileName, manager);    strcpy(tmpFileName,fileName);    return openRead(tmpFileName, manager);}FileHandle XMLPlatformUtils::openFileToWrite(const XMLCh* const fileName                                             , MemoryManager* const manager){    char* tmpFileName = XMLString::transcode(fileName, manager);    ArrayJanitor<char> janText((char*)tmpFileName, manager);    return openWrite(tmpFileName, manager);}FileHandle XMLPlatformUtils::openFileToWrite(const char* const fileName                                             , MemoryManager* const manager){    char* tmpFileName = (char*) manager->allocate    (        (strlen(fileName) + 1) * sizeof(char)    );//new char[strlen(fileName) + 1];    ArrayJanitor<char> janText((char*)tmpFileName, manager);    strcpy(tmpFileName,fileName);    return openWrite(tmpFileName, manager);}voidXMLPlatformUtils::writeBufferToFile( FileHandle     const  theFile                                   , long                  toWrite                                   , const XMLByte* const  toFlush                                   , MemoryManager* const  manager){    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;    FILE* fileHandle = (FILE*)fhiPtr->getHandle();    if (!fileHandle     ||        (toWrite <= 0 ) ||        !toFlush )        return;    XMLByte* tmpFlush = (XMLByte*) toFlush;    // For writes where the file has been opened with the "type=record"    // option we must do a lot of extra work. In this case we have    // a staging buffer that we copy data to and only write it out    // when we find a newline or line feed in the buffer.    if (fhiPtr->isRecordType())    {       XMLByte* inputBufferPtr =  tmpFlush;       XMLByte* stageBufferStartPtr =  fhiPtr->getStgBufferPtr();       int stageBufferNextByte = fhiPtr->getNextByte();       XMLByte* stageBufferAddPtr =  stageBufferStartPtr + stageBufferNextByte;       int stageThisAdd = 0;       int stageTotalAdded = 0;       int stageToWrite = 0;       int fileLrecl = fhiPtr->getLrecl();       // Check each byte passed into us. If it is a new line or       // line feed we copy up to and including that byte to the       // staging buffer starting at the next available byte. We       // then write the valid contents of the staging buffer to       // the file and then continue going thru the input data       // since a newline is not the end of the input.       // Also we want to copy the data to the staging buffer and       // write it to disk as soon as the staging buffer contains       // a logical record's worth of data.       for(int i = 0; i < toWrite; i++)       {          if ( (tmpFlush[i] == '\n') ||               (tmpFlush[i] == 0x25) ||               ((stageBufferNextByte + (i + 1)) - stageTotalAdded == fileLrecl) )          {             stageThisAdd = (i + 1) - stageTotalAdded;             memcpy((void*) stageBufferAddPtr, (void*) inputBufferPtr, stageThisAdd);             stageTotalAdded += stageThisAdd;             inputBufferPtr += stageThisAdd;             stageBufferAddPtr += stageThisAdd;             stageToWrite = stageBufferAddPtr - stageBufferStartPtr;             emptyBuffer(stageBufferStartPtr, stageToWrite, fhiPtr, manager);             stageBufferAddPtr = stageBufferStartPtr;             stageBufferNextByte = 0;          }       }  // for loop      // When we finish looping thru the input buffer we may have data      // left in it that was not copied to the staging buffer yet. Copy      // whatever is left in the input buffer to the staging buffer now      // and update the staging buffer next byte offset.      if (stageTotalAdded < toWrite)      {         stageThisAdd = toWrite - stageTotalAdded;         memcpy((void*) stageBufferAddPtr, (void*) inputBufferPtr, stageThisAdd);         stageBufferNextByte += stageThisAdd;      }      fhiPtr->setNextByte(stageBufferNextByte);    }    // Normal type of write, just write data to disk ...    else       emptyBuffer(tmpFlush, toWrite, fhiPtr, manager);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?