Examples

This example provides sample code for a stateless converter that performs an algorithm-based convertion of the IBM-850 code set to the ISO8859-1 code set.

The file name for this example is 850_88591.c

#include <stdlib.h>
#include <iconv.h>
#include "850_88591.h"
 
#define DONE     0
 
/*
 *  Name :  _iconv_exec()
 *  
 *  This contains actual conversion method.
 */
static size_t  _iconv_exec(_LC_sample_iconv_t *cd, 
      unsigned char** inbuf, size_t *inbytesleft,
      unsigned char** outbuf, size_t *outbytesleft)
/*
 *  cd      : converter descriptor
 *  inbuf       : input buffer
 *  outbuf      : output buffer
 *  inbytesleft   : number of data(in bytes) in input buffer
 *  outbytesleft    : number of data(in bytes) in output buffer
 */
{
        unsigned char   *in;   /* point the input buffer */
        unsigned char   *out;  /* point the output buffer */
        unsigned char   *e_in; /* point the end of input buffer*/
        unsigned char   *e_out; /* point the end of output buffer*/
 
    /*
     *   If given converter discripter is invalid,
     *   it sets the errno and returns the number
     *   of bytes left to be converted.
     */
        if (!cd) {
        errno = EBADF;
        return *inbytesleft;
        }
 
        /*
         *      If the input buffer does not exist or there
         *      is no character to be converted, it returns
         *      0 (no characters to be converted).
         */
        if (!inbuf || !(*inbytesleft))
                return DONE;
 
        /*
         *      Set up pointers and initialize other variables
         */
        e_in = (in = *inbuf) + *inbytesleft;
        e_out = (out = *outbuf) + *outbytesleft;
 
     /*
      *     Perform code point conversion until all input
      *     is consumed.
      *     When error occurs (i.e. buffer overflow), error
      *     number is set and exit this loop.
      */
         while (in < e_in) {
 
        /*
         *   If there is not enough space left in output buffer
         *   to hold the converted data, it stops converting and 
         *   sets the errno to E2BIG.
         */
        if (e_out <= out) {
            errno = E2BIG;
            break;
        }
 
        /*
         *   Convert the input data and store it into the output
         *   buffer, then advance the pointers which point to the 
         *   buffers.
         */
        *out++ = table[*in++];
 
    }   /* while */
 
    /*
     *  Update the pointers to the buffers and
     *  input /output byte counts
     */
     *inbuf = in;
        *outbuf = out;
    *inbytesleft = e_in - in;
    *outbytesleft = e_out - out;
 
    /*
     *   Reurn the number of bytes left to be converted
     *   (0 for successful conversion completion)
     */
    return *inbytesleft;
}
 
/*
 *  Name :  _iconv_close()
 *  
 *  Free the allocated converter descriptor
 */
static void _iconv_close(iconv_t cd)
{
    if (!cd)
        free(cd);
    else
        /*
         *  If given converter is not valid,
         *  it sets the errno to EBADF
         */
        errno = EBADF;
}
 
/*
 *  Name :  init()
 *  
 *  This allocates and initializes the converter descriptor.
 */
static _LC_sample_iconv_t*
init (_LC_core_iconv_t *core_cd,  char* toname, char* fromname)
{
        _LC_sample_iconv_t *cd; /* converter descriptor */
 
    /*
     *   Allocate a converter descriptor
     */
        if (!(cd = (_LC_sample_iconv_t *)
                        malloc(sizeof(_LC_sample_iconv_t))))
                return (NULL);
 
    /*
     *Copy the core part of converter descriptor which is passed       *in
     */
        cd->core = *core_cd;
 
    /*
     *   Return the converter descriptor
     */
        return cd;
}
 
/*
 *  Name :  instantiate()
 *  
 *  Core part of a converter descriptor is initialized here.
 */
_LC_core_iconv_t*   instantiate(void)
{
        static _LC_core_iconv_t  cd;
 
    /*
     *  Initialize 
     *  _LC_MAGIC and _LC_VERSION are defined in <lc_core.h>.
     *  _LC_ICONV and _LC_core_iconv_t are defined in <iconv.h>.
     */
    cd.hdr.magic = _LC_MAGIC;
    cd.hdr.version = _LC_VERSION;
    cd.hdr.type_id = _LC_ICONV;
    cd.hdr.size = sizeof (_LC_core_iconv_t);
 
    /*
     *  Set pointers to each method.
     */
        cd.init = init;
        cd.exec = _iconv_exec;
        cd.close = _iconv_close;
 
    /*
     *  Returns the core part
     */
        return &cd;
}

This example contains a sample header file named 850_88591.h.

#ifndef _ICONV_SAMPLE_H
#define _ICONV_SAMPLE_H
 
/*
 *      Define _LC_sample_iconv_t
 */
typedef struct _LC_sample_iconv_rec {
        _LC_core_iconv_t   core;
} _LC_sample_iconv_t;
 
static unsigned char     table[] = { /*
 
 
        _______________________________________
        |                                       |
        |      IBM-850               ISO8859-1  |
        |_______________________________________|       
        /*      0x00     */              0x00,
        /*      0x01     */              0x01,
        /*      0x02     */              0x02,
        /*      0x03     */              0x03,
        /*      0x04     */              0x04,
        /*      0x05     */              0x05,
        /*      0x06     */              0x06,
        /*      0x07     */              0x07,
        /*      0x08     */              0x08,
        /*      0x09     */              0x09,
        /*      0x0A     */              0x0A,
        /*      0x0B     */              0x0B,
        /*      0x0C     */              0x0C,
        /*      0x0D     */              0x0D,
        .
        .
        .
        /*      0xF3     */              0xBE,
        /*      0xF4     */              0xB6,
        /*      0xF5     */              0xA7,
        /*      0xF6     */              0xF7,
        /*      0xF7     */              0xB8,
        /*      0xF8     */              0xB0,
        /*      0xF9     */              0xA8,
        /*      0xFA     */              0xB7,
        /*      0xFB     */              0xB9,
        /*      0xFC     */              0xB3,
        /*      0xFD     */              0xB2,
        /*      0xFE     */              0x1A,
        /*      0xFF     */              0xA0,
};
#endif

This example is a sample makefile.

SHELL   = /bin/ksh
CFLAGS  = $(COMPOPT) $(INCLUDE) $(DEFINES)
INCLUDE = -I.
COMPOPT =
DEFINES = -D_POSIX_SOURCE -D_XOPEN_SOURCE
CC      = /bin/xlc
LD      = /bin/ld
RM      = /bin/rm
 
SRC     = 850_88591.c
TARGET  = 850_88591
 
ENTRY_POINT       = instantiate
 
$(TARGET) : 
       cc -e $(ENTRY_POINT) -o $(TARGET) $(SRC) -l iconv 
 
clean :
        $(RM) -f $(TARGET)
        $(RM) -f *.o