From 9cea3acce75ec8c1ed1dc324dd9ca420e23c280a Mon Sep 17 00:00:00 2001
From: David Abram Cargill <cargilld@apache.org>
Date: Wed, 18 May 2005 13:44:44 +0000
Subject: [PATCH] OS400 updates from Jay Hansen.

git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@176407 13f79535-47bb-0310-9956-ffa450edef68
---
 src/xercesc/util/Compilers/OS400SetDefs.hpp   |  10 +-
 .../util/Platforms/OS400/OS400Defs.hpp        |  11 +
 .../Platforms/OS400/OS400PlatformUtils.cpp    | 201 +++++++++++++++---
 .../Platforms/OS400/OS400PlatformUtils.hpp    |  11 +
 .../Iconv400/Iconv400TransService.cpp         |  14 +-
 .../Iconv400/Iconv400TransService.hpp         |   8 +
 .../util/Transcoders/Iconv400/iconv_cnv.hpp   |  11 +
 .../util/Transcoders/Iconv400/iconv_util.cpp  |  16 +-
 .../util/Transcoders/Iconv400/iconv_util.hpp  |  20 +-
 9 files changed, 264 insertions(+), 38 deletions(-)

diff --git a/src/xercesc/util/Compilers/OS400SetDefs.hpp b/src/xercesc/util/Compilers/OS400SetDefs.hpp
index 9ddd27297..5a980c6af 100644
--- a/src/xercesc/util/Compilers/OS400SetDefs.hpp
+++ b/src/xercesc/util/Compilers/OS400SetDefs.hpp
@@ -1,3 +1,7 @@
+#if (__OS400_TGTVRM__>=510)                               /* @01a */
+    #pragma datamodel(P128)                               /* @01a */
+#endif                                                    /* @01a */
+
 /*
  * Copyright 1999-2002,2004 The Apache Software Foundation.
  * 
@@ -57,7 +61,7 @@
 //  Indicate that we support C++ namespace
 //  Do not define it if the compile cannot handle C++ namespace
 // ---------------------------------------------------------------------------
-// #define XERCES_HAS_CPP_NAMESPACE
+#define XERCES_HAS_CPP_NAMESPACE
 
 // ---------------------------------------------------------------------------
 //  Define our version of the XML character
@@ -107,3 +111,7 @@ typedef int            XMLInt32;
 const char* const Xerces_DLLName = "libxercesc";
 
 #endif //OS400SETDEFS_H
+#if (__OS400_TGTVRM__>=510)                                /* @01a */  
+     #pragma datamodel(pop)                                /* @01a */ 
+#endif                                                     /* @01a */
+
diff --git a/src/xercesc/util/Platforms/OS400/OS400Defs.hpp b/src/xercesc/util/Platforms/OS400/OS400Defs.hpp
index d13f2a143..23fc0fde0 100644
--- a/src/xercesc/util/Platforms/OS400/OS400Defs.hpp
+++ b/src/xercesc/util/Platforms/OS400/OS400Defs.hpp
@@ -1,3 +1,7 @@
+#if (__OS400_TGTVRM__>=510)                               /* @01a */
+    #pragma datamodel(P128)                               /* @01a */
+#endif                                                    /* @01a */
+
 /*
  * Copyright 1999-2000,2004 The Apache Software Foundation.
  * 
@@ -16,6 +20,9 @@
 
 /**
  * $Log$
+ * Revision 1.4  2005/05/18 13:44:43  cargilld
+ * OS400 updates from Jay Hansen.
+ *
  * Revision 1.3  2004/09/23 21:44:13  cargilld
  * Fixes to build on OS400.  Thanks to Patrick Townsend and Jay Hansen.
  *
@@ -44,3 +51,7 @@
 //  And define our file handle abstraction
 // ---------------------------------------------------------------------------
 typedef void* FileHandle;
+#if (__OS400_TGTVRM__>=510)                                /* @01a */  
+     #pragma datamodel(pop)                                /* @01a */ 
+#endif                                                     /* @01a */
+
diff --git a/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.cpp b/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.cpp
index be6deffcd..fb95c762a 100644
--- a/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.cpp
+++ b/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.cpp
@@ -22,12 +22,13 @@
 //  Includes
 // ---------------------------------------------------------------------------
 #define MY_XP_CPLUSPLUS
