You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xerces.apache.org by tn...@apache.org on 2002/11/22 15:57:32 UTC

cvs commit: xml-xerces/c/src/xercesc/util/Platforms/OS390 FileHandleImpl.cpp FileHandleImpl.hpp Path390.cpp Path390.hpp Makefile.in OS390PlatformUtils.cpp

tng         2002/11/22 06:57:32

  Modified:    c/src/xercesc/util/Platforms/OS390 Makefile.in
                        OS390PlatformUtils.cpp
  Added:       c/src/xercesc/util/Platforms/OS390 FileHandleImpl.cpp
                        FileHandleImpl.hpp Path390.cpp Path390.hpp
  Log:
  390: support record-oriented MVS datasets with the DOM Level 3 serialization APIs.  Patch by Chris Larsson and Stephen Dulin.
  
  Revision  Changes    Path
  1.3       +7 -1      xml-xerces/c/src/xercesc/util/Platforms/OS390/Makefile.in
  
  Index: Makefile.in
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/Platforms/OS390/Makefile.in,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- Makefile.in	26 Jul 2002 16:49:28 -0000	1.2
  +++ Makefile.in	22 Nov 2002 14:57:32 -0000	1.3
  @@ -54,6 +54,9 @@
   # <http://www.apache.org/>.
   #
   # $Log$
  +# Revision 1.3  2002/11/22 14:57:32  tng
  +# 390: support record-oriented MVS datasets with the DOM Level 3 serialization APIs.  Patch by Chris Larsson and Stephen Dulin.
  +#
   # Revision 1.2  2002/07/26 16:49:28  tng
   # [Bug 2681] Can't build with gcc/g++ not named 'gcc'/'g++'.  Patch from Jonathan Lennox.
   #
  @@ -94,6 +97,9 @@
   
   SUBMODULE = Platforms/OS390
   CPP_PUBHEADERS = OS390Defs.hpp
  -CPP_OBJECTS = OS390PlatformUtils.$(TO)
  +CPP_OBJECTS = \
  +         OS390PlatformUtils.$(TO) \
  +         Path390.$(TO) \
  +         FileHandleImpl.$(TO)
   
   include ../../Makefile.util.submodule
  
  
  
  1.6       +509 -309  xml-xerces/c/src/xercesc/util/Platforms/OS390/OS390PlatformUtils.cpp
  
  Index: OS390PlatformUtils.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xerces/c/src/xercesc/util/Platforms/OS390/OS390PlatformUtils.cpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- OS390PlatformUtils.cpp	4 Nov 2002 15:13:01 -0000	1.5
  +++ OS390PlatformUtils.cpp	22 Nov 2002 14:57:32 -0000	1.6
  @@ -1,7 +1,7 @@
   /*
    * The Apache Software License, Version 1.1
    *
  - * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  + * Copyright (c) 1999-2002 The Apache Software Foundation.  All rights
    * reserved.
    *
    * Redistribution and use in source and binary forms, with or without
  @@ -88,9 +88,13 @@
   #include    <xercesc/util/XMLString.hpp>
   #include    <xercesc/util/XMLUniDefs.hpp>
   #include    <xercesc/util/XMLUni.hpp>
  +#include    "Path390.hpp"
  +#include    "FileHandleImpl.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
  @@ -119,20 +123,21 @@
   
   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
  -	{
  +   try
  +   {
        XMLPlatformUtils::recognizeNEL(true);
  -	}
  -	catch (...)
  -	{
  -	   panic(XMLPlatformUtils::Panic_SystemInit);
  -	}
  +   }
  +   catch (...)
  +   {
  +      panic(XMLPlatformUtils::Panic_SystemInit);
  +   }
   #endif
   
   // The next section checks if Posix is enabled on the OS/390 system.
  @@ -143,20 +148,19 @@
   // Assumption: Once this is enabled, it cannot be reset and
   // should remain the same during the same process.
   
  -#ifdef OS390BATCH
  -	try
  -	{
  -	   if (__isPosixOn())
  -	   {
  +   try
  +   {
  +      if (__isPosixOn())
  +      {
           if (!isPosixEnabled)
               isPosixEnabled = true;
  -	   }
  -	}
  -	catch (...)
  -	{
  -	   panic(XMLPlatformUtils::Panic_SystemInit);
  -	}
  -#endif
  +      }
  +   }
  +   catch (...)
  +   {
  +      panic(XMLPlatformUtils::Panic_SystemInit);
  +   }
  +
   }
   
   // ---------------------------------------------------------------------------
  @@ -193,7 +197,7 @@
   
       catch(...)
       {
  -	panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
  +   panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
       }
       return retVal;
   }
  @@ -210,6 +214,11 @@
   
       return new ICUTransService;
   }
  +#elif defined (XML_USE_UNICONV390_TRANSCODER)
  +{
  +
  +    return new Uniconv390TransService;
  +}
   #else
   {
       return new Iconv390TransService;
  @@ -245,55 +254,119 @@
   
   
   // ---------------------------------------------------------------------------
  -//  XMLPlatformUtils: File Methods
  +//  Local Functions
   // ---------------------------------------------------------------------------
  -unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  -{
  -    // Get the current position
  -    int curPos = ftell( (FILE*)theFile);
  -    if (curPos == -1)
  -		ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize);
  +static void emptyBuffer(XMLByte* writeBuffer,
  +                        size_t   bytesToWrite,
  +                        FileHandleImpl* fhiPtr)
  +{
  +     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;
   
  -    return (unsigned int)curPos;
  -}
  +        }
  +        else
  +           bytesThisPass = bytesToWrite;
   
  -void XMLPlatformUtils::closeFile(FileHandle theFile)
  -{
  -    if (fclose((FILE*)theFile))
  -		ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  +        bytesThisWrite = fwrite(writeBuffer, sizeof(XMLByte), bytesThisPass, fileHandle);
  +
  +        if (ferror(fileHandle))
  +           ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  +
  +        bytesToWrite -= bytesThisWrite;
  +        writeBuffer += bytesThisWrite;
  +     }  // while (bytesToWrite > 0)
  +
  +  return;
   }
   
  -unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  +
  +static FileHandleImpl* openRead(char* tmpFileName)
   {
  -    // Get the current position
  -    long  int curPos = ftell((FILE*)theFile);
  -    if (curPos == -1)
  -		ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  +     FileHandleImpl* retVal;
  +     FILE* fileHandle = 0;
  +     Path390 pathobj;
  +     pathobj.setPath(tmpFileName);
  +     int optionBufferSize = strlen("rb,");
   
  -    // Seek to the end and save that value for return
  -     if (fseek( (FILE*)theFile, 0, SEEK_END) )
  -		ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
  +     // 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.
   
  -    long int retVal = ftell( (FILE*)theFile);
  -    if (retVal == -1)
  -		ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
  +     if (pathobj.getfopenParms())
  +     {
  +        optionBufferSize += (strlen(pathobj.getfopenParms()) + 1);
  +     }
   
  +     char* optionBuffer = new char[optionBufferSize];
  +     ArrayJanitor<char> janText((char*)optionBuffer);
  +     strcpy(optionBuffer,"rb");
   
  -    // And put the pointer back
  -    if (fseek( (FILE*)theFile, curPos, SEEK_SET) )
  -		ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToPos);
  +     // Build the options buffer
   
  -    return (unsigned int)retVal;
  -}
  +     if (pathobj.getfopenParms())
  +     {
  +        strcpy(optionBuffer + 2, ",");
  +        strcpy(optionBuffer + 3, pathobj.getfopenParms());
  +     }
   
  -FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  -{
  -    char* tmpFileName = XMLString::transcode(fileName);
  -    ArrayJanitor<char> janText((char*)tmpFileName);
  -    FileHandle retVal = (FILE*)fopen( tmpFileName , "rb" );
  +     // 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 FileHandleImpl(fileHandle, _FHI_READ, pathobj.isRecordType());
   
  -#ifdef OS390BATCH
  -    if (retVal == NULL) {
  +     // 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)
  +           ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  +
  +        if (fileinfo.__dsorgHFS)
  +        {
  +           if (fclose(fileHandle))
  +              ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  +
  +           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:
  @@ -305,7 +378,7 @@
       //     path/path2/filename      => //path.path2.filename
   
       char* datasetName = new char[ strlen(tmpFileName) + 5 ];
  -    ArrayJanitor<char> janText((char*)datasetName);
  +    ArrayJanitor<char> janText1((char*)datasetName);
       char *datasetPos = datasetName, *tmpPos = tmpFileName;
   
       // We are in EBCDIC mode here
  @@ -313,7 +386,7 @@
       // or a MVS data set
   
       strcpy(datasetName, "//");
  -    *datasetPos += 2;
  +    datasetPos += 2;
   
       // If we have a leading '/' then the path is absolute
   
  @@ -361,283 +434,405 @@
       if( *tmpFileName == '/' ) *datasetPos++ = '\'';
       *datasetPos = '\0';
   
  -    retVal = (FILE*)fopen( datasetName , "rb" );
  +    fileHandle = fopen( datasetName , optionBuffer);
  +    retVal->setHandle(fileHandle);
   
       }
  -#endif
   
       // 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 (retVal == NULL) {
  -	if ((tmpFileName[0] == '/') && (tmpFileName[1] == '/')) {
  -	    char *srcName = tmpFileName + 1; // points past the first '/'
  -	    retVal = (FILE*)fopen( srcName , "rb" );
  -	}
  +
  +    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)
  +                 ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  +
  +               if (fileinfo.__dsorgHFS)
  +               {
  +                  if (fclose(fileHandle))
  +                     ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  +
  +                  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;
       }
   
  -    if( retVal == NULL )
  -	return 0;
       return retVal;
  +
   }
   
  -FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  +
  +static FileHandleImpl* openWrite(char* tmpFileName)
   {
  -    FileHandle retVal = (FILE*)fopen( fileName , "rb" );
  +    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 = new char[optionBufferSize];
  +    ArrayJanitor<char> janText((char*)optionBuffer);
  +    strcpy(optionBuffer,"wb");
   
  -#ifdef OS390BATCH
  -    if (retVal == NULL) {
  -    //
  -    // 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
  +    // Build the options buffer
   
  -    char* datasetName = new char[ strlen(fileName) + 5 ];
  -    ArrayJanitor<char> janText((char*)datasetName);
  -    char *datasetPos = datasetName, *tmpPos = (char *)fileName;
  +    if (pathobj.getfopenParms())
  +    {
  +       strcpy(optionBuffer + 2, ",");
  +       strcpy(optionBuffer + 3, pathobj.getfopenParms());
  +    }
   
  -    // We are in EBCDIC mode here
  -    // Specify "//" to indicate that the filename refers to a non-POSIX file
  -    // or a MVS data set
  +    // FileHandleImpl class. The constructor will allocate our staging
  +    // buffer if it is a "type=record" open.
   
  -    strcpy(datasetName, "//");
  -    *datasetPos += 2;
  +    fileHandle = fopen(pathobj.getfopenPath(),optionBuffer);
   
  -    // If we have a leading '/' then the path is absolute
  +    // 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( *tmpPos == '/' ) {
  -        *datasetPos++ = '\'';
  -        tmpPos++;
  -    }
  +    if (pathobj.isRecordType())
  +    {
  +       isTypeRecord = _FHI_TYPE_RECORD;
  +       fldata_rc = fldata(fileHandle, pathobj.getfopenPath(), &fileinfo);
   
  -    // Find the last '/' in the path - this seperates the path from the
  -    // filename.  Then copy the pathname.
  +       if (fldata_rc)
  +          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
   
  -    char* pathEnd = strrchr((char*) tmpPos, '/' );
  -    if( pathEnd == NULL ) pathEnd = tmpPos - 1;
  -    while( tmpPos <= pathEnd ) {
  -        switch( *tmpPos ) {
  -                case '/':
  -                        *datasetPos = '.';
  -                        break;
  -                default:
  -                        *datasetPos = *tmpPos;
  -        }
  -        datasetPos++; tmpPos++;
  -    }
  +       fileLrecl = fileinfo.__maxreclen;
   
  -    // Now we try to locate the extension, and copy that.
  +       // 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.
   
  -    char* extStart = strrchr((char*) fileName, '.' );
  -    if ( extStart != NULL ) {
  -        tmpPos = extStart + 1;
  -        while( *tmpPos != '\0' ) {
  -                *datasetPos++ = *tmpPos++;
  -        }
  -        *datasetPos++ = '(';
  -    }
  +       if (fileinfo.__dsorgHFS)
  +       {
  +          if (fclose(fileHandle))
  +            ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
   
  -    // Now we copy in the filename.
  +          fileHandle=fopen(pathobj.getfopenPath(), "wb");
  +
  +       }
  +      // end temp fix
   
  -    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( *fileName == '/' ) *datasetPos++ = '\'';
  -    *datasetPos = '\0';
  +    // 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.
   
  -    retVal = (FILE*)fopen( datasetName , "rb" );
  +    if (fileHandle == NULL)
  +       retVal = 0;
  +    else
  +       retVal = new FileHandleImpl(fileHandle, _FHI_WRITE, isTypeRecord,fileLrecl);
   
  -    }
  -#endif
  +    return retVal;
  +}
   
  -    // fix for file:// protocol
  -    // the fileName 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 (retVal == NULL) {
  -	if ((fileName[0] == '/') && (fileName[1] == '/')) {
  -	    const char *srcName = fileName + 1; // points past the first '/'
  -	    retVal = (FILE*)fopen( srcName , "rb" );
  -	}          	
  +
  +// ---------------------------------------------------------------------------
  +//  XMLPlatformUtils: File Methods
  +// ---------------------------------------------------------------------------
  +unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  +{
  +    // Get the current position
  +    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;
  +    FILE* fileHandle = (FILE*)fhiPtr->getHandle();
  +    int curPos = ftell(fileHandle);
  +
  +    if (curPos == -1)
  +       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize);
  +
  +    return (unsigned int)curPos;
  +}
  +
  +void XMLPlatformUtils::closeFile(FileHandle theFile)
  +{
  +    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);
       }
   
  -    if( retVal == NULL )
  -        return 0;
  -    return retVal;
  +    // Do the regular close stuff ....
  +
  +    if (fclose(fileHandle))
  +       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  +
  +    // Delete the instance of the FileHandleImpl class (this will free the
  +    // staging buffer for us)
  +
  +    delete fhiPtr;
  +
   }
   
  -FileHandle XMLPlatformUtils::openFileToWrite(const XMLCh* const fileName)
  +unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
   {
  -    const char* tmpFileName = XMLString::transcode(fileName);
  -    ArrayJanitor<char> janText((char*)tmpFileName);
  -    char* semicolon;
  -    char* optStart;
  -    int   optOffset = 0;
  -    int   dsnSize = 0;
  -    int   optSize = 0;
  -
  -    // Check if this is an MVS dataset. If it is we need to allow
  -    // DCB options to be passed in the URI we get. The options
  -    // will be after the ";" in the URI in this case.
  -    if ((tmpFileName[0] == '/') && (tmpFileName[1] == '/'))
  -    {
  -       semicolon = strrchr((char*)tmpFileName,';');
  -       if (semicolon == NULL)
  -          dsnSize = strlen(tmpFileName);
  -       else
  -       {
  -          dsnSize = semicolon - tmpFileName;
  -          optStart = semicolon;
  -          optStart++;
  -          optOffset = optStart - tmpFileName;
  -          optSize = (strlen(tmpFileName) - optOffset);
  -        }
  +    // Get the current position
  +    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;
  +    FILE* fileHandle = (FILE*)fhiPtr->getHandle();
  +    long  int curPos = ftell(fileHandle);
   
  -        // Make a copy of the dataset name to pass to fopen
  -        char* dsnbuf = new char[dsnSize + 1];
  -        ArrayJanitor<char> janText1((char*)dsnbuf);
  -        strncpy(dsnbuf, tmpFileName, dsnSize);
  -
  -        // If no options specified, then we just put a "wb" in there.
  -        // Otherwise we put a "wb" followed by a comma followed by
  -        // the options string.
  -        if (optSize == 0)
  -           optSize += 3;
  -        else
  -           optSize += 4;
  +    if (curPos == -1)
  +       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
   
  -        // Save the options for fopen
  -        char* optbuf = new char[optSize];
  -        ArrayJanitor<char> janText2((char*)optbuf);
  -        strcpy(optbuf, "wb");
  +    // Seek to the end and save that value for return
  +     if (fseek(fileHandle, 0, SEEK_END))
  +        ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
   
  -        if (optSize != 3)
  -        {
  -           strcpy(optbuf + 2, ",");
  -           strncpy(optbuf +3, optStart, optSize);
  -        }
  +    long int retVal = ftell(fileHandle);
   
  -        return fopen(dsnbuf, optbuf);
  +    if (retVal == -1)
  +       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
   
  -    }
  -    else
  -       return fopen(tmpFileName, "wb");
   
  +    // And put the pointer back
  +    if (fseek(fileHandle, curPos, SEEK_SET) )
  +       ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToPos);
  +
  +    return (unsigned int)retVal;
   }
   
  -FileHandle XMLPlatformUtils::openFileToWrite(const char* const fileName)
  +FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
   {
  -    char* semicolon;
  -    char* optStart;
  -    int   optOffset = 0;
  -    int   dsnSize = 0;
  -    int   optSize = 0;
  -
  -    // Check if this is an MVS dataset. If it is we need to allow
  -    // DCB options to be passed in the URI we get. The options
  -    // will be after the ";" in the URI in this case.
  -    if ((fileName[0] == '/') && (fileName[1] == '/'))
  -    {
  -       semicolon = strrchr((char*)fileName,';');
  -       if (semicolon == NULL)
  -          dsnSize = strlen(fileName);
  -       else
  -       {
  -          dsnSize = semicolon - fileName;
  -          optStart = semicolon;
  -          optStart++;
  -          optOffset = optStart - fileName;
  -          optSize = (strlen(fileName) - optOffset);
  -        }
  +    char* tmpFileName = XMLString::transcode(fileName);
  +    ArrayJanitor<char> janText((char*)tmpFileName);
   
  -        // Make a copy of the dataset name to pass to fopen
  -        char* dsnbuf = new char[dsnSize + 1];
  -        ArrayJanitor<char> janText1((char*)dsnbuf);
  -        strncpy(dsnbuf, fileName, dsnSize);
  -
  -        // If no options specified, then we just put a "wb" in there.
  -        // Otherwise we put a "wb" followed by a comma followed by
  -        // the options string.
  -        if (optSize == 0)
  -           optSize += 3;
  -        else
  -           optSize += 4;
  +    return openRead(tmpFileName);
  +}
   
  -        // Save the options for fopen
  -        char* optbuf = new char[optSize];
  -        ArrayJanitor<char> janText2((char*)optbuf);
  -        strcpy(optbuf, "wb");
   
  -        if (optSize != 3)
  -        {
  -           strcpy(optbuf + 2, ",");
  -           strncpy(optbuf +3, optStart, optSize);
  -        }
  +FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  +{
  +    char* tmpFileName = new char[strlen(fileName) + 1];
  +    ArrayJanitor<char> janText((char*)tmpFileName);
  +    strcpy(tmpFileName,fileName);
   
  -        return fopen(dsnbuf, optbuf);
  +    return openRead(tmpFileName);
  +}
   
  -    }
  -    else
  -       return fopen(fileName, "wb");
   
  +FileHandle XMLPlatformUtils::openFileToWrite(const XMLCh* const fileName)
  +{
  +    char* tmpFileName = XMLString::transcode(fileName);
  +    ArrayJanitor<char> janText((char*)tmpFileName);
  +
  +    return openWrite(tmpFileName);
   }
   
  +
  +FileHandle XMLPlatformUtils::openFileToWrite(const char* const fileName)
  +{
  +    char* tmpFileName = new char[strlen(fileName) + 1];
  +    ArrayJanitor<char> janText((char*)tmpFileName);
  +    strcpy(tmpFileName,fileName);
  +
  +    return openWrite(tmpFileName);
  +}
  +
  +
   void
   XMLPlatformUtils::writeBufferToFile( FileHandle     const  theFile
                                      , long                  toWrite
                                      , const XMLByte* const  toFlush)
   {
  -    if (!theFile        ||
  +    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;
  +    FILE* fileHandle = (FILE*)fhiPtr->getHandle();
  +
  +    if (!fileHandle     ||
           (toWrite <= 0 ) ||
  -        !toFlush         )
  +        !toFlush )
           return;
   
  -    const XMLByte* tmpFlush = (const XMLByte*) toFlush;
  -    size_t bytesWritten = 0;
  +    XMLByte* tmpFlush = (XMLByte*) toFlush;
   
  -    while (true)
  +    // 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())
       {
  -        bytesWritten=fwrite(tmpFlush, sizeof(XMLByte), toWrite, (FILE*)theFile);
  +       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.
   
  -        if(ferror((FILE*)theFile))
  -        {
  -            ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  -        }
  +       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);
  +             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;
  +      }
   
  -        if (bytesWritten < toWrite) //incomplete write
  -        {
  -            tmpFlush+=bytesWritten;
  -            toWrite-=bytesWritten;
  -            bytesWritten=0;
  -        }
  -        else
  -            return;
  +      fhiPtr->setNextByte(stageBufferNextByte);
       }
   
  -    return;
  +    // Normal type of write, just write data to disk ...
  +
  +    else
  +       emptyBuffer(tmpFlush, toWrite, fhiPtr);
  +
  +  return;
   }
   
  +
   unsigned int
   XMLPlatformUtils::readFileBuffer(  FileHandle      theFile
                                   , const unsigned int    toRead
                                   , XMLByte* const  toFill)
   {
  -    size_t noOfItemsRead = fread( (void*) toFill, 1, toRead, (FILE*)theFile);
  +    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;
  +    FILE* fileHandle = (FILE*)fhiPtr->getHandle();
  +    size_t noOfItemsRead = 0;
  +    bool isTypeRecord = fhiPtr->isRecordType();
  +
  +    // On a read, if this was a "type=record" open then we do not want
  +    // to return any terminating NULLS that fill out a logical
  +    // record. We also will discard a record that is all NULLS.
   
  -    if(ferror((FILE*)theFile))
  +    while (true)
       {
  -		ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  -    }
  +       noOfItemsRead = fread( (void*) toFill, 1, toRead, fileHandle);
  +
  +       if(ferror(fileHandle))
  +          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  +
  +       if (isTypeRecord)
  +       {
  +          if (noOfItemsRead == 0)
  +              break;
  +
  +          // Go thru the data we read and strip off trailing NULLS
  +          // until a non-NULL is encountered. If a record is all
  +          // NULLS then we discard it.
  +
  +          bool recordIsValid = false;
  +
  +          for (int i = noOfItemsRead; i > 0; i--)
  +          {
  +             if (toFill[i - 1])
  +             {
  +                recordIsValid = true;
  +                break;
  +             }
  +             else
  +                noOfItemsRead--;
  +          }
  +
  +          // If we didn't hit a non-NULL we need will go read another
  +          // record in hopes of returning some valid data.
  +
  +          if (recordIsValid)
  +             break;
  +          else
  +          {
  +             noOfItemsRead = 0;
  +             break;
  +          }
  +       } // isTypeRecord
  +       // for a "non-type=record" read we do only one read
  +       else
  +          break;
  +    }  // while (true)
   
       return (unsigned int)noOfItemsRead;
   }
  @@ -646,11 +841,12 @@
   void XMLPlatformUtils::resetFile(FileHandle theFile)
   {
       // Seek to the start of the file
  -    if (fseek((FILE*)theFile, 0, SEEK_SET) )
  -	ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
  +    FileHandleImpl* fhiPtr = (FileHandleImpl*) theFile;
  +    FILE* fileHandle = (FILE*)fhiPtr->getHandle();
  +    if (fseek(fileHandle, 0, SEEK_SET) )
  +   ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
   }
   
  -
   // ---------------------------------------------------------------------------
   //  XMLPlatformUtils: File system methods
   // ---------------------------------------------------------------------------
  @@ -665,22 +861,23 @@
       char* newSrc = XMLString::transcode(srcPath);
       ArrayJanitor<char> janText(newSrc);
   
  -    if ( (newSrc != NULL) && (newSrc[0] != NULL) && (newSrc[1] != NULL) && //@DEM
  -         (newSrc[0] == '/') && (newSrc[1] == '/') )       //@DEM
  -        return XMLString::transcode(newSrc);              //@DEM
  +    Path390 pathobj;
  +    pathobj.setPath(newSrc);
   
  +    char* retPath = 0;
       // Use a local buffer that is big enough for the largest legal path
       char *absPath = new char[_POSIX_PATH_MAX];
       ArrayJanitor<char> janText2(absPath);
  -	//get the absolute path
  -	char* retPath = realpath(newSrc, absPath);
  -
   
  -    if (!retPath)
  -    {
  -                ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName);
  +    if ( (pathobj.getPathType() == PATH390_HFS) || (pathobj.getPathType() == PATH390_OTHER) ) {
  +       //get the absolute path
  +       char* retPath = realpath(pathobj.getfopenPath(), absPath);
  +       if (!retPath) {
  +          ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName);
  +          }
  +       return XMLString::transcode(absPath);
       }
  -    return XMLString::transcode(absPath);
  +    return XMLString::transcode(newSrc);
   }
   
   bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  @@ -700,7 +897,6 @@
       if (toCheck[0] == 0x2F)
           return false;
   
  -#ifdef OS390BATCH
       //
       //  Determine whether we are using the DD convention
       //  'D': 0x44 'd': 0x64 ':': 0x3A
  @@ -710,13 +906,22 @@
             ((toCheck[0] == (0x44)) || (toCheck[0] == (0x64))) &&
             ((toCheck[1] == (0x44)) || (toCheck[1] == (0x64))) &&
             (toCheck[2] == XMLCh(0x3A))
  -	 )
  -	return false;
  +         )
  +         return false;
       }
  -#endif
   
  -    // Else assume its a relative path
  -    return true;
  +    char* tmpFileName = XMLString::transcode(toCheck);
  +    ArrayJanitor<char> janText((char*)tmpFileName);
  +    Path390 pathobj;
  +    pathobj.setPath(tmpFileName);
  +
  +    // let Path390 do the final determination
  +    return pathobj.isRelative();
  +
  +
  +
  +
  +
   }
   
   XMLCh* XMLPlatformUtils::weavePaths
  @@ -807,7 +1012,7 @@
   
               // The base cannot provide enough levels, so its in error/
               if (basePtr < basePath)
  -				ThrowXML(XMLPlatformUtilsException,	XMLExcepts::File_BasePathUnderflow);
  +            ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_BasePathUnderflow);
   
           }
       }
  @@ -837,6 +1042,7 @@
   
   }
   
  +
   // -----------------------------------------------------------------------
   //  Mutex methods
   //  OS390BATCH: Unless POSIX(ON) is specified, pthread functions are
  @@ -848,57 +1054,47 @@
   {
       if (mtxHandle == NULL)
           return;
  -#ifdef OS390BATCH
       if (isPosixEnabled) {
  -#endif
       if (pthread_mutex_destroy( (pthread_mutex_t*)mtxHandle))
       {
  -	ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotDestroy);
  +   ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotDestroy);
       }
       if ( (pthread_mutex_t*)mtxHandle)
           delete mtxHandle;
  -#ifdef OS390BATCH
       } // __isPosixOn
       else {
       if ( (int*)mtxHandle)
           delete mtxHandle;
       }
  -#endif
   }
   void XMLPlatformUtils::lockMutex(void* const mtxHandle)
   {
       if (mtxHandle == NULL)
           return;
  -#ifdef OS390BATCH
       if (isPosixEnabled) {
  -#endif
       if (pthread_mutex_lock( (pthread_mutex_t*)mtxHandle))
       {
  -	ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotLock);
  +   ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotLock);
       }
  -#ifdef OS390BATCH
       } // __isPosixOn
       else {
  -	int locked = 1, unlocked;
  +   int locked = 1, unlocked;
   
       do {
           unlocked = 0;
           compareAndSwap( (void**) &mtxHandle, (void*) locked, (void*) unlocked );
       } while( unlocked != 0 );
       }
  -#endif
       return;
   
   }
   void* XMLPlatformUtils::makeMutex()
   {
  -#ifdef OS390BATCH
       if (isPosixEnabled) {
  -#endif
       pthread_mutex_t* mutex = new pthread_mutex_t;
       if (mutex == NULL)
       {
  -	ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotCreate);
  +   ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotCreate);
       }
   
       pthread_mutexattr_t*  attr = new pthread_mutexattr_t;
  @@ -914,33 +1110,27 @@
   
       return (void*)(mutex);
   
  -#ifdef OS390BATCH
       } // __isPosixOn
       else {
  -	int* mutex = new int;
  -	*mutex = 0;
  -	return (void*)(mutex);
  +   int* mutex = new int;
  +   *mutex = 0;
  +   return (void*)(mutex);
       }
  -#endif
   }
   void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
   {
       if (mtxHandle == NULL)
           return;
  -#ifdef OS390BATCH
       if (isPosixEnabled) {
  -#endif
       if (pthread_mutex_unlock( (pthread_mutex_t*)mtxHandle))
       {
  -	ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotUnlock);
  +   ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotUnlock);
       }
  -#ifdef OS390BATCH
       } // __isPosixOn
       else {
  -	if (*(int*) mtxHandle == 0 )
  -	*(int*) mtxHandle = 0;
  +   if (*(int*) mtxHandle == 0 )
  +   *(int*) mtxHandle = 0;
       }
  -#endif
   }
   
   #else // #ifndef APP_NO_THREADS
  @@ -964,6 +1154,7 @@
   
   #endif // APP_NO_THREADS
   
  +
   // -----------------------------------------------------------------------
   //  Miscellaneous synchronization methods
   // -----------------------------------------------------------------------
  @@ -1001,7 +1192,16 @@
   
   FileHandle XMLPlatformUtils::openStdInHandle()
   {
  -    return (FileHandle)fdopen(dup(0), "rb");
  +     FileHandleImpl* retVal;
  +     FILE* fileHandle = 0;
  +     fileHandle = fdopen(dup(0), "rb");
  +     if (fileHandle)
  +        retVal = new FileHandleImpl(fileHandle, _FHI_READ, _FHI_NOT_TYPE_RECORD);
  +     else
  +        retVal = 0;
  +
  +     return retVal;
  +
   }
   
   void XMLPlatformUtils::platformTerm()
  
  
  
  1.1                  xml-xerces/c/src/xercesc/util/Platforms/OS390/FileHandleImpl.cpp
  
  Index: FileHandleImpl.cpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 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 apache\@apache.org.
   *
   * 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: FileHandleImpl.cpp,v 1.1 2002/11/22 14:57:32 tng Exp $
   */
  
  #include <fstream.h>
  #include <stdio.h>
  #include <ctype.h>
  #include <typeinfo>
  #define _XOPEN_SOURCE_EXTENDED 1
  #include <stdlib.h>
  #include <xercesc/util/XMLUniDefs.hpp>
  #include "FileHandleImpl.hpp"
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  //Constructor:
  FileHandleImpl::FileHandleImpl(FILE* open_handle, int o_type, bool r_type, int fileLrecl): Handle(open_handle), openType(o_type), recordType(r_type), lrecl(fileLrecl) {
  
     stgBufferPtr = 0;
     nextByte = 0;
  
     if ((openType == _FHI_WRITE) &&
         (recordType == _FHI_TYPE_RECORD) &&
         (lrecl != 0))
     {
        stgBufferPtr = new XMLByte [lrecl];
     }
  
  // printf("FileHandleImpl constructor called\n");
  // printf("stgBufferPtr is: x%8.8X\n", stgBufferPtr);
  // printf("Handle is: x%8.8X\n", Handle);
  // printf("openType is : %d\n",openType);
  // printf("recordType is : %d\n",recordType);
  // printf("lrecl is : %d\n",lrecl);
  
  }
  
  //Destructor:
  
  FileHandleImpl::~FileHandleImpl() {
  
  // printf("FileHandleImpl destructor called\n");
  // printf("stgBufferPtr is: x%8.8X\n", stgBufferPtr);
  // printf("Handle is: x%8.8X\n", Handle);
  // printf("openType is : %d\n",openType);
  // printf("recordType is : %d\n",recordType);
  
     if (stgBufferPtr != 0)
     {
  // printf("stgBufferPtr is being freed at: x%8.8X\n", stgBufferPtr);
        delete [] stgBufferPtr;
     }
  }
  
  XERCES_CPP_NAMESPACE_END
  
  
  
  1.1                  xml-xerces/c/src/xercesc/util/Platforms/OS390/FileHandleImpl.hpp
  
  Index: FileHandleImpl.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 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 apache\@apache.org.
   *
   * 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: FileHandleImpl.hpp,v 1.1 2002/11/22 14:57:32 tng Exp $
   */
  
  #ifndef FILEHANDLEIMPL_HPP
  #define FILEHANDLEIMPL_HPP
  
  #include <xercesc/util/XercesDefs.hpp>
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  class FileHandleImpl
  {
    private:
    FILE*      Handle;       // handle from fopen
    XMLByte*   stgBufferPtr; // address of staging buffer
    int        nextByte;     // NAB in staging buffer
    int        openType;     // 0=write, 1=read
    int        lrecl;        // LRECL if openType is write
    bool       recordType;   // true if "type=record"
  
    public:
    FileHandleImpl(FILE* open_handle, int o_type, bool r_type, int fileLrecl=0);
   ~FileHandleImpl();
    void  setHandle(FILE* newHandlePtr) { Handle = newHandlePtr; }
    void* getHandle() { return Handle; }
    XMLByte* getStgBufferPtr() { return stgBufferPtr; }
    int   getNextByte() { return nextByte; }
    void  setNextByte(int newNextByte)  { nextByte = newNextByte; }
    int   getOpenType() { return openType; }
    bool  isRecordType() { return recordType; }
    void  setRecordType(bool newType) { recordType = newType; }
    int   getLrecl() { return lrecl; }
    void  setLrecl(int newLrecl)  { lrecl = newLrecl; }
  };
  
  // Constants for the openType member
  #define _FHI_WRITE 0
  #define _FHI_READ 1
  // Constant for the typeRecord member
  #define _FHI_NOT_TYPE_RECORD 0
  #define _FHI_TYPE_RECORD 1
  
  XERCES_CPP_NAMESPACE_END
  
  #endif
  
  
  
  1.1                  xml-xerces/c/src/xercesc/util/Platforms/OS390/Path390.cpp
  
  Index: Path390.cpp
  ===================================================================
  
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 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 apache\@apache.org.
   *
   * 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: Path390.cpp,v 1.1 2002/11/22 14:57:32 tng Exp $
   */
  
  //#include "stdafx.h"
  #include <fstream.h>
  #include <stdio.h>
  #include <ctype.h>
  #include <typeinfo>
  #define _XOPEN_SOURCE_EXTENDED 1
  #include <stdlib.h>
  #include <string.h>
  #include "Path390.hpp"
  
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  //Constructors:
  Path390::Path390() {
     _error = 0;
     _absolute = false;
     _dsnabsolute = false;
     _parsestate=PARSE_NONE;
     _orgparms=0;
     _resultpath=0;
     _orgpath=0;
  }
  Path390::Path390(char * s) {
     _error = 0;
     _absolute = false;
     _dsnabsolute = false;
     _parsestate=PARSE_NONE;
     _orgparms=0;
     _resultpath=0;
     _orgpath=0;
     setPath(s);
  }
  
  
  //Destructor:
  Path390::~Path390() {
     if (_orgparms)
        free (_orgparms);
     if (_resultpath)
        free(_resultpath);
     if (_orgpath)
        free(_orgpath);
  }
  
  // This path parser is state driven in order to support an incremental parse of the input path.
  // This is so that, for example, someone only wants to determine whether the path is absolute or
  // relative, then it will only parse sufficient information to determine this. This information
  // is saved in the object so that this does not need to be re-parsed if later one wanted to
  // retrieve, for example, the parameters.
  // The states are:
  //    PARSE_NONE - initial state, nothing is parsed.
  //    PARSE_ABSOLUTE_URI - Absolute or relative path has been determined.
  //    PARSE_PATHTYPE - The type of the path has been determined
  //    PARSE_PUNCT - The important delimiters have been located to make later parsing simpler.
  //    PARSE_PARMS - The parms have been located and retrieved.
  //    PARSE_PARSED - The path has been fully parsed.
  //
  // Each of the following methods handle the parsing corresponding to each state.
  //
  
  
  
  
  // Determine if the path is absolute or relative.
  void Path390::_determine_uri_abs() {
     if (_parsestate == PARSE_NONE) {
        if (*_curpos == '/') {
           _uriabsolute=true;
           _curpos++;
        } else
           _uriabsolute=false;
        _parsestate = PARSE_ABSOLUTE_URI;
     }
  }
  
  
  // Determine the path type. This could be:
  //    PATH390_HFS - format is hfs:/xxx/xxx...
  //    PATH390_DSN1 - format is dsn:/xxx/xxx...
  //    PATH390_DSN2 - format is dsn://xxxxx...
  //    PATH390_DD - format is dd:xxx...
  //    PATH390_OTHER - format is any other paths.
  void Path390::_determine_type() {
     char firstfour[5];
     if (_parsestate == PARSE_ABSOLUTE_URI) {
        char * ff=firstfour;
        int ffi=0;
        while ((_curpos[ffi]) && (ffi<4)) {ff[ffi] = toupper(_curpos[ffi]); ffi++;}
  
        if ( (ffi>=4) && !strncmp(firstfour,"DSN:",4) ) {
           _pathtype = PATH390_DSN1;
           _curpos+=4;
           _absolute = true;
           if ( ((*_curpos) && (*_curpos == '/')) && ((*(_curpos+1)) && (*(_curpos+1) == '/')) ) {
              _pathtype = PATH390_DSN2;
              }
           }
        else if ( (ffi>=4) && !strncmp(firstfour,"HFS:",4) ) {
           _pathtype = PATH390_HFS;
           _curpos+=4;
           if (*_curpos == '/')
              _absolute = true;
           else
              _absolute = false;
           }
        else if ( (ffi>=3) && !strncmp(firstfour,"DD:",3) ) {
           _absolute = true;
           _pathtype = PATH390_DD;
           _curpos+=3;
           }
        else {
           _pathtype = PATH390_OTHER;
           if (_uriabsolute)
              _curpos--;
           }
        _parsestate = PARSE_PATHTYPE;
     }
  }
  
  // This takes one pass through the path any determines the location of important delimiters
  // including / ; . and (
  // It will also detect some error conditions
  void Path390::_determine_punct() {
  
     if (_parsestate == PARSE_PATHTYPE) {
        char * source = _curpos;
        _lastsemi = 0;
        _lastslash = 0;
        _lastparen = 0;
        _parmStart = 0;
        _pathEnd = 0;
        _numperiods = 0;
        _numsemicolons = 0;
        _extStart = 0;
        while (*source) {
           switch (*source) {
              case ';':
                 _lastsemi = source;
                 _parmStart = source+1;
                 _numsemicolons++;
                 break;
              case '/':
                 _lastslash = source;
                 _pathEnd = source;
                 break;
              case '.':
                 _extStart = source+1;
                 _numperiods++;
                 break;
              case '(':
                 _lastparen = source+1;
                 break;
           }
           *source++;
        }
        if ( (_parmStart) && (_parmStart<=_pathEnd) ) {
           _error = ERROR_SEMICOLON_NOT_ALLOWED;
           _lastsemi = 0;
           _parmStart = 0;
        }
        if ( ((_pathtype == PATH390_DD) || (_pathtype == PATH390_DSN1) || (_pathtype == PATH390_DSN1)) &&
             (_extStart <= _pathEnd) ) {
           if (_extStart)
              _error = ERROR_PERIOD_NOT_ALLOWED;
           _extStart = 0;
        }
        if (_extStart < _lastparen)
           _extStart = 0;
        _parsestate = PARSE_PUNCT;
     }
  }
  
  // This extracts the parameters from the path if there are any. It also determines if the parameters
  // contain type=record
  void Path390::_determine_parms() {
  
     if (_parsestate == PARSE_PUNCT) {
        char * tr = 0;
        if (_parmStart) {
           _orgparmlen = strlen(_parmStart)+1;
           _orgparms = (char *) malloc(_orgparmlen);
           char * ts=_parmStart;
           char * td=_orgparms;
           while (*ts)
             *td++ = tolower(*ts++);
           *td = 0;
           *_lastsemi = 0;
           tr = strstr(_orgparms,"type=record");
        }
        if (tr)
          _typerecord = tr - _orgparms;
        else
          _typerecord = -1;
  
        _parsestate = PARSE_PARMS;
     }
  }
  
  // Complete the rest of the parse.
  void Path390::_parse_rest() {
  
     if (_parsestate == PARSE_PARMS) {
        char *source;
        char *dest;
        char * filename_start;
        char * tmpPos;
        int pathlen = strlen(_curpos);
        _resultpath = (char *) malloc(pathlen+10);
  
        source = _curpos;
        dest = _resultpath;
  
        switch (_pathtype) {
           case PATH390_DSN1:
              // This format needs to be mangled from a hierarchical (hfs style) path to the
              // traditional MVS format. First check for some errors.
              if (_lastparen) {
                 _error = ERROR_NO_PAREN_ALLOWED;
                 break;
              }
  
              if ((_uriabsolute) && (!_absolute)) {
                 _error = ERROR_ABS_PATH_REQUIRED;
                 break;
              }
  
              if ( ((_extStart) && (_numperiods > 1)) ||
                   ((!_extStart) && (_numperiods)) ) {
                 _error = ERROR_NO_EXTRA_PERIODS_ALLOWED;
                 break;
              }
  
              if ( ((_parmStart) && (_numsemicolons > 1)) ||
                   ((!_parmStart) && (_numsemicolons)) ) {
                 _error = ERROR_NO_EXTRA_SEMIS_ALLOWED;
                 break;
              }
  
              // start out the result with //
              *dest++ = '/';
              *dest++ = '/';
              // If the input path starts with a / then it is absolute and it must be
              // enclosed in 's
              _dsnabsolute = false;
              if (*source == '/') {
                _dsnabsolute = true;
                source++;
              } else if (_uriabsolute) {
                 _error = ERROR_MUST_BE_ABSOLUTE;
                 break;
              }
  
              char * pathstart;
              pathstart = source;
  
              // Add in the ' if this is an absolute path'
              if (_dsnabsolute) *dest++ = '\'';
  
              // If there is a / in the path....
              tmpPos = source;
              if (_pathEnd > source) {
                 // copy everything up to the last /, replacing / with .
                 while( source < _pathEnd ) {
                    switch( *source ) {
                        case '/':
                           *dest = '.';
                           break;
                        default:
                           *dest = *source;
                    }
                    dest++; source++;
                 }
                 // bump past the last /
                 source++;
              }
  
              // Now we try to locate the extension, and copy that.
              filename_start = 0;
              if ( _extStart != NULL ) {
                 tmpPos = _extStart;
                 if ( (*tmpPos != '\0') && (*tmpPos != ';') && (source != pathstart) )
                    *dest++='.';
                 while ( (*tmpPos != '\0') && (*tmpPos != ';') ) {
                    *dest++ = *tmpPos++;
                 }
                 // if there is a filename, add a (
                 if (source < (_extStart-1)) {
                   filename_start = tmpPos;
                   *dest++ = '(';
                   }
              }
              else if (source != pathstart)
                 *dest++ = '.';
  
              // Now we copy in the filename.
              tmpPos = source;
              while( ((*tmpPos != '\0') && (*tmpPos != ';'))  && ((_extStart == NULL) || (tmpPos < (_extStart-1))) ) {
                 *dest++ = *tmpPos++;
              }
  
              // Finally cap off the filename with optional ")"
              if ( (_extStart != NULL) && (filename_start) ) *dest++ = ')';
  
              // Add on the ending ' if necessary.
              if (_dsnabsolute) *dest++ = '\'';
  
              // make it a null terminated string.
              *dest = '\0';
              break;
           case PATH390_HFS:
              // it is in hfs: format. If it is relative, then add on a ./ otherwise
              // just copy the string.
              if (!_absolute) {
                 if (_uriabsolute) {
                    _error = ERROR_MUST_BE_ABSOLUTE;
                    break;
                 }
                 *dest++='.';
                 *dest++='/';
              }
              strcpy(dest,source);
              break;
           case PATH390_DD:
              // It's in dd: format. This is similar to the dsn: format, just shorter.
              // Start it out with dd:
              *dest++='D';
              *dest++='D';
              *dest++=':';
  
              tmpPos = source;
              // if there is a / present in the path...
              if (_pathEnd > source) {
                 // copy everything up to the last /, replacing / with .
                 while( source < _pathEnd ) {
                    switch( *source ) {
                        case '/':
                           *dest = '.';
                           break;
                        default:
                           *dest = *source;
                    }
                    dest++; source++;
                 }
                 // bump past the last /
                 source++;
              }
  
              // Now we try to locate the extension, and copy that.
              filename_start = 0;
              if ( _extStart != NULL ) {
                 tmpPos = _extStart;
                 if ( (*tmpPos != '\0') && (*tmpPos != ';') && (source != _curpos) )
                    *dest++='.';
                 while ( (*tmpPos != '\0') && (*tmpPos != ';') ) {
                    *dest++ = *tmpPos++;
                 }
                 // if there is a filename, add a (
                 if (source < (_extStart-1)) {
                   filename_start = tmpPos;
                   *dest++ = '(';
                   }
              }
              else if (source != _curpos)
                 *dest++ = '.';
  
              // Now we copy in the filename.
              tmpPos = source;
              while( ((*tmpPos != '\0') && (*tmpPos != ';'))  && ((_extStart == NULL) || (tmpPos < (_extStart-1))) ) {
                 *dest++ = *tmpPos++;
              }
  
              // Finally cap off the filename with optional ")"
              if ( (_extStart != NULL) && (filename_start) ) *dest++ = ')';
  
              *dest = '\0';
              break;
           case PATH390_DSN2:
              // This is in dsn: format with the traditional MVS dataset name. Just fall into
              // the default case to copy the path to the destination after making sure that
              // there are no extra slashes.
              {
              int lastslash=5;
              if (_uriabsolute)
                lastslash=6;
              if ( (_lastslash) && ((_lastslash-_orgpath)>lastslash) ) {
                 _error = ERROR_BAD_DSN2;
                 break;
              }
              }
           default:
              // for all other cases simply copy over the string.
              strcpy(dest,source);
              break;
        }
        _parsestate = PARSE_PARSED;
     }
  
  
  }
  // Public methods start here:
  
  // This sets a new path into the object. Re-initialize everything and do an initial
  // parse.
  void Path390::setPath(char * s) {
     if (_orgparms)
        free (_orgparms);
     if (_resultpath)
        free(_resultpath);
     if (_orgpath)
        free(_orgpath);
     _error = 0;
     _absolute = false;
     _dsnabsolute = false;
     _orglen = strlen(s);
     _orgpath = (char *) malloc(_orglen+1);
     strcpy(_orgpath,s);
     _curpos = _orgpath;
     _parsestate=PARSE_NONE;
  
     // Do an initial parse...
     _determine_uri_abs();
     _determine_type();
  }
  
  // Do the parse to completion and return any errors found.
  int Path390::fullParse() {
  
     // Do an initial parse...
     _determine_uri_abs();
     _determine_type();
     _determine_punct();
     if (_error) {
  //      printf("found error-%d\n",_error);
        return _error;
     }
     _determine_parms();
  
     _parse_rest();
     return _error;
  }
  
  // Get the path in a format which is required by fopen. First make sure that the path is
  // completely parsed
  char * Path390::getfopenPath() {
  
     _determine_uri_abs();
     _determine_type();
     _determine_punct();
     if (_error)  {
  //      printf("found error-%d\n",_error);
        return 0;
     }
     _determine_parms();
     _parse_rest();
     if (_error)  {
  //      printf("found error-%d\n",_error);
        return 0;
     }
  
     if (_resultpath[0])
        return _resultpath;
     else
        return 0;
  }
  
  
  // Get the parms in a format which is required by fopen. First make sure that the path is
  // completely parsed
  char * Path390::getfopenParms() {
     _determine_uri_abs();
     _determine_type();
     _determine_punct();
     if (_error)  {
  //      printf("found error-%d\n",_error);
        return 0;
     }
     _determine_parms();
     _parse_rest();
     if (_error)  {
  //      printf("found error-%d\n",_error);
        return 0;
     }
  
     if ( (_orgparms) && (_orgparms[0]) )
        return _orgparms;
     else
        return 0;
  }
  
  // return whether there is type=record parameter in the parameter list.
  bool Path390::isRecordType() {
     _determine_uri_abs();
     _determine_type();
     _determine_punct();
     if (_error)  {
  //      printf("found error-%d\n",_error);
        return false;
     }
     _determine_parms();
     _parse_rest();
     if (_error)  {
  //      printf("found error-%d\n",_error);
        return false;
     }
     if ( (_orgparms) && (_typerecord>=0) )
        return true;
     else
        return false;
  }
  
  // This returns the path type
  int Path390::getPathType() {
     _determine_uri_abs();
     _determine_type();
     return _pathtype;
  }
  
  // This returns the error code which was found when the path was parsed
  int Path390::getError() {
     _determine_uri_abs();
     _determine_type();
     _determine_punct();
     if (_error)  {
   //     return _error;
     }
     _determine_parms();
     _parse_rest();
     if (_error)  {
   //     return _error;
     }
     return _error;
  }
  
  // returns whether the path is relative or absolute.
  bool Path390::isRelative() {
     _determine_uri_abs();
     _determine_type();
  return !(_absolute|_uriabsolute);
  }
  
  XERCES_CPP_NAMESPACE_END
  
  
  
  1.1                  xml-xerces/c/src/xercesc/util/Platforms/OS390/Path390.hpp
  
  Index: Path390.hpp
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2002 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 apache\@apache.org.
   *
   * 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: Path390.hpp,v 1.1 2002/11/22 14:57:32 tng Exp $
   */
  
  #ifndef PATH390_HPP
  #define PATH390_HPP
  
  #include <xercesc/util/XercesDefs.hpp>
  
  XERCES_CPP_NAMESPACE_BEGIN
  
  class  Path390
  {
   public:
      // Constructors and Destructor
      Path390();
      ~Path390();
      Path390(char *s);
  
      // Set a new path in the object. This will overlay any existing path and
      // re-initialize the object.
      void setPath(char *s);
  
      // This performs a complete parse of the path. It returns the error code or 0
      // if there was no error.
      int  fullParse();
  
      // This returns the path in a format as required by fopen
      char * getfopenPath();
  
      // This returns the parameters in a format as required by fopen
      char * getfopenParms();
  
      // This returns the type of the path. See the constants defined below.
      int  getPathType();
  
      // This returns the error code that was found during the parse
      int  getError();
  
      // Returns whether the path is relative or absolute
      bool isRelative();
  
      // Returns whether or not type=record shows up in the path.
      bool isRecordType();
  
   private:
      int _pathtype;
      char * _orgpath;
      int _orglen;
      char * _resultpath;
      bool _absolute;
      bool _uriabsolute;
      bool _dsnabsolute;
      char * _curpos;
      int _parsestate;
      int _numperiods;
      int _numsemicolons;
  
      int _error;
      char * _orgparms;
      int _orgparmlen;
  
      char * _lastsemi;
      char * _lastslash;
      char * _lastparen;
      char * _parmStart;
      char * _pathEnd;
      char * _extStart;
  
      int _typerecord;
      // internal only methods:
      void _determine_uri_abs();
      void _determine_type();
      void _determine_punct();
      void _determine_parms();
      void _parse_rest();
  
  };
  
  // Internal constants for the _parsestate variable:
  #define PARSE_NONE         0
  #define PARSE_ABSOLUTE_URI 1
  #define PARSE_PATHTYPE     2
  #define PARSE_PUNCT        3
  #define PARSE_PARMS        4
  #define PARSE_PARSED       5
  
  // These are the possible error return codes:
  #define NO_ERROR                        0
  #define ERROR_SEMICOLON_NOT_ALLOWED    101
  #define ERROR_PERIOD_NOT_ALLOWED       102
  #define ERROR_NO_PAREN_ALLOWED         103
  #define ERROR_ABS_PATH_REQUIRED        104
  #define ERROR_NO_EXTRA_PERIODS_ALLOWED 105
  #define ERROR_MUST_BE_ABSOLUTE         106
  #define ERROR_BAD_DD                   107
  #define ERROR_BAD_DSN2                 108
  #define ERROR_NO_EXTRA_SEMIS_ALLOWED   109
  
  // Constants for the _pathtype variable and the return value from getPathType() method:
  #define PATH390_HFS      1
  #define PATH390_DSN1     2 // format is dsn:/chrisl/data/xml/member1.
  #define PATH390_DSN2     3 // format is dsn://'chrisl.data.xml(member1)'
  #define PATH390_DD       4
  #define PATH390_OTHER    5
  
  XERCES_CPP_NAMESPACE_END
  
  #endif
  
  
  

---------------------------------------------------------------------
To unsubscribe, e-mail: xerces-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xerces-cvs-help@xml.apache.org