~ubuntu-branches/ubuntu/gutsy/icu/gutsy-updates

« back to all changes in this revision

Viewing changes to source/common/uresdata.c

  • Committer: Package Import Robot
  • Author(s): Jay Berkenbilt
  • Date: 2005-11-19 11:29:31 UTC
  • mfrom: (1.1.2)
  • Revision ID: package-import@ubuntu.com-20051119112931-vcizkrp10tli4enw
Tags: 3.4-3
Explicitly build with g++ 3.4.  The current ICU fails its test suite
with 4.0 but not with 3.4.  Future versions should work properly with
4.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
*******************************************************************************
3
 
*                                                                             *
4
 
* Copyright (C) 1999-2001, International Business Machines Corporation        *
5
 
*               and others. All Rights Reserved.                              *
6
 
*                                                                             *
7
 
*******************************************************************************
8
 
*   file name:  uresdata.c
9
 
*   encoding:   US-ASCII
10
 
*   tab size:   8 (not used)
11
 
*   indentation:4
12
 
*
13
 
*   created on: 1999dec08
14
 
*   created by: Markus W. Scherer
15
 
* Modification History:
16
 
*
17
 
*   Date        Name        Description
18
 
*   06/20/2000  helena      OS/400 port changes; mostly typecast.
19
 
*/
20
 
 
21
 
#include "unicode/utypes.h"
22
 
#include "cstring.h"
23
 
#include "unicode/udata.h"
24
 
#include "uresdata.h"
25
 
#include "uresimp.h"
26
 
 
27
 
/*
28
 
 * Resource access helpers
29
 
 */
30
 
 
31
 
/* get a const char* pointer to the key with the keyOffset byte offset from pRoot */
32
 
#define RES_GET_KEY(pRoot, keyOffset) ((const char *)(pRoot)+(keyOffset))
33
 
#define URESDATA_ITEM_NOT_FOUND 0xFFFF
34
 
 
35
 
/*
36
 
 * All the type-access functions assume that
37
 
 * the resource is of the expected type.
38
 
 */
39
 
 
40
 
 
41
 
/*
42
 
 * Array functions
43
 
 */
44
 
static Resource
45
 
_res_getArrayItem(Resource *pRoot, Resource res, int32_t indexR) {
46
 
    int32_t *p=(int32_t *)RES_GET_POINTER(pRoot, res);
47
 
    if(indexR<*p) {
48
 
        return ((Resource *)(p))[1+indexR];
49
 
    } else {
50
 
        return RES_BOGUS;   /* indexR>itemCount */
51
 
    }
52
 
}
53
 
 
54
 
/*
55
 
 * Table functions
56
 
 *
57
 
 * Important: the key offsets are 16-bit byte offsets from pRoot,
58
 
 * and the itemCount is one more 16-bit, too.
59
 
 * Thus, there are (count+1) uint16_t values.
60
 
 * In order to 4-align the Resource item values, there is a padding
61
 
 * word if count is even, i.e., there is exactly (~count&1)
62
 
 * 16-bit padding words.
63
 
 */
64
 
static const char *
65
 
_res_getTableKey(const Resource *pRoot, const Resource res, uint16_t indexS) {
66
 
    uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res);
67
 
    if(indexS<*p) {
68
 
        return RES_GET_KEY(pRoot, p[indexS+1]);
69
 
    } else {
70
 
        return NULL;    /* indexS>itemCount */
71
 
    }
72
 
}
73
 
 
74
 
static Resource
75
 
_res_getTableItem(const Resource *pRoot, const Resource res, uint16_t indexR) {
76
 
    uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res);
77
 
    uint16_t count=*p;
78
 
    if(indexR<count) {
79
 
        return ((Resource *)(p+1+count+(~count&1)))[indexR];
80
 
    } else {
81
 
        return RES_BOGUS;   /* indexR>itemCount */
82
 
    }
83
 
}
84
 
 
85
 
static Resource
86
 
_res_findTableItem(const Resource *pRoot, const Resource res, const char *key) {
87
 
    uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res);
88
 
    uint16_t i, start, limit;
89
 
 
90
 
    limit=*p++; /* number of entries */
91
 
 
92
 
    if(limit == 0) { /* this table is empty */
93
 
      return RES_BOGUS;
94
 
    }
95
 
 
96
 
    /* do a binary search for the key */
97
 
    start=0;
