Coverage Report

Created: 2025-06-24 06:43

/src/icu/source/common/udatamem.cpp
Line
Count
Source (jump to first uncovered line)
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
0
U_CFUNC void UDataMemory_init(UDataMemory *This) {
29
0
    uprv_memset(This, 0, sizeof(UDataMemory));
30
0
    This->length=-1;
31
0
}
32
33
34
0
U_CFUNC void UDatamemory_assign(UDataMemory *dest, UDataMemory *source) {
35
    /* UDataMemory Assignment.  Destination UDataMemory must be initialized first.  */
36
0
    UBool mallocedFlag = dest->heapAllocated;
37
0
    uprv_memcpy(dest, source, sizeof(UDataMemory));
38
0
    dest->heapAllocated = mallocedFlag;
39
0
}
40
41
0
U_CFUNC UDataMemory *UDataMemory_createNewInstance(UErrorCode *pErr) {
42
0
    UDataMemory *This;
43
44
0
    if (U_FAILURE(*pErr)) {
45
0
        return NULL;
46
0
    }
47
0
    This = (UDataMemory *)uprv_malloc(sizeof(UDataMemory));
48
0
    if (This == NULL) {
49
0
        *pErr = U_MEMORY_ALLOCATION_ERROR; }
50
0
    else {
51
0
        UDataMemory_init(This);
52
0
        This->heapAllocated = TRUE;
53
0
    }
54
0
    return This;
55
0
}
56
57
58
U_CFUNC const DataHeader *
59
0
UDataMemory_normalizeDataPointer(const void *p) {
60
    /* allow the data to be optionally prepended with an alignment-forcing double value */
61
0
    const DataHeader *pdh = (const DataHeader *)p;
62
0
    if(pdh==NULL || (pdh->dataHeader.magic1==0xda && pdh->dataHeader.magic2==0x27)) {
63
0
        return pdh;
64
0
    } 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
0
        return (const DataHeader *)((const double *)p+1);
81
0
#endif
82
0
    }
83
0
}
84
85
86
0
U_CFUNC void UDataMemory_setData (UDataMemory *This, const void *dataAddr) {
87
0
    This->pHeader = UDataMemory_normalizeDataPointer(dataAddr);
88
0
}
89
90
91
U_CAPI void U_EXPORT2
92
0
udata_close(UDataMemory *pData) {
93
0
    if(pData!=NULL) {
94
0
        uprv_unmapFile(pData);
95
0
        if(pData->heapAllocated ) {
96
0
            uprv_free(pData);
97
0
        } else {
98
0
            UDataMemory_init(pData);
99
0
        }
100
0
    }
101
0
}
102
103
U_CAPI const void * U_EXPORT2
104
0
udata_getMemory(UDataMemory *pData) {
105
0
    if(pData!=NULL && pData->pHeader!=NULL) {
106
0
        return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader);
107
0
    } else {
108
0
        return NULL;
109
0
    }
110
0
}
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
0
udata_getLength(const UDataMemory *pData) {
134
0
    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
0
        return pData->length-udata_getHeaderSize(pData->pHeader);
140
0
    } else {
141
0
        return -1;
142
0
    }
143
0
}
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
0
udata_getRawMemory(const UDataMemory *pData) {
152
0
    if(pData!=NULL && pData->pHeader!=NULL) {
153
0
        return pData->pHeader;
154
0
    } else {
155
0
        return NULL;
156
0
    }
157
0
}
158
159
0
U_CFUNC UBool UDataMemory_isLoaded(const UDataMemory *This) {
160
0
    return This->pHeader != NULL;
161
0
}