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 U_CFUNC void UDataMemory_init(UDataMemory *This) { 29 uprv_memset(This, 0, sizeof(UDataMemory)); 30 This->length=-1; 31 } 32 33 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; 39 } 40 41 U_CFUNC UDataMemory *UDataMemory_createNewInstance(UErrorCode *pErr) { 42 UDataMemory *This; 43 44 if (U_FAILURE(*pErr)) { 45 return NULL; 46 } 47 This = (UDataMemory *)uprv_malloc(sizeof(UDataMemory)); 48 if (This == NULL) { 49 *pErr = U_MEMORY_ALLOCATION_ERROR; } 50 else { 51 UDataMemory_init(This); 52 This->heapAllocated = TRUE; 53 } 54 return This; 55 } 56 57 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)) { 63 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 return (const DataHeader *)((const double *)p+1); 81 #endif 82 } 83 } 84 85 86 U_CFUNC void UDataMemory_setData (UDataMemory *This, const void *dataAddr) { 87 This->pHeader = UDataMemory_normalizeDataPointer(dataAddr); 88 } 89 90 91 U_CAPI void U_EXPORT2 92 udata_close(UDataMemory *pData) { 93 if(pData!=NULL) { 94 uprv_unmapFile(pData); 95 if(pData->heapAllocated ) { 96 uprv_free(pData); 97 } else { 98 UDataMemory_init(pData); 99 } 100 } 101 } 102 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); 107 } else { 108 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 udata_getLength(const UDataMemory *pData) { 134 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 return pData->length-udata_getHeaderSize(pData->pHeader); 140 } else { 141 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 udata_getRawMemory(const UDataMemory *pData) { 152 if(pData!=NULL && pData->pHeader!=NULL) { 153 return pData->pHeader; 154 } else { 155 return NULL; 156 } 157 } 158 159 U_CFUNC UBool UDataMemory_isLoaded(const UDataMemory *This) { 160 return This->pHeader != NULL; 161 } 162