Home | History | Annotate | Download | only in common
      1 /*
      2 *******************************************************************************
      3 *
      4 *   Copyright (C) 2003-2014, International Business Machines
      5 *   Corporation and others.  All Rights Reserved.
      6 *
      7 *******************************************************************************
      8 *   file name:  udataswp.h
      9 *   encoding:   US-ASCII
     10 *   tab size:   8 (not used)
     11 *   indentation:4
     12 *
     13 *   created on: 2003jun05
     14 *   created by: Markus W. Scherer
     15 *
     16 *   Definitions for ICU data transformations for different platforms,
     17 *   changing between big- and little-endian data and/or between
     18 *   charset families (ASCII<->EBCDIC).
     19 */
     20 
     21 #ifndef __UDATASWP_H__
     22 #define __UDATASWP_H__
     23 
     24 #include <stdarg.h>
     25 #include "unicode/utypes.h"
     26 
     27 /* forward declaration */
     28 
     29 U_CDECL_BEGIN
     30 
     31 struct UDataSwapper;
     32 typedef struct UDataSwapper UDataSwapper;
     33 
     34 /**
     35  * Function type for data transformation.
     36  * Transforms data, or just returns the length of the data if
     37  * the input length is -1.
     38  * Swap functions assume that their data pointers are aligned properly.
     39  *
     40  * Quick implementation outline:
     41  * (best to copy and adapt and existing swapper implementation)
     42  * check that the data looks like the expected format
     43  * if(length<0) {
     44  *   preflight:
     45  *   never dereference outData
     46  *   read inData and determine the data size
     47  *   assume that inData is long enough for this
     48  * } else {
     49  *   outData can be NULL if length==0
     50  *   inData==outData (in-place swapping) possible but not required!
     51  *   verify that length>=(actual size)
     52  *   if there is a chance that not every byte up to size is reached
     53  *     due to padding etc.:
     54  *   if(inData!=outData) {
     55  *     memcpy(outData, inData, actual size);
     56  *   }
     57  *   swap contents
     58  * }
     59  * return actual size
     60  *
     61  * Further implementation notes:
     62  * - read integers from inData before swapping them
     63  *   because in-place swapping can make them unreadable
     64  * - compareInvChars compares a local Unicode string with already-swapped
     65  *   output charset strings
     66  *
     67  * @param ds Pointer to UDataSwapper containing global data about the
     68  *           transformation and function pointers for handling primitive
     69  *           types.
     70  * @param inData Pointer to the input data to be transformed or examined.
     71  * @param length Length of the data, counting bytes. May be -1 for preflighting.
     72  *               If length>=0, then transform the data.
     73  *               If length==-1, then only determine the length of the data.
     74  *               The length cannot be determined from the data itself for all
     75  *               types of data (e.g., not for simple arrays of integers).
     76  * @param outData Pointer to the output data buffer.
     77  *                If length>=0 (transformation), then the output buffer must
     78  *                have a capacity of at least length.
     79  *                If length==-1, then outData will not be used and can be NULL.
     80  * @param pErrorCode ICU UErrorCode parameter, must not be NULL and must
     81  *                   fulfill U_SUCCESS on input.
     82  * @return The actual length of the data.
     83  *
     84  * @see UDataSwapper
     85  * @internal ICU 2.8
     86  */
     87 typedef int32_t U_CALLCONV
     88 UDataSwapFn(const UDataSwapper *ds,
     89             const void *inData, int32_t length, void *outData,
     90             UErrorCode *pErrorCode);
     91 
     92 /**
     93  * Convert one uint16_t from input to platform endianness.
     94  * @internal ICU 2.8
     95  */
     96 typedef uint16_t U_CALLCONV
     97 UDataReadUInt16(uint16_t x);
     98 
     99 /**
    100  * Convert one uint32_t from input to platform endianness.
    101  * @internal ICU 2.8
    102  */
    103 typedef uint32_t U_CALLCONV
    104 UDataReadUInt32(uint32_t x);
    105 
    106 /**
    107  * Convert one uint16_t from platform to input endianness.
    108  * @internal ICU 2.8
    109  */
    110 typedef void U_CALLCONV
    111 UDataWriteUInt16(uint16_t *p, uint16_t x);
    112 
    113 /**
    114  * Convert one uint32_t from platform to input endianness.
    115  * @internal ICU 2.8
    116  */
    117 typedef void U_CALLCONV
    118 UDataWriteUInt32(uint32_t *p, uint32_t x);
    119 
    120 /**
    121  * Compare invariant-character strings, one in the output data and the
    122  * other one caller-provided in Unicode.
    123  * An output data string is compared because strings are usually swapped
    124  * before the rest of the data, to allow for sorting of string tables
    125  * according to the output charset.
    126  * You can use -1 for the length parameters of NUL-terminated strings as usual.
    127  * Returns Unicode code point order for invariant characters.
    128  * @internal ICU 2.8
    129  */
    130 typedef int32_t U_CALLCONV
    131 UDataCompareInvChars(const UDataSwapper *ds,
    132                      const char *outString, int32_t outLength,
    133                      const UChar *localString, int32_t localLength);
    134 
    135 /**
    136  * Function for message output when an error occurs during data swapping.
    137  * A format string and variable number of arguments are passed
    138  * like for vprintf().
    139  *
    140  * @param context A function-specific context pointer.
    141  * @param fmt The format string.
    142  * @param args The arguments for format string inserts.
    143  *
    144  * @internal ICU 2.8
    145  */
    146 typedef void U_CALLCONV
    147 UDataPrintError(void *context, const char *fmt, va_list args);
    148 
    149 struct UDataSwapper {
    150     /** Input endianness. @internal ICU 2.8 */
    151     UBool inIsBigEndian;
    152     /** Input charset family. @see U_CHARSET_FAMILY @internal ICU 2.8 */
    153     uint8_t inCharset;
    154     /** Output endianness. @internal ICU 2.8 */
    155     UBool outIsBigEndian;
    156     /** Output charset family. @see U_CHARSET_FAMILY @internal ICU 2.8 */
    157     uint8_t outCharset;
    158 
    159     /* basic functions for reading data values */
    160 
    161     /** Convert one uint16_t from input to platform endianness. @internal ICU 2.8 */
    162     UDataReadUInt16 *readUInt16;
    163     /** Convert one uint32_t from input to platform endianness. @internal ICU 2.8 */
    164     UDataReadUInt32 *readUInt32;
    165     /** Compare an invariant-character output string with a local one. @internal ICU 2.8 */
    166     UDataCompareInvChars *compareInvChars;
    167 
    168     /* basic functions for writing data values */
    169 
    170     /** Convert one uint16_t from platform to input endianness. @internal ICU 2.8 */
    171     UDataWriteUInt16 *writeUInt16;
    172     /** Convert one uint32_t from platform to input endianness. @internal ICU 2.8 */
    173     UDataWriteUInt32 *writeUInt32;
    174 
    175     /* basic functions for data transformations */
    176 
    177     /** Transform an array of 16-bit integers. @internal ICU 2.8 */
    178     UDataSwapFn *swapArray16;
    179     /** Transform an array of 32-bit integers. @internal ICU 2.8 */
    180     UDataSwapFn *swapArray32;
    181     /** Transform an array of 64-bit integers. @internal ICU 53 */
    182     UDataSwapFn *swapArray64;
    183     /** Transform an invariant-character string. @internal ICU 2.8 */
    184     UDataSwapFn *swapInvChars;
    185 
    186     /**
    187      * Function for message output when an error occurs during data swapping.
    188      * Can be NULL.
    189      * @internal ICU 2.8
    190      */
    191     UDataPrintError *printError;
    192     /** Context pointer for printError. @internal ICU 2.8 */
    193     void *printErrorContext;
    194 };
    195 
    196 U_CDECL_END
    197 
    198 U_CAPI UDataSwapper * U_EXPORT2
    199 udata_openSwapper(UBool inIsBigEndian, uint8_t inCharset,
    200                   UBool outIsBigEndian, uint8_t outCharset,
    201                   UErrorCode *pErrorCode);
    202 
    203 /**
    204  * Open a UDataSwapper for the given input data and the specified output
    205  * characteristics.
    206  * Values of -1 for any of the characteristics mean the local platform's
    207  * characteristics.
    208  *
    209  * @see udata_swap
    210  * @internal ICU 2.8
    211  */
    212 U_CAPI UDataSwapper * U_EXPORT2
    213 udata_openSwapperForInputData(const void *data, int32_t length,
    214                               UBool outIsBigEndian, uint8_t outCharset,
    215                               UErrorCode *pErrorCode);
    216 
    217 U_CAPI void U_EXPORT2
    218 udata_closeSwapper(UDataSwapper *ds);
    219 
    220 /**
    221  * Read the beginning of an ICU data piece, recognize magic bytes,
    222  * swap the structure.
    223  * Set a U_UNSUPPORTED_ERROR if it does not look like an ICU data piece.
    224  *
    225  * @return The size of the data header, in bytes.
    226  *
    227  * @internal ICU 2.8
    228  */
    229 U_CAPI int32_t U_EXPORT2
    230 udata_swapDataHeader(const UDataSwapper *ds,
    231                      const void *inData, int32_t length, void *outData,
    232                      UErrorCode *pErrorCode);
    233 
    234 /**
    235  * Convert one int16_t from input to platform endianness.
    236  * @internal ICU 2.8
    237  */
    238 U_CAPI int16_t U_EXPORT2
    239 udata_readInt16(const UDataSwapper *ds, int16_t x);
    240 
    241 /**
    242  * Convert one int32_t from input to platform endianness.
    243  * @internal ICU 2.8
    244  */
    245 U_CAPI int32_t U_EXPORT2
    246 udata_readInt32(const UDataSwapper *ds, int32_t x);
    247 
    248 /**
    249  * Swap a block of invariant, NUL-terminated strings, but not padding
    250  * bytes after the last string.
    251  * @internal
    252  */
    253 U_CAPI int32_t U_EXPORT2
    254 udata_swapInvStringBlock(const UDataSwapper *ds,
    255                          const void *inData, int32_t length, void *outData,
    256                          UErrorCode *pErrorCode);
    257 
    258 U_CAPI void U_EXPORT2
    259 udata_printError(const UDataSwapper *ds,
    260                  const char *fmt,
    261                  ...);
    262 
    263 /* internal exports from putil.c -------------------------------------------- */
    264 
    265 /* declared here to keep them out of the public putil.h */
    266 
    267 /**
    268  * Swap invariant char * strings ASCII->EBCDIC.
    269  * @internal
    270  */
    271 U_CAPI int32_t U_EXPORT2
    272 uprv_ebcdicFromAscii(const UDataSwapper *ds,
    273                      const void *inData, int32_t length, void *outData,
    274                      UErrorCode *pErrorCode);
    275 
    276 /**
    277  * Copy invariant ASCII char * strings and verify they are invariant.
    278  * @internal
    279  */
    280 U_CFUNC int32_t
    281 uprv_copyAscii(const UDataSwapper *ds,
    282                const void *inData, int32_t length, void *outData,
    283                UErrorCode *pErrorCode);
    284 
    285 /**
    286  * Swap invariant char * strings EBCDIC->ASCII.
    287  * @internal
    288  */
    289 U_CFUNC int32_t
    290 uprv_asciiFromEbcdic(const UDataSwapper *ds,
    291                      const void *inData, int32_t length, void *outData,
    292                      UErrorCode *pErrorCode);
    293 
    294 /**
    295  * Copy invariant EBCDIC char * strings and verify they are invariant.
    296  * @internal
    297  */
    298 U_CFUNC int32_t
    299 uprv_copyEbcdic(const UDataSwapper *ds,
    300                 const void *inData, int32_t length, void *outData,
    301                 UErrorCode *pErrorCode);
    302 
    303 /**
    304  * Compare ASCII invariant char * with Unicode invariant UChar *
    305  * @internal
    306  */
    307 U_CFUNC int32_t
    308 uprv_compareInvAscii(const UDataSwapper *ds,
    309                      const char *outString, int32_t outLength,
    310                      const UChar *localString, int32_t localLength);
    311 
    312 /**
    313  * Compare EBCDIC invariant char * with Unicode invariant UChar *
    314  * @internal
    315  */
    316 U_CFUNC int32_t
    317 uprv_compareInvEbcdic(const UDataSwapper *ds,
    318                       const char *outString, int32_t outLength,
    319                       const UChar *localString, int32_t localLength);
    320 
    321 /* material... -------------------------------------------------------------- */
    322 
    323 #if 0
    324 
    325 /* udata.h */
    326 
    327 /**
    328  * Public API function in udata.c
    329  *
    330  * Same as udata_openChoice() but automatically swaps the data.
    331  * isAcceptable, if not NULL, may accept data with endianness and charset family
    332  * different from the current platform's properties.
    333  * If the data is acceptable and the platform properties do not match, then
    334  * the swap function is called to swap an allocated version of the data.
    335  * Preflighting may or may not be performed depending on whether the size of
    336  * the loaded data item is known.
    337  *
    338  * @param isAcceptable Same as for udata_openChoice(). May be NULL.
    339  *
    340  * @internal ICU 2.8
    341  */
    342 U_CAPI UDataMemory * U_EXPORT2
    343 udata_openSwap(const char *path, const char *type, const char *name,
    344                UDataMemoryIsAcceptable *isAcceptable, void *isAcceptableContext,
    345                UDataSwapFn *swap,
    346                UDataPrintError *printError, void *printErrorContext,
    347                UErrorCode *pErrorCode);
    348 
    349 #endif
    350 
    351 #endif
    352