98
 
    while(start<limit-1) {
99
 
        i=(uint16_t)((start+limit)/2);
100
 
        if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[i]))<0) {
101
 
            limit=i;
102
 
        } else {
103
 
            start=i;
104
 
        }
105
 
    }
106
 
 
107
 
    /* did we really find it? */
108
 
    if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[start]))==0) {
109
 
        limit=*(p-1);   /* itemCount */
110
 
        return ((Resource *)(p+limit+(~limit&1)))[start];
111
 
    } else {
112
 
        return RES_BOGUS;   /* not found */
113
 
    }
114
 
}
115
 
 
116
 
static uint16_t
117
 
_res_findTableIndex(const Resource *pRoot, const Resource res, const char *key) {
118
 
    uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res);
119
 
    uint16_t i, start, limit;
120
 
 
121
 
    limit=*p++; /* number of entries */
122
 
 
123
 
    if(limit == 0) { /* this table is empty */
124
 
      return URESDATA_ITEM_NOT_FOUND;
125
 
    }
126
 
 
127
 
    /* do a binary search for the key */
128
 
    start=0;
129
 
    while(start<limit-1) {
130
 
        i=(uint16_t)((start+limit)/2);
131
 
        if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[i]))<0) {
132
 
            limit=i;
133
 
        } else {
134
 
            start=i;
135
 
        }
136
 
    }
137
 
    
138
 
    /* did we really find it? */
139
 
    if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[start]))==0) {
140
 
        limit=*(p-1);   /* itemCount */
141
 
        return start;
142
 
    } else {
143
 
        return URESDATA_ITEM_NOT_FOUND;   /* not found */
144
 
    }
145
 
}
146
 
 
147
 
/* helper for res_load() ---------------------------------------------------- */
148
 
 
149
 
static UBool
150
 
isAcceptable(void *context,
151
 
             const char *type, const char *name,
152
 
             const UDataInfo *pInfo) {
153
 
    return (UBool)(
154
 
        pInfo->size>=20 &&
155
 
        pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
156
 
        pInfo->charsetFamily==U_CHARSET_FAMILY &&
157
 
        pInfo->sizeofUChar==U_SIZEOF_UCHAR &&
158
 
        pInfo->dataFormat[0]==0x52 &&   /* dataFormat="ResB" */
159
 
        pInfo->dataFormat[1]==0x65 &&
160
 
        pInfo->dataFormat[2]==0x73 &&
161
 
        pInfo->dataFormat[3]==0x42 &&
162
 
        pInfo->formatVersion[0]==1);
163
 
}
164
 
 
165
 
/* semi-public functions ---------------------------------------------------- */
166
 
 
167
 
U_CFUNC UBool
168
 
res_load(ResourceData *pResData,
169
 
         const char *path, const char *name, UErrorCode *errorCode) {
170
 
    /* load the ResourceBundle file */
171
 
    pResData->data=udata_openChoice(path, "res", name, isAcceptable, NULL, errorCode);
172
 
    if(U_FAILURE(*errorCode)) {
173
 
        return FALSE;
174
 
    }
175
 
 
176
 
    /* get its memory and root resource */
177
 
    pResData->pRoot=(Resource *)udata_getMemory(pResData->data);
178
 
    pResData->rootRes=*pResData->pRoot;
179
 
 
180
 
    /* currently, we accept only resources that have a Table as their roots */
181
 
    if(RES_GET_TYPE(pResData->rootRes)!=RES_TABLE) {
182
 
        udata_close(pResData->data);
183
 
        pResData->data=NULL; 
184
 
        return FALSE;
185
 
    }
186
 
 
187
 
    return TRUE;
188
 
}
189
 
 
190
 
U_CFUNC void
191
 
res_unload(ResourceData *pResData) {
192
 
    if(pResData->data!=NULL) {
193
 
        udata_close(pResData->data);
194
 
        pResData->data=NULL;
195
 
    }
196
 
}
197
 
 
198
 
U_CFUNC const UChar *
199
 
res_getString(const ResourceData *pResData, const Resource res, int32_t *pLength) {
200
 
    if(res!=RES_BOGUS && RES_GET_TYPE(res)==RES_STRING) {
201
 
        int32_t *p=(int32_t *)RES_GET_POINTER(pResData->pRoot, res);
202
 
        if (pLength) {
203
 
            *pLength=*p;
204
 
        }
205
 
        return (UChar *)++p;
206
 
    } else {
207
 
        if (pLength) {
208
 
            *pLength=0;
209
 
        }
210
 
        return NULL;
211
 
    }
212
 
}
213
 
 
214
 
