The DATA-GEN opcode generates a structured document (JSON, CSV, or any format) from an
RPG variable or data structure. It is the inverse of DATA-INTO: where DATA-INTO parses a
document into a data structure, DATA-GEN serializes a data structure into a document
string. Like DATA-INTO, DATA-GEN has no built-in generator - you name one with
%GEN, and it receives events (start, scalar value, end, etc.) and emits output text via
the QrnDg* callbacks.
data-gen source %data(receiver : options) %gen(generator : genOptions);
source- the data structure or variable to generate from.%data(receiver : options)- the variable that receives the generated output.%gen(generator : genOptions)- the generator procedure and any generator-specific options. In Triton RPG the generator is a bound procedure in the same module.
The generator interface
A generator is a procedure that takes one parameter - the generator-info data structure
(QrnDgParm_T) - and is called once per event. The generator emits output text by calling
the QrnDg* callback procedures. The compiler recognizes these callbacks by name and binds them
to its runtime:
dcl-ds QrnDgParm_T qualified template;
env pointer; // reserved (the callback environment)
handle pointer; // pass as the first argument to every callback
event int(10); // event code (3=Start, 5=StartStruct, 11=ScalarValue, etc.)
name char(100); // name of the current element
valueLenChars int(10); // length of the value in characters
value pointer; // pointer to the scalar value text
end-ds;
dcl-pr QrnDgAddText;
handle pointer value; text pointer value; len int(10) value;
end-pr;
dcl-pr QrnDgAddTextString;
handle pointer value; text pointer value options(*string);
end-pr;
dcl-pr QrnDgAddTextNewLine;
handle pointer value;
end-pr;
dcl-pr QrnDgReportError;
handle pointer value; errorCode int(10) value;
end-pr;
Event codes
| Constant | Value | Description |
|---|---|---|
QrnDgEvent_03_Start |
3 | Generation begins |
QrnDgEvent_04_End |
4 | Generation ends |
QrnDgEvent_05_StartStruct |
5 | Start of a data structure |
QrnDgEvent_06_EndStruct |
6 | End of a data structure |
QrnDgEvent_11_ScalarValue |
11 | Scalar subfield value |
For ScalarValue events, parm.name holds the subfield name and parm.value / parm.valueLenChars
hold the value pointer and length.
Example
dcl-ds info qualified;
company char(10) inz('Acme Inc');
city char(10) inz('Chicago');
end-ds;
dcl-s result varchar(200);
data-gen info %data(result) %gen(kvGen);
// result = 'company=Acme Inc ;city=Chicago ;'
dcl-proc kvGen;
dcl-pi *n;
parm likeds(QrnDgParm_T);
end-pi;
dcl-s nm char(100);
if parm.event = QrnDgEvent_11_ScalarValue;
nm = parm.name;
QrnDgAddTextString(parm.handle : %trimr(nm));
QrnDgAddTextString(parm.handle : '=');
QrnDgAddText(parm.handle : parm.value : parm.valueLenChars);
QrnDgAddTextString(parm.handle : ';');
endif;
end-proc;
The generator is called once per event. For each scalar subfield, parm.event is set to 11
(ScalarValue), parm.name holds the subfield name (preserving the original case from the
RPG source), and parm.value / parm.valueLenChars hold a pointer to the text value and
its character length.
Supported: a bound-procedure generator serializing a flat qualified data structure (scalar subfields). Nested data structures, arrays, and
doc=fileoutput are not supported.