/*
*******************************************************************************
*                                                                             *
* 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(index<count) {
        return ((Resource *)(p+1+count+(~count&1)))[index];
    } else {
        return RES_BOGUS;   /* index>itemCount */
    }
}

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(start<limit-1) {
        i=(start+limit)/2;
        if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[i]))<0) {
            limit=i;
        } else {
            start=i;
        }
    }

    /* did we really find it? */
    if(uprv_strcmp(key, RES_GET_KEY(pRoot, p[start]))==0) {
        limit=*(p-1);   /* itemCount */
        return ((Resource *)(p+limit+(~limit&1)))[start];
    } else {
        return RES_BOGUS;   /* not found */
    }
}

/* helper for res_load() ---------------------------------------------------- */

static bool_t
isAcceptable(void *context,
             const char *type, const char *name,
             UDataInfo *pInfo) {
    return
        pInfo->size>=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);
}
