16f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/* 26f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org****************************************************************************** 36f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 46f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Copyright (C) 1999-2011, International Business Machines 56f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* Corporation and others. All Rights Reserved. 66f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org* 76f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org******************************************************************************/ 86f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 96f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/*---------------------------------------------------------------------------------- 116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * UDataMemory A class-like struct that serves as a handle to a piece of memory 136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * that contains some ICU data (resource, converters, whatever.) 146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * When an application opens ICU data (with udata_open, for example, 166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * a UDataMemory * is returned. 176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *----------------------------------------------------------------------------------*/ 196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/utypes.h" 216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "cmemory.h" 226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "unicode/udata.h" 236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#include "udatamem.h" 256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC void UDataMemory_init(UDataMemory *This) { 276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memset(This, 0, sizeof(UDataMemory)); 286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This->length=-1; 296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC void UDatamemory_assign(UDataMemory *dest, UDataMemory *source) { 336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* UDataMemory Assignment. Destination UDataMemory must be initialized first. */ 346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UBool mallocedFlag = dest->heapAllocated; 356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_memcpy(dest, source, sizeof(UDataMemory)); 366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org dest->heapAllocated = mallocedFlag; 376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UDataMemory *UDataMemory_createNewInstance(UErrorCode *pErr) { 406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDataMemory *This; 416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (U_FAILURE(*pErr)) { 436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This = uprv_malloc(sizeof(UDataMemory)); 466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if (This == NULL) { 476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org *pErr = U_MEMORY_ALLOCATION_ERROR; } 486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org else { 496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDataMemory_init(This); 506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This->heapAllocated = TRUE; 516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return This; 536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC const DataHeader * 576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgUDataMemory_normalizeDataPointer(const void *p) { 586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* allow the data to be optionally prepended with an alignment-forcing double value */ 596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const DataHeader *pdh = (const DataHeader *)p; 606f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pdh==NULL || (pdh->dataHeader.magic1==0xda && pdh->dataHeader.magic2==0x27)) { 616f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pdh; 626f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 636f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#if U_PLATFORM == U_PF_OS400 646f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 656f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org TODO: Fix this once the compiler implements this feature. Keep in sync with genccode.c 666f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 676f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This is here because this platform can't currently put 686f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org const data into the read-only pages of an object or 696f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org shared library (service program). Only strings are allowed in read-only 706f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org pages, so we use char * strings to store the data. 716f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 726f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org In order to prevent the beginning of the data from ever matching the 736f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org magic numbers we must skip the initial double. 746f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org [grhoten 4/24/2003] 756f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 766f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (const DataHeader *)*((const void **)p+1); 776f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#else 786f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (const DataHeader *)((const double *)p+1); 796f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org#endif 806f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 816f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 826f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 836f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 846f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC void UDataMemory_setData (UDataMemory *This, const void *dataAddr) { 856f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org This->pHeader = UDataMemory_normalizeDataPointer(dataAddr); 866f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 876f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 886f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 896f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI void U_EXPORT2 906f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgudata_close(UDataMemory *pData) { 916f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pData!=NULL) { 926f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_unmapFile(pData); 936f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pData->heapAllocated ) { 946f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org uprv_free(pData); 956f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 966f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org UDataMemory_init(pData); 976f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 986f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 996f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1006f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1016f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const void * U_EXPORT2 1026f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgudata_getMemory(UDataMemory *pData) { 1036f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pData!=NULL && pData->pHeader!=NULL) { 1046f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader); 1056f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1066f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1076f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1086f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1096f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1106f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1116f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Get the length of the data item if possible. 1126f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The length may be up to 15 bytes larger than the actual data. 1136f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1146f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * TODO Consider making this function public. 1156f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * It would have to return the actual length in more cases. 1166f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * For example, the length of the last item in a .dat package could be 1176f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * computed from the size of the whole .dat package minus the offset of the 1186f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * last item. 1196f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * The size of a file that was directly memory-mapped could be determined 1206f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * using some system API. 1216f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1226f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * In order to get perfect values for all data items, we may have to add a 1236f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * length field to UDataInfo, but that complicates data generation 1246f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * and may be overkill. 1256f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * 1266f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @param pData The data item. 1276f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @return the length of the data item, or -1 if not known 1286f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @internal Currently used only in cintltst/udatatst.c 1296f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1306f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI int32_t U_EXPORT2 1316f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgudata_getLength(const UDataMemory *pData) { 1326f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pData!=NULL && pData->pHeader!=NULL && pData->length>=0) { 1336f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org /* 1346f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * subtract the header size, 1356f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * return only the size of the actual data starting at udata_getMemory() 1366f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1376f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pData->length-udata_getHeaderSize(pData->pHeader); 1386f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1396f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return -1; 1406f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1416f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1426f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1436f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org/** 1446f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Get the memory including the data header. 1456f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * Used in cintltst/udatatst.c 1466f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org * @internal 1476f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org */ 1486f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CAPI const void * U_EXPORT2 1496f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgudata_getRawMemory(const UDataMemory *pData) { 1506f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org if(pData!=NULL && pData->pHeader!=NULL) { 1516f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return pData->pHeader; 1526f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } else { 1536f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return NULL; 1546f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org } 1556f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 1566f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org 1576f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.orgU_CFUNC UBool UDataMemory_isLoaded(const UDataMemory *This) { 1586f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org return This->pHeader != NULL; 1596f31ac30b9092fd02a8c97e5216cf53f3e4fae4jshin@chromium.org} 160