Flat File Parser Validator Example
This example shows how to validate data before passing it to the line processor.
The data is read from a stream file on the IFS.
The same format as the one from the grouping example will be taken for this example.
1000001 1102010-12-20 2101234567890123 220450 999
Each line type is identified with an identifier (columns 1 - 3). A block of data begins and ends with a "special" line. This line can be fix or contain variable data.
In this case a complete block of data starts with a line with an identifier "100" and ends with a line with an identifier "999". So the starting line format has an image "100####" and the ending line format "999".
|Store ID||100||4 digits numeric|
|Date||110||date ISO format yyyy-MM-dd|
|Item||210||13 alphanumeric (EAN)|
|Quantity||220||4 digits numeric|
|End||999||no extra data|
Each line format can be separated into fields. Fields lie always together. There are no spaces between fields. A validator is tied to at least one field for validation. The same validator can be declared to validate multiple fields.
The validator returns *on if the field is valid and *off if it ain't valid. If the validator throws an escape message the line will be flagged as invalid by the parser.
One field can have up to 99 validators.
Implementing a Validator
A validator is a module which conforms to the following requirements:
A validator must implement the following interface which means that on the create procedure it must return a pointer which points to the following data structure:
D ffp_validator... D DS qualified template align D id 50A D userdata * D logger * * D proc_validate... D * procptr D proc_finalize... D * procptr D proc_setLogger... D * procptr
The data structure can be found in the file _validator_t.rpgle_. All procedure pointers must be set or the implementation will be marked as invalid.
A validator implementation must at least consist of the following procedures:
D ffp_validator_finalize... D PR D validator * * D ffp_validator_validate... D PR N D validator * const D data 65535A const varying * D ffp_validator_setLogger... D PR D validator * const D logger * const
The procedure names doesn't matter as the procedure pointers to these procedures are stored in the interface data structure (see Interface).
On the finalize procedure all allocated resources must be freed (f. e. allocated memory freed and opened files closed).
The logger can be used to log messages. But it may be that no logger has been set. So don't expect there to be one. You don't have to take care of the fact that the logger may be *null. The logger service program accepts *null for a logger and drops the passed message.
The framework is shipped with a range validator and a date validator.
The code will be much the same as in the grouping example. A validator will be added to the line format, not to the parser. The line will have to be partitioned into fields. Then a validator can be added to the line format for a field.
Get line format
lineFormat = ffp_getLineFormat(parser : 'quantity');
Partition line into two fields (see data format for quantity , 220)
ffp_addLineFormatField(lineFormat : 3); ffp_addLineFormatField(lineFormat : 7);
checkRange = '1 99999' + x'00'; validator = ffp_validator_range_create(%addr(checkRange));
Add validator for the quantity field (2)
ffp_addValidator(lineFormat : 2 : validator);