Reputation: 787
How to use QDFRTVFD API in RPGLE program to fetch heading in a display file. Can some one provide me with RPGLE examples which uses this API to fetch heading from a display file.
Upvotes: 2
Views: 653
Reputation: 11473
The full documentation for this API can be found here. Unfortunately, it is a very complex API, and to fully describe it even to the level that you have asked for would take a massive wall of code, so I will give you a description of how to use the API, with some examples to retrieve the base information, and leave the rest to you as an exercise. I will be using **free
format, and only giving disjointed examples so none of this is tested.
First thing to do is define all the data structures that you will need as based data structures to describe the data, and a buffer to hold the data. This based data structure can be moved around in the buffer to overlay it on the data you want to work with.
This is the Base File Formats, it is the first block of information in the buffer of returned data. QDFFBASE is only used once, so you could conceivably just make it a regular data structure, and retrieve data into it, but for the purpose of example, I am defining it the same way that I would define every other data structure. The advantage of this is that you always will have a base pointer to the structure in a variable.
**free
...
// Buffer
dcl-s buf Char(32760);
// Base File Section
dcl-ds QDFFBASE Qualified Based(pQDFFBASE);
WDFFRETN Int(10);
WDFFSIZE Int(10);
WDFFINOF Int(5);
WDFFRCS Int(5);
WDFFDPAT Char(1);
WDFFFSCR Int(5);
WDFFSRSQ Int(5);
WDFFACCSID Uns(5);
end-ds;
dcl-s pQDFFBASE Pointer;
// Screen Size Table
dcl-ds QDFFSCRA Qualified Based(pQDFFSCRA);
WDFFSCIA Int(5);
*n Char(4);
end-ds;
dcl-s pQDFFSCRA Pointer;
// Sort Sequence Table
dcl-ds QDFFSSEQ Qualified Based(pQDFFSSEQ);
WDFFSST Char(256);
WDFFSSC Uns(5);
WDFFSSN Char(10);
WDFFSSL Char(10);
WDFFSSFL Char(2);
*n Char(26);
end-ds;
dcl-s pQDFFSSEQ Pointer;
To set pQDFFBASE, use this snippet:
pQDFFBASE = %addr(buf);
You could optionally initialize the basing pointer pQDFFBASE with the address of buf, but you can only do that with this one pointer. The rest are calculated as offsets and/or lengths from this pointer.
To set the location of the Screen Size Table use:
pQDFFSCRA = pQDFFBASE + %len(QDFFBASE);
That is the base pointer plus the length of the QDFFBASE structure since QDFFSRCA follows immediately after that structure.
To set the location of the Sort Sequence Table use:
pQDFFSSEQ = pQDFFBASE + qdffbase.wdffsrsq
That is the base pointer plus the offset (displacement) to the sort sequence table.
It might be tempting to just calculate these lengths and displacements in your head, and hard code them into the program. Don't do that! If IBM changes the structure, your program could suddenly stop working properly. This takes a few forms: First it might crash and you now have to determine why you suddenly are getting data incompatibility errors or pointer errors in a program that has been working fine. Second, and more insidiously, it may just keep working because the API change did not cause any data incompatibility errors in the fields you were using, but instead it is either doing the wrong thing, or providing the wrong output.
Always use the lengths and offsets provided in the return data with pointers to find the data in the buffer. See the offset to the file header section in QDFFBASE? Use that.
To use the data in the buffer you just use qdffbase.wdffsize
for instance after you have set the basing pointer for the structure. Once that basing pointer is set the elements of the structure are all available. Before the pointer is set, any attempt to use the structure will result in a pointer error.
Some structures like the screen size table have multiple entries in the buffer. To loop through them you can use a for loop like this:
pQDFFSCRA = pQDFFBASE + %len(qdffbase);
for ix = 1 to qdffbase.wdffscr;
// Do something with qdffscra.wdffscia
pQDFFSCRA += %len(qdffscra);
endfor;
Note that I am using the length of the structure which is less than optimal here, but IBM didn't provide a length value for this structure in the data. If they had, I would use that. It is still better than using a hard coded constant, because you only have to update the data structure to take advantage of changes made by IBM.
To call the program, you only need a prototype:
dcl-pr QDFRTVFD ExtPgm('QDFRTVFD');
buffer Char(327600) options(*varsize);
bufferlen Int(10) const;
format Char(8) const;
qualname Char(20) const;
ec Like(ec_t) options(*varsize);
This is called by using:
QDFRTVFD(buf: %len(buf): 'DSPF0100': file: ec);
This is long enough. I will leave to you to decide how to define the qualified file name and error code parameters.
You will also have to put some effort in to define the structures you will be using, and to design the looping to get at them.
Upvotes: 4