Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

uresdata.c

00001 /*
00002 *******************************************************************************
00003 *                                                                             *
00004 * Copyright (C) 1999, International Business Machines Corporation and others. *
00005 *                     All Rights Reserved.                                    *
00006 *                                                                             *
00007 *******************************************************************************
00008 *   file name:  uresdata.c
00009 *   encoding:   US-ASCII
00010 *   tab size:   8 (not used)
00011 *   indentation:4
00012 *
00013 *   created on: 1999dec08
00014 *   created by: Markus W. Scherer
00015 * Modification History:
00016 *
00017 *   Date        Name        Description
00018 *   06/20/2000  helena      OS/400 port changes; mostly typecast.
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  * Resource access helpers
00030  */
00031 
00032 /* get a const char* pointer to the key with the keyOffset byte offset from pRoot */
00033 #define RES_GET_KEY(pRoot, keyOffset) ((const char *)(pRoot)+(keyOffset))
00034 #define URESDATA_ITEM_NOT_FOUND 0xFFFF
00035 
00036 /*
00037  * All the type-access functions assume that
00038  * the resource is of the expected type.
00039  */
00040 
00041 /*
00042  * Unicode String functions
00043  *
00044  * Note that the type value for strings is 0, therefore
00045  * res itself contains the offset value.
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  * Array functions
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;   /* indexR>itemCount */
00083     }
00084 }
00085 
00086 /*
00087  * Table functions
00088  *
00089  * Important: the key offsets are 16-bit byte offsets from pRoot,
00090  * and the itemCount is one more 16-bit, too.
00091  * Thus, there are (count+1) uint16_t values.
00092  * In order to 4-align the Resource item values, there is a padding
00093  * word if count is even, i.e., there is exactly (~count&1)
00094  * 16-bit padding words.
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;    /* indexS>itemCount */
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;   /* indexR>itemCount */
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++; /* number of entries */
00123 
00124     /* do a binary search for the key */
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     /* did we really find it? */
00136     if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[start]))==0) {
00137         limit=*(p-1);   /* itemCount */
00138         return ((Resource *)(p+limit+(~limit&1)))[start];
00139     } else {
00140         return RES_BOGUS;   /* not found */
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++; /* number of entries */
00150 
00151     /* do a binary search for the key */
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     /* did we really find it? */
00163     if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[start]))==0) {
00164         limit=*(p-1);   /* itemCount */
00165         return start;
00166     } else {
00167         return URESDATA_ITEM_NOT_FOUND;   /* not found */
00168     }
00169 }
00170 
00171 /* helper for res_load() ---------------------------------------------------- */
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 &&   /* dataFormat="ResB" */
00183         pInfo->dataFormat[1]==0x65 &&
00184         pInfo->dataFormat[2]==0x73 &&
00185         pInfo->dataFormat[3]==0x42 &&
00186         pInfo->formatVersion[0]==1);
00187 }
00188 
00189 /* semi-public functions ---------------------------------------------------- */
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     /* load the ResourceBundle file */
00199     pResData->data=udata_openChoice(path, "res", name, isAcceptable, NULL, errorCode);
00200     if(U_FAILURE(*errorCode)) {
00201         return FALSE;
00202     }
00203 
00204     /* get its memory and root resource */
00205     pResData->pRoot=(Resource *)udata_getMemory(pResData->data);
00206     pResData->rootRes=*pResData->pRoot;
00207 
00208     /* currently, we accept only resources that have a Table as their roots */
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 

Generated at Tue Dec 5 10:48:11 2000 for ICU by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000