• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *******************************************************************************
3 *
4 *   Copyright (C) 2003-2005, 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 invariant-character string. @internal ICU 2.8 */
182     UDataSwapFn *swapInvChars;
183 
184     /**
185      * Function for message output when an error occurs during data swapping.
186      * Can be NULL.
187      * @internal ICU 2.8
188      */
189     UDataPrintError *printError;
190     /** Context pointer for printError. @internal ICU 2.8 */
191     void *printErrorContext;
192 };
193 
194 U_CDECL_END
195 
196 U_CAPI UDataSwapper * U_EXPORT2
197 udata_openSwapper(UBool inIsBigEndian, uint8_t inCharset,
198                   UBool outIsBigEndian, uint8_t outCharset,
199                   UErrorCode *pErrorCode);
200 
201 /**
202  * Open a UDataSwapper for the given input data and the specified output
203  * characteristics.
204  * Values of -1 for any of the characteristics mean the local platform's
205  * characteristics.
206  *
207  * @see udata_swap
208  * @internal ICU 2.8
209  */
210 U_CAPI UDataSwapper * U_EXPORT2
211 udata_openSwapperForInputData(const void *data, int32_t length,
212                               UBool outIsBigEndian, uint8_t outCharset,
213                               UErrorCode *pErrorCode);
214 
215 U_CAPI void U_EXPORT2
216 udata_closeSwapper(UDataSwapper *ds);
217 
218 /**
219  * Read the beginning of an ICU data piece, recognize magic bytes,
220  * swap the structure.
221  * Set a U_UNSUPPORTED_ERROR if it does not look like an ICU data piece.
222  *
223  * @return The size of the data header, in bytes.
224  *
225  * @internal ICU 2.8
226  */
227 U_CAPI int32_t U_EXPORT2
228 udata_swapDataHeader(const UDataSwapper *ds,
229                      const void *inData, int32_t length, void *outData,
230                      UErrorCode *pErrorCode);
231 
232 /**
233  * Convert one int16_t from input to platform endianness.
234  * @internal ICU 2.8
235  */
236 U_CAPI int16_t U_EXPORT2
237 udata_readInt16(const UDataSwapper *ds, int16_t x);
238 
239 /**
240  * Convert one int32_t from input to platform endianness.
241  * @internal ICU 2.8
242  */
243 U_CAPI int32_t U_EXPORT2
244 udata_readInt32(const UDataSwapper *ds, int32_t x);
245 
246 /**
247  * Swap a block of invariant, NUL-terminated strings, but not padding
248  * bytes after the last string.
249  * @internal
250  */
251 U_CAPI int32_t U_EXPORT2
252 udata_swapInvStringBlock(const UDataSwapper *ds,
253                          const void *inData, int32_t length, void *outData,
254                          UErrorCode *pErrorCode);
255 
256 U_CAPI void U_EXPORT2
257 udata_printError(const UDataSwapper *ds,
258                  const char *fmt,
259                  ...);
260 
261 /* internal exports from putil.c -------------------------------------------- */
262 
263 /* declared here to keep them out of the public putil.h */
264 
265 /**
266  * Swap invariant char * strings ASCII->EBCDIC.
267  * @internal
268  */
269 U_CAPI int32_t U_EXPORT2
270 uprv_ebcdicFromAscii(const UDataSwapper *ds,
271                      const void *inData, int32_t length, void *outData,
272                      UErrorCode *pErrorCode);
273 
274 /**
275  * Copy invariant ASCII char * strings and verify they are invariant.
276  * @internal
277  */
278 U_CFUNC int32_t
279 uprv_copyAscii(const UDataSwapper *ds,
280                const void *inData, int32_t length, void *outData,
281                UErrorCode *pErrorCode);
282 
283 /**
284  * Swap invariant char * strings EBCDIC->ASCII.
285  * @internal
286  */
287 U_CFUNC int32_t
288 uprv_asciiFromEbcdic(const UDataSwapper *ds,
289                      const void *inData, int32_t length, void *outData,
290                      UErrorCode *pErrorCode);
291 
292 /**
293  * Copy invariant EBCDIC char * strings and verify they are invariant.
294  * @internal
295  */
296 U_CFUNC int32_t
297 uprv_copyEbcdic(const UDataSwapper *ds,
298                 const void *inData, int32_t length, void *outData,
299                 UErrorCode *pErrorCode);
300 
301 /**
302  * Compare ASCII invariant char * with Unicode invariant UChar *
303  * @internal
304  */
305 U_CFUNC int32_t
306 uprv_compareInvAscii(const UDataSwapper *ds,
307                      const char *outString, int32_t outLength,
308                      const UChar *localString, int32_t localLength);
309 
310 /**
311  * Compare EBCDIC invariant char * with Unicode invariant UChar *
312  * @internal
313  */
314 U_CFUNC int32_t
315 uprv_compareInvEbcdic(const UDataSwapper *ds,
316                       const char *outString, int32_t outLength,
317                       const UChar *localString, int32_t localLength);
318 
319 /* material... -------------------------------------------------------------- */
320 
321 #if 0
322 
323 /* udata.h */
324 
325 /**
326  * Public API function in udata.c
327  *
328  * Same as udata_openChoice() but automatically swaps the data.
329  * isAcceptable, if not NULL, may accept data with endianness and charset family
330  * different from the current platform's properties.
331  * If the data is acceptable and the platform properties do not match, then
332  * the swap function is called to swap an allocated version of the data.
333  * Preflighting may or may not be performed depending on whether the size of
334  * the loaded data item is known.
335  *
336  * @param isAcceptable Same as for udata_openChoice(). May be NULL.
337  *
338  * @internal ICU 2.8
339  */
340 U_CAPI UDataMemory * U_EXPORT2
341 udata_openSwap(const char *path, const char *type, const char *name,
342                UDataMemoryIsAcceptable *isAcceptable, void *isAcceptableContext,
343                UDataSwapFn *swap,
344                UDataPrintError *printError, void *printErrorContext,
345                UErrorCode *pErrorCode);
346 
347 #endif
348 
349 #endif
350