Re: 15Meg PDF in XML files



Hi Joel,

> Sorry I got ahead of myself after trying to research the program flow..

Absolutely no problem with that.

> 1 what does this do and if my XML is already in unicode and I want to write
> to the IFS in JOBCCSID 37 do I really need this procedure?

XMLString_toJOBCCSID takes a pointer to a Unicode string and returns a converted "traditional" RPG string. So indeed that procedures might be the key.

I am pretty sure that you need that procedure because of the following reason:

The Unix write() function can only convert from job CCSID to the IFS file CCSID (if the file already exists). If the file does not yet exist at open time, the write procedure expects the bytes to write in the CCSID of the IFS file. So actually no conversion takes place then. Since there is no Unicode job CCSID (isn´t it?) write() can not convert to CCSID 37.

That is why I agree with you that most likely going the way you described is fine:

Create a new XMLdocument_getNodeValueAsPtr function which:

1) Determines the length of the XML string.
2) Allocate/reallocate memory for the transcoded string.
3) Converts the XML string to job CCSID.

I would not allocate memory inside XMLdocument_getNodeValueAsPtr because then the programmer might not remember to deallocate the memory. What I would prefer is to pass an empty pointer to XMLdocument_getNodeValueAsPtr and then allocate (if NULL) or reallocate (if not NULL) memory. So the procedure interface might look like this:

int size = XMLdocument_getNodeValueAsPtr(* pBuffer)

Or like this:

