(recode.info)Task level
Task level functions
====================
The task level functions are used internally by the request level
functions, they allow more explicit control over files and memory
buffers holding input and output to recoding processes. The interface
specification of task level functions is still subject to change a bit.
To get started with task level functions, here is a full example of a
program which sole job is to filter `ibmpc' code on its standard input
into `latin1' code on its standard output. That is, this program has
the same goal as the one from the previous section, but does its things
a bit differently.
#include <stdio.h>
#include <stdbool.h>
#include <recodext.h>
const char *program_name;
int
main (int argc, char *const *argv)
{
program_name = argv[0];
RECODE_OUTER outer = recode_new_outer (false);
RECODE_REQUEST request = recode_new_request (outer);
RECODE_TASK task;
bool success;
recode_scan_request (request, "ibmpc..latin1");
task = recode_new_task (request);
task->input.file = "";
task->output.file = "";
success = recode_perform_task (task);
recode_delete_task (task);
recode_delete_request (request);
recode_delete_outer (outer);
exit (success ? 0 : 1);
}
The header file `<recode.h>' declares a `RECODE_TASK' structure,
which the programmer should use for allocating a variable in his
program. This `task' variable is given as a first argument to all task
level functions. The programmer ought to change and possibly consult a
few fields in this structure, using special functions.
* Initialisation functions
RECODE_TASK recode_new_task (REQUEST);
bool recode_delete_task (TASK);
No TASK variable may be used in other task level functions of the
recoding library without having first been initialised with
`recode_new_task'. There may be many such TASK variables, in
which case, they are independent of one another and they all need
to be initialised separately. To avoid memory leaks, a TASK
variable should not be initialised a second time without calling
`recode_delete_task' to "un-initialise" it. This function also
accepts a REQUEST argument and associates the request to the task.
In fact, a task is essentially a set of recoding transformations
with the specification for its current input and its current
output.
The REQUEST variable may be scanned before or after the call to
`recode_new_task', it does not matter so far. Immediately after
initialisation, before further changes, the TASK variable
associates REQUEST empty in-memory buffers for both input and
output. The output buffer will later get allocated automatically
on the fly, as needed, by various task processors.
Even if a call to `recode_delete_task' is not strictly mandatory
before ending the program, it is cleaner to always include it.
Moreover, in some future version of the recoding library, it might
become required.
* Fields of `struct task_request'
Here are the fields of a `struct task_request' which may be
meaningfully changed, once a TASK has been initialised by
`recode_new_task'. In fact, fields are expected to change. Once
again, to access the fields, you need to include `recodext.h'
_instead_ of `recode.h', in which case there also is a greater
chance that you need to recompile your programs if a new version
of the recoding library gets installed.
`request'
The field `request' points to the current recoding request,
but may be changed as needed between recoding calls, for
example when there is a need to achieve the construction of a
resulting text made up of many pieces, each being recoded
differently.
`input.name'
`input.file'
If `input.name' is not `NULL' at start of a recoding, this is
a request that a file by that name be first opened for
reading and later automatically closed once the whole file
has been read. If the file name is not `NULL' but an empty
string, it means that standard input is to be used. The
opened file pointer is then held into `input.file'.
If `input.name' is `NULL' and `input.file' is not, than
`input.file' should point to a file already opened for read,
which is meant to be recoded.
`input.buffer'
`input.cursor'
`input.limit'
When both `input.name' and `input.file' are `NULL', three
pointers describe an in-memory buffer containing the text to
be recoded. The buffer extends from `input.buffer' to
`input.limit', yet the text to be recoded only extends from
`input.cursor' to `input.limit'. In most situations,
`input.cursor' starts with the value that `input.buffer' has.
(Its value will internally advance as the recoding goes,
until it reaches the value of `input.limit'.)
`output.name'
`output.file'
If `output.name' is not `NULL' at start of a recoding, this
is a request that a file by that name be opened for write and
later automatically closed after the recoding is done. If
the file name is not `NULL' but an empty string, it means
that standard output is to be used. The opened file pointer
is then held into `output.file'. If several passes with
intermediate files are needed to produce the recoding, the
`output.name' file is opened only for the final pass.
If `output.name' is `NULL' and `output.file' is not, then
`output.file' should point to a file already opened for
write, which will receive the result of the recoding.
`output.buffer'
`output.cursor'
`output.limit'
When both `output.name' and `output.file' are `NULL', three
pointers describe an in-memory buffer meant to receive the
text, once it is recoded. The buffer is already allocated
from `output.buffer' to `output.limit'. In most situations,
`output.cursor' starts with the value that `output.buffer'
has. Once the recoding is done, `output.cursor' will point
at the next free byte in the buffer, just after the recoded
text, so another recoding could be called without changing
any of these three pointers, for appending new information to
it. The number of recoded bytes in the buffer is the
difference between `output.cursor' and `output.buffer'.
Each time `output.cursor' reaches `output.limit', the buffer
is reallocated bigger, possibly at a different location in
memory, always held up-to-date in `output.buffer'. It is
still possible to call a task level function with no output
buffer at all to start with, in which case all three fields
should have `NULL' as a value. This is the situation
immediately after a call to `recode_new_task'.
`strategy'
This field, which is of type `enum recode_sequence_strategy',
tells how various recoding steps (passes) will be
interconnected. Its initial value is
`RECODE_STRATEGY_UNDECIDED', which is a constant defined in
the header file `<recodext.h>'. Other possible values are:
`RECODE_SEQUENCE_IN_MEMORY'
Keep intermediate recodings in memory.
`RECODE_SEQUENCE_WITH_FILES'
Do not fork, use intermediate files.
`RECODE_SEQUENCE_WITH_PIPE'
Fork processes connected with `pipe(2)'.
The best for now is to leave this field alone, and let the
recoding library decide its strategy, as many combinations
have not been tested yet.
`byte_order_mark'
This field, which is preset to `true', indicates that a byte
order mark is to be expected at the beginning of any
canonical `UCS-2' or `UTF-16' text, and that such a byte
order mark should be also produced for these charsets.
`fail_level'
This field, which is of type `enum recode_error' (Note:
Errors), sets the error level at which task level functions
should report a failure. If an error being detected is equal
or greater than `fail_level', the function will eventually
return `false' instead of `true'. The preset value for this
field is `RECODE_NOT_CANONICAL', that means that if not reset
to another value, the library will report failure on _any_
error.
`abort_level'
This field, which is of type `enum recode_error' (Note:
Errors), sets the error level at which task level functions
should immediately interrupt their processing. If an error
being detected is equal or greater than `abort_level', the
function returns immediately, but the returned value (`true'
or `false') is still is decided from the setting of
`fail_level', not `abort_level'. The preset value for this
field is `RECODE_MAXIMUM_ERROR', that means that is not reset
to another value, the library will never interrupt a recoding
task.
`error_so_far'
This field, which is of type `enum recode_error' (Note:
Errors), maintains the maximum error level met so far while
the recoding task was proceeding. The preset value is
`RECODE_NO_ERROR'.
* Task execution
recode_perform_task (TASK);
recode_filter_open (TASK, FILE);
recode_filter_close (TASK);
The function `recode_perform_task' reads as much input as possible,
and recode all of it on prescribed output, given a properly
initialised TASK.
Functions `recode_filter_open' and `recode_filter_close' are only
planned for now. They are meant to read input in piecemeal ways.
Even if functionality already exists informally in the library, it
has not been made available yet through such interface functions.
automatically generated by info2www version 1.2.2.9