H NOMAIN D/COPY QRPGLESRC,ALLOC_P *===================================================================== * copy_mem() - Copy a section of allocated memory and return the * pointer to the new memory. *===================================================================== P copy_mem B Export D PI * D From@ * Const D FromLen 10I 0 Const *--------------------------------------------------------------------- D To@ S * Inz *--------------------------------------------------------------------- * * Allocate a section of dynamic memory * C Alloc(e) FromLen To@ * C If %error C Return *Null C Endif * * Use built-in C function memcpy() to copy memory * C Return memcpy( To@ : From@ : FromLen ) * C *PSSR Begsr C Return *Null C Endsr * P E *===================================================================== * copy_mem_to_var() - Copy a section of memory to a variable. * * Parameters: From@ - Pointer to data to be copied * FromLen - Length of data to be copied * To@ - Pointer to variable into which to copy the data * ToSize - Length of to-variable (if not passed, procedure * will copy FromLen amount of data) * *===================================================================== P copy_mem_to_var... P B Export D PI 10I 0 D From@ * Const D P_FromLen 10I 0 Const D To@ * Const D ToSize 10I 0 Const Options(*Nopass) *--------------------------------------------------------------------- D FromLen S 10I 0 Inz *--------------------------------------------------------------------- * C Eval FromLen = P_FromLen * * Quit immediately if invalid data passed * C If From@ = *Null or C To@ = *Null or C FromLen = 0 C Exsr *PSSR C Endif * * If the ToSize was passed, initialize the to-variable to blanks * C If %parms > 3 and C ToSize > 0 C If FromLen > ToSize C Eval FromLen = ToSize C Endif C Callp(e) memset( To@ : 64 : ToSize ) C If %error C Exsr *PSSR C Endif C Endif * * Copy the from-data to the to-variable * C Callp(e) memmove( To@ : From@ : FromLen ) C If %error C Exsr *PSSR C Endif * C Return 0 * C *PSSR Begsr C Return -1 C Endsr * P E *===================================================================== * scan_mem() - Scan memory. * * Parameters: Mem@ - Pointer to allocated memory to be scanned * MemLen - Length of allocated memory to be scanned * Scan - String to be scanned for * ScanLen - Length of string to be scanned for * StartPos - Position to start scan from (if not passed, * procedure starts scanning from start) * *===================================================================== P scan_mem B Export D PI 10I 0 D Mem@ * Value D MemLen 10I 0 Value D Scan 65535A Value D ScanLen 10I 0 Value D P_StartPos 10I 0 Value Options(*Nopass) *--------------------------------------------------------------------- D Scan@ S * D Num S 3U 0 Based(Scan@) D StartPos S 10I 0 Inz(0) D Found@ S * D Search@ S * *--------------------------------------------------------------------- * C If Scan = *Blanks C Return 0 C Endif C Eval Scan@ = %addr( Scan ) * C If ScanLen = 0 C Eval ScanLen = %len( %trimr( Scan ) ) C Endif * C If %parms > 3 and C P_StartPos > 1 C Eval StartPos = P_StartPos - 1 C Endif * C Eval Search@ = Mem@ C Dou StartPos <= ( Found@ - Mem@ ) and C memcmp( Found@ : Scan@ : ScanLen ) = 0 C Eval Found@ = memchr( Search@ : C Num : C MemLen - C ( Search@ - Mem@ ) ) C If Found@ = *Null C Return 0 C Endif C Eval Search@ = Found@ + 1 C Enddo * C Return ( Found@ - Mem@ ) + 1 * C *PSSR Begsr C Return -1 C Endsr * P E *===================================================================== * replace_mem() - Replace memory * * Parameters: Mem@ - Pointer to allocated memory * MemLen - Length of allocated memory * FromPos - Position at which to start replacement * FromLen - Length of memory to replace * With - Data to insert * WithLen - Length of data to insert * DataLen - Length of non-blank data in allocated memory * *===================================================================== P replace_mem B Export D PI 10I 0 D Mem@ * Value D MemLen 10I 0 Value D FromPos 10I 0 Value D FromLen 10I 0 Value D With 65535A Value D WithLen 10I 0 Value D P_DataLen 10I 0 Value Options(*Nopass) *--------------------------------------------------------------------- D With@ S * D DataLen S 10I 0 Inz(0) D WrkLen S 10I 0 Inz(0) D To@ S * D From@ S * *--------------------------------------------------------------------- * * Replacement data won't fit in available space or data is invalid * C If MemLen < 0 or C FromPos < 0 or C FromLen < 0 or C FromPos - 1 + WithLen > MemLen C Exsr *PSSR C Endif * C Eval With@ = %addr( With ) * * Determine data (non-blank) length of allocated memory * C If %parms > 5 and C P_DataLen > 0 and C P_DataLen <= MemLen C Eval DataLen = P_DataLen C Else C Eval DataLen = rtv_data_len( Mem@ : MemLen ) C Endif * * If FromPos is specified, then we need to 'move' existing data... * C If FromPos > 0 * * ...so determine the amount of trailing characters to copy (truncate * if necessary) and then copy them after the From string... * C Eval To@ = Mem@ + FromPos + WithLen - 1 C Eval From@ = Mem@ + FromPos + FromLen - 1 C Eval WrkLen = DataLen - ( From@ - Mem@ ) C If ( To@ - Mem@ ) + WrkLen > MemLen C Eval WrkLen = MemLen - ( To@ - Mem@ ) C Endif C Callp(e) memmove( To@ : From@ : WrkLen ) C If %error C Exsr *PSSR C Endif * * ...and if the With string is shorter than the From string, then we * must also overwrite the final data with blanks (blank char is 64)... * C If WithLen < FromLen C Eval To@ = Mem@ + DataLen + WithLen - FromLen C Callp(e) memset( To@ : 64 : FromLen - WithLen ) C If %error C Exsr *PSSR C Endif C Endif * C Else * * ...otherwise (if FromPos is zero) simply add the data to the end * and set FromLen to zero so return value is calculated correctly. * C If DataLen + WithLen > MemLen C Exsr *PSSR C Else C Eval FromPos = DataLen + 1 C Eval FromLen = 0 C Endif * C Endif * * Copy the With string into memory at the appropriate spot * C Eval To@ = Mem@ + FromPos - 1 C Callp(e) memmove( To@ : With@ : WithLen ) C If %error C Exsr *PSSR C Endif * * Return the newly calculated non-blank data length. * C Return DataLen + WithLen - FromLen * C *PSSR Begsr C Return -1 C Endsr * P E *===================================================================== * append_mem() - Append data to memory * * Parameters: Mem@ - Pointer to allocated memory * MemLen - Length of allocated memory * Data - Data to append to existing non-blank data * DataLen - Length of non-blank data in allocated memory (if * not passed, the current length of the non-blank * data will be calculated using rtv_data_len(). * * Note: Mem@ and DataLen are saved in each call as Prv@ and PrvLen to * avoid them needing to be calculated each time. * *===================================================================== P append_mem B Export D PI 10I 0 D Mem@ * Value D MemLen 10I 0 Value D Data 65535A Value D P_DataLen 10I 0 Value Options(*Nopass) *--------------------------------------------------------------------- D DataLen S 10I 0 Inz D Prv@ S * Inz Static D PrvLen S 10I 0 Inz Static *--------------------------------------------------------------------- * C If %parms > 3 and C P_DataLen > 0 C Eval DataLen = P_DataLen C Else C Eval DataLen = %len( %trimr( Data ) ) C Endif * * If MemLen is passed as zero, reset Prv@ and PrvLen and return * C If MemLen = 0 C Eval Prv@ = *Null C Eval PrvLen = 0 C Return 0 C Endif * * Retrieve and save the pointer and non-blank length of the memory * C If Prv@ = *Null or C Prv@ <> Mem@ or C PrvLen <= 0 C Eval Prv@ = Mem@ C Eval PrvLen = rtv_data_len( Mem@ : MemLen ) C If PrvLen = -1 C Exsr *PSSR C Endif C Endif * * Determine if the data will fit in the allocated length * C If PrvLen + DataLen > MemLen C Exsr *PSSR C Endif * * Append the data to the existing non-blank data in memory * C Callp(e) memmove( Prv@ + PrvLen : C %addr( Data ) : C DataLen ) C If %error C Exsr *PSSR C Endif C Eval PrvLen = PrvLen + DataLen * C Return 0 * C *PSSR Begsr C Return -1 C Endsr * P E *===================================================================== * rtv_data_len() - Retrieve the non-blank length of allocated memory * * Parameters: Mem@ - Pointer to allocated memory * MemLen - Length of allocated memory * *===================================================================== P rtv_data_len B Export D PI 10I 0 D Mem@ * Value D MemLen 10I 0 Value *--------------------------------------------------------------------- D Block@ S * D Block S 65535A Based(Block@) D BlockLen C 65535 D DataLen S 10I 0 Inz(0) *--------------------------------------------------------------------- * * Determine data (non-blank) length * C If MemLen <= BlockLen C Eval Block@ = Mem@ C Return %len( %trimr( %subst(Block:1:MemLen) ) ) C Else C Eval Block@ = Mem@ + MemLen - BlockLen C Eval DataLen = MemLen C Dou DataLen <= 0 C Eval DataLen = DataLen - BlockLen C If Block <> *Blanks C Return DataLen + %len( %trimr( Block ) ) C Endif C If DataLen <= BlockLen C Eval Block@ = Mem@ C Return %len( %trimr( %subst(Block:1:DataLen) ) ) C Endif C Eval Block@ = Block@ - BlockLen C Enddo * C Endif * C *PSSR Begsr C Return -1 C Endsr * P E