Coverage Report

Created: 2026-09-28 06:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/icu/icu4c/source/common/udatamem.cpp
Line
Count
Source
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
232k
U_CFUNC void UDataMemory_init(UDataMemory *This) {
29
232k
    uprv_memset(This, 0, sizeof(UDataMemory));
30
232k
    This->length=-1;
31
232k
}
32
33
34
26
U_CFUNC void UDatamemory_assign(UDataMemory *dest, UDataMemory *source) {
35
    /* UDataMemory Assignment.  Destination UDataMemory must be initialized first.  */
36
26
    UBool mallocedFlag = dest->heapAllocated;
37
26
    uprv_memcpy(dest, source, sizeof(UDataMemory));
38
26
    dest->heapAllocated = mallocedFlag;
39
26
}
40
41
27.7k
U_CFUNC UDataMemory *UDataMemory_createNewInstance(UErrorCode *pErr) {
42
27.7k
    UDataMemory *This;
43
44
27.7k
    if (U_FAILURE(*pErr)) {
45
0
        return nullptr;
46
0
    }
47
27.7k
    This = (UDataMemory *)uprv_malloc(sizeof(UDataMemory));
48
27.7k
    if (This == nullptr) {
49
0
        *pErr = U_MEMORY_ALLOCATION_ERROR; }
50
27.7k
    else {
51
27.7k
        UDataMemory_init(This);
52
27.7k
        This->heapAllocated = true;
53
27.7k
    }
54
27.7k
    return This;
55
27.7k
}
56
57
U_CFUNC const DataHeader*
58
26
UDataMemory_normalizeDataPointer(const void* p U_LIFETIME_BOUND) {
59
    /* allow the data to be optionally prepended with an alignment-forcing double value */
60
26
    const DataHeader *pdh = (const DataHeader *)p;
61
26
    if(pdh==nullptr || (pdh->dataHeader.magic1==0xda && pdh->dataHeader.magic2==0x27)) {
62
26
        return pdh;
63
26
    } else {
64
#if U_PLATFORM == U_PF_OS400
65
        /*
66
        TODO: Fix this once the compiler implements this feature. Keep in sync with genccode.c
67
68
        This is here because this platform can't currently put
69
        const data into the read-only pages of an object or
70
        shared library (service program). Only strings are allowed in read-only
71
        pages, so we use char * strings to store the data.
72
73
        In order to prevent the beginning of the data from ever matching the
74
        magic numbers we must skip the initial double.
75
        [grhoten 4/24/2003]
76
        */
77
        return (const DataHeader *)*((const void **)p+1);
78
#else
79
0
        return (const DataHeader *)((const double *)p+1);
80
0
#endif
81
0
    }
82
26
}
83
84
85
26
U_CFUNC void UDataMemory_setData (UDataMemory *This, const void *dataAddr) {
86
26
    This->pHeader = UDataMemory_normalizeDataPointer(dataAddr);
87
26
}
88
89
90
U_CAPI void U_EXPORT2
91
21.0k
udata_close(UDataMemory *pData) {
92
21.0k
    if(pData!=nullptr) {
93
21.0k
        uprv_unmapFile(pData);
94
21.0k
        if(pData->heapAllocated ) {
95
21.0k
            uprv_free(pData);
96
21.0k
        } else {
97
0
            UDataMemory_init(pData);
98
0
        }
99
21.0k
    }
100
21.0k
}
101
102
U_CAPI const void* U_EXPORT2
103
6.87k
udata_getMemory(UDataMemory* pData U_LIFETIME_BOUND) {
104
6.87k
    if(pData!=nullptr && pData->pHeader!=nullptr) {
105
6.87k
        return (char *)(pData->pHeader)+udata_getHeaderSize(pData->pHeader);
106
6.87k
    } else {
107
0
        return nullptr;
108
0
    }
109
6.87k
}
110
111
/**
112
 * Get the length of the data item if possible.
113
 * The length may be up to 15 bytes larger than the actual data.
114
 *
115
 * TODO Consider making this function public.
116
 * It would have to return the actual length in more cases.
117
 * For example, the length of the last item in a .dat package could be
118
 * computed from the size of the whole .dat package minus the offset of the
119
 * last item.
120
 * The size of a file that was directly memory-mapped could be determined
121
 * using some system API.
122
 *
123
 * In order to get perfect values for all data items, we may have to add a
124
 * length field to UDataInfo, but that complicates data generation
125
 * and may be overkill.
126
 *
127
 * @param pData The data item.
128
 * @return the length of the data item, or -1 if not known
129
 * @internal Currently used only in cintltst/udatatst.c
130
 */
131
U_CAPI int32_t U_EXPORT2
132
2
udata_getLength(const UDataMemory *pData) {
133
2
    if(pData!=nullptr && pData->pHeader!=nullptr && pData->length>=0) {
134
        /*
135
         * subtract the header size,
136
         * return only the size of the actual data starting at udata_getMemory()
137
         */
138
2
        return pData->length-udata_getHeaderSize(pData->pHeader);
139
2
    } else {
140
0
        return -1;
141
0
    }
142
2
}
143
144
/**
145
 * Get the memory including the data header.
146
 * Used in cintltst/udatatst.c
147
 * @internal
148
 */
149
U_CAPI const void* U_EXPORT2
150
0
udata_getRawMemory(const UDataMemory* pData U_LIFETIME_BOUND) {
151
0
    if(pData!=nullptr && pData->pHeader!=nullptr) {
152
0
        return pData->pHeader;
153
0
    } else {
154
0
        return nullptr;
155
0
    }
156
0
}
157
158
24
U_CFUNC UBool UDataMemory_isLoaded(const UDataMemory *This) {
159
24
    return This->pHeader != nullptr;
160
24
}