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
);