2 ******************************************************************************* 
   4 *   Copyright (C) 2003-2014, International Business Machines 
   5 *   Corporation and others.  All Rights Reserved. 
   7 ******************************************************************************* 
   8 *   file name:  udataswp.h 
  10 *   tab size:   8 (not used) 
  13 *   created on: 2003jun05 
  14 *   created by: Markus W. Scherer 
  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). 
  21 #ifndef __UDATASWP_H__ 
  22 #define __UDATASWP_H__ 
  25 #include "unicode/utypes.h" 
  27 /* forward declaration */ 
  32 typedef struct UDataSwapper UDataSwapper
; 
  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. 
  40  * Quick implementation outline: 
  41  * (best to copy and adapt and existing swapper implementation) 
  42  * check that the data looks like the expected format 
  45  *   never dereference outData 
  46  *   read inData and determine the data size 
  47  *   assume that inData is long enough for this 
  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); 
  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 
  67  * @param ds Pointer to UDataSwapper containing global data about the 
  68  *           transformation and function pointers for handling primitive 
  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. 
  87 typedef int32_t U_CALLCONV
 
  88 UDataSwapFn(const UDataSwapper 
*ds
, 
  89             const void *inData
, int32_t length
, void *outData
, 
  90             UErrorCode 
*pErrorCode
); 
  93  * Convert one uint16_t from input to platform endianness. 
  96 typedef uint16_t U_CALLCONV
 
  97 UDataReadUInt16(uint16_t x
); 
 100  * Convert one uint32_t from input to platform endianness. 
 103 typedef uint32_t U_CALLCONV
 
 104 UDataReadUInt32(uint32_t x
); 
 107  * Convert one uint16_t from platform to input endianness. 
 110 typedef void U_CALLCONV
 
 111 UDataWriteUInt16(uint16_t *p
, uint16_t x
); 
 114  * Convert one uint32_t from platform to input endianness. 
 117 typedef void U_CALLCONV
 
 118 UDataWriteUInt32(uint32_t *p
, uint32_t x
); 
 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. 
 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
); 
 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(). 
 140  * @param context A function-specific context pointer. 
 141  * @param fmt The format string. 
 142  * @param args The arguments for format string inserts. 
 146 typedef void U_CALLCONV
 
 147 UDataPrintError(void *context
, const char *fmt
, va_list args
); 
 149 struct UDataSwapper 
{ 
 150     /** Input endianness. @internal ICU 2.8 */ 
 152     /** Input charset family. @see U_CHARSET_FAMILY @internal ICU 2.8 */ 
 154     /** Output endianness. @internal ICU 2.8 */ 
 155     UBool outIsBigEndian
; 
 156     /** Output charset family. @see U_CHARSET_FAMILY @internal ICU 2.8 */ 
 159     /* basic functions for reading data values */ 
 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
; 
 168     /* basic functions for writing data values */ 
 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
; 
 175     /* basic functions for data transformations */ 
 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
; 
 187      * Function for message output when an error occurs during data swapping. 
 191     UDataPrintError 
*printError
; 
 192     /** Context pointer for printError. @internal ICU 2.8 */ 
 193     void *printErrorContext
; 
 198 U_CAPI UDataSwapper 
* U_EXPORT2
 
 199 udata_openSwapper(UBool inIsBigEndian
, uint8_t inCharset
, 
 200                   UBool outIsBigEndian
, uint8_t outCharset
, 
 201                   UErrorCode 
*pErrorCode
); 
 204  * Open a UDataSwapper for the given input data and the specified output 
 206  * Values of -1 for any of the characteristics mean the local platform's 
 212 U_CAPI UDataSwapper 
* U_EXPORT2
 
 213 udata_openSwapperForInputData(const void *data
, int32_t length
, 
 214                               UBool outIsBigEndian
, uint8_t outCharset
, 
 215                               UErrorCode 
*pErrorCode
); 
 217 U_CAPI 
void U_EXPORT2
 
 218 udata_closeSwapper(UDataSwapper 
*ds
); 
 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. 
 225  * @return The size of the data header, in bytes. 
 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
); 
 235  * Convert one int16_t from input to platform endianness. 
 238 U_CAPI 
int16_t U_EXPORT2
 
 239 udata_readInt16(const UDataSwapper 
*ds
, int16_t x
); 
 242  * Convert one int32_t from input to platform endianness. 
 245 U_CAPI 
int32_t U_EXPORT2
 
 246 udata_readInt32(const UDataSwapper 
*ds
, int32_t x
); 
 249  * Swap a block of invariant, NUL-terminated strings, but not padding 
 250  * bytes after the last string. 
 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
); 
 258 U_CAPI 
void U_EXPORT2
 
 259 udata_printError(const UDataSwapper 
*ds
, 
 263 /* internal exports from putil.c -------------------------------------------- */ 
 265 /* declared here to keep them out of the public putil.h */ 
 268  * Swap invariant char * strings ASCII->EBCDIC. 
 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
); 
 277  * Copy invariant ASCII char * strings and verify they are invariant. 
 281 uprv_copyAscii(const UDataSwapper 
*ds
, 
 282                const void *inData
, int32_t length
, void *outData
, 
 283                UErrorCode 
*pErrorCode
); 
 286  * Swap invariant char * strings EBCDIC->ASCII. 
 290 uprv_asciiFromEbcdic(const UDataSwapper 
*ds
, 
 291                      const void *inData
, int32_t length
, void *outData
, 
 292                      UErrorCode 
*pErrorCode
); 
 295  * Copy invariant EBCDIC char * strings and verify they are invariant. 
 299 uprv_copyEbcdic(const UDataSwapper 
*ds
, 
 300                 const void *inData
, int32_t length
, void *outData
, 
 301                 UErrorCode 
*pErrorCode
); 
 304  * Compare ASCII invariant char * with Unicode invariant UChar * 
 308 uprv_compareInvAscii(const UDataSwapper 
*ds
, 
 309                      const char *outString
, int32_t outLength
, 
 310                      const UChar 
*localString
, int32_t localLength
); 
 313  * Compare EBCDIC invariant char * with Unicode invariant UChar * 
 317 uprv_compareInvEbcdic(const UDataSwapper 
*ds
, 
 318                       const char *outString
, int32_t outLength
, 
 319                       const UChar 
*localString
, int32_t localLength
); 
 321 /* material... -------------------------------------------------------------- */ 
 328  * Public API function in udata.c 
 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. 
 338  * @param isAcceptable Same as for udata_openChoice(). May be NULL. 
 342 U_CAPI UDataMemory 
* U_EXPORT2
 
 343 udata_openSwap(const char *path
, const char *type
, const char *name
, 
 344                UDataMemoryIsAcceptable 
*isAcceptable
, void *isAcceptableContext
, 
 346                UDataPrintError 
*printError
, void *printErrorContext
, 
 347                UErrorCode 
*pErrorCode
);