OLD | NEW |
(Empty) | |
| 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 me
mory |
| 13 * that contains some ICU data (resource, converters, whatever.
) |
| 14 * |
| 15 * When an application opens ICU data (with udata_open, for exa
mple, |
| 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 |
| 26 U_CFUNC void UDataMemory_init(UDataMemory *This) { |
| 27 uprv_memset(This, 0, sizeof(UDataMemory)); |
| 28 This->length=-1; |
| 29 } |
| 30 |
| 31 |
| 32 U_CFUNC void UDatamemory_assign(UDataMemory *dest, UDataMemory *source) { |
| 33 /* UDataMemory Assignment. Destination UDataMemory must be initialized firs
t. */ |
| 34 UBool mallocedFlag = dest->heapAllocated; |
| 35 uprv_memcpy(dest, source, sizeof(UDataMemory)); |
| 36 dest->heapAllocated = mallocedFlag; |
| 37 } |
| 38 |
| 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 * |
| 57 UDataMemory_normalizeDataPointer(const void *p) { |
| 58 /* allow the data to be optionally prepended with an alignment-forcing doubl
e value */ |
| 59 const DataHeader *pdh = (const DataHeader *)p; |
| 60 if(pdh==NULL || (pdh->dataHeader.magic1==0xda && pdh->dataHeader.magic2==0x2
7)) { |
| 61 return pdh; |
| 62 } else { |
| 63 #ifdef OS400 |
| 64 /* |
| 65 TODO: Fix this once the compiler implements this feature. Keep in sync w
ith 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 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 |
| 157 U_CFUNC UBool UDataMemory_isLoaded(const UDataMemory *This) { |
| 158 return This->pHeader != NULL; |
| 159 } |
OLD | NEW |