I was actually worried varchar wouldn't work, but figured I'd find out when I got to testing.
I appreciate you providing an example, I'm hoping to get back on this tomorrow, but it may not be until next week (client in the office will be demanding my time).
Thanks for the feedback,
System Development Manager, Service Delivery Platform
From: RPG400-L [mailto:rpg400-l-bounces@xxxxxxxxxxxx] On Behalf Of Barbara Morris
Sent: Wednesday, November 15, 2017 4:00 PM
Subject: Re: RPG & Teraspace Storage Model
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'); ...
value varchar(MAX_ELEM_LEN) const;
// 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;
// Append the new data
%subst(gSoapMsg_view : 1 : %len(value) = value;
// Update the cur pointer and length
gp_soapMsg_cur += %len(value);
gSoapMsgLen = gSoapMsgNewLen;
This is the RPG programming on the IBM i (AS/400 and iSeries) (RPG400-L) mailing list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options,
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at https://archive.midrange.com/rpg400-l
Please contact support@xxxxxxxxxxxx for any subscription related questions.
Help support midrange.com by shopping at amazon.com with our affiliate link: http://amzn.to/2dEadiD