On 2017-11-15 11:46 AM, Kurt Anderson wrote:
I've added in the allocated data structure logic per your article (not yet tested, but it compiled so that's a start). I'm now trying to build a giant string and I'm having issues. The DS stuff worked b/c field sizes aren't changing, I just moved from having an explicit array to using a pointer instead. But for the single field, I have to give it a size, and that size is limited to 16773100. If I make it a smaller value, reallocating doesn't seem to allow it to have a value larger than the initial definition. I figure my approach is wrong here so any help would be great.

In this example, (just for ease of testing) I made the initial size 10 characters, but I want to add a value that is longer than 10 characters.

dcl-s formattedElement varchar( 100 );
dcl-s gp_SoapMsg pointer;
dcl-s gSoapMessage varchar( 10 ) Based( gp_SoapMsg );

gp_SoapMsg = %Alloc( SOAP_INCREMENT );
formattedElement = 'This is my new test element value';
gSoapMessage += formattedElement;

The contents of gSoapMessage is: 'This is my'

To build a string longer than RPG allows, you won't be able to use +=. And you won't be able to use VARCHAR.

The idea is to have a based fixed length character field, where you set the basing pointer to where you want to add more data, gradually walking your basing pointer along the allocated storage. The based field has to be fixed length character, because if it was varying length, RPG would be adding the varying-length prefix all through your string.

The based field should be, as Jon said, as big as the largest value you want to append.

This is untested, but I hope you get the idea. I didn't add dcl-s for all the variables I made up. The code to append the new value got pretty complicated when I added code to ensure the allocated storage was big enough, so I made it a procedure.

DCL-C MAX_ELEM_LEN 100
dcl-s gp_SoapMsg pointer;
dcl-s formattedElement varchar(MAX_ELEM_LEN); // ok to be varchar
dcl-s gp_soapMsg_cur pointer;
dcl-s gSoapMsg_view char(MAX_ELEM_LEN)
based(gp_soapMsg); // can't be varchar

gp_SoapMsg = %Alloc (SOAP_INCREMENT);
gSoapMsgAllocSize = SOAP_INCREMENT;
gSoapMsgLen = 0;
gp_soapMsg_cur = gp_SoapMsg; // start at the beginning

// A new element to add
formattedElement = 'This is my new test element value';
appendElement (formattedElement);
appendElement ('Another value');
...


dcl-proc appendElement;
dcl-pi *n;
value varchar(MAX_ELEM_LEN) const;
end-pi;
// Make sure there's room
gSoapMsgNewLen = gSoapMsgLen + %len(value);
if gSoapMsgNewLen > gSoapMsgAllocSize;
// Allocate more storage
gSoapMsgAllocSize += SOAP_INCREMENT;
gp_SoapMsg = %Realloc(gp_SoapMsg : gSoapMsgAllocSize);
// Reposition any pointers within gp_SoapMsg
gp_soapMsg_cur = gp_SoapMsg + gSoapMsgLen;
endif;
// Append the new data
%subst(gSoapMsg_view : 1 : %len(value) = value;

// Update the cur pointer and length
gp_soapMsg_cur += %len(value);
gSoapMsgLen = gSoapMsgNewLen;
end-proc;


This thread ...

Follow-Ups:
Replies:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2019 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].