1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/common/udatamem.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,159 @@ 1.4 +/* 1.5 +****************************************************************************** 1.6 +* 1.7 +* Copyright (C) 1999-2011, International Business Machines 1.8 +* Corporation and others. All Rights Reserved. 1.9 +* 1.10 +******************************************************************************/ 1.11 + 1.12 + 1.13 +/*---------------------------------------------------------------------------------- 1.14 + * 1.15 + * UDataMemory A class-like struct that serves as a handle to a piece of memory 1.16 + * that contains some ICU data (resource, converters, whatever.) 1.17 + * 1.18 + * When an application opens ICU data (with udata_open, for example, 1.19 + * a UDataMemory * is returned. 1.20 + * 1.21 + *----------------------------------------------------------------------------------*/ 1.22 + 1.23 +#include "unicode/utypes.h" 1.24 +#include "cmemory.h" 1.25 +#include "unicode/udata.h" 1.26 + 1.27 +#include "udatamem.h" 1.28 + 1.29 +U_CFUNC void UDataMemory_init(UDataMemory *This) { 1.30 + uprv_memset(This, 0, sizeof(UDataMemory)); 1.31 + This->length=-1; 1.32 +} 1.33 + 1.34 + 1.35 +U_CFUNC void UDatamemory_assign(UDataMemory *dest, UDataMemory *source) { 1.36 + /* UDataMemory Assignment. Destination UDataMemory must be initialized first. */ 1.37 + UBool mallocedFlag = dest->heapAllocated; 1.38 + uprv_memcpy(dest, source, sizeof(UDataMemory)); 1.39 + dest->heapAllocated = mallocedFlag; 1.40 +} 1.41 + 1.42 +U_CFUNC UDataMemory *UDataMemory_createNewInstance(UErrorCode *pErr) { 1.43 + UDataMemory *This; 1.44 + 1.45 + if (U_FAILURE(*pErr)) { 1.46 + return NULL; 1.47 + } 1.48 + This = uprv_malloc(sizeof(UDataMemory)); 1.49 + if (This == NULL) { 1.50 + *pErr = U_MEMORY_ALLOCATION_ERROR; } 1.51 + else { 1.52 + UDataMemory_init(This); 1.53 + This->heapAllocated = TRUE; 1.54 + } 1.55 + return This; 1.56 +} 1.57 + 1.58 + 1.59 +U_CFUNC const DataHeader * 1.60 +UDataMemory_normalizeDataPointer(const void *p) { 1.61 + /* allow the data to be optionally prepended with an alignment-forcing double value */ 1.62 + const DataHeader *pdh = (const DataHeader *)p; 1.63 + if(pdh==NULL || (pdh->dataHeader.magic1==0xda && pdh->dataHeader.magic2==0x27)) { 1.64 + return pdh; 1.65 + } else { 1.66 +#if U_PLATFORM == U_PF_OS400 1.67 + /* 1.68 + TODO: Fix this once the compiler implements this feature. Keep in sync with genccode.c 1.69 + 1.70 + This is here because this platform can't currently put 1.71 + const data into the read-only pages of an object or 1.72 + shared library (service program). Only strings are allowed in read-only 1.73 + pages, so we use char * strings to store the data. 1.74 + 1.75 + In order to prevent the beginning of the data from ever matching the 1.76 + magic numbers we must skip the initial double. 1.77 + [grhoten 4/24/2003] 1.78 + */ 1.79 + return (const DataHeader *)*((const void **)p+1); 1.80 +#else 1.81 + return (const DataHeader *)((const double *)p+1); 1.82 +#endif 1.83 + } 1.84 +} 1.85 + 1.86 + 1.87 +U_CFUNC void UDataMemory_setData (UDataMemory *This, const void *dataAddr) { 1.88 + This->pHeader = UDataMemory_normalizeDataPointer(dataAddr); 1.89 +} 1.90 + 1.91 + 1.92 +U_CAPI void U_EXPORT2 1.93 +udata_close(UDataMemory *pData) { 1.94 + if(pData!=NULL) { 1.95 + uprv_unmapFile(pData); 1.96 + if(pData->heapAllocated ) { 1.97 + uprv_free(pData); 1.98 + } else { 1.99 + UDataMemory_init(pData); 1.100 + } 1.101 + } 1.102 +} 1.103 + 1.104 +U_CAPI const void * U_EXPORT2 1.105 +udata_getMemory(UDataMemory *pData) { 1.106 + if(pData!=NULL && pData->pHeader!=NULL) { 1.107 + return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader); 1.108 + } else { 1.109 + return NULL; 1.110 + } 1.111 +} 1.112 + 1.113 +/** 1.114 + * Get the length of the data item if possible. 1.115 + * The length may be up to 15 bytes larger than the actual data. 1.116 + * 1.117 + * TODO Consider making this function public. 1.118 + * It would have to return the actual length in more cases. 1.119 + * For example, the length of the last item in a .dat package could be 1.120 + * computed from the size of the whole .dat package minus the offset of the 1.121 + * last item. 1.122 + * The size of a file that was directly memory-mapped could be determined 1.123 + * using some system API. 1.124 + * 1.125 + * In order to get perfect values for all data items, we may have to add a 1.126 + * length field to UDataInfo, but that complicates data generation 1.127 + * and may be overkill. 1.128 + * 1.129 + * @param pData The data item. 1.130 + * @return the length of the data item, or -1 if not known 1.131 + * @internal Currently used only in cintltst/udatatst.c 1.132 + */ 1.133 +U_CAPI int32_t U_EXPORT2 1.134 +udata_getLength(const UDataMemory *pData) { 1.135 + if(pData!=NULL && pData->pHeader!=NULL && pData->length>=0) { 1.136 + /* 1.137 + * subtract the header size, 1.138 + * return only the size of the actual data starting at udata_getMemory() 1.139 + */ 1.140 + return pData->length-udata_getHeaderSize(pData->pHeader); 1.141 + } else { 1.142 + return -1; 1.143 + } 1.144 +} 1.145 + 1.146 +/** 1.147 + * Get the memory including the data header. 1.148 + * Used in cintltst/udatatst.c 1.149 + * @internal 1.150 + */ 1.151 +U_CAPI const void * U_EXPORT2 1.152 +udata_getRawMemory(const UDataMemory *pData) { 1.153 + if(pData!=NULL && pData->pHeader!=NULL) { 1.154 + return pData->pHeader; 1.155 + } else { 1.156 + return NULL; 1.157 + } 1.158 +} 1.159 + 1.160 +U_CFUNC UBool UDataMemory_isLoaded(const UDataMemory *This) { 1.161 + return This->pHeader != NULL; 1.162 +}