int size = XMLdocument_getNodeValueAsPtr(* pBuffer, [int CCSID)

size = Length of the RPG string buffer.
pBuffer = Pointer to the RPG string buffer.
CCSID = Optional. Target CCSID. Default: job CCSID.

Sample:

D pBuffer S * inz(*NULL)
D size S 10I 0 inz

size = XMLdocument_getNodeValueAsPtr(pBuffer);
if size > 0;
size = write(hFile: pBuffer: size);
endif;
if pBuffer <> *NULL;
dealloc(N) pBuffer;
endif;

Do you think that this is a way to go?

> 3 All your fields seem to eventually be based on pDummy where is this field
> ever created or declared. Is this a reserved field within QXML4PR500
> service program or the C function library the parser tool is based on??

The fields that are based on pointer "pDummy" are used as reference fields, also known as type definitions.

Using C you can define type definitions like this:

typedef float SFLOAT;

Since unfortunately there is no equivalent for that in RPG I had the idea of creating reference fields based on pointer "pDummy":

D long_t S 10I 0 based(pDummy)

Because the fields are based on a pointer that never gets memory, it is impossible to assing an value to that fields. Also these fields do not waste memory for nothing.

> Thanks for your time and great program.

You are welcome. Your idea will greatly improve the XMLRPG service program. I will gladly adopt your code if you are willing to share it.

Regards,

Thomas Raddatz.



jrock64 schrieb:
Sorry I got ahead of myself after trying to research the program flow..

I think I may have it figured out.

Yes I am using Scott Klements procedures to handle the base64 encode/decode issues.

My program will navigate to the correct node and then
1. call XMLdocument_getFirstChildNode which accepts and returns a pointer (no problem here)

2. then call XMLdocument_getNodeValue which accepts a pointer but returns a field *like(xmlnodevalue_t) 8192A Varying
digging deeper xmldocument_getnodevalue calls two functions

2.1 QXMLDOMNode_getNodeValue accepts and returns a pointer (no problem here)
2.2 XMLString_toJOBCCSID accepts a pointer but returns a field *like(xmlnodevalue_t) 8192A Varying
and
2.2.1 QXMLTranscode accepts and returns a pointer (no real documentation other than the prototype)

so the problem appears to be in the XMLString_toJOBCCSID procedure.

1 what does this do and if my XML is already in unicode and I want to write to the IFS in JOBCCSID 37 do I really need this procedure?

2. If #1 is yes I will make the following modifications.

2.1 A new version of XMLString_toJOBCCSID will use XMLstring_length to determine length and use %alloc to create a new pointer of adequate length. the pointer will be passed to QXMLTranscode and be ruturned on completion. and leave out the ""rpgString = %trimR(%str(%addr(rpgStringFixLen))); "" line.

2.2 a new version of XMLdocument_getNodeValue will return the new pointer.

2.3 My parser program will further manipulate the pointer contents or dump the entire contents directly to the IFS with "writeIfsFile"
then dealloc the new pointer for cleanup.

I think I just answered my own question. Will the above plan work???? should be easy to modify.


a general questions that I cannot find in your programs or IBM documentation.

3 All your fields seem to eventually be based on pDummy where is this field ever created or declared. Is this a reserved field within QXML4PR500 service program or the C function library the parser tool is based on??


Thanks for your time and great program.

I compare your work to CGIDEV someone who took an IBM tool or program that was incomprehensible/unusable and repackaged it into a very easy to use and productive application.

Joel Rose

Solutions



"Thomas Raddatz" <thomas.DOTraddatz@xxxxxxxxxxxxxxxx> wrote in message news:427E7D1E.9020208@xxxxxxxxxxxxxxxxxxx

Joel,

Honestly I have no idea of what exactly to do with base64 encoded data. I assume that it has to be decoded somehow prior to write it to an IFS file.

But basically since QXMLDOMNODE_getNodeValue returns a pointer to a Unicode string I assume that there is no limit of the string size. After having called QXMLDOMNODE_getNodeValue it should be possible to use the Unix write() function to write that buffer to an IFS file.

I never tried that yet, but I strongly believe that it should work.

Probably Scott Klement's "Base64 Encode/Decode" service program might be helpful:

http://www.scottklement.com/base64/

Please keep me up to date. Most likely it is a good idea to enhance the XMLRPG service program based on your experiences.

Thomas Raddatz.


jrock64 schrieb:

I am using the XML parsing service programs by Thomas Raddatz to "unmarshall" an XML.

No problem retrieving the various Elements and Attributes due to Tom's excellent programs.

The base XML is about 3K in size any nodes can easily be materialized to a 64K variable before being reassigned to a final variable.

However one element contains a base64 encoded PDF that can be over 15meg but on average 1 to 3 meg in size.

Can QXMLDOMNODE_getNodeValue materialize a value larger than 64K perhaps to a pointer or dirrectly to the IFS.

Any help will be most appreciated.

Plan B will be to read the raw XML file from the IFS scanning tor the desired ELEMENT tags and diverting the content to a new IFS file.

Joel Rose

Solutions





.



Relevant Pages

  • Re: 15Meg PDF in XML files
    ... call XMLdocument_getFirstChildNode which accepts and returns a pointer ... to the IFS in JOBCCSID 37 do I really need this procedure? ... Unix writefunction to write that buffer to an IFS file. ... "unmarshall" an XML. ...
    (comp.sys.ibm.as400.misc)
  • Re: "Mastering C Pointers"....
    ... A pointer is a kind of variable that can "point to" some object. ... has a type (pointer to int), and a value of some kind. ... You may know that you can access these integers by using array notation ... The function will take one argument, a string, and will return the length ...
    (comp.lang.c)
  • Re: pesky Pointers !!
    ... > and the function takes it as a reference instead of a copy. ... function may access the string passed directly, ... > *px dereferences the pointer to get the value ... If pTest is a pointer-to-string, *pTest is the string it points to ...
    (alt.comp.lang.learn.c-cpp)
  • Re: strtok ( ) help
    ... > splitCommandssomehow modifying the pointer, but I HAVE to call that ... Here's an idea of how to use the strtok() function. ... don't mind trashing the contents of a string s, ... will give you a loop that extracts the tokens one at a time from s. ...
    (comp.lang.c)
  • Re: new IL: C (sort of...).
    ... C doesn't need a string type... ... variant of PL/1 which was very Pascal-ish. ... - C does implement an array declaration. ... effectively converted into a pointer that can be used with the offset ...
    (comp.lang.misc)