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