1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
4 ******************************************************************************
6 * Copyright (C) 1999-2011, International Business Machines
7 * Corporation and others. All Rights Reserved.
9 ******************************************************************************/
12 /*----------------------------------------------------------------------------------
14 * UDataMemory A class-like struct that serves as a handle to a piece of memory
15 * that contains some ICU data (resource, converters, whatever.)
17 * When an application opens ICU data (with udata_open, for example,
18 * a UDataMemory * is returned.
20 *----------------------------------------------------------------------------------*/
22 #include "unicode/utypes.h"
24 #include "unicode/udata.h"
28 U_CFUNC
void UDataMemory_init(UDataMemory
*This
) {
29 uprv_memset(This
, 0, sizeof(UDataMemory
));
34 U_CFUNC
void UDatamemory_assign(UDataMemory
*dest
, UDataMemory
*source
) {
35 /* UDataMemory Assignment. Destination UDataMemory must be initialized first. */
36 UBool mallocedFlag
= dest
->heapAllocated
;
37 uprv_memcpy(dest
, source
, sizeof(UDataMemory
));
38 dest
->heapAllocated
= mallocedFlag
;
41 U_CFUNC UDataMemory
*UDataMemory_createNewInstance(UErrorCode
*pErr
) {
44 if (U_FAILURE(*pErr
)) {
47 This
= (UDataMemory
*)uprv_malloc(sizeof(UDataMemory
));
49 *pErr
= U_MEMORY_ALLOCATION_ERROR
; }
51 UDataMemory_init(This
);
52 This
->heapAllocated
= TRUE
;
58 U_CFUNC
const DataHeader
*
59 UDataMemory_normalizeDataPointer(const void *p
) {
60 /* allow the data to be optionally prepended with an alignment-forcing double value */
61 const DataHeader
*pdh
= (const DataHeader
*)p
;
62 if(pdh
==NULL
|| (pdh
->dataHeader
.magic1
==0xda && pdh
->dataHeader
.magic2
==0x27)) {
65 #if U_PLATFORM == U_PF_OS400
67 TODO: Fix this once the compiler implements this feature. Keep in sync with genccode.c
69 This is here because this platform can't currently put
70 const data into the read-only pages of an object or
71 shared library (service program). Only strings are allowed in read-only
72 pages, so we use char * strings to store the data.
74 In order to prevent the beginning of the data from ever matching the
75 magic numbers we must skip the initial double.
78 return (const DataHeader
*)*((const void **)p
+1);
80 return (const DataHeader
*)((const double *)p
+1);
86 U_CFUNC
void UDataMemory_setData (UDataMemory
*This
, const void *dataAddr
) {
87 This
->pHeader
= UDataMemory_normalizeDataPointer(dataAddr
);
92 udata_close(UDataMemory
*pData
) {
94 uprv_unmapFile(pData
);
95 if(pData
->heapAllocated
) {
98 UDataMemory_init(pData
);
103 U_CAPI
const void * U_EXPORT2
104 udata_getMemory(UDataMemory
*pData
) {
105 if(pData
!=NULL
&& pData
->pHeader
!=NULL
) {
106 return (char *)(pData
->pHeader
)+udata_getHeaderSize(pData
->pHeader
);
113 * Get the length of the data item if possible.
114 * The length may be up to 15 bytes larger than the actual data.
116 * TODO Consider making this function public.
117 * It would have to return the actual length in more cases.
118 * For example, the length of the last item in a .dat package could be
119 * computed from the size of the whole .dat package minus the offset of the
121 * The size of a file that was directly memory-mapped could be determined
122 * using some system API.
124 * In order to get perfect values for all data items, we may have to add a
125 * length field to UDataInfo, but that complicates data generation
126 * and may be overkill.
128 * @param pData The data item.
129 * @return the length of the data item, or -1 if not known
130 * @internal Currently used only in cintltst/udatatst.c
132 U_CAPI
int32_t U_EXPORT2
133 udata_getLength(const UDataMemory
*pData
) {
134 if(pData
!=NULL
&& pData
->pHeader
!=NULL
&& pData
->length
>=0) {
136 * subtract the header size,
137 * return only the size of the actual data starting at udata_getMemory()
139 return pData
->length
-udata_getHeaderSize(pData
->pHeader
);
146 * Get the memory including the data header.
147 * Used in cintltst/udatatst.c
150 U_CAPI
const void * U_EXPORT2
151 udata_getRawMemory(const UDataMemory
*pData
) {
152 if(pData
!=NULL
&& pData
->pHeader
!=NULL
) {
153 return pData
->pHeader
;
159 U_CFUNC UBool
UDataMemory_isLoaded(const UDataMemory
*This
) {
160 return This
->pHeader
!= NULL
;