Sent from a stupid smartphone, excuse my brevity.
---- Wilson, Jonathan wrote ----
I am currently playing with basing pointer usage to return multiple
formats of data from a service program.
The idea is that the called service program will handle all the data
access nicely wrapped up in procedures defined around the functional
description and not the data accessed.
For example, Status = GetBibliographicDataFirst(Data:'*KEYSONLY');
The "Data" passed both ways is a structure containing keys and a
variable length area to allow for data to be returned.
The second parameter denotes the data format to be returned, in this
simplified example it could be *NONE, *KEYSONLY, FMT001, or FMT002.
Now I have this all working using basing pointers in the function,
something along the lines of...
DataLayout00 (based p_inputData)
Keys.ISBN<
http://Keys.ISBN>
Keys.SupplierNo<
http://Keys.SupplierNo>
DataLayout01 (based p_inputData)
Keys.ISBN<
http://Keys.ISBN>
Keys.SupplierNo<
http://Keys.SupplierNo>
MTBIBLDS
DataLayout02 (based p_inputData)
Keys.ISBN<
http://Keys.ISBN>
Keys.SupplerNo<
http://Keys.SupplerNo>
MTBIBLDS
TitleDS
AuthorDS
// do file stuff with data passed in, setting IsFound to record status
select
where DataType = '*NONE' or p_inputData = *null
return IsFound
where DataType = '*KEYSONLY'
// Set keys of DS to keys of file.
return IsFound
where DataType = 'FMT001'
// Set keys of DS to keys of file.
// Set MTBIBLDS to RecordDS
return IsFound
where DataType = 'FMT002'
// Set keys of DS to keys of file
// Set MTBIBLDS to RecordDS
// Set TitleDS from title file
// Set AuthorDS from author file
return IsFound
endsl
So far so good, it all works as expected...
But, the caller is the one setting up the "Data" to be returned and as
such I have no control over if this field is long enough, even if I were
to have extra parameters with say the length of the "Data" there is
nothing stopping the caller lying and, as far as I know, there is no
programmable way of finding out the definition (or at least its length)
of the field in the caller that was actually passed.
Now to prevent the called service program from corrupting memory, I was
wondering if the use of the %realloc would be sensible way of guarding
against overwriting memory, in the called procedure I always perform a
realloc to set up the data to the desired length prior to setting up the
data. Something along the lines of...
where format type is..
p_inputData = %realloc(p_inputData:%size(DataLayout02))
// do stuff
// return status.
endsl
Now if the callers field was to small, it can't see the extra data
returned so no problems - actually its a different problem but one I can
live with as its not a silent corruption or an escape/MCH style function
check if program code is stomped on, or the inbuilt bounds checks
catches it.
Now I understand that the above, assuming it works, adds an overhead as
it has to allocate memory and copy the existing data to it and that its
possible that the realloc might fail.
But I am curious as to how others have dealt with this problem or done
something similar, or if prevented by just not doing multi-format data
passing.
--
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<mailto:RPG400-L@xxxxxxxxxxxx>
To subscribe, unsubscribe, or change list options,
visit:
http://lists.midrange.com/mailman/listinfo/rpg400-l
or email: RPG400-L-request@xxxxxxxxxxxx<mailto:RPG400-L-request@xxxxxxxxxxxx>
Before posting, please take a moment to review the archives
at
http://archive.midrange.com/rpg400-l.
As an Amazon Associate we earn from qualifying purchases.