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