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