From 4c2da3984938e560fadec66b050c78d4ba182976 Mon Sep 17 00:00:00 2001 From: Markus Scherer Date: Thu, 9 Dec 1999 18:35:11 +0000 Subject: [PATCH] ICU-184 first code for udata-style .res files with C access implementation X-SVN-Rev: 360 --- icu4c/source/common/common.dsp | 8 ++ icu4c/source/common/uresdata.c | 224 +++++++++++++++++++++++++++++++++ icu4c/source/common/uresdata.h | 116 +++++++++++++++++ 3 files changed, 348 insertions(+) create mode 100644 icu4c/source/common/uresdata.c create mode 100644 icu4c/source/common/uresdata.h diff --git a/icu4c/source/common/common.dsp b/icu4c/source/common/common.dsp index 2b6faedba80..0542c38ae03 100644 --- a/icu4c/source/common/common.dsp +++ b/icu4c/source/common/common.dsp @@ -261,6 +261,10 @@ SOURCE=.\ures.cpp # End Source File # Begin Source File +SOURCE=.\uresdata.c +# End Source File +# Begin Source File + SOURCE=.\ustring.c # End Source File # Begin Source File @@ -990,6 +994,10 @@ InputPath=.\ures.h # End Source File # Begin Source File +SOURCE=.\uresdata.h +# End Source File +# Begin Source File + SOURCE=.\ustring.h !IF "$(CFG)" == "common - Win32 Release" diff --git a/icu4c/source/common/uresdata.c b/icu4c/source/common/uresdata.c new file mode 100644 index 00000000000..7f84465bf5e --- /dev/null +++ b/icu4c/source/common/uresdata.c @@ -0,0 +1,224 @@ +/* +******************************************************************************* +* * +* 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 "utypes.h" +#include "cstring.h" +#include "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]==0x55 && /* dataFormat="UPro" */ + pInfo->dataFormat[1]==0x50 && + pInfo->dataFormat[2]==0x72 && + pInfo->dataFormat[3]==0x6f && + 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); +} diff --git a/icu4c/source/common/uresdata.h b/icu4c/source/common/uresdata.h new file mode 100644 index 00000000000..5c75862441a --- /dev/null +++ b/icu4c/source/common/uresdata.h @@ -0,0 +1,116 @@ +/* +******************************************************************************* +* * +* Copyright (C) 1999, International Business Machines Corporation and others. * +* All Rights Reserved. * +* * +******************************************************************************* +* file name: uresdata.h +* encoding: US-ASCII +* tab size: 8 (not used) +* indentation:4 +* +* created on: 1999dec08 +* created by: Markus W. Scherer +*/ + +#ifndef __RESDATA_H__ +#define __RESDATA_H__ + +#include "utypes.h" +#include "udata.h" + +/* + * A Resource is a 32-bit value that has 2 bit fields: + * 31..28 4-bit type, see enum below + * 27..0 28-bit four-byte-offset or value according to the type + */ +typedef uint32_t Resource; + +#define RES_BOGUS 0xffffffff + +#define RES_GET_TYPE(res) ((res)>>28UL) +#define RES_GET_OFFSET(res) ((res)&0xfffffff) +#define RES_GET_POINTER(pRoot, res) ((pRoot)+RES_GET_OFFSET(res)) + +/* + * Resource types: + * Most resources have their values stored at four-byte offsets from the start + * of the resource data. These values are at least 4-aligned. + * Some resource values are stored directly in the offset field of the Resource itself. + * + * Type Name Memory layout of values + * (in parentheses: scalar, non-offset values) + * + * 0 Unicode String: int32_t length, UChar[length], (UChar)0, (padding) + * or (empty string ("") if offset==0) + * + * 1 Integer Vector: int32_t length, int32_t[length] + * 2 Binary: int32_t length, uint8_t[length], (padding) + * - this value should be 16-aligned - + * + * 7 Integer: (28-bit offset is integer value) + * + * 14 Array: int32_t count, Resource[count] + * 15 Table: uint16_t count, uint16_t keyStringOffsets[count], (uint16_t padding), Resource[count] + */ +enum { + RES_STRING, + RES_INT_VECTOR, + RES_BINARY, + + RES_INT=7, + + RES_ARRAY=14, + RES_TABLE +}; + +/* + * Structure for a single, memory-mapped ResourceBundle. + */ +typedef struct { + UDataMemory *data; + Resource *pRoot; + Resource rootRes; +} ResourceData; + +/* + * Load a resource bundle file. + * The ResourceData structure must be allocated externally. + */ +U_CFUNC bool_t +res_load(ResourceData *pResData, + const char *path, const char *name, UErrorCode *errorCode); + +/* + * Release a resource bundle file. + * This does not release the ResourceData structure itself. + */ +U_CFUNC void +res_unload(ResourceData *pResData); + +/* + * Return a pointer to a zero-terminated, const UChar* string + * and set its length in *pLength. + * Returns NULL if not found. + */ +U_CFUNC const UChar * +res_getString(ResourceData *pResData, const char *key, int32_t *pLength); + +/* + * Get a Resource handle for an array of strings, and get the number of strings. + * Returns RES_BOGUS if not found. + */ +U_CFUNC Resource +res_getStringArray(ResourceData *pResData, const char *key, int32_t *pCount); + +/* + * Get a string from a string array. + * This assumes that arrayRes is a valid handle to an array of strings as returned + * by res_getStringArray(), and that index is within bounds. + */ +U_CFUNC const UChar * +res_getStringArrayItem(ResourceData *pResData, + Resource arrayRes, int32_t index, int32_t *pLength); + +#endif