2 ******************************************************************************
4 * Copyright (C) 1999-2011, International Business Machines
5 * Corporation and others. All Rights Reserved.
7 ******************************************************************************/
10 /*----------------------------------------------------------------------------------
12 * UDataMemory A class-like struct that serves as a handle to a piece of memory
13 * that contains some ICU data (resource, converters, whatever.)
15 * When an application opens ICU data (with udata_open, for example,
16 * a UDataMemory * is returned.
18 *----------------------------------------------------------------------------------*/
20 #include "unicode/utypes.h"
22 #include "unicode/udata.h"
26 U_CFUNC
void UDataMemory_init(UDataMemory
*This
) {
27 uprv_memset(This
, 0, sizeof(UDataMemory
));
32 U_CFUNC
void UDatamemory_assign(UDataMemory
*dest
, UDataMemory
*source
) {
33 /* UDataMemory Assignment. Destination UDataMemory must be initialized first. */
34 UBool mallocedFlag
= dest
->heapAllocated
;
35 uprv_memcpy(dest
, source
, sizeof(UDataMemory
));
36 dest
->heapAllocated
= mallocedFlag
;
39 U_CFUNC UDataMemory
*UDataMemory_createNewInstance(UErrorCode
*pErr
) {
42 if (U_FAILURE(*pErr
)) {
45 This
= uprv_malloc(sizeof(UDataMemory
));
47 *pErr
= U_MEMORY_ALLOCATION_ERROR
; }
49 UDataMemory_init(This
);
50 This
->heapAllocated
= TRUE
;
56 U_CFUNC
const DataHeader
*
57 UDataMemory_normalizeDataPointer(const void *p
) {
58 /* allow the data to be optionally prepended with an alignment-forcing double value */
59 const DataHeader
*pdh
= (const DataHeader
*)p
;
60 if(pdh
==NULL
|| (pdh
->dataHeader
.magic1
==0xda && pdh
->dataHeader
.magic2
==0x27)) {
63 #if U_PLATFORM == U_PF_OS400
65 TODO: Fix this once the compiler implements this feature. Keep in sync with genccode.c
67 This is here because this platform can't currently put
68 const data into the read-only pages of an object or
69 shared library (service program). Only strings are allowed in read-only
70 pages, so we use char * strings to store the data.
72 In order to prevent the beginning of the data from ever matching the
73 magic numbers we must skip the initial double.
76 return (const DataHeader
*)*((const void **)p
+1);
78 return (const DataHeader
*)((const double *)p
+1);
84 U_CFUNC
void UDataMemory_setData (UDataMemory
*This
, const void *dataAddr
) {
85 This
->pHeader
= UDataMemory_normalizeDataPointer(dataAddr
);
90 udata_close(UDataMemory
*pData
) {
92 uprv_unmapFile(pData
);
93 if(pData
->heapAllocated
) {
96 UDataMemory_init(pData
);
101 U_CAPI
const void * U_EXPORT2
102 udata_getMemory(UDataMemory
*pData
) {
103 if(pData
!=NULL
&& pData
->pHeader
!=NULL
) {
104 return (char *)(pData
->pHeader
)+udata_getHeaderSize(pData
->pHeader
);
111 * Get the length of the data item if possible.
112 * The length may be up to 15 bytes larger than the actual data.
114 * TODO Consider making this function public.
115 * It would have to return the actual length in more cases.
116 * For example, the length of the last item in a .dat package could be
117 * computed from the size of the whole .dat package minus the offset of the
119 * The size of a file that was directly memory-mapped could be determined
120 * using some system API.
122 * In order to get perfect values for all data items, we may have to add a
123 * length field to UDataInfo, but that complicates data generation
124 * and may be overkill.
126 * @param pData The data item.
127 * @return the length of the data item, or -1 if not known
128 * @internal Currently used only in cintltst/udatatst.c
130 U_CAPI
int32_t U_EXPORT2
131 udata_getLength(const UDataMemory
*pData
) {
132 if(pData
!=NULL
&& pData
->pHeader
!=NULL
&& pData
->length
>=0) {
134 * subtract the header size,
135 * return only the size of the actual data starting at udata_getMemory()
137 return pData
->length
-udata_getHeaderSize(pData
->pHeader
);
144 * Get the memory including the data header.
145 * Used in cintltst/udatatst.c
148 U_CAPI
const void * U_EXPORT2
149 udata_getRawMemory(const UDataMemory
*pData
) {
150 if(pData
!=NULL
&& pData
->pHeader
!=NULL
) {
151 return pData
->pHeader
;
157 U_CFUNC UBool
UDataMemory_isLoaded(const UDataMemory
*This
) {
158 return This
->pHeader
!= NULL
;