]> git.saurik.com Git - apple/icu.git/blame - icuSources/common/udatamem.c
ICU-400.42.tar.gz
[apple/icu.git] / icuSources / common / udatamem.c
CommitLineData
b75a7d8f
A
1/*
2******************************************************************************
3*
374ca955 4* Copyright (C) 1999-2004, International Business Machines
b75a7d8f
A
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
26void UDataMemory_init(UDataMemory *This) {
27 uprv_memset(This, 0, sizeof(UDataMemory));
374ca955 28 This->length=-1;
b75a7d8f
A
29}
30
31
32void 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
39UDataMemory *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
56const DataHeader *
57UDataMemory_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
84void UDataMemory_setData (UDataMemory *This, const void *dataAddr) {
85 This->pHeader = UDataMemory_normalizeDataPointer(dataAddr);
86}
87
88
89U_CAPI void U_EXPORT2
90udata_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
101U_CAPI const void * U_EXPORT2
102udata_getMemory(UDataMemory *pData) {
103 if(pData!=NULL && pData->pHeader!=NULL) {
374ca955 104 return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader);
b75a7d8f
A
105 } else {
106 return NULL;
107 }
108}
109
374ca955
A
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 */
130U_CAPI int32_t U_EXPORT2
131udata_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 */
148U_CAPI const void * U_EXPORT2
149udata_getRawMemory(const UDataMemory *pData) {
150 if(pData!=NULL && pData->pHeader!=NULL) {
151 return pData->pHeader;
152 } else {
153 return NULL;
154 }
155}
b75a7d8f
A
156
157UBool UDataMemory_isLoaded(UDataMemory *This) {
158 return This->pHeader != NULL;
159}
160