00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "unicode/utypes.h"
00022 #include "cstring.h"
00023 #include "cmemory.h"
00024 #include "unicode/udata.h"
00025 #include "uresdata.h"
00026 #include "uresimp.h"
00027
00028
00029
00030
00031
00032
00033 #define RES_GET_KEY(pRoot, keyOffset) ((const char *)(pRoot)+(keyOffset))
00034 #define URESDATA_ITEM_NOT_FOUND 0xFFFF
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 static const UChar nulUChar=0;
00048
00049 static const UChar *
00050 _res_getString(Resource *pRoot, Resource res, int32_t *pLength) {
00051 if(res==0) {
00052 *pLength=0;
00053 return &nulUChar;
00054 } else {
00055 int32_t *p=(int32_t *)RES_GET_POINTER(pRoot, res);
00056 *pLength=*p++;
00057 return (UChar *)p;
00058 }
00059 }
00060
00061 static const uint8_t *
00062 _res_getBinary(Resource *pRoot, Resource res, int32_t *pLength) {
00063 if(res==0) {
00064 *pLength=0;
00065 return NULL;
00066 } else {
00067 int32_t *p=(int32_t *)RES_GET_POINTER(pRoot, res);
00068 *pLength=*p++;
00069 return (uint8_t *)p;
00070 }
00071 }
00072
00073
00074
00075
00076 static Resource
00077 _res_getArrayItem(Resource *pRoot, Resource res, int32_t indexR) {
00078 int32_t *p=(int32_t *)RES_GET_POINTER(pRoot, res);
00079 if(indexR<*p) {
00080 return ((Resource *)(p))[1+indexR];
00081 } else {
00082 return RES_BOGUS;
00083 }
00084 }
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096 static const char *
00097 _res_getTableKey(const Resource *pRoot, const Resource res, uint16_t indexS) {
00098 uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res);
00099 if(indexS<*p) {
00100 return RES_GET_KEY(pRoot, p[indexS+1]);
00101 } else {
00102 return NULL;
00103 }
00104 }
00105
00106 static Resource
00107 _res_getTableItem(const Resource *pRoot, const Resource res, uint16_t indexR) {
00108 uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res);
00109 uint16_t count=*p;
00110 if(indexR<count) {
00111 return ((Resource *)(p+1+count+(~count&1)))[indexR];
00112 } else {
00113 return RES_BOGUS;
00114 }
00115 }
00116
00117 static Resource
00118 _res_findTableItem(const Resource *pRoot, const Resource res, const char *key) {
00119 uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res);
00120 uint16_t i, start, limit;
00121
00122 limit=*p++;
00123
00124
00125 start=0;
00126 while(start<limit-1) {
00127 i=(uint16_t)((start+limit)/2);
00128 if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[i]))<0) {
00129 limit=i;
00130 } else {
00131 start=i;
00132 }
00133 }
00134
00135
00136 if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[start]))==0) {
00137 limit=*(p-1);
00138 return ((Resource *)(p+limit+(~limit&1)))[start];
00139 } else {
00140 return RES_BOGUS;
00141 }
00142 }
00143
00144 static uint16_t
00145 _res_findTableIndex(const Resource *pRoot, const Resource res, const char *key) {
00146 uint16_t *p=(uint16_t *)RES_GET_POINTER(pRoot, res);
00147 uint16_t i, start, limit;
00148
00149 limit=*p++;
00150
00151
00152 start=0;
00153 while(start<limit-1) {
00154 i=(uint16_t)((start+limit)/2);
00155 if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[i]))<0) {
00156 limit=i;
00157 } else {
00158 start=i;
00159 }
00160 }
00161
00162
00163 if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[start]))==0) {
00164 limit=*(p-1);
00165 return start;
00166 } else {
00167 return URESDATA_ITEM_NOT_FOUND;
00168 }
00169 }
00170
00171
00172
00173 static UBool
00174 isAcceptable(void *context,
00175 const char *type, const char *name,
00176 const UDataInfo *pInfo) {
00177 return (UBool)(
00178 pInfo->size>=20 &&
00179 pInfo->isBigEndian==U_IS_BIG_ENDIAN &&
00180 pInfo->charsetFamily==U_CHARSET_FAMILY &&
00181 pInfo->sizeofUChar==U_SIZEOF_UCHAR &&
00182 pInfo->dataFormat[0]==0x52 &&
00183 pInfo->dataFormat[1]==0x65 &&
00184 pInfo->dataFormat[2]==0x73 &&
00185 pInfo->dataFormat[3]==0x42 &&
00186 pInfo->formatVersion[0]==1);
00187 }
00188
00189
00190
00191 U_CFUNC UBool
00192 res_load(ResourceData *pResData,
00193 const char *path, const char *name, UErrorCode *errorCode) {
00194 if(errorCode==NULL || U_FAILURE(*errorCode)) {
00195 return FALSE;
00196 }
00197
00198
00199 pResData->data=udata_openChoice(path, "res", name, isAcceptable, NULL, errorCode);
00200 if(U_FAILURE(*errorCode)) {
00201 return FALSE;
00202 }
00203
00204
00205 pResData->pRoot=(Resource *)udata_getMemory(pResData->data);
00206 pResData->rootRes=*pResData->pRoot;
00207
00208
00209 if(RES_GET_TYPE(pResData->rootRes)!=RES_TABLE) {
00210 udata_close(pResData->data);
00211 pResData->data=NULL;
00212 return FALSE;
00213 }
00214
00215 return TRUE;
00216 }
00217
00218 U_CFUNC void
00219 res_unload(ResourceData *pResData) {
00220 if(pResData->data!=NULL) {
00221 udata_close(pResData->data);
00222 pResData->data=NULL;
00223 }
00224 }
00225
00226 U_CFUNC const UChar *
00227 res_getString(const ResourceData *pResData, const Resource res, int32_t *pLength) {
00228 if(res!=RES_BOGUS && RES_GET_TYPE(res)==RES_STRING) {
00229 return _res_getString(pResData->pRoot, res, pLength);
00230 } else {
00231 *pLength=0;
00232 return NULL;
00233 }
00234 }
00235
00236 U_CFUNC const uint8_t *
00237 res_getBinary(const ResourceData *pResData, const Resource res, int32_t *pLength) {
00238 if(res!=RES_BOGUS && RES_GET_TYPE(res)==RES_BINARY) {
00239 return _res_getBinary(pResData->pRoot, res, pLength);
00240 } else {
00241 *pLength=0;
00242 return NULL;
00243 }
00244 }
00245
00246 U_CFUNC int32_t
00247 res_countArrayItems(const ResourceData *pResData, const Resource res) {
00248 if(res!=RES_BOGUS) {
00249 if(RES_GET_TYPE(res)==RES_STRING) {
00250 return 1;
00251 } else if(RES_GET_TYPE(res)==RES_ARRAY) {
00252 Resource *p=RES_GET_POINTER(pResData->pRoot, res);
00253 int32_t count=*(int32_t *)p;
00254 return count;
00255 } else if(RES_GET_TYPE(res)==RES_TABLE) {
00256 return res_getTableSize(pResData, res);
00257 }
00258 }
00259 return 0;
00260 }
00261
00262 U_CFUNC Resource
00263 res_getResource(const ResourceData *pResData, const char *key) {
00264 return _res_findTableItem(pResData->pRoot, pResData->rootRes, key);
00265 }
00266
00267 U_CFUNC Resource res_getArrayItem(const ResourceData *pResData, const Resource array, const int32_t indexR) {
00268 return _res_getArrayItem(pResData->pRoot, array, indexR);
00269 }
00270
00271 U_CFUNC Resource res_getTableItemByKey(const ResourceData *pResData, const Resource table, int32_t* indexR, const char* * key) {
00272 uint16_t tempIndex;
00273 if(key != NULL) {
00274 tempIndex = _res_findTableIndex(pResData->pRoot, table, *key);
00275 if(tempIndex != URESDATA_ITEM_NOT_FOUND) {
00276 *key = _res_getTableKey(pResData->pRoot, table, tempIndex);
00277 *indexR = tempIndex;
00278 return _res_getTableItem(pResData->pRoot, table, tempIndex);
00279 } else {
00280 return RES_BOGUS;
00281 }
00282 } else {
00283 return RES_BOGUS;
00284 }
00285 }
00286
00287 U_CFUNC Resource res_getTableItemByIndex(const ResourceData *pResData, const Resource table, int32_t indexR, const char * * key) {
00288 if(indexR>-1) {
00289 if(key != NULL) {
00290 *key = _res_getTableKey(pResData->pRoot, table, (uint16_t)indexR);
00291 }
00292 return _res_getTableItem(pResData->pRoot, table, (uint16_t)indexR);
00293 } else {
00294 return RES_BOGUS;
00295 }
00296 }
00297
00298 U_CFUNC int32_t res_getTableSize(const ResourceData *pResData, Resource table) {
00299 uint16_t *p=(uint16_t *)RES_GET_POINTER(pResData->pRoot, table);
00300 return *p;
00301 }
00302
00303 U_CFUNC void
00304 res_getNextStringTableItem(const ResourceData *pResData, Resource table, const UChar **value, const char **key, int32_t *len, int16_t *indexS) {
00305 Resource next;
00306 if(*indexS == -1) {
00307 *indexS = 0;
00308 }
00309 next = _res_getTableItem(pResData->pRoot, table, *indexS);
00310 if ((next == RES_BOGUS) || (RES_GET_TYPE(next) != RES_STRING)) {
00311 *key = NULL;
00312 *value = NULL;
00313 len = 0;
00314 return;
00315 }
00316 *key = _res_getTableKey(pResData->pRoot, table, *indexS);
00317 (*indexS)++;
00318 *value = _res_getString(pResData->pRoot, next, len);
00319 }
00320