/* ******************************************************************************* * * * Copyright (C) 1999, International Business Machines Corporation and others. * * All Rights Reserved. * * * ******************************************************************************* * file name: uresdata.c * encoding: US-ASCII * tab size: 8 (not used) * indentation:4 * * created on: 1999dec08 * created by: Markus W. Scherer */ #include "unicode/utypes.h" #include "cstring.h" #include "unicode/udata.h" #include "uresdata.h" /* * Resource access helpers */ /* get a const char* pointer to the key with the keyOffset byte offset from pRoot */ #define RES_GET_KEY(pRoot, keyOffset) ((const char *)(pRoot)+(keyOffset)) /* get signed and unsigned integer values directly from the Resource handle */ #define RES_GET_INT(res) (((int32_t)((res)<<4L))>>4L) #define RES_GET_UINT(res) ((res)&0xfffffff) /* * All the type-access functions assume that * the resource is of the expected type. */ /* * Unicode String functions * * Note that the type value for strings is 0, therefore * res itself contains the offset value. */ static const UChar nulUChar=0; static const UChar * _res_getString(Resource *pRoot, Resource res, int32_t *pLength) { if(res==0) { *pLength=0; return &nulUChar; } else { int32_t *p=(int32_t *)(pRoot+res); *pLength=*p++; return (UChar *)p; } } /* * Array functions */ static Resource _res_getArrayItem(Resource *pRoot, Resource res, int32_t index) { int32_t *p=(int32_t *)RES_GET_POINTER(pRoot, res); if(index<*p) { return ((Resource *)(p))[1+index]; } else { return RES_BOGUS; /* index>itemCount */ } } /* * Table functions * * Important: the key offsets are 16-bit byte offsets from pRoot, * and the itemCount is one more 16-bit, too. * Thus, there are (count+1) uint16_t values. * In order to 4-align the Resource item values, there is a padding * word if count is even, i.e., there is exactly (~count&1) * 16-bit padding words. */ static const char * _res_getTableKey(Resource *pRoot, Resource res, uint16_t index) { uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res); if(index<*p) { return RES_GET_KEY(pRoot, p[index+1]); } else { return NULL; /* index>itemCount */ } } static Resource _res_getTableItem(Resource *pRoot, Resource res, uint16_t index) { uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res); uint16_t count=*p; if(indexitemCount */ } } static Resource _res_findTableItem(Resource *pRoot, Resource res, const char *key) { uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res); uint16_t i, start, limit; limit=*p++; /* number of entries */ /* do a binary search for the key */ start=0; while(startsize>=20 && pInfo->isBigEndian==U_IS_BIG_ENDIAN && pInfo->charsetFamily==U_CHARSET_FAMILY && pInfo->sizeofUChar==U_SIZEOF_UCHAR && pInfo->dataFormat[0]==0x52 && /* dataFormat="ResB" */ pInfo->dataFormat[1]==0x65 && pInfo->dataFormat[2]==0x73 && pInfo->dataFormat[3]==0x42 && pInfo->formatVersion[0]==1; } /* semi-public functions ---------------------------------------------------- */ U_CFUNC bool_t res_load(ResourceData *pResData, const char *path, const char *name, UErrorCode *errorCode) { if(errorCode==NULL || U_FAILURE(*errorCode)) { return FALSE; } /* load the ResourceBundle file */ pResData->data=udata_openChoice(path, "res", name, isAcceptable, NULL, errorCode); if(U_FAILURE(*errorCode)) { return FALSE; } /* get its memory and root resource */ pResData->pRoot=(Resource *)udata_getMemory(pResData->data); pResData->rootRes=*pResData->pRoot; /* currently, we accept only resources that have a Table as their roots */ if(RES_GET_TYPE(pResData->rootRes)!=RES_TABLE) { udata_close(pResData->data); pResData->data=NULL; return FALSE; } return TRUE; } U_CFUNC void res_unload(ResourceData *pResData) { if(pResData->data!=NULL) { udata_close(pResData->data); pResData->data=NULL; } } U_CFUNC const UChar * res_getString(ResourceData *pResData, const char *key, int32_t *pLength) { Resource res=_res_findTableItem(pResData->pRoot, pResData->rootRes, key); if(res!=RES_BOGUS && RES_GET_TYPE(res)==RES_STRING) { return _res_getString(pResData->pRoot, res, pLength); } else { *pLength=0; return NULL; } } U_CFUNC Resource res_getStringArray(ResourceData *pResData, const char *key, int32_t *pCount) { Resource res=_res_findTableItem(pResData->pRoot, pResData->rootRes, key); if(res!=RES_BOGUS && RES_GET_TYPE(res)==RES_ARRAY) { Resource *p=RES_GET_POINTER(pResData->pRoot, res); int32_t count=*(int32_t *)p; *pCount=count; /* check to make sure all items are strings */ while(count>0) { if(RES_GET_TYPE(*++p)!=RES_STRING) { *pCount=0; return RES_BOGUS; } --count; } return res; } else { *pCount=0; return RES_BOGUS; } } U_CFUNC const UChar * res_getStringArrayItem(ResourceData *pResData, Resource arrayRes, int32_t index, int32_t *pLength) { return _res_getString(pResData->pRoot, _res_getArrayItem(pResData->pRoot, arrayRes, index), pLength); }