Line data Source code
1 : // © 2016 and later: Unicode, Inc. and others.
2 : // License & terms of use: http://www.unicode.org/copyright.html
3 : /*
4 : ******************************************************************************
5 : *
6 : * Copyright (C) 1999-2011, International Business Machines
7 : * Corporation and others. All Rights Reserved.
8 : *
9 : ******************************************************************************/
10 :
11 :
12 : /*----------------------------------------------------------------------------------
13 : *
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.)
16 : *
17 : * When an application opens ICU data (with udata_open, for example,
18 : * a UDataMemory * is returned.
19 : *
20 : *----------------------------------------------------------------------------------*/
21 :
22 : #include "unicode/utypes.h"
23 : #include "cmemory.h"
24 : #include "unicode/udata.h"
25 :
26 : #include "udatamem.h"
27 :
28 52 : U_CFUNC void UDataMemory_init(UDataMemory *This) {
29 52 : uprv_memset(This, 0, sizeof(UDataMemory));
30 52 : This->length=-1;
31 52 : }
32 :
33 :
34 12 : U_CFUNC void UDatamemory_assign(UDataMemory *dest, UDataMemory *source) {
35 : /* UDataMemory Assignment. Destination UDataMemory must be initialized first. */
36 12 : UBool mallocedFlag = dest->heapAllocated;
37 12 : uprv_memcpy(dest, source, sizeof(UDataMemory));
38 12 : dest->heapAllocated = mallocedFlag;
39 12 : }
40 :
41 16 : U_CFUNC UDataMemory *UDataMemory_createNewInstance(UErrorCode *pErr) {
42 : UDataMemory *This;
43 :
44 16 : if (U_FAILURE(*pErr)) {
45 0 : return NULL;
46 : }
47 16 : This = (UDataMemory *)uprv_malloc(sizeof(UDataMemory));
48 16 : if (This == NULL) {
49 0 : *pErr = U_MEMORY_ALLOCATION_ERROR; }
50 : else {
51 16 : UDataMemory_init(This);
52 16 : This->heapAllocated = TRUE;
53 : }
54 16 : return This;
55 : }
56 :
57 :
58 : U_CFUNC const DataHeader *
59 3 : UDataMemory_normalizeDataPointer(const void *p) {
60 : /* allow the data to be optionally prepended with an alignment-forcing double value */
61 3 : const DataHeader *pdh = (const DataHeader *)p;
62 3 : if(pdh==NULL || (pdh->dataHeader.magic1==0xda && pdh->dataHeader.magic2==0x27)) {
63 3 : return pdh;
64 : } else {
65 : #if U_PLATFORM == U_PF_OS400
66 : /*
67 : TODO: Fix this once the compiler implements this feature. Keep in sync with genccode.c
68 :
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.
73 :
74 : In order to prevent the beginning of the data from ever matching the
75 : magic numbers we must skip the initial double.
76 : [grhoten 4/24/2003]
77 : */
78 : return (const DataHeader *)*((const void **)p+1);
79 : #else
80 0 : return (const DataHeader *)((const double *)p+1);
81 : #endif
82 : }
83 : }
84 :
85 :
86 3 : U_CFUNC void UDataMemory_setData (UDataMemory *This, const void *dataAddr) {
87 3 : This->pHeader = UDataMemory_normalizeDataPointer(dataAddr);
88 3 : }
89 :
90 :
91 : U_CAPI void U_EXPORT2
92 0 : udata_close(UDataMemory *pData) {
93 0 : if(pData!=NULL) {
94 0 : uprv_unmapFile(pData);
95 0 : if(pData->heapAllocated ) {
96 0 : uprv_free(pData);
97 : } else {
98 0 : UDataMemory_init(pData);
99 : }
100 : }
101 0 : }
102 :
103 : U_CAPI const void * U_EXPORT2
104 7 : udata_getMemory(UDataMemory *pData) {
105 7 : if(pData!=NULL && pData->pHeader!=NULL) {
106 7 : return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader);
107 : } else {
108 0 : return NULL;
109 : }
110 : }
111 :
112 : /**
113 : * Get the length of the data item if possible.
114 : * The length may be up to 15 bytes larger than the actual data.
115 : *
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
120 : * last item.
121 : * The size of a file that was directly memory-mapped could be determined
122 : * using some system API.
123 : *
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.
127 : *
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
131 : */
132 : U_CAPI int32_t U_EXPORT2
133 0 : udata_getLength(const UDataMemory *pData) {
134 0 : if(pData!=NULL && pData->pHeader!=NULL && pData->length>=0) {
135 : /*
136 : * subtract the header size,
137 : * return only the size of the actual data starting at udata_getMemory()
138 : */
139 0 : return pData->length-udata_getHeaderSize(pData->pHeader);
140 : } else {
141 0 : return -1;
142 : }
143 : }
144 :
145 : /**
146 : * Get the memory including the data header.
147 : * Used in cintltst/udatatst.c
148 : * @internal
149 : */
150 : U_CAPI const void * U_EXPORT2
151 0 : udata_getRawMemory(const UDataMemory *pData) {
152 0 : if(pData!=NULL && pData->pHeader!=NULL) {
153 0 : return pData->pHeader;
154 : } else {
155 0 : return NULL;
156 : }
157 : }
158 :
159 9 : U_CFUNC UBool UDataMemory_isLoaded(const UDataMemory *This) {
160 9 : return This->pHeader != NULL;
161 : }
|