1ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/* 2ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru****************************************************************************** 3ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 483a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius* Copyright (C) 1999-2011, International Business Machines 5ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 6ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru* 7ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru******************************************************************************/ 8ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 9ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 10ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/*---------------------------------------------------------------------------------- 11ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 12ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * UDataMemory A class-like struct that serves as a handle to a piece of memory 13ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * that contains some ICU data (resource, converters, whatever.) 14ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 15ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * When an application opens ICU data (with udata_open, for example, 16ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * a UDataMemory * is returned. 17ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 18ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *----------------------------------------------------------------------------------*/ 19ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 20ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/utypes.h" 21ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "cmemory.h" 22ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "unicode/udata.h" 23ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 24ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#include "udatamem.h" 25ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 2627f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CFUNC void UDataMemory_init(UDataMemory *This) { 27ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memset(This, 0, sizeof(UDataMemory)); 28ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This->length=-1; 29ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 30ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 31ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 3227f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CFUNC void UDatamemory_assign(UDataMemory *dest, UDataMemory *source) { 33ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* UDataMemory Assignment. Destination UDataMemory must be initialized first. */ 34ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UBool mallocedFlag = dest->heapAllocated; 35ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_memcpy(dest, source, sizeof(UDataMemory)); 36ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru dest->heapAllocated = mallocedFlag; 37ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 38ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 3927f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CFUNC UDataMemory *UDataMemory_createNewInstance(UErrorCode *pErr) { 40ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataMemory *This; 41ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 42ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (U_FAILURE(*pErr)) { 43ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 44ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 45ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This = uprv_malloc(sizeof(UDataMemory)); 46ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if (This == NULL) { 47ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru *pErr = U_MEMORY_ALLOCATION_ERROR; } 48ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru else { 49ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataMemory_init(This); 50ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This->heapAllocated = TRUE; 51ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 52ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return This; 53ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 54ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 55ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 5627f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CFUNC const DataHeader * 57ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruUDataMemory_normalizeDataPointer(const void *p) { 58ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* allow the data to be optionally prepended with an alignment-forcing double value */ 59ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const DataHeader *pdh = (const DataHeader *)p; 60ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pdh==NULL || (pdh->dataHeader.magic1==0xda && pdh->dataHeader.magic2==0x27)) { 61ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pdh; 62ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 6383a171d1a62abf406f7f44ae671823d5ec20db7dCraig Cornelius#if U_PLATFORM == U_PF_OS400 64ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 65ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru TODO: Fix this once the compiler implements this feature. Keep in sync with genccode.c 66ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 67ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This is here because this platform can't currently put 68ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru const data into the read-only pages of an object or 69ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru shared library (service program). Only strings are allowed in read-only 70ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru pages, so we use char * strings to store the data. 71ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 72ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru In order to prevent the beginning of the data from ever matching the 73ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru magic numbers we must skip the initial double. 74ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru [grhoten 4/24/2003] 75ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 76ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (const DataHeader *)*((const void **)p+1); 77ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#else 78ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (const DataHeader *)((const double *)p+1); 79ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru#endif 80ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 81ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 82ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 83ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 8427f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CFUNC void UDataMemory_setData (UDataMemory *This, const void *dataAddr) { 85ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru This->pHeader = UDataMemory_normalizeDataPointer(dataAddr); 86ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 87ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 88ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 89ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI void U_EXPORT2 90ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_close(UDataMemory *pData) { 91ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pData!=NULL) { 92ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_unmapFile(pData); 93ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pData->heapAllocated ) { 94ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru uprv_free(pData); 95ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 96ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru UDataMemory_init(pData); 97ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 98ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 99ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 100ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 101ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const void * U_EXPORT2 102ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_getMemory(UDataMemory *pData) { 103ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pData!=NULL && pData->pHeader!=NULL) { 104ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader); 105ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 106ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 107ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 108ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 109ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 110ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 111ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Get the length of the data item if possible. 112ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The length may be up to 15 bytes larger than the actual data. 113ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 114ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * TODO Consider making this function public. 115ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * It would have to return the actual length in more cases. 116ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * For example, the length of the last item in a .dat package could be 117ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * computed from the size of the whole .dat package minus the offset of the 118ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * last item. 119ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * The size of a file that was directly memory-mapped could be determined 120ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * using some system API. 121ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 122ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * In order to get perfect values for all data items, we may have to add a 123ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * length field to UDataInfo, but that complicates data generation 124ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * and may be overkill. 125ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * 126ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @param pData The data item. 127ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @return the length of the data item, or -1 if not known 128ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @internal Currently used only in cintltst/udatatst.c 129ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 130ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI int32_t U_EXPORT2 131ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_getLength(const UDataMemory *pData) { 132ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pData!=NULL && pData->pHeader!=NULL && pData->length>=0) { 133ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru /* 134ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * subtract the header size, 135ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * return only the size of the actual data starting at udata_getMemory() 136ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 137ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pData->length-udata_getHeaderSize(pData->pHeader); 138ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 139ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return -1; 140ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 141ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 142ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 143ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru/** 144ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Get the memory including the data header. 145ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * Used in cintltst/udatatst.c 146ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru * @internal 147ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru */ 148ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste QueruU_CAPI const void * U_EXPORT2 149ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queruudata_getRawMemory(const UDataMemory *pData) { 150ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru if(pData!=NULL && pData->pHeader!=NULL) { 151ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return pData->pHeader; 152ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } else { 153ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return NULL; 154ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru } 155ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 156ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru 15727f654740f2a26ad62a5c155af9199af9e69b889clairehoU_CFUNC UBool UDataMemory_isLoaded(const UDataMemory *This) { 158ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru return This->pHeader != NULL; 159ac04d0bbe12b3ef54518635711412f178cb4d16Jean-Baptiste Queru} 160