[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: WSDL2RPG/HTTPAPI and passing more than 16mb data



Sam,

I changed the memory manager of the next coming version of WSDL2RPG. The new parameter does not exist in the current version or in v15beta8.

Because of module WSDL2R84 did not change since v1.14.1 you can replace your WSDL2R84 and PWSDL2R84 with the attached versions. Though you should make a copy before.

You may also consider to change procedure "_initializeMemoryManager" of your WS_SRV source member to match the one attached. Do not completely replace your WS_SRV with the the new version, since it might not work with v1.15beta8. Only replace or update procedure "_initializeMemoryManager" if you want to use separate heaps for all new web service stubs.

Thomas.

Am 09.09.2013 17:20, schrieb Sam:
Thomas,
Thanks for all the help you give and to Scott too,
I have v1.15beta8, I didn't see the third parm to pass(use separate heaps) in the memory manager procedure, am I missing something.
I checked wsdl2r84 and pwsdl2r84.

Sent from my iPhone

On Sep 9, 2013, at 9:18 AM, thomas.raddatz@xxxxxx wrote:

   This way I just sent a message of roughly 41mb to the server:
   User-Agent: http-api/1.24
   Content-Length: 43116439
   Content-Type: text/xml
   SOAPAction:
   sendraw(): entered
   <?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope ...
   Thomas.
   ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx schrieb am 09.09.2013 15:47:27:
Von: thomas.raddatz@xxxxxx
An: ftpapi@xxxxxxxxxxxxxxxxxxxxxx,
Datum: 09.09.2013 15:56
Betreff: Re: WSDL2RPG/HTTPAPI and passing more than 16mb data
Gesendet von: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx


Sam,

Today dynamic arrays do not (really) help to get beyond 16mb because
   all
dynamic arrays share the same memory heap. The advantage of dynamic
   arrays
is that the 16mb are used more efficiently and that that the total
   message
size can grow up to 32mb. 16mb of static storage of the
   request/response
data structure plus 16mb additional heap storage.

For the next release I changed the WSDL2RPG memory manager to
   optionally
create one heap per array. This way each array can grow up to 16mb.
   If you
are on WSDL2RPG v1.14.1 or higher, you may consider to replace
   WSDL2R84
(and PWSDL2R84) to use the new manager. After having generated the
   stub
you need to change module WS_SRV like this:

  // Start memory manager, do not use symbolic names
  // Note 1: It is strongly recommended not to use symbolic names
  //         due to high performance degradation.
  // Note 2: Set "use separate heaps" to cTRUE, if your
  //         request/response messages uses dynamic arrays
  //         and exceeds 16MB.
  MemoryManager_attachService(uuid       // web service uuid
                              : cFalse   // do not use symbolic names
   for
arrays
                              : cTrue);  // use separate heaps for
   arrays
!!!

Thomas.



ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx schrieb am 08.09.2013 16:45:26:

Von: Cdssi@xxxxxxx
An: ftpapi@xxxxxxxxxxxxxxxxxxxxxx,
Datum: 08.09.2013 19:47
Betreff: WSDL2RPG/HTTPAPI and passing more than 16mb data
Gesendet von: ftpapi-bounces@xxxxxxxxxxxxxxxxxxxxxx


Hello,
We are on iSeries V7.1 and use wsdl2rpg, there is a need to pass
   more
than
16mb of data to consume web services,
Please suggest alternatives or If we are doing something
   incorrectly.
Will using Dynamic arrays help?, I think there is an example in
   wsdl2rpg

library,
Thanks in advance.
   Sam.-------------------------------------------------------------------
   ----
This is the FTPAPI mailing list.  To unsubscribe, please go to:
[1]http://www.scottklement.com/mailman/listinfo/ftpapi
   -----------------------------------------------------------------------


--
IMPORTANT NOTICE:
This email is confidential, may be legally privileged, and is for the
intended recipient only. Access, disclosure, copying, distribution,
   or
reliance on any of it by anyone else is prohibited and may be a
   criminal
offence. Please delete if obtained in error and email confirmation
to the
   sender.----------------------------------------------------------------
   -------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
[2]http://www.scottklement.com/mailman/listinfo/ftpapi
   -----------------------------------------------------------------------

   --
   IMPORTANT NOTICE:
   This email is confidential, may be legally privileged, and is for the
   intended recipient only. Access, disclosure, copying, distribution, or
   reliance on any of it by anyone else is prohibited and may be a
   criminal
   offence. Please delete if obtained in error and email confirmation to
   the sender.

References

   1. http://www.scottklement.com/mailman/listinfo/ftpapi
   2. http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------
-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------

      /IF NOT DEFINED(PWSDL2R84)
      /DEFINE PWSDL2R84
      *
      /COPY QWSDL2RPG,TYPES
      *
      *  Initializes the MemoryManager for a given Web Service stub.
     D MemoryManager_attachService...
     D                 PR                         like(wsdl_uuid_t       )
     D                                     extproc('WSDL2R84_+
     D                                     MemoryManager_attachService+
     D                                     ')
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
     D                                            options(*nopass)
     D  i_useSymbolicNames...
     D                                 N   const  options(*nopass: *omit)
     D  i_useSeparateHeaps...
     D                                 N   const  options(*nopass: *omit)
      *
      *  Removes a given web service from the MemoryManager and frees
      *  all allocate memory blocks.
     D MemoryManager_detachService...
     D                 PR
     D                                     extproc('WSDL2R84_+
     D                                     MemoryManager_detachService+
     D                                     ')
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
      *
      *  Returns the heap ID of the heap that is associated to a given
      *  web service ID.
     D MemoryManager_getHeap...
     D                 PR            10I 0
     D                                     extproc('WSDL2R84_+
     D                                     MemoryManager_getHeap+
     D                                     ')
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
      *
      *  Returns a new dynamic array object.
     D MemoryManager_createArray...
     D                 PR                         like(wsdl_hArray_t )
     D                                     extproc('WSDL2R84_+
     D                                     MemoryManager_createArray+
     D                                     ')
     D  i_serviceUUID                      const  like(wsdl_uuid_t   )
     D  i_elemSize                   10I 0 const
     D  i_name                             const  like(wsdl_arrayName_t)
     D                                            options(*nopass: *omit)
     D  i_ensureUniqueName...
     D                                 N   const  options(*nopass: *omit)
     D  i_increment                  10U 0 const  options(*nopass: *omit)
      *
      *  Deletes a given dynamic array.
     D MemoryManager_deleteArray...
     D                 PR                  opdesc
     D                                     extproc('WSDL2R84_+
     D                                     MemoryManager_deleteArray+
     D                                     ')
     D  i_serviceUUID                      const  like(wsdl_uuid_t   )
      /IF DEFINED(INTERNALLY_COMPILE_WSDL2R84)
     D  io_hArray                                 like(wsdl_hArray_t )
      /ELSE
     D  io_hArray                          const  like(wsdl_hArray_t )
     D                                            options(*string)
      /ENDIF
      *
      *  Dumps the status of the Memory Manager.
     D MemoryManager_dump...
     D                 PR
     D                                     extproc('WSDL2R84_+
     D                                     MemoryManager_dump+
     D                                     ')
      *
      /ENDIF
      *=====================================================================*
      *  WSDL2RPG: Memory Manager                                           *
      *=====================================================================*
      *  Author  :  Thomas Raddatz                                          *
      *  Date    :  12.06.2008                                              *
      *  E-mail  :  thomas.raddatz@xxxxxxxxxxx                              *
      *  Homepage:  www.tools400.de                                         *
      *=====================================================================*
      *                                                                     *
      *  This software is free software, you can redistribute it and/or     *
      *  modify it under the terms of the GNU General Public License (GPL)  *
      *  as published by the Free Software Foundation.                      *
      *                                                                     *
      *  See GNU General Public License for details.                        *
      *          http://www.opensource.org                                  *
      *          http://www.opensource.org/licenses/gpl-license.html        *
      *                                                                     *
      *=====================================================================*
      *  History:                                                           *
      *                                                                     *
      *  Date        Name          Description                              *
      *  ----------  ------------  ---------------------------------------  *
      *  18.02.2012  Th.Raddatz    Fixed bug that procedure                 *
      *                            MemoryManager_createArray() did not      *
      *                            properly produced a unique array name.   *
      *                                                                     *
      *  21.02.2012  Th.Raddatz    Changed deleteHeap() to correctly        *
      *                            delete all arrays that are associated    *
      *                            to the heap.                             *
      *                                                                     *
      *  06.03.2012  Th.Raddatz    Added parameter i_useSymbolicNames to    *
      *                            procedure MemoryManager_attachService()  *
      *                            to specify whether or not to use         *
      *                            symbolic names for arrays.               *
      *                                                                     *
      *  09.09.2013  Th.Raddatz    Added option to use separate heaps for   *
      *                            each dynamic array.                      *
      *                                                                     *
      *=====================================================================*
      *   >>PRE-COMPILER<<                                                  *
      *                                                                     *
      *     >>CRTCMD<<  CRTRPGMOD   MODULE(&LI/&OB) +                       *
      *                             SRCFILE(&SL/&SF) +                      *
      *                             SRCMBR(&SM);                            *
      *                                                                     *
      *     >>COMPILE<<                                                     *
      *       >>PARM<< TRUNCNBR(*NO);                                       *
      *       >>PARM<< DBGVIEW(*LIST);                                      *
      *       >>PARM<< TGTRLS(V6R1M0  );                                    *
      *     >>END-COMPILE<<                                                 *
      *                                                                     *
      *     >>EXECUTE<<                                                     *
      *                                                                     *
      *   >>END-PRE-COMPILER<<                                              *
      *=====================================================================*
 CPY H NOMAIN
      /COPY QWSDL2RPG,H_SPEC
      *=====================================================================*
     FQPRINT    O    F  132        PRINTER oflind(*in70)
     F                                     usropn
     D g_printData     S            115A
      *
      * ------------------------------------
      *  Constants
      * ------------------------------------
      *
      * ------------------------------------
      *  Type Definitions
      * ------------------------------------
      /COPY QWSDL2RPG,TYPES
      *
     D heapEntry_t...
     D                 DS                  qualified               based(pDummy)
     D  ID                           10I 0
     D  hArrayList                         like(BasicList_handle_t )
     D  unqCount                     20U 0
     D  useNames                       N
     D  useNamesMsg                    N
     D  useSeparateHeaps...
     D                                 N
      *
     D arrayMapEntry_t...
     D                 DS                  qualified               based(pDummy)
     D  hArray                             like(wsdl_hArray_t     )
     D  index                        10I 0
     D  arrayHeapID                  10I 0
      *
      * ------------------------------------
      *  Exported prototypes
      * ------------------------------------
      /DEFINE INTERNALLY_COMPILE_WSDL2R84
      /COPY QWSDL2RPG,PWSDL2R84
      *
      * ------------------------------------
      *  Imported prototypes
      * ------------------------------------
      /COPY QBASICS1,PBASICS1                      Tools/400 Runtime Library
      /COPY QLOG4RPG,PLOG4RPG                      Log4rpg
      /COPY QWSDL2RPG,HEAPAPI                      CEE Heap APIs
      /COPY QWSDL2RPG,CEELIB                       Prototypes for CEE APIs
      *
      /COPY QWSDL2RPG,PWSDL2R71                    WSDL2RPG: Debug Log
      /COPY QWSDL2RPG,PWSDL2R82                    WSDL2RPG: Dynamic Array
      *
      * ------------------------------------
      *  Internal prototypes
      * ------------------------------------
      *
      *  Create a new heap map.
     D createHeapMap...
     D                 PR              *
     D                                     extproc('createHeapMap')
      *
     D deleteHeapMap...
     D                 PR
     D                                     extproc('deleteHeapMap')
     D  io_hHeapMap                               like(BasicMap_handle_t )
      *
      *  Create a new heap.
     D createHeap...
     D                 PR              *
     D                                     extproc('createHeap')
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
     D  i_useSymbolicNames...
     D                                 N   const
     D  i_useSeparateHeaps...
     D                                 N   const
      *
      *  Delete heap.
     D deleteHeap...
     D                 PR
     D                                     extproc('deleteHeap')
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
      *
      *  Activation group exit:    Terminate MemoryManager
     D ActGrpExit_terminateMemoryManager...
     D                 PR
     D                                     extproc('ActGrpExit_+
     D                                     terminateMemoryManager')
      *
      *  Initializes this module.
     D initializeModule...
     D                 PR
     D                                     extproc('initializeModule')
      *
      *  Opens the dump output stream.
     D Dump_open...
     D                 PR                  extproc('Dump_open')
      *
      *  Prints a line
     D Dump_print...
     D                 PR                  extproc('Dump_print')
     D  i_text                      128A   value  options(*nopass)
      *
      *  Closes the dump output stream.
     D Dump_close...
     D                 PR                  extproc('Dump_close')
      *
      * ------------------------------------
      *  Global fields & constants
      * ------------------------------------
     D g_isInit        S               N   inz(cFalse)
      *
     D g_hLogger       S                   like(LOG4RPG_hLogger_t  )
      *
     D g_hHeapMap      S                   like(BasicMap_handle_t   ) inz
      *
      * =====================================================================
      *  O-Spec to print the sample data
      * =====================================================================
     OQPRINT    e            PrintLine
     O                       g_printData        125
      *
      *=====================================================================*
      *  Initializes the MemoryManager for a given Web Service stub.
      *=====================================================================*
     P MemoryManager_attachService...
     P                 B                   export
      *
     D MemoryManager_attachService...
     D                 PI                         like(wsdl_uuid_t       )
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
     D                                            options(*nopass)
     D  i_useSymbolicNames...
     D                                 N   const  options(*nopass: *omit)
     D  i_useSeparateHeaps...
     D                                 N   const  options(*nopass: *omit)
      *
      *  Parameter positions
     D p_serviceUUID   C                   1
     D p_useSymbolicNames...
     D                 C                   2
     D p_useSeparateHeaps...
     D                 C                   3
      *
      *  Fields for optional parameters and return parameter
     D serviceUUID     S                   like(i_serviceUUID     ) inz
     D useSymbolicNames...
     D                 S                   like(i_useSymbolicNames) inz
     D useSeparateHeaps...
     D                 S                   like(i_useSeparateHeaps) inz
      *
      *  Helper fields
     D uuid            DS                  likeds(uuid_t       ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         initializeModule();

         if (%parms() >= p_serviceUUID);
            serviceUUID = i_serviceUUID;
         else;
            uuid = f_genUUID(cUUID_STRING);
            serviceUUID = %subst(uuid.value: 1: uuid.length);
         endif;

         if (%parms() >= p_useSymbolicNames);
            useSymbolicNames = i_useSymbolicNames;
         else;
            useSymbolicNames = cTrue;
         endif;

         if (%parms() >= p_useSeparateHeaps);
            useSeparateHeaps = i_useSeparateHeaps;
         else;
            useSeparateHeaps = cFalse;
         endif;

         if (BasicMap_isNull(g_hHeapMap));
            g_hHeapMap = createHeapMap();
         endif;

         p_assert(not BasicMap_containsKey(g_hHeapMap: serviceUUID)
                  : 'Web Service ID ' + serviceUUID +
                    ' must not yet exist in heap map');

         createHeap(serviceUUID: useSymbolicNames: useSeparateHeaps);

         return serviceUUID;

      /END-FREE
      *
     P MemoryManager_attachService...
     P                 E
      *
      *=====================================================================*
      *  Removes a given web service from the MemoryManager and frees
      *  all allocate memory blocks.
      *=====================================================================*
     P MemoryManager_detachService...
     P                 B                   export
      *
     D MemoryManager_detachService...
     D                 PI
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
      *
      *  Local fields
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         initializeModule();

         p_assert(not BasicMap_isNull(g_hHeapMap)
                  : 'Heap map does not exist');

         deleteHeap(i_serviceUUID);

         if (BasicMap_getNumE(g_hHeapMap) = 0);
            deleteHeapMap(g_hHeapMap);
         endif;

         return;

      /END-FREE
      *
     P MemoryManager_detachService...
     P                 E
      *
      *=====================================================================*
      *  Returns the heap ID of the heap that is associated to a given
      *  web service ID.
      *=====================================================================*
     P MemoryManager_getHeap...
     P                 B                   export
      *
     D MemoryManager_getHeap...
     D                 PI            10I 0
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
      *
      *  Local fields
     D heapEntry       DS                  likeds(heaPEntry_t )
     D                                     based(pHeapEntry)
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         initializeModule();

         p_assert(not BasicMap_isNull(g_hHeapMap)
                  : 'Heap map does not exist');

         pHeapEntry = BasicMap_get(g_hHeapMap: i_serviceUUID);

         p_assert(pHeapEntry <> *NULL
                  : 'Web Service ID ' + i_serviceUUID +
                    ' not found in heap map');

         return heapEntry.ID;

      /END-FREE
      *
     P MemoryManager_getHeap...
     P                 E
      *
      *=====================================================================*
      *  Returns a new dynamic array object.
      *=====================================================================*
      *  i_name:      not present   -  generates a uuid as name
      *               empty ('')    -  does not use a symbolic name at all
      *=====================================================================*
     P MemoryManager_createArray...
     P                 B                   export
      *
     D MemoryManager_createArray...
     D                 PI                         like(wsdl_hArray_t )
     D  i_serviceUUID                      const  like(wsdl_uuid_t   )
     D  i_elemSize                   10I 0 const
     D  i_name                             const  like(wsdl_arrayName_t)
     D                                            options(*nopass: *omit)
     D  i_ensureUniqueName...
     D                                 N   const  options(*nopass: *omit)
     D  i_increment                  10U 0 const  options(*nopass: *omit)
      *
      *  Return value
     D hArray          S                   like(wsdl_hArray_t )inz
      *
      *  Parameter positions
     D p_name          C                   const(3)
     D p_ensureUniqueName...
     D                 C                   const(4)
     D p_increment     C                   const(5)
      *
      *  Fields for optional parameters
     D name            S                   like(i_name            ) inz
     D tmpName         S                   like(i_name            ) inz
     D ensureUniqueName...
     D                 S                   like(i_ensureUniqueName) inz
     D increment       S                   like(i_increment       ) inz
      *
      *  Local fields
     D x               S             10I 0 inz
     D useUuid         S               N   inz(cFalse)
     D arrayHeapID     S             10I 0 inz
     D uuid            DS                  likeds(uuid_t          ) inz
     D heapEntry       DS                  likeds(heapEntry_t     )
     D                                     based(pHeapEntry)
     D arrayMapEntry   DS                  likeds(arrayMapEntry_t )
     D                                     based(pArrayMapEntry   )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         initializeModule();

         p_assert(not BasicMap_isNull(g_hHeapMap)
                  :'Heap map does not exist. Initialize Memory Manager first.');

         pHeapEntry = BasicMap_get(g_hHeapMap: i_serviceUUID);

         p_assert(pHeapEntry <> *NULL
                  : 'Web Service ID ' + i_serviceUUID +
                    ' not found in heap map');

         // Get values of optional parameters
         // ... i_name
         if (%parms() >= p_name and %addr(i_name) <> *NULL);
            name = i_name;
            useUuid = cFalse;
         else;
            if (heapEntry.useNames);
               uuid = f_genUUID(cUUID_STRING);
               name = %subst(uuid.value: 1: uuid.length);
               useUuid = cTrue;
            else;
               name = '';
               useUuid = cFalse;
            endif;
         endif;

         // ... i_ensureUniqueName
         if (%parms() >= p_ensureUniqueName and
             %addr(i_ensureUniqueName) <> *NULL);
            ensureUniqueName = i_ensureUniqueName;
         else;
            ensureUniqueName = cFalse;
         endif;

         if (useUuid);
            ensureUniqueName = cFalse;
         endif;

         if (not heapEntry.useNames);
            name = '';
            ensureUniqueName = cFalse;
         endif;

         if (heapEntry.useNames and not heapEntry.useNamesMsg);
            http_DebugLog_appendText(
               '** Using symbolic names is not recommended +
                due to significant performance degrades for +
                large dynamic arrays');
            http_DebugLog_appendText(
               '** Disable symbolic names to improve performance: +
                MemoryManager_attachService( .. : cFalse)');
            heapEntry.useNamesMsg = cTrue;
         endif;

         // ... i_increment
         if (%parms() >= p_increment and %addr(i_increment) <> *NULL);
            increment = i_increment;
         else;
            increment = 256;
         endif;

         if (ensureUniqueName);
            tmpName = name;
            dow (Array_existName(tmpName));
               tmpName = name + '_' + %char(heapEntry.unqCount);
               heapEntry.unqCount = heapEntry.unqCount + 1;
            enddo;
            name = tmpName;
         endif;

         if (heapEntry.useSeparateHeaps);
            CEECRHP(arrayHeapID: *omit: *omit: *omit: *omit);
         else;
            arrayHeapID = heapEntry.ID;
         endif;

         hArray = Array_new(i_elemSize: name: increment: arrayHeapID);

         // Add array to the array list of the specified heap
         pArrayMapEntry = %alloc(%size(arrayMapEntry));
         arrayMapEntry.hArray = hArray;
         arrayMapEntry.arrayHeapID = arrayHeapID;
         x = BasicList_add(heapEntry.hArrayList
                          : %addr(arrayMapEntry)
                          : %size(arrayMapEntry));
         dealloc(N) pArrayMapEntry;

         // Update position of the array in the list of arrays of the heap
         pArrayMapEntry = BasicList_get(heapEntry.hArrayList: x);
         arrayMapEntry.index = x;
         Array_setHeapIndex(arrayMapEntry.hArray: arrayMapEntry.index);

         Logger_debug(g_hLogger
                      : 'Created array ''' + name + '''' +
                        ' for service ID ' + i_serviceUUID +
                        ' using heap with ID ' + %char(heapEntry.ID));

         return hArray;

      /END-FREE
      *
     P MemoryManager_createArray...
     P                 E
      *
      *=====================================================================*
      *  Deletes a given dynamic array.
      *=====================================================================*
     P MemoryManager_deleteArray...
     P                 B                   export
      *
     D MemoryManager_deleteArray...
     D                 PI                  opdesc
     D  i_serviceUUID                      const  like(wsdl_uuid_t   )
     D  io_hArray                                 like(wsdl_hArray_t )
      *
      *  Parameter positions
     D p_hArray        C                   2
      *
      *  Get string information
     D s_hArray        DS                  likeds(strInf_t ) inz
     D fc              DS                  likeds(cee_fc_t ) inz
      *
      *  Local fields
     D x               S             10I 0 inz
     D isTrueHandle    S               N   inz(cFalse)
     D hArray          S                   like(io_hArray       ) inz
     D name            S                   like(wsdl_arrayName_t) inz
     D heapEntry       DS                  likeds(heaPEntry_t )
     D                                     based(pHeapEntry)
     D arrayMapEntry   DS                  likeds(arrayMapEntry_t )
     D                                     based(pArrayMapEntry)
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         initializeModule();

         CEEGSI(p_hArray
                : s_hArray.datatype: s_hArray.curlen: s_hArray.maxlen: fc);
         if (fc.MsgSev = 0 and fc.Msg_No = 0);
            hArray = Array_getHandle(%str(io_hArray));
            isTrueHandle = cFalse;
         else;
            hArray = io_hArray;
            isTrueHandle = cTrue;
         endif;

         p_assert(not BasicMap_isNull(g_hHeapMap)
                  : 'Heap map does not exist');

         pHeapEntry = BasicMap_get(g_hHeapMap: i_serviceUUID);

         p_assert(pHeapEntry <> *NULL
                  : 'Web Service ID ' + i_serviceUUID +
                    ' not found in heap map');

         // Delete array and renmove it from array list
         name = Array_getName(hArray);

         x = Array_getHeapIndex(hArray);
         pArrayMapEntry = BasicList_get(heapEntry.hArrayList: x);
         p_assert(hArray = arrayMapEntry.hArray
                  : 'hArray must match: arrayMapEntry.hArray');

         Array_delete(hArray);

         arrayMapEntry.hArray = Array_null();
         arrayMapEntry.index  = -1;

         p_assert((heapEntry.useSeparateHeaps and
                   (heapEntry.ID <> arrayMapEntry.arrayHeapID)) or
                  (not heapEntry.useSeparateHeaps and
                   (heapEntry.ID = arrayMapEntry.arrayHeapID)):
                  'Invalid combination of heap IDs');

         if (heapEntry.useSeparateHeaps);
            CEEDSHP(arrayMapEntry.arrayHeapID: *omit);
         endif;

         arrayMapEntry.arrayHeapID = -1;

         Logger_debug(g_hLogger
                      : 'Deleted array '''+ name + '''' +
                        ' of service ID: ' + i_serviceUUID);

         if (isTrueHandle);
            io_hArray = Array_null();
         endif;

         return;

      /END-FREE
      *
     P MemoryManager_deleteArray...
     P                 E
      *
      *=====================================================================*
      *  Dumps the status of the Memory Manager.
      *=====================================================================*
     P MemoryManager_dump...
     P                 B                   export
      *
     D MemoryManager_dump...
     D                 PI
      *
      *  Local fields
     D x               S             10I 0 inz
     D y               S             10I 0 inz
     D numE            S              5I 0 inz
     D heapEntry       DS                  likeds(heaPEntry_t )
     D                                     based(pHeapEntry)
     D arrayMapEntry   DS                  likeds(arrayMapEntry_t)
     D                                     based(pArrayMapEntry)
      *
     D line            DS                  qualified
     D  heapID                 6     15A
     D  arrayName             18     50A
     D  numE                  53     58A
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         initializeModule();

         Dump_open();

         clear line;
         line.heapID    = 'Heap';
         line.arrayName = 'Array name';
         line.numE      = '#Items';
         Dump_print(line);

         clear line;
         line.heapID    = *ALL'-';
         line.arrayName = *ALL'-';
         line.numE      = *ALL'-';
         Dump_print(line);

         for x = 1 to BasicMap_getNumE(g_hHeapMap);
            pHeapEntry = BasicMap_getValueByIndex(g_hHeapMap: x);

            clear line;
            line.heapID = %char(heapEntry.ID);
            Dump_print(line);

            for y = 1 to BasicMap_getNumE(heapEntry.hArrayList);
               pArrayMapEntry = BasicList_get(heapEntry.hArrayList: y);

               numE = Array_getNumE(arrayMapEntry.hArray);

               clear line;
               line.arrayName = Array_getName(arrayMapEntry.hArray);
               line.numE      = %editc(numE: 'Z');
               Dump_print(line);
            endfor;

         endfor;

         Dump_close();

         return;

      /END-FREE
      *
     P MemoryManager_dump...
     P                 E
      *
      *=====================================================================*
      *  Create a new heap map.
      *=====================================================================*
     P createHeapMap...
     P                 B
      *
     D createHeapMap...
     D                 PI              *
      *
      *  Local fields
     D hHeapMap        S                   like(BasicMap_handle_t ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         hHeapMap = BasicMap_new();
         Logger_debug(g_hLogger
                      : 'Created new heap map.');

         return hHeapMap;

      /END-FREE
      *
     P createHeapMap...
     P                 E
      *
      *=====================================================================*
      *  Deletes the heap map.
      *=====================================================================*
     P deleteHeapMap...
     P                 B
      *
     D deleteHeapMap...
     D                 PI
     D  io_hHeapMap                               like(BasicMap_handle_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         BasicMap_delete(io_hHeapMap);
         Logger_debug(g_hLogger
                      : 'Deleted heap map.');

         return;

      /END-FREE
      *
     P deleteHeapMap...
     P                 E
      *
      *=====================================================================*
      *  Create a new heap.
      *=====================================================================*
     P createHeap...
     P                 B
      *
     D createHeap...
     D                 PI              *
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
     D  i_useSymbolicNames...
     D                                 N   const
     D  i_useSeparateHeaps...
     D                                 N   const
      *
      *  Local fields
     D heapID          S             10I 0 inz
     D heapEntry       DS                  likeds(heapEntry_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         CEECRHP(heapID: *omit: *omit: *omit: *omit);

         Logger_debug(g_hLogger
                      : 'Created heap with ID: ' + %char(heapID));

         clear heapEntry;
         heapEntry.ID          = heapID;
         heapEntry.hArrayList  = BasicList_new();
         heapEntry.unqCount    = 0;
         heapEntry.useNames    = i_useSymbolicNames;
         heapEntry.useNamesMsg = cFalse;
         heapEntry.useSeparateHeaps = i_useSeparateHeaps;

         BasicMap_put(g_hHeapMap: i_serviceUUID
                      : %addr(heapEntry): %size(heapEntry));

         Logger_debug(g_hLogger
                      : 'Assigned heap with ID ' + %char(heapEntry.ID) +
                        ' to service ID ' + i_serviceUUID);

         return BasicMap_get(g_hHeapMap: i_serviceUUID);

      /END-FREE
      *
     P createHeap...
     P                 E
      *
      *=====================================================================*
      *  Delete heap.
      *=====================================================================*
     P deleteHeap...
     P                 B
      *
     D deleteHeap...
     D                 PI
     D  i_serviceUUID                      const  like(wsdl_uuid_t       )
      *
      *  Local fields
     D numE            S             10I 0 inz
     D pHeapEntry      S               *   inz
     D heapEntry       DS                  likeds(heapEntry_t     ) inz
     D arrayMapEntry   DS                  likeds(arrayMapEntry_t )
     D                                     based(pArrayMapEntry)
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         pHeapEntry = BasicMap_get(g_hHeapMap: i_serviceUUID
                                   : %addr(heapEntry): %size(heapEntry));

         p_assert(pHeapEntry <> *NULL
                  : 'Web Service ID ' + i_serviceUUID +
                    ' not found in heap map');

         numE = BasicList_getNumE(heapEntry.hArrayList);
         dow (numE > 0);
            pArrayMapEntry = BasicList_get(heapEntry.hArrayList: numE);
            // MemoryManager_deleteArray(i_serviceUUID: arrayMapEntry.hArray);
            if (not Array_isNull(arrayMapEntry.hArray));
               Array_delete(arrayMapEntry.hArray);
            endif;
            BasicList_remove(heapEntry.hArrayList: numE);
            numE = numE - 1;
         enddo;

         p_assert(BasicList_getNumE(heapEntry.hArrayList) = 0
                  : 'Array map of Web Service ID ' + i_serviceUUID +
                    ' is not empty');

         CEEDSHP(heapEntry.ID: *omit);

         Logger_debug(g_hLogger
                      : 'Deleted heap with ID: ' + %char(heapEntry.ID));

         BasicMap_remove(g_hHeapMap: i_serviceUUID);

         Logger_debug(g_hLogger
                      : 'Removed heap with ID ' + %char(heapEntry.ID) +
                        ' from service ID ' + i_serviceUUID + ':');

         if (not (BasicList_isNull(heapEntry.hArrayList)));
            BasicList_delete(heapEntry.hArrayList);
         endif;

         clear heapEntry;

         return;

      /END-FREE
      *
     P deleteHeap...
     P                 E
      *
      *=====================================================================*
    R *  *** private ***
      *  Activation group exit:    Terminate MemoryManager
      *=====================================================================*
     P ActGrpExit_terminateMemoryManager...
     P                 B
      *
     D ActGrpExit_terminateMemoryManager...
     D                 PI
      *
      *  Local fields
     D serviceUUID     S                   like(wsdl_uuid_t ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         Logger_debug(g_hLogger
                      : 'Shutting down MemoryManager ...');

         dow (not BasicMap_isNull(g_hHeapMap) and
              BasicMap_getNumE(g_hHeapMap) > 0);
            serviceUUID = BasicMap_getKeyByIndex(
                                g_hHeapMap: BasicMap_getNumE(g_hHeapMap));
            MemoryManager_detachService(serviceUUID);
         enddo;

         Logger_debug(g_hLogger
                      : '... MemoryManager terminated.');

         return;

      /END-FREE
      *
     P ActGrpExit_terminateMemoryManager...
     P                 E
      *
      * =====================================================================
      *  *** private ***
      *  Opens the dump output stream.
      * =====================================================================
     P Dump_open...
     P                 B
      *
     D Dump_open...
     D                 PI
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         monitor;
            open QPRINT;
         on-error;
         endmon;

         return;

      /end-free
      *
     P Dump_open...
     P                 E
      *
      * =====================================================================
      *  *** private ***
      *  Prints a line of text.
      * =====================================================================
     P Dump_print...
     P                 B
      *
     D Dump_print...
     D                 PI
     D  i_text                      128A   value  options(*nopass)
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (not %open(QPRINT));
            g_printData = '';
            return;
         endif;

         if (%parms() >= 1);
            g_printData = i_text;
         else;
            g_printData = '';
         endif;

         Except PrintLine;
         g_printData = '';

         return;

      /end-free
      *
     P Dump_print...
     P                 E
      *
      * =====================================================================
      *  *** private ***
      *  Closes the dump output stream.
      * =====================================================================
     P Dump_close...
     P                 B
      *
     D Dump_close...
     D                 PI
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (%open(QPRINT));
            close QPRINT;
         endif;

         return;

      /end-free
      *
     P Dump_close...
     P                 E
      *
      *=====================================================================*
    R *  *** private ***
      *  Initializes this module.
      *=====================================================================*
     P initializeModule...
     P                 B
      *
     D initializeModule...
     D                 PI
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /FREE

         if (g_isInit);
            return;
         endif;

         g_hLogger = Logger_getLogger(cLOGGER + cLOGGER_MEMORY_MANAGER);

         CEE4RAGE(%paddr('ActGrpExit_terminateMemoryManager'): *omit);

         g_isInit = cTrue;

         return;

      /END-FREE
      *
     P initializeModule...
     P                 E
      *
      /IF NOT DEFINED(PROTOTYPE_%(var:outmbr))
      *======================================================================
      *  Generated by WSDL2RPG %(var:versionInfo)
      *  Built on %(var:buildOn)
      *  Built for %(var:tgtrls)
      *  Based on WS_SRV v1.16.0
      *======================================================================
      *
      *   This source member contains the common procedures
      *   of web service port:
      *
      *      %(var:wsdlPortName;75)
      *
      *======================================================================
      *   Pre-Compiler tags used by STRPREPRC to retrieve creation
      *   commands from the source member.
      * ---------------------------------------------------------------------
      * >>PRE-COMPILER<<
      *   >>CRTCMD<< CRTRPGMOD    MODULE(&LI/&OB) +
      *                           SRCFILE(&SL/&SF) +
      *                           SRCMBR(&SM);
      *   >>COMPILE<<
      *     >>PARM<< TRUNCNBR(*NO);
      *     >>PARM<< DBGVIEW(*LIST);
      *   >>END-COMPILE<<
      *   >>EXECUTE<<
      *   >>CMD<<    CRTSRVPGM +
      *              SRVPGM(&LI/&OB ) +
      *              MODULE(&LI/&OB   +
      *   %(generate:listOfStubModules)
      *                             ) +
      *              EXPORT(*ALL) +
      *              BNDSRVPGM(*LIBL/WSDL2RPGRT  +
      /IF DEFINED(BASE64_PTR)
      *                        *LIBL/WSDL2UTILS  +
      /ENDIF
      *                        *LIBL/MIME        +
      *                        *LIBL/HTTPMIME    +
      *                        *LIBL/BASICS1   ) +
      *              TEXT('+
      *              %(var:memberText;75;'+')+
      *              ') +
      *              DETAIL(*BASIC);
      * >>END-PRE-COMPILER<<
      *======================================================================
     H NOMAIN
     H DEBUG
     H BNDDIR('HTTPAPI': 'QC2LE')
     H OPTION(*SRCSTMT : *NODEBUGIO)
     H EXTBININT(*YES)
      /ENDIF
      /IF NOT DEFINED(PROTOTYPE_DEFINED_%(var:outmbr))
      /DEFINE PROTOTYPE_DEFINED_%(var:outmbr)
      *
      *   Type definitions
      /COPY QWSDL2RPG,TYPES_H
      /IF DEFINED(DYNAMIC_ARRAYS)
      *
      *   Imported prototypes
      /COPY QWSDL2RPG,PWSDL2R82                    WSDL2RPG: Dynamic Array
      /COPY QWSDL2RPG,PWSDL2R84                    WSDL2RPG: MemoryManager
      /ENDIF
      /COPY QWSDL2RPG,PWSDL2R88                    WSDL2RPG: Public Helper Procedures
      /COPY QWSDL2RPG,PWSDL2R90                    WSDL2RPG: AppMsg
      *
      *   Array dimensions:
      *   %(generate:dimensions)
      *
      *   Web Service specific types:
      *   %(generate:types)
      *
      *   Public prototypes
      *
      *   Web service: Returns the endpoint of the Web service
     D %(var:portName+_Endpoint_get...;75;'...')
     D                 PR         32767A          varying
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Endpoint_get+
     D                                     ')
      *
      *   Web service: Sets the endpoint of the Web service
     D %(var:portName+_Endpoint_set...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Endpoint_set+
     D                                     ')
     D  i_url                     32767A   const varying  options(*varsize)
      *
      *   Web service: Returns the host name of the Web Service endpoint
     D %(var:portName+_Endpoint_getHost...;75;'...')
     D                 PR         32767A          varying
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Endpoint_getHost+
     D                                     ')
      *
      *   Web service: Sets the host name of the Web service endpoint
     D %(var:portName+_Endpoint_setHost...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Endpoint_setHost+
     D                                     ')
     D  i_url                     32767A   const varying  options(*varsize)
      *
      *   Web service: Returns the port of the Web Service endpoint
     D %(var:portName+_Endpoint_getPort...;75;'...')
     D                 PR            10I 0
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Endpoint_getPort+
     D                                     ')
      *
      *   Web service: Sets the port of the Web service endpoint
     D %(var:portName+_Endpoint_setPort...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Endpoint_setPort+
     D                                     ')
     D  i_port                       10I 0 const
      *
      *   Web service: Initializes the web services port
     D %(var:portName+_Port_initialize...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_initialize+
     D                                     ')
     D  i_operName                         const  like(wsdl_operName_t )
      *
      *   Web service: Sets the proxy server to use for the connection
     D %(var:portName+_Port_setHttpProxy...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_setHttpProxy+
     D                                     ')
     D  i_server                    256A   const
     D  i_port                       10I 0 const
      *
      *   Web service: Returns the proxy server to use for the connection
     D %(var:portName+_Port_getHttpProxy...;75;'...')
     D                 PR                         likeds(wsdl_proxy_t )
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_getHttpProxy+
     D                                     ')
      *
      *   Web service: Enables/disables the debug log of HTTP API
     D %(var:portName+_Port_setHttpDebug...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_setHttpDebug+
     D                                     ')
     D   i_status                      N   const
     D   i_fileName                 500A   const  varying  options(*nopass)
     D   i_verbose                     N   const  options(*nopass)
      *
      *   Web service: Returns the HTTP API debug settings
     D %(var:portName+_Port_getHttpDebug...;75;'...')
     D                 PR                         likeds(wsdl_httpDebug_t )
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_getHttpDebug+
     D                                     ')
      *
      *   Web service: Sets the CCSID used for POST data.
     D %(var:portName+_Port_setPostCcsid...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_setPostCcsid+
     D                                     ')
     D  i_post_ccsid                 10I 0 const
      *
      *   Web service: Returns the CCSID used for POST data.
     D %(var:portName+_Port_getPostCcsid...;75;'...')
     D                 PR            10I 0
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_getPostCcsid+
     D                                     ')
      *
      *   Web service: Sets the timeout that HTTPAPI uses
      *   when connecting to the server or waiting for response.
     D %(var:portName+_Port_setTimeout...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_setTimeout+
     D                                     ')
     D  i_timeout                    10I 0 const
      *
      *   Web service: Returns the timeout that HTTPAPI uses
      *   when connecting to the server or waiting for response.
     D %(var:portName+_Port_getTimeout...;75;'...')
     D                 PR            10I 0
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_getTimeout+
     D                                     ')
      *
      *   Web service: Sets the user-agent that HTTPAPI uses
      *   to identify the client at the server.
     D %(var:portName+_Port_setUserAgent...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_setUserAgent+
     D                                     ')
     D  i_userAgent                        const  like(wsdl_userAgent_t )
      *
      *   Web service: Returns the user-agent that HTTPAPI uses
      *   to identify the client at the server.
     D %(var:portName+_Port_getUserAgent...;75;'...')
     D                 PR                         like(wsdl_userAgent_t )
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_getUserAgent+
     D                                     ')
      *
      *   Web service: Clears all error information
     D %(var:portName+_Port_clearErrors...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_clearErrors+
     D                                     ')
     D  io_errors                                 likeds(wsdl_errors_t )
      *
      *   Web service: Sets error information
     D %(var:portName+_Port_setErrors...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _Port_setErrors+
     D                                     ')
     D  i_errors                           const  likeds(wsdl_errors_t )
      *
      *   Http: Returns cTrue in case of an error, else cFalse.
     D %(var:portName+_Port_isError...;75;'...')
     D                 PR              N
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Port_isError+
     D                                     ')
      *
      *   Http: Returns the last HTTP error (code) that occurred.
     D %(var:portName+_HttpError_getCode...;75;'...')
     D                 PR                  like(wsdl_http_ErrorNo_t  )
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _HttpError_getCode+
     D                                     ')
      *
      *   Http: Returns the last HTTP error (text) that occurred.
     D %(var:portName+_HttpError_getText...;75;'...')
     D                 PR                  like(wsdl_http_ErrorText_t)
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _HttpError_getText+
     D                                     ')
      *
      *   Soap: Returns the last SOAP error (code) that occurred.
     D %(var:portName+_SoapError_getCode...;75;'...')
     D                 PR                  like(wsdl_soap_faultcode_t  )
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _SoapError_getCode+
     D                                     ')
      *
      *   Soap: Returns the last SOAP error (text) that occurred.
     D %(var:portName+_SoapError_getText...;75;'...')
     D                 PR                  like(wsdl_soap_faultstring_t)
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _SoapError_getText+
     D                                     ')
      *
      *   Soap: Returns the last XML error (code) that occurred.
     D %(var:portName+_XmlError_getCode...;75;'...')
     D                 PR                  like(wsdl_xml_errorNo_t    )
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _XmlError_getCode+
     D                                     ')
      *
      *   Soap: Returns the last XML error (text) that occurred.
     D %(var:portName+_XmlError_getText...;75;'...')
     D                 PR                  like(wsdl_xml_ErrorText_t  )
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _XmlError_getText+
     D                                     ')
      *
      *   Registers an user callback procedure, that is called whenever
      *   a web service requires user authentification.
     D %(var:portName+_Port_registerLoginCallback...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Port_registerLoginCallback+
     D                                     ')
     D  i_pLoginProc                   *   value  procptr
      *
      *   Returns *ON if a login procedures has been registered.
     D %(var:portName+_Port_hasLoginCallback...;75;'...')
     D                 PR              N
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Port_hasLoginCallback+
     D                                     ')
      *
      *   Login to proxy server or web service.
     D %(var:portName+_Port_login...;75;'...')
     D                 PR            10I 0
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Port_login+
     D                                     ')
     D  i_http_err                   10I 0 value
     D  i_numAttempts                10I 0 value
      *
      *   Returns the name of the web service port.
     D %(var:portName+_Port_getName...;75;'...')
     D                 PR           512A          varying
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Port_getName+
     D                                     ')
      *
      *   Returns the UUID of the web service port.
     D %(var:portName+_Port_getUuid...;75;'...')
     D                 PR                         like(wsdl_uuid_t )
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Port_getUuid+
     D                                     ')
      *
      *   Adds an attachments to the list of attachments.
     D %(var:portName+_Attachments_put...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Attachments_put+
     D                                     ')
     D  i_attachmentID...
     D                                     const  like(wsdl_attachmentID_t )
     D  i_fileName                         const  like(wsdl_path_t         )
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
      *   Returns the file name of the attachment that is associated to
      *   a given content ID.
     D %(var:portName+_Attachments_get...;75;'...')
     D                 PR                  like(wsdl_path_t     )
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Attachments_get+
     D                                     ')
     D  i_attachmentID...
     D                                     const  like(wsdl_attachmentID_t )
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
      *   Returns the file name of the attachment that is associated to
      *   a given index.
     D %(var:portName+_Attachments_getAtPos...;75;'...')
     D                 PR                  likeds(wsdl_attachment_t )
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Attachments_getAtPos+
     D                                     ')
     D  i_index                      10I 0 const
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
      *   Returns the number of attachments that were downloaded with the
      *   last call to the web service.
     D %(var:portName+_Attachments_getNumE...;75;'...')
     D                 PR            10I 0
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Attachments_getNumE+
     D                                     ')
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
      *   Removes all attachments from the list of attachments of this web service.
     D %(var:portName+_Attachments_removeAll...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Attachments_removeAll+
     D                                     ')
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
      *   Specifies the name of the folder where to put attachments in.
     D %(var:portName+_Attachments_setFolder...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Attachments_setFolder+
     D                                     ')
     D  i_folder                           const  like(wsdl_pathLong_t )
      *
      *   Returns the name of the folder where attachments are stored.
     D %(var:portName+_Attachments_getFolder...;75;'...')
     D                 PR                         like(wsdl_pathLong_t )
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Attachments_getFolder+
     D                                     ')
      /IF DEFINED(DYNAMIC_ARRAYS)
      *
      *   Initializes the memory manager.
     D %(var:portName+_initializeMemoryManager...;75;'...')
     D                 PR                         like(wsdl_uuid_t )
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _initializeMemoryManager+
     D                                     ')
     D  i_uuid                             const  like(wsdl_uuid_t )
     D                                            options(*nopass: *omit)
      *
      *   Frees all allocated memory blocks of all dynamic List objects.
     D %(var:portName+_terminateMemoryManager...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _terminateMemoryManager+
     D                                     ')
     D  i_uuid                             const  like(wsdl_uuid_t )
     D                                            options(*nopass: *omit)
      /ENDIF
      *
      *   Enables redirection of the HTTP response message to a
      *   stream file in the IFS.
     D %(var:portName+_RedirectResponse_toStmf...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _RedirectResponse_toStmf+
     D                                     ')
     D  i_stmf                             const  like(wsdl_pathLong_t )
     D  i_replace                      N   const  options(*nopass: *omit)
     D  i_ccsid                      10I 0 const  options(*nopass: *omit)
     D  i_auth                       10I 0 const  options(*nopass: *omit)
      *
      *   Returns cTrue if response redirection is active, otherwise cFalse.
     D %(var:portName+_RedirectResponse_isActive...;75;'...')
     D                 PR              N
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _RedirectResponse_isActive+
     D                                     ')
      *
      *   Terminates a response redirection and closes the
      *   file that receiced the response.
     D %(var:portName+_RedirectResponse_write...;75;'...')
     D                 PR              N
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _RedirectResponse_write+
     D                                     ')
     D  i_data                         *   value
     D  i_length                     10I 0 value
      *
      *   Terminates a response redirection and closes the
      *   file that receiced the response.
     D %(var:portName+_RedirectResponse_terminate...;75;'...')
     D                 PR
     D                                     extproc('+
     D                                     %(var:portName;80;'+')+
     D                                     _RedirectResponse_terminate+
     D                                     ')
      *
      /ENDIF
      /IF DEFINED(PROTOTYPE_%(var:outmbr))
      /EOF
      /ENDIF
      * ---------------------------------------------------------------------
      *
      * ------------------------------------
      *  Imported prototypes
      * ------------------------------------
      /COPY QBASICS1,PBASICS1                      Tools/400 Runtime Library
      /COPY QRPGLESRC,HTTPAPI_H                    HTTP-API Service Program
      *
      /COPY QWSDL2RPG,PWSDL2R71                    WSDL2RPG: HTTP Debug Log
      /COPY QWSDL2RPG,PWSDL2R89                    WSDL2RPG: List of Attachments
      *
      * ------------------------------------
      *  Internal prototypes
      * ------------------------------------
      *
     D getEndpoint...
     D                 PR         32767A          varying
     D                                     extproc('+
     D                                     getEndpoint+
     D                                     ')
      *
     D setEndpoint...
     D                 PR
     D                                     extproc('+
     D                                     setEndpoint+
     D                                     ')
     D  i_url                     32767A   const varying  options(*varsize)
      *
      * ------------------------------------
      *  Global fields & constants
      * ------------------------------------
      *
      *   Web service port name
     D cWEB_SERVICE_PORT_NAME...
     D                 C                   %(qvar:portName;75;'+')
      *
      *   UUID of the web service as generated by WSDL2RPG
     D cWEB_SERVICE_UUID...
     D                 C                   %(qvar:serviceUUID)
      *
      *   Default and current attachment folder
     D cATTACHMENT_FOLDER...
     D                 C                   '/tmp/attachments/'
      *
      *   Default POST data CCSID (1208 = UTF-8)
     D cPOST_DATA_CCSID...
     D                 C                   1208
      *
      *   Web service endpoint as specified in the WSDL file.
      *   %(generate:webServiceEndPoint)
      *
      *   Web service endpoint
     D g_url           S          32767A   varying inz(cURL)
      *
      *   Proxy server to use
     D g_proxy         DS                  likeds(wsdl_proxy_t     ) inz
      *
      *   HTTPAPI debug settings
     D g_httpDebug     DS                  likeds(wsdl_httpDebug_t ) inz
      *
      *   POST data CCSID (1208 = UTF-8)
     D g_post_ccsid...
     D                 S             10I 0 inz(cPOST_DATA_CCSID)
      *
      *   Timeout in seconds used when connecting to the server
      *   or waiting for response from the server.
     D g_timeout...
     D                 S             10I 0 inz(HTTP_TIMEOUT)
      *
      *   User-agent used when connecting to the server.
     D g_userAgent...
     D                 S                   like(wsdl_userAgent_t )
     D                                     inz(HTTP_USERAGENT)
      *
      *   Name of the directory used to store attachments
     D g_attachmentFolder...
     D                 S                   like(wsdl_pathLong_t )
     D                                     inz(cATTACHMENT_FOLDER)
      *
      *   Redirect response status information
     D g_redirectResponse...
     D                 DS                  qualified
     D  isActive                       N   inz(cFalse)
     D  ccsid                        10I 0 inz
     D  auth                         10I 0 inz
     D  options                      10I 0 inz
     D  fd                           10I 0 inz(-1)
     D  path                               like(wsdl_pathLong_t ) inz
      *
      *   Web service error information
     D g_errors        DS                  likeds(wsdl_errors_t    ) inz
      *
      *   User callback to supply login information
      *   Returns WSDL_SUCCESS if successful, WSDL_ERROR upon error.
     D g_getLoginDataImpl...
     D                 S               *   procptr inz
      *
      *   User callback to supply login information
      *   Returns WSDL_SUCCESS if successful, WSDL_ERROR upon error.
      *
      *   Parameter description:
      *     i_authType         Authentication type:
      *                          WSDL_AUTH_TYPE_HTTP  - HTTP server.
      *                          WSDL_AUTH_TYPE_PROXY - Proxy server.
      *     i_realm            Authentication realm.
      *     i_numAttempts      Number of login attempts.
      *     o_user             UserName to use.
      *     o_password         Password to use.
      *
     D %(var:portName+_Port_supplyLoginData...;75;'...')
     D                 PR            10I 0
     D                                     extproc('+
     D                                     %(var:portName;79;'+')+
     D                                     _Port_supplyLoginData+
     D                                     ')
     D  i_authType                   14A          const  varying
     D  i_realm                     126A          const  varying
     D  i_numAttempts                10I 0        const
     D  o_user                       50A                 varying
     D  o_password                   50A                 varying
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Returns the endpoint of the Web service
      * =====================================================================
     P %(var:portName+_Endpoint_get...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Endpoint_get...;75;'...')
     D                 PI         32767A          varying
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return getEndpoint();

      /end-free
      *
     P %(var:portName+_Endpoint_get...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Sets the endpoint of the Web service
      * =====================================================================
     P %(var:portName+_Endpoint_set...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Endpoint_set...;75;'...')
     D                 PI
     D  i_url                     32767A   const varying  options(*varsize)
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         setEndpoint(%subst(i_url: 1: %len(i_url)));

         return;

      /end-free
      *
     P %(var:portName+_Endpoint_set...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Returns the host name of the Web Service endpoint
      * =====================================================================
     P %(var:portName+_Endpoint_getHost...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Endpoint_getHost...;75;'...')
     D                 PI         32767A          varying
      *
     D tmpUrl          S                   like(url_t ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         tmpUrl = URL_new(getEndpoint());

         return URL_getHost(tmpUrl);

      /end-free
      *
     P %(var:portName+_Endpoint_getHost...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Sets the host name of the Web service endpoint
      * =====================================================================
     P %(var:portName+_Endpoint_setHost...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Endpoint_setHost...;75;'...')
     D                 PI
     D  i_host                    32767A   const varying  options(*varsize)
      *
     D tmpUrl          S                   like(url_t ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         tmpUrl = URL_new(getEndpoint());
         URL_setHost(tmpUrl: %subst(i_host: 1: %len(i_host)));
         setEndpoint(URL_toString(tmpUrl));

         return;

      /end-free
      *
     P %(var:portName+_Endpoint_setHost...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Returns the port of the Web Service endpoint
      * =====================================================================
     P %(var:portName+_Endpoint_getPort...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Endpoint_getPort...;75;'...')
     D                 PI            10I 0
      *
     D tmpUrl          S                   like(url_t ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         tmpUrl = URL_new(getEndpoint());

         return URL_getPort(tmpUrl);

      /end-free
      *
     P %(var:portName+_Endpoint_getPort...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Sets the port of the Web service endpoint
      * =====================================================================
     P %(var:portName+_Endpoint_setPort...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Endpoint_setPort...;75;'...')
     D                 PI
     D  i_port                       10I 0 const
      *
     D tmpUrl          S                   like(url_t ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         tmpUrl = URL_new(getEndpoint());
         URL_setPort(tmpUrl: i_port);
         setEndpoint(URL_toString(tmpUrl));

         return;

      /end-free
      *
     P %(var:portName+_Endpoint_setPort...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Web service: Initializes the web service port.
      * =====================================================================
     P %(var:portName+_Port_initialize...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_initialize...;75;'...')
     D                 PI
     D  i_operName                         const  like(wsdl_operName_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         // This procedure is called from every web service
         // operation right at the beginning of the operation.
         // This procedure may be used to perform any type
         // of initialization that is the same for all web
         // service operations.
         // For example you may want to register a procedure
         // to supply login credentials like this:

         if (not %(var:portName+_Port_hasLoginCallback;75;'...')());
            %(var:portName+_Port_registerLoginCallback;75;'...')(
               %paddr('+
                  %(var:portName+_Port_supplyLoginData;75;'+')+
               '));
         endif;

         return;

      /end-free
      *
     P %(var:portName+_Port_initialize...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by *_Port_login() ***
      *   Web service: Supplies login credentials for web services that
      *                require BASIC or DIGEST authentication.
      * =====================================================================
     P %(var:portName+_Port_supplyLoginData...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_supplyLoginData...;75;'...')
     D                 PI            10I 0
     D  i_authType                   14A          const  varying
     D  i_realm                     126A          const  varying
     D  i_numAttempts                10I 0        const
     D  o_user                       50A                 varying
     D  o_password                   50A                 varying
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         // This procedure is called when a web service requires
         // BASIC or DIGEST authentication.
         // You may use the realm value for reading the credentials
         // from a file. Make sure that you do not get into an endless
         // loop in case the credentials are retrieved from a file.
         // The credentials might be wrong!

         // Prevent endless loop when reading the credentials from a file
         // You may remove this IF statement when a user enters the
         // credentials.
         if (i_numAttempts > 1);
            return WSDL_ERROR;
         endif;

         // Set o_user and o_password here and remove the error message.
         // Return WSDL_SUCCESS to let the caller know that user and
         // password have been set, otherwise return WSDL_ERROR.

         clear USR0048;
         USR00481 = f_this();
         AppMsg_sendCancelMsg(AppMsg_newError('USR0048': USR0048));

         return WSDL_ERROR;

      /end-free
      *
     P %(var:portName+_Port_supplyLoginData...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Sets the proxy server to use for the connection
      * =====================================================================
     P %(var:portName+_Port_setHttpProxy...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_setHttpProxy...;75;'...')
     D                 PI
     D  i_server                    256A   const
     D  i_port                       10I 0 const
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_proxy.server = i_server;

         if (g_proxy.server = '');
            g_proxy.port = 0;
         else;
            g_proxy.port = i_port;
         endif;

         return;

      /end-free
      *
     P %(var:portName+_Port_setHttpProxy...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Returns the proxy server to use for the connection
      * =====================================================================
     P %(var:portName+_Port_getHttpProxy...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_getHttpProxy...;75;'...')
     D                 PI                         likeds(wsdl_proxy_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_proxy;

      /end-free
      *
     P %(var:portName+_Port_getHttpProxy...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Enables/disables the debug log of HTTP API
      * =====================================================================
     P %(var:portName+_Port_setHttpDebug...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_setHttpDebug...;75;'...')
     D                 PI
     D   i_status                      N   const
     D   i_fileName                 500A   const  varying  options(*nopass)
     D   i_verbose                     N   const  options(*nopass)
      *
      *  Parameter positions
     D p_fileName      C                   2
     D p_verbose       C                   3
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_httpDebug.status = i_status;

         if (%parms() >= p_fileName);
            g_httpDebug.fileName = i_fileName;
         else;
            g_httpDebug.fileName = '';
         endif;

         if (i_status);
            if (g_httpDebug.fileName = '');
               g_httpDebug.fileName = HTTP_API_DEFAULT_LOG_FILE;
            endif;
         else;
            g_httpDebug.fileName = '';
         endif;

         if (i_status);
            http_DebugLog_open(g_httpDebug.fileName);
         else;
            http_DebugLog_close();
         endif;

         if (%parms() >= p_verbose);
            http_DebugLog_setVerbose(i_verbose);
         else;
            http_DebugLog_setVerbose(cFalse);
         endif;

         return;

      /end-free
      *
     P %(var:portName+_Port_setHttpDebug...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Returns the HTTP API debug settings
      * =====================================================================
     P %(var:portName+_Port_getHttpDebug...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_getHttpDebug...;75;'...')
     D                 PI                         likeds(wsdl_httpDebug_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (g_httpDebug.fileName = '');
            g_httpDebug.fileName = HTTP_API_DEFAULT_LOG_FILE;
         endif;

         return g_httpDebug;

      /end-free
      *
     P %(var:portName+_Port_getHttpDebug...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Sets the CCSID used for POST data.
      *   An application may call this procedure right before the web service
      *   operation in order to specify a POST ccsid different from 1208.
      *   Usually it is not necessary to call this procedure.
      * =====================================================================
     P %(var:portName+_Port_setPostCcsid...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_setPostCcsid...;75;'...')
     D                 PI
     D  i_post_ccsid                 10I 0 const
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_post_ccsid = i_post_ccsid;

         return;

      /end-free
      *
     P %(var:portName+_Port_setPostCcsid...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Returns the CCSID used for POST
      * =====================================================================
     P %(var:portName+_Port_getPostCcsid...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_getPostCcsid...;75;'...')
     D                 PI            10I 0
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_post_ccsid;

      /end-free
      *
     P %(var:portName+_Port_getPostCcsid...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Sets the timeout that HTTPAPI uses
      *   when connecting to the server or waiting for response.
      *   Usually it is not necessary to call this procedure.
      * =====================================================================
     P %(var:portName+_Port_setTimeout...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_setTimeout...;75;'...')
     D                 PI
     D  i_timeout                    10I 0 const
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_timeout = i_timeout;

         return;

      /end-free
      *
     P %(var:portName+_Port_setTimeout...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Returns the timeout that HTTPAPI uses
      *   when connecting to the server or waiting for response.
      * =====================================================================
     P %(var:portName+_Port_getTimeout...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_getTimeout...;75;'...')
     D                 PI            10I 0
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_timeout;

      /end-free
      *
     P %(var:portName+_Port_getTimeout...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Sets the user-agent that HTTPAPI uses
      *   to identify the client at the server.
      *   Usually it is not necessary to call this procedure.
      * =====================================================================
     P %(var:portName+_Port_setUserAgent...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_setUserAgent...;75;'...')
     D                 PI
     D  i_userAgent                        const  like(wsdl_userAgent_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_userAgent = i_userAgent;

         return;

      /end-free
      *
     P %(var:portName+_Port_setUserAgent...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Web service: Returns the user-agent that HTTPAPI uses
      *   to identify the client at the server.
      * =====================================================================
     P %(var:portName+_Port_getUserAgent...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_getUserAgent...;75;'...')
     D                 PI                         like(wsdl_userAgent_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_userAgent;

      /end-free
      *
     P %(var:portName+_Port_getUserAgent...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Web service: Clears all error information.
      * =====================================================================
     P %(var:portName+_Port_clearErrors...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_clearErrors...;75;'...')
     D                 PI
     D  io_errors                                 likeds(wsdl_errors_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         clear g_errors;
         g_errors.errType = WSDL_HTTP_SUCCESS;

         io_errors = g_errors;

         return;

      /end-free
      *
     P %(var:portName+_Port_clearErrors...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Web service: Sets error information of last service call.
      * =====================================================================
     P %(var:portName+_Port_setErrors...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_setErrors...;75;'...')
     D                 PI
     D  i_errors                           const  likeds(wsdl_errors_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_errors = i_errors;

         return;

      /end-free
      *
     P %(var:portName+_Port_setErrors...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Http: Returns the last HTTP error (code) that occurred.
      *   An application should use this procedure to check whether or not
      *   the web service operation has bee successfully executed.
      * =====================================================================
     P %(var:portName+_Port_isError...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_isError...;75;'...')
     D                 PI              N
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (g_errors.errType = WSDL_HTTP_SUCCESS);
            return cFalse;
         else;
            return cTrue;
         endif;

      /end-free
      *
     P %(var:portName+_Port_isError...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Http: Returns the last HTTP error (code) that occurred.
      * =====================================================================
     P %(var:portName+_HttpError_getCode...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_HttpError_getCode...;75;'...')
     D                 PI                  like(wsdl_http_ErrorNo_t  )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_errors.httpError.no;

      /end-free
      *
     P %(var:portName+_HttpError_getCode...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Http: Returns the last HTTP error (text) that occurred.
      * =====================================================================
     P %(var:portName+_HttpError_getText...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_HttpError_getText...;75;'...')
     D                 PI                  like(wsdl_http_ErrorText_t)
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_errors.httpError.text;

      /end-free
      *
     P %(var:portName+_HttpError_getText...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Soap: Returns the last SOAP error (code) that occurred.
      * =====================================================================
     P %(var:portName+_SoapError_getCode...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_SoapError_getCode...;75;'...')
     D                 PI                  like(wsdl_soap_faultcode_t  )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_errors.soapFault.code;

      /end-free
      *
     P %(var:portName+_SoapError_getCode...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Soap: Returns the last SOAP error (text) that occurred.
      * =====================================================================
     P %(var:portName+_SoapError_getText...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_SoapError_getText...;75;'...')
     D                 PI                  like(wsdl_soap_faultstring_t)
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_errors.soapFault.string;

      /end-free
      *
     P %(var:portName+_SoapError_getText...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   XML: Returns the last XML error (code) that occurred.
      * =====================================================================
     P %(var:portName+_XmlError_getCode...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_XmlError_getCode...;75;'...')
     D                 PI                  like(wsdl_xml_ErrorNo_t    )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_errors.xmlError.code;

      /end-free
      *
     P %(var:portName+_XmlError_getCode...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   XML: Returns the last XML error (text) that occurred.
      * =====================================================================
     P %(var:portName+_XmlError_getText...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_XmlError_getText...;75;'...')
     D                 PI                  like(wsdl_xml_ErrorText_t  )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_errors.xmlError.text;

      /end-free
      *
     P %(var:portName+_XmlError_getText...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Registers an user callback procedure, that is called whenever
      *   a web service requires user authentification.
      *   An application may call this procedure in order to register a
      *   user and password provider different from *_Port_supplyLoginData().
      *   Usually *_Port_supplyLoginData() should be modified to match the
      *   requirements of the application.
      * =====================================================================
     P %(var:portName+_Port_registerLoginCallback...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_registerLoginCallback...;75;'...')
     D                 PI
  D  D  i_pLoginProc                   *   value  procptr
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_getLoginDataImpl = i_pLoginProc;

         return;

      /end-free
      *
     P %(var:portName+_Port_registerLoginCallback...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Returns *ON if a login procedures has been registered.
      *   This procedure is used by WS_OPER() but might also be called
      *   by the application to see whether or not a user and password
      *   provider is present.
      * =====================================================================
     P %(var:portName+_Port_hasLoginCallback...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_hasLoginCallback...;75;'...')
     D                 PI              N
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (g_getLoginDataImpl <> *NULL);
            return *ON;
         endif;

         return *OFF;

      /end-free
      *
     P %(var:portName+_Port_hasLoginCallback...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Login to proxy server or web service.
      * =====================================================================
     P %(var:portName+_Port_login...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_login...;75;'...')
     D                 PI            10I 0
     D  i_http_err                   10I 0 value
     D  i_numAttempts                10I 0 value
      *
      *  Return value
     D rc              S             10I 0 inz
      *
      *  Helper fields
     D basic           S               N   inz
     D digest          S               N   inz
     D realm           S            124A   inz
     D authTarget      S             14A   inz varying
     D authType        S              1A   inz
     D userid          S             50A   inz varying
     D password        S             50A   inz varying
      *
     D getLoginDataImpl...
     D                 PR            10I 0
     D                                     extproc(g_getLoginDataImpl)
     D  i_authType                   14A          const  varying
     D  i_realm                     126A          const  varying
     D  i_numAttempts                10I 0        const
     D  o_user                       50A                 varying
     D  o_password                   50A                 varying
      *
     D authErr         S             10I 0 inz
     D err             S             10I 0 inz
     D errText         S             80A   inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (i_http_err = HTTP_NDAUTH);
            http_getauth(basic: digest: realm);
            authTarget = WSDL_AUTH_TYPE_HTTP;
         else;
            http_proxy_getauth(basic: realm);
            authTarget = WSDL_AUTH_TYPE_PROXY;
         endif;

         rc = getLoginDataImpl(authTarget: realm
                               : i_numAttempts: userid: password);
         if (rc <> 1);
            userid = '';
            password = '';
            return rc;
         endif;

         if (i_http_err = HTTP_NDAUTH);
            select;
            when (digest);
               authType = HTTP_AUTH_MD5_DIGEST;
               authErr = http_setAuth(HTTP_AUTH_MD5_DIGEST
                                      : userid: password);
            when (basic);
               authType = HTTP_AUTH_BASIC;
               authErr = http_setAuth(HTTP_AUTH_BASIC
                                      : userid: password);
            other;
               // WSDL_AUTH_NTLM must match the value of HTTP_AUTH_NTLM!
               authType = WSDL_AUTH_NTLM;
               authErr = http_setAuth(WSDL_AUTH_NTLM
                                      : userid: password);
            endsl;
         else;
            select;
            when (digest);
               authType = HTTP_AUTH_MD5_DIGEST;
               authErr = http_proxy_setAuth(HTTP_AUTH_MD5_DIGEST
                                            : userid: password);
            when (basic);
               authType = HTTP_AUTH_BASIC;
               authErr = http_proxy_setAuth(HTTP_AUTH_BASIC
                                            : userid: password);
            other;
               // not yet supported
               http_DebugLog_appendText(
                  '** NTLM authentication is not supported +
                   for proxy authentication');
               authErr = -1;
            endsl;
         endif;

         if (authErr = -1);
            errText = http_error(err);
            http_DebugLog_appendText('** Failed to login: ' + errText);
            if (authtype = WSDL_AUTH_NTLM);
               http_DebugLog_appendText('** Your version of HTTPAPI +
                                         does not support NTLM authentication');
            endif;
            rc = WSDL_ERROR;
         endif;

         userid = '';
         password = '';

         return rc;

      /end-free
      *
     P %(var:portName+_Port_login...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Returns the name of the web service port.
      *   This procedure is used by WS_OPER() but might also be called
      *   by the application for information purposes.
      * =====================================================================
     P %(var:portName+_Port_getName...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_getName...;75;'...')
     D                 PI                         like(wsdl_portName_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return cWEB_SERVICE_PORT_NAME;

      /end-free
      *
     P %(var:portName+_Port_getName...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Returns the UUID of the web service port.
      * =====================================================================
     P %(var:portName+_Port_getUuid...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Port_getUuid...;75;'...')
     D                 PI                         like(wsdl_uuid_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return cWEB_SERVICE_UUID;

      /end-free
      *
     P %(var:portName+_Port_getUuid...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Adds an attachments to the list of attachments.
      * =====================================================================
     P %(var:portName+_Attachments_put...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Attachments_put...;75;'...')
     D                 PI
     D  i_attachmentID...
     D                                     const  like(wsdl_attachmentID_t )
     D  i_fileName                         const  like(wsdl_path_t         )
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
     D p_uuid          C                   3
      *
     D uuid            S                   like(i_uuid          ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (%parms() >= p_uuid);
            uuid = i_uuid;
         else;
            uuid = %(var:portName+_Port_getUuid;75;'...')();
         endif;

         Attachments_put(Attachments_theInstance()
                         : uuid
                         : i_attachmentID
                         : i_fileName);

         return;

      /end-free
      *
     P %(var:portName+_Attachments_put...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Returns the file name of the attachment that is associated to
      *   a given content ID.
      *   An application can use this procedure to get an attachments
      *   of the last web service operation.
      * =====================================================================
     P %(var:portName+_Attachments_get...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Attachments_get...;75;'...')
     D                 PI                  like(wsdl_path_t     )
     D  i_attachmentID...
     D                                     const  like(wsdl_attachmentID_t )
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
     D p_uuid          C                   2
      *
     D uuid            S                   like(i_uuid          ) inz
     D fileName        S                   like(wsdl_path_t     ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (%parms() >= p_uuid);
            uuid = i_uuid;
         else;
            uuid = %(var:portName+_Port_getUuid;75;'...')();
         endif;

         fileName = Attachments_get(Attachments_theInstance()
                                    : uuid
                                    : i_attachmentID);
         return fileName;

      /end-free
      *
     P %(var:portName+_Attachments_get...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Returns the file name of the attachment that is associated to
      *   a given index.
      *   An application can use this procedure to get an attachments
      *   of the last web service operation.
      * =====================================================================
     P %(var:portName+_Attachments_getAtPos...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Attachments_getAtPos...;75;'...')
     D                 PI                  likeds(wsdl_attachment_t )
     D  i_index                      10I 0 const
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
     D p_uuid          C                   2
      *
     D uuid            S                   like(i_uuid          ) inz
     D attachment      DS                  likeds(wsdl_attachment_t ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (%parms() >= p_uuid);
            uuid = i_uuid;
         else;
            uuid = %(var:portName+_Port_getUuid;75;'...')();
         endif;

         attachment = Attachments_getAtPos(Attachments_theInstance()
                                           : uuid
                                           : i_index);
         return attachment;

      /end-free
      *
     P %(var:portName+_Attachments_getAtPos...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Returns the number of attachments that were downloaded with
      *   the last call of the web service.
      * =====================================================================
     P %(var:portName+_Attachments_getNumE...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Attachments_getNumE...;75;'...')
     D                 PI            10I 0
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
     D p_uuid          C                   1
      *
     D uuid            S                   like(i_uuid          ) inz
     D numE            S             10I 0 inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (%parms() >= p_uuid);
            uuid = i_uuid;
         else;
            uuid = %(var:portName+_Port_getUuid;75;'...')();
         endif;

         numE = Attachments_getNumAttachments(
                      Attachments_theInstance(): uuid);

         return numE;

      /end-free
      *
     P %(var:portName+_Attachments_getNumE...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Removes all attachments from the list of attachments of
      *   this web service.
      *   An application should call this procedure once that the
      *   attachments of the last web service operation are obsolete.
      *   This procedure is also used by WS_OPER() to remove all attachments
      *   before the next web service call.
      * =====================================================================
     P %(var:portName+_Attachments_removeAll...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Attachments_removeAll...;75;'...')
     D                 PI
     D  i_uuid                             const  like(wsdl_uuid_t         )
     D                                            options(*nopass)
      *
     D p_uuid          C                   1
      *
     D uuid            S                   like(i_uuid          ) inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (%parms() >= p_uuid);
            uuid = i_uuid;
         else;
            uuid = %(var:portName+_Port_getUuid;75;'...')();
         endif;

         Attachments_removeAll(Attachments_theInstance(): uuid);

         return;

      /end-free
      *
     P %(var:portName+_Attachments_removeAll...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Specifies the name of the folder where to put attachments in.
      *   An application may use this procedure to specify a folder where
      *   to store attachements. The default value is '/tmp/attachments/'.
      * =====================================================================
     P %(var:portName+_Attachments_setFolder...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Attachments_setFolder...;75;'...')
     D                 PI
     D  i_folder                           const  like(wsdl_pathLong_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_attachmentFolder = i_folder;

         g_attachmentFolder = %trimR(%xlate('\': '/': g_attachmentFolder));
         if (not f_endsWith('/': g_attachmentFolder));
            g_attachmentFolder = g_attachmentFolder + '/';
         endif;

         return;

      /end-free
      *
     P %(var:portName+_Attachments_setFolder...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Returns the name of the folder where attachments are stored.
      * =====================================================================
     P %(var:portName+_Attachments_getFolder...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_Attachments_getFolder...;75;'...')
     D                 PI                         like(wsdl_pathLong_t )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_attachmentFolder;

      /end-free
      *
     P %(var:portName+_Attachments_getFolder...;75;'...')
     P                 E
      /IF DEFINED(DYNAMIC_ARRAYS)
      *
      * =====================================================================
      *   *** public ***
      *   Initializes the memory manager.
      *   This procedure has to be called by the application in case
      *   the web service stub has be generated for using dynamic arrays.
      * =====================================================================
     P %(var:portName+_initializeMemoryManager...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_initializeMemoryManager...;75;'...')
     D                 PI                         like(wsdl_uuid_t )
     D  i_uuid                             const  like(wsdl_uuid_t )
     D                                            options(*nopass: *omit)
      *
      *  Parameter positions
     D p_uuid          C                   1
      *
      *  Fields for optional parameters
     D uuid            S                          like(i_uuid      )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (%parms() >= p_uuid and %addr(i_uuid) <> *NULL);
            uuid = i_uuid;
         else;
            uuid = %(var:portName+_Port_getUuid;75;'...')();
         endif;

         // Start memory manager, do not use symbolic names
         // Note 1: It is strongly recommended not to use symbolic names
         //         due to high performance degradation.
         // Note 2: Set "use separate heaps" to cTRUE, if your
         //         request/response messages uses dynamic arrays
         //         and exceeds 16MB.
         MemoryManager_attachService(uuid       // web service uuid
                                     : cFalse   // do not use symbolic names for arrays
                                     : cFalse); // do not use separate heaps for arrays

         return uuid;

      /end-free
      *
     P %(var:portName+_initializeMemoryManager...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** public ***
      *   Frees all allocated memory blocks of all dynamic arrays.
      *   This procedure has to be called by the application in case
      *   the web service stub has be generated for using dynamic arrays.
      * =====================================================================
     P %(var:portName+_terminateMemoryManager...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_terminateMemoryManager...;75;'...')
     D                 PI
     D  i_uuid                             const  like(wsdl_uuid_t )
     D                                            options(*nopass: *omit)
      *
      *  Parameter positions
     D p_uuid          C                   1
      *
      *  Fields for optional parameters
     D uuid            S                          like(i_uuid      )
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (%parms() >= p_uuid and %addr(i_uuid) <> *NULL);
            uuid = i_uuid;
         else;
            uuid = %(var:portName+_Port_getUuid;75;'...')();
         endif;

         // Terminate MemoryManager
         MemoryManager_detachService(uuid);

         return;

      /end-free
      *
     P %(var:portName+_terminateMemoryManager...;75;'...')
     P                 E
      /ENDIF
      *
      * =====================================================================
      *   *** public ***
      *   Enables redirection of the HTTP response message to a
      *   stream file in the IFS.
      * =====================================================================
     P %(var:portName+_RedirectResponse_toStmf...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_RedirectResponse_toStmf...;75;'...')
     D                 PI
     D  i_stmf                             const  like(wsdl_pathLong_t )
     D  i_replace                      N   const  options(*nopass: *omit)
     D  i_ccsid                      10I 0 const  options(*nopass: *omit)
     D  i_auth                       10I 0 const  options(*nopass: *omit)
      *
      *  Parameter positions
     D p_replace       C                   2
     D p_ccsid         C                   3
     D p_auth          C                   4
      *
      *  Optional parameter fields
     D replace         S                   like(i_replace ) inz
     D ccsid           S                   like(i_ccsid   ) inz
     D auth            S                   like(i_auth    ) inz
      *
      *  Helper fields
     D options         S             10I 0 inz
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         %(var:portName+_RedirectResponse_terminate;75;'...')();

         if (%trim(i_stmf) = '');
            g_redirectResponse.isActive = cFalse;
            g_redirectResponse.ccsid    = 0;
            g_redirectResponse.auth     = 0;
            g_redirectResponse.options  = 0;
            g_redirectResponse.fd       = -1;
            g_redirectResponse.path     = '';
            return;
         endif;

         http_DebugLog_appendText(
         '** Response redirected to: ' + i_stmf);

         if (%parms() >= p_replace and %addr(i_replace) <> *NULL);
            replace = i_replace;
         else;
            replace = cFalse;
         endif;

         if (%parms() >= p_ccsid and %addr(i_ccsid) <> *NULL);
            ccsid = i_ccsid;
         else;
            ccsid = 1208;   // UTF-8
         endif;

         if (%parms() >= p_auth and %addr(i_auth) <> *NULL);
            auth = i_auth;
         else;
            auth = S_IRWXU + S_IRWXG + S_IRWXO;
         endif;

         options = O_CREAT + O_SHARE_RDONLY + O_WRONLY + O_CCSID;
         if (replace);
            options = options + O_TRUNC;
         else;
            options = options + O_EXCL + O_APPEND;
         endif;

         g_redirectResponse.isActive = cTrue;
         g_redirectResponse.ccsid    = ccsid;
         g_redirectResponse.auth     = auth;
         g_redirectResponse.options  = options;
         g_redirectResponse.fd       = -1;
         g_redirectResponse.path     = i_stmf;

         return;

      /end-free
      *
     P %(var:portName+_RedirectResponse_toStmf...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Returns cTrue if response redirection is active, otherwise cFalse.
      * =====================================================================
     P %(var:portName+_RedirectResponse_isActive...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_RedirectResponse_isActive...;75;'...')
     D                 PI              N
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_redirectResponse.isActive;

      /end-free
      *
     P %(var:portName+_RedirectResponse_isActive...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Terminates a response redirection and closes the
      *   file that receiced the response.
      * =====================================================================
     P %(var:portName+_RedirectResponse_write...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_RedirectResponse_write...;75;'...')
     D                 PI              N
     D  i_data                         *   value
     D  i_length                     10I 0 value
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         // Open output file
         if (g_redirectResponse.fd = -1);
            g_redirectResponse.fd = open(g_redirectResponse.path
                                        : g_redirectResponse.options
                                        : g_redirectResponse.auth
                                        : g_redirectResponse.ccsid);
            if (g_redirectResponse.fd = -1);
               http_DebugLog_appendText(
               '** '+ %char(%timestamp()) +': Failed to open: ' +
                                              g_redirectResponse.path);
               return cFalse;
            endif;
         endif;

         // Append data to output file
         if (write(g_redirectResponse.fd: i_data: i_length) <> i_length);
               http_DebugLog_appendText(
               '** '+ %char(%timestamp()) +': Failed to append ' +
                                              %char(i_length) + ' bytes to: ' +
                                              g_redirectResponse.path);
            return cFalse;
         endif;

         return cTrue;

      /end-free
      *
     P %(var:portName+_RedirectResponse_write...;75;'...')
     P                 E
      *
      * =====================================================================
      *   *** private, automatically called by WS_OPER() ***
      *   Terminates a response redirection and closes the
      *   file that receiced the response.
      * =====================================================================
     P %(var:portName+_RedirectResponse_terminate...;75;'...')
     P                 B                   export
      *
     D %(var:portName+_RedirectResponse_terminate...;75;'...')
     D                 PI
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         if (g_redirectResponse.fd <> -1);
            callp close(g_redirectResponse.fd);
            g_redirectResponse.fd = -1;
         endif;

         g_redirectResponse.path = '';
         g_redirectResponse.isActive = cFalse;

         return;

      /end-free
      *
     P %(var:portName+_RedirectResponse_terminate...;75;'...')
     P                 E
      *
      * =====================================================================
      *   Internal procedure to get the endpoint.
      * =====================================================================
     P getEndpoint...
     P                 B
      *
     D getEndpoint...
     D                 PI         32767A          varying
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         return g_url;

      /end-free
      *
     P getEndpoint...
     P                 E
      *
      * =====================================================================
      *   Internal procedure to set the endpoint.
      * =====================================================================
     P setEndpoint...
     P                 B
      *
     D setEndpoint...
     D                 PI
     D  i_url                     32767A   const varying  options(*varsize)
      * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      /free

         g_url = %subst(i_url: 1: %len(i_url));

      /end-free
      *
     P setEndpoint...
     P                 E
      *
-----------------------------------------------------------------------
This is the FTPAPI mailing list.  To unsubscribe, please go to:
http://www.scottklement.com/mailman/listinfo/ftpapi
-----------------------------------------------------------------------