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 + -
显示快捷键?