blob: 329db09b969812985f75bca0656cf2136ce9ceb3 [file] [log] [blame]
/*-
* Copyright (c) 1999,2000
* Konstantin Chuguev. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Konstantin Chuguev
* and its contributors.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#ifndef _ICONV_H_
#define _ICONV_H_
#include "apr.h"
#include "apr_pools.h"
#include "apr_iconv.h"
#ifdef WIN32
#define ICONV_DEFAULT_PATH "iconv"
#define API_USE_BUILTIN_ALIASES /* Use the built-in charset alias table */
#else
#include "apr_iconv_private.h" /* contains ICONV_DEFAULT_PATH */
#endif
#include <stddef.h>
#ifdef ICONV_INTERNAL
/*
* iconv module types
*/
#define ICMOD_ANY 0
#define ICMOD_LIB 1
#define ICMOD_UC_CCS 0x100 /* UC - CCS for CES */
#define ICMOD_UC_CES 0x101 /* UC - CES */
/*
* iconv module flags
*/
#define ICMODF_LOADED 0x8000
/*
* iconv module handler events
*/
#define ICMODEV_LOAD 1 /* module load. after dependencies resolved */
#define ICMODEV_UNLOAD 2 /* module unload */
#define ICMODEV_DYN_LOAD 3 /* load dynamic dependencies */
#define ICMODEV_DYN_UNLOAD 4 /* unload dynamic dependencies */
struct iconv_module_depend {
int md_type;
const char * md_name;
const void * md_data;
};
struct iconv_module;
/* _tbl_simple.c table_load_ccs() calls apr_iconv_mod_load(...ctx) */
typedef int iconv_mod_event_t(struct iconv_module *, int, apr_pool_t *ctx);
struct iconv_module_desc {
int imd_type;
iconv_mod_event_t *imd_event;
const struct iconv_module_depend *imd_depend;
const void * imd_data;
};
#define END_ICONV_MODULE_DEPEND {0, NULL, NULL}
#define ICONV_MODULE(type,data) struct iconv_module_desc iconv_module \
{(type), (data)}
struct iconv_module {
int im_flags;
void * im_handle;
struct iconv_module_desc *im_desc;
struct iconv_module *im_next;
struct iconv_module *im_deplist;
int im_depcnt;
const void * im_methods;
void * im_data;
const void * im_depdata; /* data if module loaded from dependency */
const void * im_args;
/* This is module-private data. Nothing outside the module
itself may touch it. */
void *im_private;
};
#define ICONV_MOD_LOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_LOAD,ctx)
#define ICONV_MOD_UNLOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_UNLOAD,ctx)
#define ICONV_MOD_DYN_LOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_DYN_LOAD,ctx)
#define ICONV_MOD_DYN_UNLOAD(mod,ctx) (mod)->im_desc->imd_event(mod, ICMODEV_DYN_UNLOAD,ctx)
/*
* iconv converter definitions.
*/
typedef int iconv_open_t(const char *, const char *, void **, apr_pool_t *);
typedef int iconv_close_t(void *, apr_pool_t *);
typedef apr_status_t iconv_conv_t(void *, const unsigned char **, apr_size_t *,
unsigned char **, apr_size_t *, apr_size_t *);
struct iconv_converter_desc {
iconv_open_t * icd_open;
iconv_close_t * icd_close;
iconv_conv_t * icd_conv;
};
struct iconv_converter {
struct iconv_converter_desc *ic_desc;
void * ic_data;
};
/*
* internal data types and functions used by charset conversion modules
*/
#define UCS_CHAR_ZERO_WIDTH_NBSP 0xFEFF
#define UCS_CHAR_INVALID 0xFFFE
#define UCS_CHAR_NONE 0xFFFF
typedef apr_uint16_t ucs2_t; /* Unicode character [D5] */
typedef apr_uint32_t ucs4_t; /* Unicode scalar character [D28] */
#define ucs_t ucs4_t
/*
* one-level coded character set conversion tables
*/
typedef struct {
apr_uint16_t data[128];
} iconv_ccs_convtable_7bit; /* 7-bit charset to Unicode */
typedef struct {
apr_uint16_t data[256];
} iconv_ccs_convtable_8bit; /* 8-bit charset to Unicode */
/*
* two-level coded character set conversion tables
*/
typedef struct {
const iconv_ccs_convtable_7bit *data[128];
} iconv_ccs_convtable_14bit; /* 14-bit charset to Unicode */
typedef struct {
const iconv_ccs_convtable_8bit *data[256];
} iconv_ccs_convtable_16bit; /* 16-bit charset to Unicode;
* Unicode to any charset */
/*
* abstract coded character set conversion table
*/
typedef union {
iconv_ccs_convtable_7bit _7bit;
iconv_ccs_convtable_8bit _8bit;
iconv_ccs_convtable_14bit _14bit;
iconv_ccs_convtable_16bit _16bit;
} iconv_ccs_convtable;
/*
* function for table-driven conversion
*/
typedef ucs2_t iconv_ccs_converter_t (ucs2_t ch);
/*
* charset conversion module descriptor
*/
struct iconv_ccs_desc {
const char * const * names;
int nbits;
const iconv_ccs_convtable * from_ucs;
const iconv_ccs_convtable * to_ucs;
iconv_ccs_converter_t * convert_from_ucs;
iconv_ccs_converter_t * convert_to_ucs;
};
/*
* inline functions for use in charset conversion modules
*/
static APR_INLINE ucs2_t
iconv_ccs_convert_7bit(const iconv_ccs_convtable *table, ucs2_t ch)
{
return ch & 0x80 ? UCS_CHAR_INVALID : table->_7bit.data[ch];
}
static APR_INLINE ucs2_t
iconv_ccs_convert_8bit(const iconv_ccs_convtable *table, ucs2_t ch)
{
return table->_8bit.data[ch];
}
static APR_INLINE ucs2_t
iconv_ccs_convert_14bit(const iconv_ccs_convtable *table, ucs2_t ch)
{
const iconv_ccs_convtable_7bit *sub_table;
sub_table = ch & 0x8080 ? NULL : table->_14bit.data[ch >> 8];
return sub_table ? sub_table->data[ch & 0x7F] : UCS_CHAR_INVALID;
}
static APR_INLINE ucs2_t
iconv_ccs_convert_16bit(const iconv_ccs_convtable *table, ucs2_t ch)
{
const iconv_ccs_convtable_8bit *sub_table;
sub_table = table->_16bit.data[ch >> 8];
return sub_table ? sub_table->data[ch & 0xFF] : UCS_CHAR_INVALID;
}
#define ICONV_CCS_CONVERT_FROM_UCS(ccsd, ch) \
((ccsd)->convert_from_ucs(ch))
#define ICONV_CCS_CONVERT_TO_UCS(ccsd, ch) \
((ccsd)->convert_to_ucs(ch))
/*
* generic character encoding schemes and functions
*/
struct iconv_ces;
typedef int iconv_ces_open_t(struct iconv_ces *, apr_pool_t *);
typedef int iconv_ces_close_t(struct iconv_ces *);
typedef void iconv_ces_reset_t(struct iconv_ces *);
typedef const char * const *iconv_ces_names_t(struct iconv_ces *);
typedef int iconv_ces_nbits_t(struct iconv_ces *);
typedef int iconv_ces_nbytes_t(struct iconv_ces *);
typedef apr_ssize_t iconv_ces_convert_from_ucs_t
(struct iconv_ces *data, ucs_t in,
unsigned char **outbuf, apr_size_t *outbytesleft);
typedef ucs_t iconv_ces_convert_to_ucs_t
(struct iconv_ces *data,
const unsigned char **inbuf, apr_size_t *inbytesleft);
struct iconv_ces_desc {
iconv_ces_open_t * open;
iconv_ces_close_t * close;
iconv_ces_reset_t * reset;
iconv_ces_names_t * names;
iconv_ces_nbits_t * nbits;
iconv_ces_nbytes_t * nbytes;
iconv_ces_convert_from_ucs_t * convert_from_ucs;
iconv_ces_convert_to_ucs_t * convert_to_ucs;
const void *data;
};
struct iconv_ces {
struct iconv_ces_desc * desc;
void * data;
struct iconv_module * mod;
};
API_DECLARE_NONSTD(int) apr_iconv_ces_open(const char *ces_name, struct iconv_ces **cespp, apr_pool_t *ctx);
API_DECLARE_NONSTD(int) apr_iconv_ces_close(struct iconv_ces *ces, apr_pool_t *ctx);
API_DECLARE_NONSTD(int) apr_iconv_ces_open_func(struct iconv_ces *ces, apr_pool_t *ctx);
API_DECLARE_NONSTD(int) apr_iconv_ces_close_func(struct iconv_ces *ces);
API_DECLARE_NONSTD(void) apr_iconv_ces_reset_func(struct iconv_ces *ces);
API_DECLARE_NONSTD(void) apr_iconv_ces_no_func(struct iconv_ces *ces);
API_DECLARE_NONSTD(int) apr_iconv_ces_nbits7(struct iconv_ces *ces);
API_DECLARE_NONSTD(int) apr_iconv_ces_nbits8(struct iconv_ces *ces);
API_DECLARE_NONSTD(int) apr_iconv_ces_zero(struct iconv_ces *ces);
/* Safe for _NONSTD APIs since the C caller pops the stack and the
* apr_pool_t *cxt arg is simply ignored:
*/
#define apr_iconv_ces_open_zero (iconv_ces_open_t*)apr_iconv_ces_zero
#define iconv_char32bit(ch) ((ch) & 0xFFFF0000)
#define ICONV_CES_OPEN(ces,ctx) (ces)->desc->open(ces,ctx)
#define ICONV_CES_CLOSE(ces) (ces)->desc->close(ces)
#define ICONV_CES_RESET(ces) (ces)->desc->reset(ces)
#define ICONV_CES_CONVERT_FROM_UCS(cesd, in, outbuf, outbytes) \
((cesd)->desc->convert_from_ucs((cesd), (in), (outbuf), (outbytes)))
#define ICONV_CES_CONVERT_TO_UCS(cesd, inbuf, inbytes) \
((cesd)->desc->convert_to_ucs((cesd), (inbuf), (inbytes)))
#define ICONV_CES_DRIVER_DECL(name) \
iconv_ces_open_t iconv_##name##_open; \
iconv_ces_close_t iconv_##name##_close; \
iconv_ces_reset_t iconv_##name##_reset; \
iconv_ces_nbits_t iconv_##name##_nbits; \
iconv_ces_convert_from_ucs_t iconv_##name##_convert_from_ucs; \
iconv_ces_convert_to_ucs_t iconv_##name##_convert_to_ucs
/*
************************************************
* EUC character encoding schemes and functions *
************************************************
*/
typedef struct iconv_ces_euc_ccs {
const char *prefix;
apr_size_t prefixlen;
} iconv_ces_euc_ccs_t;
ICONV_CES_DRIVER_DECL(euc);
/*
* ISO-2022 character encoding schemes and functions
*/
enum { ICONV_SHIFT_SI = 0, ICONV_SHIFT_SO, ICONV_SHIFT_SS2, ICONV_SHIFT_SS3 };
typedef struct iconv_ces_iso2022_ccs {
int shift;
const char * designator;
apr_size_t designatorlen;
} iconv_ces_iso2022_ccs_t;
typedef struct {
const int * shift_tab;
int nccs;
const struct iconv_ces_iso2022_ccs *ccs;
} iconv_ces_iso2022_data;
ICONV_CES_DRIVER_DECL(iso2022);
API_DECLARE_NONSTD(int) apr_iconv_mod_load(const char *, int, const void *, struct iconv_module **, apr_pool_t *);
API_DECLARE_NONSTD(int) apr_iconv_mod_unload(struct iconv_module *,apr_pool_t *ctx);
API_DECLARE_NONSTD(int) apr_iconv_mod_noevent(struct iconv_module *mod, int event, apr_pool_t *ctx);
API_DECLARE_NONSTD(int) apr_iconv_ccs_event(struct iconv_module *mod, int event, apr_pool_t *ctx);
int iconv_malloc(apr_size_t size, void **pp);
extern struct iconv_converter_desc iconv_uc_desc;
API_DECLARE_NONSTD(apr_status_t) apr_iconv_euc_open(struct iconv_ces *ces, apr_pool_t *ctx);
API_DECLARE_NONSTD(apr_status_t) apr_iconv_euc_close(struct iconv_ces *ces);
API_DECLARE_NONSTD(apr_ssize_t) apr_iconv_euc_convert_from_ucs(struct iconv_ces *ces, ucs_t in, unsigned char **outbuf, apr_size_t *outbytesleft);
API_DECLARE_NONSTD(ucs_t) apr_iconv_euc_convert_to_ucs(struct iconv_ces *ces, const unsigned char **inbuf, apr_size_t *inbytesleft);
API_DECLARE_NONSTD(apr_status_t) apr_iconv_iso2022_open(struct iconv_ces *ces, apr_pool_t *ctx);
API_DECLARE_NONSTD(int) apr_iconv_iso2022_close(struct iconv_ces *ces);
API_DECLARE_NONSTD(void) apr_iconv_iso2022_reset(struct iconv_ces *ces);
API_DECLARE_NONSTD(apr_ssize_t) apr_iconv_iso2022_convert_from_ucs(struct iconv_ces *ces, ucs_t in, unsigned char **outbuf, apr_size_t *outbytesleft);
API_DECLARE_NONSTD(ucs_t) apr_iconv_iso2022_convert_to_ucs(struct iconv_ces *ces, const unsigned char **inbuf, apr_size_t *inbytesleft);
#endif /* ICONV_INTERNAL */
#endif /* _ICONV_H_ */