os390platformutils.cpp

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

CPP
1,122
字号
/* * Copyright 1999-2004 The Apache Software Foundation. *  * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *  *      http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *//* * $Id: OS390PlatformUtils.cpp,v 1.19 2004/09/08 13:56:41 peiyongz Exp $ */// ---------------------------------------------------------------------------//  Includes// ---------------------------------------------------------------------------#ifdef OS390#define _OPEN_SYS#endif#ifndef APP_NO_THREADS#include    <pthread.h>#endif#include    <xercesc/util/PlatformUtils.hpp>#include    <xercesc/util/RuntimeException.hpp>#include    <xercesc/util/Janitor.hpp>#include    <stdio.h>#include    <stdlib.h>#include    <errno.h>#include    <libgen.h>#ifdef EXM_OS390#include    <timeb.h>#else#include    <sys/timeb.h>#endif#include    <string.h>#include    <unistd.h>#include    <limits.h>#include    <xercesc/util/XMLString.hpp>#include    <xercesc/util/XMLUniDefs.hpp>#include    <xercesc/util/XMLUni.hpp>#include    <xercesc/util/PanicHandler.hpp>#include    "Path390.hpp"#include    "FileHandleImpl.hpp"#include    <xercesc/util/OutOfMemoryException.hpp>#if defined (XML_USE_ICU_TRANSCODER)    #include <xercesc/util/Transcoders/ICU/ICUTransService.hpp>#elif defined (XML_USE_UNICONV390_TRANSCODER)    #include <xercesc/util/Transcoders/Uniconv390/Uniconv390TransService.hpp>#else   // use native transcoder    #include <xercesc/util/Transcoders/Iconv390/Iconv390TransService.hpp>#endif#if defined (XML_USE_ICU_MESSAGELOADER)    #include <xercesc/util/MsgLoaders/ICU/ICUMsgLoader.hpp>#elif defined (XML_USE_ICONV_MESSAGELOADER)    #include <xercesc/util/MsgLoaders/MsgCatalog/MsgCatalogLoader.hpp>#else   // use In-memory message loader    #include <xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.hpp>   //hint for the user to include this file.#endif#if defined (XML_USE_NETACCESSOR_SOCKET)    #include <xercesc/util/NetAccessors/Socket/SocketNetAccessor.hpp>#endifXERCES_CPP_NAMESPACE_BEGIN// ---------------------------------------------------------------------------//  Static data// ---------------------------------------------------------------------------static bool isPosixEnabled = false;// ---------------------------------------------------------------------------//  XMLPlatformUtils: Platform init method// ---------------------------------------------------------------------------void XMLPlatformUtils::platformInit(){// The next conditional section is to turn on support for allowing// the NEL character as a valid whitespace character. Once this is// enabled the parser is non-compliant with the XML standard.// Assumption: Once this is enabled, it cannot be reset and// should remain the same during the same process.#if defined XML_ALLOW_NELWS   try   {     XMLPlatformUtils::recognizeNEL(true);   }   catch(const OutOfMemoryException&)   {     throw;   }   catch (...)   {      panic(PanicHandler::Panic_SystemInit);   }#endif// The next section checks if Posix is enabled on the OS/390 system.// It stores the result in the static isPosixEnabled flag.// The __isPosixOn() native routine uses too much// overhead to call repeatedly at runtime so this will be the only// remaining call of it.// Assumption: Once this is enabled, it cannot be reset and// should remain the same during the same process.   try   {      if (__isPosixOn())      {        if (!isPosixEnabled)            isPosixEnabled = true;      }   }   catch(const OutOfMemoryException&)   {      throw;   }   catch (...)   {      panic(PanicHandler::Panic_SystemInit);   }}// ---------------------------------------------------------------------------//  XMLPlatformUtils: Private Static Methods// ---------------------------------------------------------------------------XMLNetAccessor* XMLPlatformUtils::makeNetAccessor(){#if defined (XML_USE_NETACCESSOR_SOCKET)    return new SocketNetAccessor();#else    return 0;#endif}////  This method is called by the platform independent part of this class//  when client code asks to have one of the supported message sets loaded.//  In our case, we use the ICU based message loader mechanism.//XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain){    XMLMsgLoader* retVal;    try    {#if defined (XML_USE_ICU_MESSAGELOADER)        retVal = new ICUMsgLoader(msgDomain);#elif defined (XML_USE_ICONV_MESSAGELOADER)        retVal = new MsgCatalogLoader(msgDomain);#else        retVal = new InMemMsgLoader(msgDomain);#endif    }    catch(const OutOfMemoryException&)    {        throw;    }    catch(...)    {        panic(PanicHandler::Panic_CantLoadMsgDomain);    }    return retVal;}////  This method is called very early in the bootstrapping process. This guy//  must create a transcoding service and return it. It cannot use any string//  methods, any transcoding services, throw any exceptions, etc... It just//  makes a transcoding service and returns it, or returns zero on failure.//XMLTransService* XMLPlatformUtils::makeTransService()#if defined (XML_USE_ICU_TRANSCODER){    return new ICUTransService;}#elif defined (XML_USE_UNICONV390_TRANSCODER){    return new Uniconv390TransService;}#else{    return new Iconv390TransService;}#endif// ---------------------------------------------------------------------------//  XMLPlatformUtils: The panic method// ---------------------------------------------------------------------------void XMLPlatformUtils::panic(const PanicHandler::PanicReasons reason){    fgUserPanicHandler? fgUserPanicHandler->panic(reason) : fgDefaultPanicHandler->panic(reason);	}// ---------------------------------------------------------------------------//  Local Functions// ---------------------------------------------------------------------------static void emptyBuffer(XMLByte* writeBuffer,                        size_t   bytesToWrite,                        FileHandleImpl* fhiPtr                        , MemoryManager* const manager){     FILE* fileHandle = (FILE*)fhiPtr->getHandle();     size_t bytesThisWrite = 0;     size_t bytesThisPass = 0;     int typeRecordLrecl = 0;     bool isTypeRecord = fhiPtr->isRecordType();     if (isTypeRecord)        typeRecordLrecl = fhiPtr->getLrecl();     // Try to write as many bytes as possible at a time to the file.     // If less than the total bytes were written then loop as many times     // as necessary until all bytes are written. For the case of     // an MVS dataset with "type=record" specified, we must not     // attempt to write more than one logical record at a time     // or it will fail and not return the number of bytes remaining.     while (bytesToWrite > 0)     {        if ((isTypeRecord) &&            (bytesToWrite > typeRecordLrecl))        {           bytesThisPass = typeRecordLrecl;        }        else           bytesThisPass = bytesToWrite;        bytesThisWrite = fwrite(writeBuffer, sizeof(XMLByte), bytesThisPass, fileHandle);        if (ferror(fileHandle))           ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile, manager);        bytesToWrite -= bytesThisWrite;        writeBuffer += bytesThisWrite;     }  // while (bytesToWrite > 0)  return;}static FileHandleImpl* openRead(char* tmpFileName                                , MemoryManager* const manager){     FileHandleImpl* retVal;     FILE* fileHandle = 0;     Path390 pathobj;     pathobj.setPath(tmpFileName);     int optionBufferSize = strlen("rb,");     // Check if we have fopen options specified in addition to a     // filename. If we do then we need to build a buffer that has     // "rb," followed by the options. Otherwise we just pass "rb"     // 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,"rb");     // Build the options buffer     if (pathobj.getfopenParms())     {        strcpy(optionBuffer + 2, ",");        strcpy(optionBuffer + 3, pathobj.getfopenParms());     }     // If we don't have a valid path specified just exit now     if (pathobj.getfopenPath() == NULL)        return 0;     // Take the file handle returned by fopen and create an instance     // of the FileHandleImpl class.     fileHandle = fopen(pathobj.getfopenPath(), optionBuffer);     retVal = new (manager) FileHandleImpl(fileHandle, _FHI_READ, pathobj.isRecordType(), 0, manager);     // 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()) && (fileHandle != NULL))     {        int fldata_rc = 0;        fldata_t fileinfo;        fldata_rc = fldata(fileHandle, pathobj.getfopenPath(), &fileinfo);        if (fldata_rc)           ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile, manager);        if (fileinfo.__dsorgHFS)        {           if (fclose(fileHandle))              ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile, manager);           fileHandle=fopen(pathobj.getfopenPath(), "rb");           retVal->setHandle(fileHandle);           retVal->setRecordType(_FHI_NOT_TYPE_RECORD);        }     }     // End temp fix ......    if ((fileHandle == NULL) && (pathobj.getPathType() == PATH390_OTHER)) {    //    // We failed to open the file using its native format (OE or MVS)    // Try to go an extra step to map the path into a MVS dataset under BATCH:    //    //     /path/path2/filename.ext => //'path.path2.ext(filename)'    //     /path/path2/filename     => //'path.path2.filename'    // and    //     path/path2/filename.ext  => //path.path2.ext(filename)    //     path/path2/filename      => //path.path2.filename    char* datasetName = (char*) manager->allocate    (        (strlen(tmpFileName) + 5) * sizeof(char)    );//new char[ strlen(tmpFileName) + 5 ];    ArrayJanitor<char> janText1((char*)datasetName, manager);    char *datasetPos = datasetName, *tmpPos = tmpFileName;    // We are in EBCDIC mode here    // Specify "//" to indicate that the filename refers to a non-POSIX file    // or a MVS data set    strcpy(datasetName, "//");    datasetPos += 2;    // If we have a leading '/' then the path is absolute    if( *tmpPos == '/' ) {        *datasetPos++ = '\'';        tmpPos++;    }    // Find the last '/' in the path - this seperates the path from the    // filename.  Then copy the pathname.    char* pathEnd = strrchr( tmpPos, '/' );    if( pathEnd == NULL ) pathEnd = tmpPos - 1;    while( tmpPos <= pathEnd ) {        switch( *tmpPos ) {                case '/':                        *datasetPos = '.';                        break;                default:                        *datasetPos = *tmpPos;        }        datasetPos++; tmpPos++;    }    // Now we try to locate the extension, and copy that.

⌨️ 快捷键说明

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