Home | History | Annotate | Download | only in common
      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