+#include    <xercesc/util/XMLUniDefs.hpp>
+#include    <xercesc/util/XercesDefs.hpp>
 #include    <pthread.h>
 #include    <xercesc/util/PlatformUtils.hpp>
 #include    <xercesc/util/RuntimeException.hpp>
 #include    <xercesc/util/Janitor.hpp>
 #include    <xercesc/util/XMLString.hpp>
-#include    <xercesc/util/XMLUniDefs.hpp>
 #include    <xercesc/util/PanicHandler.hpp>
 #include    <stdio.h>
 #include    <stdlib.h>
@@ -48,7 +49,9 @@
 
 #if defined (XML_USE_ICONV400_TRANSCODER)
     #include <xercesc/util/Transcoders/Iconv400/Iconv400TransService.hpp>
+XERCES_CPP_NAMESPACE_BEGIN    
 	void cleanupDefaultConverter();
+XERCES_CPP_NAMESPACE_END    
 #elif defined (XML_USE_ICU_TRANSCODER)
     #include <xercesc/util/Transcoders/ICU/ICUTransService.hpp>
 #else
@@ -340,28 +343,176 @@ void XMLPlatformUtils::resetFile(FileHandle theFile
 // ---------------------------------------------------------------------------
 //  XMLPlatformUtils: File system methods
 // ---------------------------------------------------------------------------
-/* since we do not have the realpath function on AS/400 and it appears
-to no be important that we convert the name to the real path we will
-only verify that the path exists  - note that this may make AS/400 output a different error for the pathname but customer should
-be able to determine what the name is suppose to be*/
 
-char *realpath(const char *file_name, char *resolved_name)
-{
- if (file_name== NULL)
- {
-   errno = EINVAL;
-   return(NULL);
- }
- if (access(file_name,F_OK)) /* verify that the file exists*/
- {
-  errno = EACCES;
-  return(NULL);
- }
- else
- /* code says that we make a copy of the file name so do it */
-  strcpy(resolved_name,file_name);
-  return(resolved_name);
-}
+//-------------------------
+//-- BEGIN realpath code --
+//-------------------------
+
+#include <limits.h>
+#include <unistd.h>
+#include <errno.h>
+
+//
+// realpath
+//
+// Resolve a file name into its absolute name
+// This function doesn't exist in the iSeries C runtime library so this partial replacement was
+//  written to handle most of its function.  This implementation doesn't resolve symbolic links
+//  to their "real" paths because for the purposes of reading files the symlinks will work just
+//  fine.
+//
+char *realpath(const char *file_name, char *resolved_name) {
+    // Input: file_name - the name of a file or directory
+    // Output: resolved_name - file_name with a fully qualified path and all "extraneous" path stuff removed
+    // Returned value: Same as resolved_name unless there is an error in which case NULL is returned
+    //
+    // Possible errors:  (no)==we don't check that
+    //  EACCES      Read or search permission was denied for a component of the path name.
+    //  EINVAL     File_name or resolved_name is a null pointer.
+    //  (no) ELOOP     Too many symbolic links are encountered in translating file_name.
+    //  ENAMETOOLONG     The length of file_name or resolved_name exceeds PATH_MAX or a path name component is longer than NAME_MAX.
+    //  ENOENT     The file_name parameter does not exist or points to an empty string.
+    //  (no) ENOTDIR     A component of the file_name prefix is not a directory.
+    // If there is an error in resolving the name the return value will be NULL (i.e., 0) and resolved_name
+    //  will be changed to an empty string (a 0 will be written into its first character position)
+
+    // Note for future expansion:  "readlink" for links
+
+    // Check for null name errors
+     if (resolved_name == NULL) {
+        errno = EINVAL;
+        return(NULL);
+     }
+    // Assumption: At this point resolved_name points to a character array large enough to hold at least PATH_MAX characters
+     if (file_name == NULL) {
+        errno = EINVAL;
+        *resolved_name = '\0';
+        return(NULL);
+     }
+    // Assumption: At this point file_name is a valid null terminated string
+
+    // Check for empty name error
+     if (*file_name == '\0') {
+        errno = ENOENT;
+        *resolved_name = '\0';
+        return(NULL);
+     }
+
+    char *from = (char*)file_name;
+    char *to = resolved_name;
+    int fromIdx=0, toIdx=0;
+
+    if (*file_name == '/') {
+        // If file_name starts with a '/', it's an absolute path
+        // Everything's already set up properly
+        to[toIdx++] = '/';
+    } // if
+    else {
+        // file_name doesn't start with a '/' so it is relative to the current directory
+        // Prepend the current working directory before the file name
+        getcwd(to, PATH_MAX);
+        size_t cwd_len = strlen(resolved_name);
+        // Assumption: getcwd returns a non-empty, valid, null terminated string
+
+        // Add '/' on the cwd if needed
+        // Note: I think the only time a '/' will end the cwd is if it is just "/"
+        //  but this covers otherwise just in case
+        toIdx = cwd_len;
+        if ((toIdx < PATH_MAX-1) &&
+            (to[toIdx] != '/')) {
+             to[toIdx++] = '/';
+        } // if
+    } // else
+
+    // The target ends in a '/' at this point
+    // Skip any leading '/'s in the source
+    while (from[fromIdx] == '/') {
+        fromIdx++;
+    } // while
+
+    // Copy from the source to the target removing extraneous "."s, "/"s, and ".."s as we go
+    // Assumption: looking ahead for characters is OK because all the string end with '/0'
+    while (from[fromIdx] != '\0' ) {
+        // Assumption - at top of loop we are either at '..', '.', or 'xxxxxxxx' (where x is any non-'/' character), each either followed by a '/' or a closing '\0'
+        //  "../" => "/", also strips trailing ".."
+        if ((from[fromIdx] == '.') &&
+            (from[fromIdx+1] == '.') &&
+            ((from[fromIdx+2] == '/') || (from[fromIdx+2] == '\0'))) {
+            fromIdx += (from[fromIdx+2] == '\0') ? 2 : 3;
+            // Back up to the previous '/' in the target except if we are at the first '/' already
+            if (toIdx >= 2) {
+                // Back up past the current '/'
+                --toIdx;
+                // Look back until we find the previous '/'
+                while(to[toIdx-1] != '/') {
+                     --toIdx;
+                } // while
+            } // if
+        } // if
+
+        // "./" => "/", also strips trailing "."
+        else if ((from[fromIdx] == '.') &&
+                 ((from[fromIdx+1] == '/') || (from[fromIdx+1] == '\0'))) {
+             fromIdx += (from[fromIdx+1] == '\0') ? 1 : 2;
+        } // else if
+
+        else {
+            // Copy the characters up to the next '/' or to the closing '\0'
+            while((from[fromIdx] != '/') && (from[fromIdx] != '\0')) {
+                // Check that the file name won't be too long (allow for the '\0' too)
+                if (toIdx >= PATH_MAX-1) {
+                    errno = ENAMETOOLONG;
+                    *resolved_name = '\0';
+                    return(NULL);
+                } // if
+
+                to[toIdx++] = from[fromIdx++];
+            } // while
+        } // else
+
+        if (from[fromIdx] == '/') {
+            // Skip any remaining '/'s in the source
+            while (from[fromIdx] == '/') {
+                fromIdx++;
+            } // while
+
+            // insert a '/' if there's more path to come (and room for it)
+            if (from[fromIdx] != '\0') {
+                // Check that the file name won't be too long (allow for the '\0' too)
+                if (toIdx >= PATH_MAX-1) {
+                    errno = ENAMETOOLONG;
+                    *resolved_name = '\0';
+                    return(NULL);
+                } // if
+
+                to[toIdx++] = '/';
+            } // if
+        } // if
+
+    } // while
+
+    // Remove a trailing '/' (except from "/")
+    if ((toIdx > 1) &&
+        (to[toIdx-1] == '/'))
+        --toIdx;
+
+    // End the string properly
+    to[toIdx] = '\0';
+
+    // Check if the file exists
+    if (access(resolved_name,F_OK)) {
+        errno = EACCES;
+        *resolved_name = '\0';
+        return(NULL);
+    } // if
+
+    // The file exists, return its name.
+     return(resolved_name);
+}
+
+//-----------------------
+//-- END realpath code --
+//-----------------------
 
 
 
@@ -562,7 +713,7 @@ public:
 
     RecursiveMutex() {
 		       if (pthread_mutex_init(&mutex, NULL))
-			        XMLPlatformUtils::panic(PanicHandler::Panic_MutexErr);
+			    XMLPlatformUtils::panic(PanicHandler::Panic_MutexErr);
                        recursionCount = 0;
                        tid.reservedHiId = 0;
 		       tid.reservedLoId = 0;
@@ -593,7 +744,7 @@ public:
 
 			  if (pthread_mutex_unlock(&mutex) != 0)
 			      XMLPlatformUtils::panic(PanicHandler::Panic_MutexErr);
-              tid.reservedHandle= 0;
+                          tid.reservedHandle= 0;
 			  tid.reservedHiId = 0;
 			  tid.reservedLoId = 0;
                        }
@@ -746,7 +897,7 @@ return;
 
 FileHandle XMLPlatformUtils::openStdInHandle(MemoryManager* const manager)
 {
-    return (FileHandle)fdopen(dup(0), "rb");
+    return (FileHandle)fdopen(dup(0), "r");
 }
 
 void XMLPlatformUtils::platformTerm()
diff --git a/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.hpp b/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.hpp
index d91183c9e..bdcc96173 100644
--- a/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.hpp
+++ b/src/xercesc/util/Platforms/OS400/OS400PlatformUtils.hpp
@@ -1,3 +1,7 @@
+#if (__OS400_TGTVRM__>=510)                               /* @01a */
+    #pragma datamodel(P128)                               /* @01a */
+#endif                                                    /* @01a */
+
 /*
  * Copyright 1999-2001,2004 The Apache Software Foundation.
  * 
@@ -16,6 +20,9 @@
 
 /**
  * $Log$
+ * Revision 1.4  2005/05/18 13:44:43  cargilld
+ * OS400 updates from Jay Hansen.
+ *
  * Revision 1.3  2004/09/08 13:56:41  peiyongz
  * Apache License Version 2.0
  *
@@ -50,3 +57,7 @@ XERCES_CPP_NAMESPACE_END
 
 #endif /* _OS400PLATFORMUTILS_H */
 
+#if (__OS400_TGTVRM__>=510)                                /* @01a */  
+     #pragma datamodel(pop)                                /* @01a */ 
+#endif                                                     /* @01a */
+
diff --git a/src/xercesc/util/Transcoders/Iconv400/Iconv400TransService.cpp b/src/xercesc/util/Transcoders/Iconv400/Iconv400TransService.cpp
index 289e03198..c81049cd8 100644
--- a/src/xercesc/util/Transcoders/Iconv400/Iconv400TransService.cpp
+++ b/src/xercesc/util/Transcoders/Iconv400/Iconv400TransService.cpp
@@ -17,12 +17,15 @@
 /**
  * @01A D998714.1 V5R2M0    100301   Swan    :Fix error return flags
  * @02A           V5R2M0    200419   jrhansen : support lowercase function
+ * @03A D93234.1  V1R1M0    102804   JRHansen :fix transcode overflow 
+ * @04A D93234.3  V1R1M0    022505   JRHansen :fix transcode error check 
  * $Id$
  */
 
 // ---------------------------------------------------------------------------
 //  Includes
 // ---------------------------------------------------------------------------
+#include <xercesc/util/XMLUniDefs.hpp>
 #include <xercesc/util/TranscodingException.hpp>
 #include "Iconv400TransService.hpp"
 #include <string.h>
@@ -30,7 +33,6 @@
 #include "iconv_cnv.hpp"
 #include "iconv_util.hpp"
 #include <qusec.h>
-#include <xercesc/util/XMLUniDefs.hpp>
 #include <xercesc/util/XMLString.hpp>
 #include <xercesc/util/Janitor.hpp>
 
@@ -381,7 +383,9 @@ Iconv400Transcoder::transcodeFrom(const  XMLByte* const          srcData
         , &err
     );
 
-    if ((err != U_ZERO_ERROR) && (err != U_INDEX_OUTOFBOUNDS_ERROR))
+
+    if ((err != U_ZERO_ERROR) && (err != U_INDEX_OUTOFBOUNDS_ERROR) &&
+	(err != U_BUFFER_OVERFLOW_ERROR))   // @03c
     {
         if (orgTarget != (UChar*)toFill)
             getMemoryManager()->deallocate(orgTarget);//delete [] orgTarget;
@@ -856,10 +860,11 @@ XMLCh* Iconv400LCPTranscoder::transcode(const char* const toTranscode)
             , &err
         );
 
-        if (err != U_BUFFER_OVERFLOW_ERROR)
+        if (err == U_BUFFER_OVERFLOW_ERROR)  // @04c
 	{
 
         err = U_ZERO_ERROR;
+	delete [] retVal;  // @04a
         retVal = new XMLCh[targetCap];
         ucnv_toUChars
         (
@@ -928,10 +933,11 @@ XMLCh* Iconv400LCPTranscoder::transcode(const char* const toTranscode,
             , &err
         );
 
-        if (err != U_BUFFER_OVERFLOW_ERROR)
+        if (err == U_BUFFER_OVERFLOW_ERROR)  // @04c
 	{
 
         err = U_ZERO_ERROR;
+        manager->deallocate(retVal);  //@04a
         retVal = (XMLCh*) manager->allocate(targetCap * sizeof(XMLCh));//new XMLCh[targetCap];
         ucnv_toUChars
         (
diff --git a/src/xercesc/util/Transcoders/Iconv400/Iconv400TransService.hpp b/src/xercesc/util/Transcoders/Iconv400/Iconv400TransService.hpp
index 13e89857e..8254ef124 100644
--- a/src/xercesc/util/Transcoders/Iconv400/Iconv400TransService.hpp
+++ b/src/xercesc/util/Transcoders/Iconv400/Iconv400TransService.hpp
@@ -1,3 +1,7 @@
+#if (__OS400_TGTVRM__>=510)                               /* @01a */
+    #pragma datamodel(P128)                               /* @01a */
+#endif                                                    /* @01a */
+
 /*
  * Copyright 1999-2002,2004 The Apache Software Foundation.
  * 
@@ -252,3 +256,7 @@ private :
 XERCES_CPP_NAMESPACE_END
 
 #endif
+#if (__OS400_TGTVRM__>=510)                                /* @01a */  
+     #pragma datamodel(pop)                                /* @01a */ 
+#endif                                                     /* @01a */
+
diff --git a/src/xercesc/util/Transcoders/Iconv400/iconv_cnv.hpp b/src/xercesc/util/Transcoders/Iconv400/iconv_cnv.hpp
index 763d965f1..2c3a5444b 100644
--- a/src/xercesc/util/Transcoders/Iconv400/iconv_cnv.hpp
+++ b/src/xercesc/util/Transcoders/Iconv400/iconv_cnv.hpp
@@ -1,3 +1,7 @@
+#if (__OS400_TGTVRM__>=510)                               /* @01a */
+    #pragma datamodel(P128)                               /* @01a */
+#endif                                                    /* @01a */
+
 /*
  * Copyright 1999-2001,2004 The Apache Software Foundation.
  * 
@@ -16,6 +20,9 @@
 
 /**
  * $Log$
+ * Revision 1.4  2005/05/18 13:44:44  cargilld
+ * OS400 updates from Jay Hansen.
+ *
  * Revision 1.3  2004/09/08 13:56:45  peiyongz
  * Apache License Version 2.0
  *
@@ -315,3 +322,7 @@ XERCES_CPP_NAMESPACE_END
 
 #endif
 
+#if (__OS400_TGTVRM__>=510)                                /* @01a */  
+     #pragma datamodel(pop)                                /* @01a */ 
+#endif                                                     /* @01a */
+
diff --git a/src/xercesc/util/Transcoders/Iconv400/iconv_util.cpp b/src/xercesc/util/Transcoders/Iconv400/iconv_util.cpp
index ffce06c81..6a701833e 100644
--- a/src/xercesc/util/Transcoders/Iconv400/iconv_util.cpp
+++ b/src/xercesc/util/Transcoders/Iconv400/iconv_util.cpp
@@ -16,6 +16,12 @@
 
 /**
  * $Log$
+ * Revision 1.5  2005/05/18 13:44:44  cargilld
+ * OS400 updates from Jay Hansen.
+ *
+ * Revision 1.5  2005/03/09 21:44:13  jrhansen
+ * Use qlgusr.h instead of QlgCvtTextDescToDesc prototype  jrhansen  @15
+ * 
  * Revision 1.4  2004/09/23 21:44:13  cargilld
  * Fixes to build on OS400.  Thanks to Patrick Townsend and Jay Hansen.
  *
@@ -39,14 +45,16 @@
  *
  */
 
-#include <iconv.h>
 #include <xercesc/util/XercesDefs.hpp>
+#include <iconv.h>
 #include <xercesc/util/Platforms/OS400/OS400PlatformUtils.hpp>
 #include <stdlib.h>
 #include <unistd.h>
 #include <iconv_util.hpp>
 #include <iconv_cnv.hpp>
 #include <ctype.h>
+#include <qlgusr.h>   // @15a
+
 
 XERCES_CPP_NAMESPACE_BEGIN
 
@@ -58,8 +66,8 @@ static UErrorCode gErr = U_ZERO_ERROR;
 
 #include "utypes.h"
 
-void   shareConverterData (UConverterSharedData * data,char *InDescriptor) ;
-UConverterSharedData *getSharedConverterData(char *Descriptor);
+// void   shareConverterData (UConverterSharedData * data,char *InDescriptor) ;
+// UConverterSharedData *getSharedConverterData(char *Descriptor);
 #define defaultConverter (_defaultConverter==NULL)?_defaultConverter=ucnv_open(NULL, &gErr):_defaultConverter
 
 
@@ -124,7 +132,7 @@ char* u_austrcpy(char *s1,
  * -Call dataConverter initializer (Data=TRUE, Cached=TRUE)
  * -Call AlgorithmicConverter initializer (Data=FALSE, Cached=TRUE)
  */
-int QlgCvtTextDescToDesc(int,int,char *,int,char *,int,int);
+// int QlgCvtTextDescToDesc(int,int,char *,int,char *,int,int);  @14d
 
 
 
diff --git a/src/xercesc/util/Transcoders/Iconv400/iconv_util.hpp b/src/xercesc/util/Transcoders/Iconv400/iconv_util.hpp
index 5cc75258e..1ef5e124e 100644
--- a/src/xercesc/util/Transcoders/Iconv400/iconv_util.hpp
+++ b/src/xercesc/util/Transcoders/Iconv400/iconv_util.hpp
@@ -1,3 +1,7 @@
+#if (__OS400_TGTVRM__>=510)                               /* @01a */
+    #pragma datamodel(P128)                               /* @01a */
+#endif                                                    /* @01a */
+
 /*
  * Copyright 1999-2001,2004 The Apache Software Foundation.
  * 
@@ -16,6 +20,9 @@
 
 /**
  * $Log$
+ * Revision 1.4  2005/05/18 13:44:44  cargilld
+ * OS400 updates from Jay Hansen.
+ *
  * Revision 1.3  2004/09/08 13:56:45  peiyongz
  * Apache License Version 2.0
  *
@@ -34,13 +41,14 @@
  */
 
 
-const char* iconv_getDefaultCodepage(void);
-
-
 #include "utypes.h"
 #include <iconv.h>
 
-extern "C" int QlgCvtTextDescToDesc (int, int, char *, int, char*, int, int);
+XERCES_CPP_NAMESPACE_BEGIN
+
+const char* iconv_getDefaultCodepage(void);
+
+// extern "C" int QlgCvtTextDescToDesc (int, int, char *, int, char*, int, int);
 
 #define MAX_CONVERTER_NAME_LENGTH 60
 #define MAX_SUBCHAR_LEN 4
@@ -127,3 +135,7 @@ static void   initializeDataConverter (UConverter * myUConverter);
 UConverter *createConverter (const char *converterName, UErrorCode * err);
 
 XERCES_CPP_NAMESPACE_END
+#if (__OS400_TGTVRM__>=510)                                /* @01a */  
+     #pragma datamodel(pop)                                /* @01a */ 
+#endif                                                     /* @01a */
+
-- 
GitLab