Preserve state information

Most code sets are not state dependent; that is, the characters of these code sets can be decoded with only one algorithm, and each byte sequence represents a unique character.

In contrast, byte sequences in state-dependent code sets can represent more than one character. Which character a sequence represents depends on the current state. State-dependent code sets occur primarily on IBM® mainframe computers, and they affect only code-set conversion.

When you fragment a complete source string into two or more nonadjacent source buffers, you must call the ifx_gl_cv_mconv() function multiple times, to perform code-set conversion on each fragment of the string. Because of the nature of state-dependent code sets (and because the caller of this function cannot know whether either the source or destination code set is a state-dependent code set), you must preserve state information across the multiple calls of ifx_gl_cv_mconv(). The ifx_gl_cv_mconv() argument state is used for this purpose.

The state argument is a pointer to a conv_state_t structure. This structure contains two fields that you must set to indicate that you are performing code-set conversion on fragmented strings: first_frag and last_frag. The following table lists the different fragments of a string and the corresponding values to which you must set these two conv_state_t fields.
String fragment Value of first_frag field Value of last_frag field
String is the first of n fragments. 1 0
String is the 2nd, ..., nth-1 fragment. 0 0
String is the last (nth) fragment. 0 1
String is not fragmented; it is a complete string. 1 1
Important: The conv_state_t structure contains other fields that are for internal use only. HCL Informix® does not guarantee that these other internal fields of conv_state_t will not change in future releases. Therefore, to create portable code, set only the first_frag and last_frag fields of the conv_state_t structure.

Pass the fragments to the ifx_gl_cv_mconv() function in the same order in which they appear in the complete string. Use the same conv_state_t structure for all of the fragments of the same complete string.

The following code performs code-set conversion on a complete character string that is not fragmented:
int unfrag_strng(out_str, out_len, out_cs, in_str,
        in_len, in_cs)
    gl_mchar_t *out_str;
    int out_len;
    char *out_cs;
    gl_mchar_t *in_str;
    int in_len;
    char *in_cs;
{
    conv_state_t state;
    int ret;

    state.first_frag = 1;
    state.last_frag = 1;
    ret = ifx_gl_cv_mconv(&state, &out_str, &out_len,
            out_cs, &in_str, &in_len, in_cs);
    ...
}

This code assigns both the first_frag and last_frag fields a value of 1 to indicate that the multibyte string is not fragmented.

Suppose that you have a complete multibyte-character string that is fragmented into four different buffers. The following code performs code-set conversion on this fragmented string:
int frag_strng(out_str, out_len, out_cs, in_str,
        in_len, in_cs)
    gl_mchar_t *out_str;
    int out_len;
    char *out_cs;
    gl_mchar_t *in_str[];
    int in_len;
    char *in_cs;
{
    conv_state_t state;
    int ret;
/* Perform code-set conversion on the FIRST fragment:
 * first_frag = 1; last_frag = 0 */
   state.first_frag = 1;
   state.last_frag = 0;
   ret = ifx_gl_cv_mconv(&state, &out_str, &out_len, out_cs,
       &in_str[0], &in_len, in_cs);
   ...
/* Perform code-set conversion on the SECOND fragment:
    first_frag = 0; last_frag = 0 */
    state.first_frag = 0;
    state.last_frag = 0;
    ret = ifx_gl_cv_mconv(&state, &out_str, &out_len, out_cs,
        &in_str[1], &in_len, in_cs);
    ...
/* Perform code-set conversion on the THIRD fragment.
 * No need to set the first_frag and last_frag fields again,
 * because they are already 0 */
    ret = ifx_gl_cv_mconv(&state, &out_str, &out_len, out_cs,
        &in_str[2], &in_len, in_cs);
    ...
/* Perform code-set conversion on the FOURTH (last)
 * fragment: first_frag = 0; last_frag = 1 */
    state.first_frag = 0;
    state.last_frag = 1;
    ret = ifx_gl_cv_mconv(&state, &out_str, &out_len, out_cs,
        &in_str[3], &in_len, in_cs);
    ...
}