(recode.info)Task level


Next: Charset level Prev: Request level Up: Library
Enter node , (file) or (file)node

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