U_CFUNC const uint8_t *
215
 
res_getBinary(const ResourceData *pResData, const Resource res, int32_t *pLength) {
216
 
    if(res!=RES_BOGUS) {
217
 
        int32_t *p=(int32_t *)RES_GET_POINTER(pResData->pRoot, res);
218
 
        *pLength=*p++;
219
 
        if (*pLength == 0) {
220
 
            p = NULL;
221
 
        }
222
 
        return (uint8_t *)p;
223
 
    } else {
224
 
        *pLength=0;
225
 
        return NULL;
226
 
    }
227
 
}
228
 
 
229
 
 
230
 
U_CFUNC const int32_t *
231
 
res_getIntVector(const ResourceData *pResData, const Resource res, int32_t *pLength) {
232
 
    if(res!=RES_BOGUS && RES_GET_TYPE(res)==RES_INT_VECTOR) {
233
 
        int32_t *p=(int32_t *)RES_GET_POINTER(pResData->pRoot, res);
234
 
        *pLength=*p++;
235
 
        if (*pLength == 0) {
236
 
            p = NULL;
237
 
        }
238
 
        return (const int32_t *)p;
239
 
    } else {
240
 
        *pLength=0;
241
 
        return NULL;
242
 
    }
243
 
}
244
 
 
245
 
U_CFUNC int32_t
246
 
res_countArrayItems(const ResourceData *pResData, const Resource res) {
247
 
    if(res!=RES_BOGUS) {
248
 
        if(RES_GET_TYPE(res)==RES_STRING) {
249
 
            return 1;
250
 
        } else if(RES_GET_TYPE(res)==RES_ARRAY) {
251
 
            Resource *p=RES_GET_POINTER(pResData->pRoot, res);
252
 
            int32_t count=*(int32_t *)p;   
253
 
            return count;
254
 
        } else if(RES_GET_TYPE(res)==RES_TABLE) {
255
 
            return res_getTableSize(pResData, res);
256
 
        }
257
 
    } 
258
 
    return 0;
259
 
}
260
 
 
261
 
U_CFUNC Resource
262
 
res_getResource(const ResourceData *pResData, const char *key) {
263
 
    return _res_findTableItem(pResData->pRoot, pResData->rootRes, key);
264
 
}
265
 
 
266
 
U_CFUNC Resource 
267
 
res_getArrayItem(const ResourceData *pResData, const Resource array, const int32_t indexR) {
268
 
    return _res_getArrayItem(pResData->pRoot, array, indexR);
269
 
}
270
 
 
271
 
U_CFUNC Resource 
272
 
res_getTableItemByKey(const ResourceData *pResData, const Resource table, int32_t* indexR, const char* *  key) {
273
 
    uint16_t tempIndex;
274
 
    if(key != NULL) {
275
 
        tempIndex  = _res_findTableIndex(pResData->pRoot, table, *key);
276
 
        if(tempIndex != URESDATA_ITEM_NOT_FOUND) {
277
 
            *key = _res_getTableKey(pResData->pRoot, table, tempIndex);
278
 
            *indexR = tempIndex;
279
 
            return _res_getTableItem(pResData->pRoot, table, tempIndex);
280
 
        } else {
281
 
            return RES_BOGUS;
282
 
        }
283
 
    } else {
284
 
        return RES_BOGUS;
285
 
    }
286
 
}
287
 
 
288
 
U_CFUNC Resource 
289
 
res_getTableItemByIndex(const ResourceData *pResData, const Resource table, int32_t indexR, const char * * key) {
290
 
    if(indexR>-1) {
291
 
        if(key != NULL) {
292
 
            *key = _res_getTableKey(pResData->pRoot, table, (uint16_t)indexR);
293
 
        }
294
 
        return _res_getTableItem(pResData->pRoot, table, (uint16_t)indexR);
295
 
    } else {
296
 
        return RES_BOGUS;
297
 
    }
298
 
}
299
 
 
300
 
U_CFUNC int32_t 
301
 
res_getTableSize(const ResourceData *pResData, Resource table) {
302
 
    uint16_t *p=(uint16_t *)RES_GET_POINTER(pResData->pRoot, table);
303
 
    return *p;
304
 
}
305