michael@0: /******************************************************************** michael@0: * COPYRIGHT: michael@0: * Copyright (c) 2002-2006, International Business Machines Corporation and michael@0: * others. All Rights Reserved. michael@0: ********************************************************************/ michael@0: michael@0: /* Created by weiv 05/09/2002 */ michael@0: michael@0: #include "unicode/datamap.h" michael@0: #include "unicode/resbund.h" michael@0: #include "hash.h" michael@0: #include michael@0: michael@0: DataMap::~DataMap() {} michael@0: DataMap::DataMap() {} michael@0: michael@0: int32_t michael@0: DataMap::utoi(const UnicodeString &s) const michael@0: { michael@0: char ch[256]; michael@0: const UChar *u = s.getBuffer(); michael@0: int32_t len = s.length(); michael@0: u_UCharsToChars(u, ch, len); michael@0: ch[len] = 0; /* include terminating \0 */ michael@0: return atoi(ch); michael@0: } michael@0: michael@0: U_CDECL_BEGIN michael@0: void U_CALLCONV michael@0: deleteResBund(void *obj) { michael@0: delete (ResourceBundle *)obj; michael@0: } michael@0: U_CDECL_END michael@0: michael@0: michael@0: RBDataMap::~RBDataMap() michael@0: { michael@0: delete fData; michael@0: } michael@0: michael@0: RBDataMap::RBDataMap() michael@0: { michael@0: UErrorCode status = U_ZERO_ERROR; michael@0: fData = new Hashtable(TRUE, status); michael@0: fData->setValueDeleter(deleteResBund); michael@0: } michael@0: michael@0: // init from table resource michael@0: // will put stuff in hashtable according to michael@0: // keys. michael@0: RBDataMap::RBDataMap(UResourceBundle *data, UErrorCode &status) michael@0: { michael@0: fData = new Hashtable(TRUE, status); michael@0: fData->setValueDeleter(deleteResBund); michael@0: init(data, status); michael@0: } michael@0: michael@0: // init from headers and resource michael@0: // with checking the whether the size of resource matches michael@0: // header size michael@0: RBDataMap::RBDataMap(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status) michael@0: { michael@0: fData = new Hashtable(TRUE, status); michael@0: fData->setValueDeleter(deleteResBund); michael@0: init(headers, data, status); michael@0: } michael@0: michael@0: michael@0: void RBDataMap::init(UResourceBundle *data, UErrorCode &status) { michael@0: int32_t i = 0; michael@0: fData->removeAll(); michael@0: UResourceBundle *t = NULL; michael@0: for(i = 0; i < ures_getSize(data); i++) { michael@0: t = ures_getByIndex(data, i, t, &status); michael@0: fData->put(UnicodeString(ures_getKey(t), -1, US_INV), new ResourceBundle(t, status), status); michael@0: } michael@0: ures_close(t); michael@0: } michael@0: michael@0: void RBDataMap::init(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status) michael@0: { michael@0: int32_t i = 0; michael@0: fData->removeAll(); michael@0: UResourceBundle *t = NULL; michael@0: const UChar *key = NULL; michael@0: int32_t keyLen = 0; michael@0: if(ures_getSize(headers) == ures_getSize(data)) { michael@0: for(i = 0; i < ures_getSize(data); i++) { michael@0: t = ures_getByIndex(data, i, t, &status); michael@0: key = ures_getStringByIndex(headers, i, &keyLen, &status); michael@0: fData->put(UnicodeString(key, keyLen), new ResourceBundle(t, status), status); michael@0: } michael@0: } else { michael@0: // error michael@0: status = U_INVALID_FORMAT_ERROR; michael@0: } michael@0: ures_close(t); michael@0: } michael@0: michael@0: const ResourceBundle *RBDataMap::getItem(const char* key, UErrorCode &status) const michael@0: { michael@0: if(U_FAILURE(status)) { michael@0: return NULL; michael@0: } michael@0: michael@0: UnicodeString hashKey(key, -1, US_INV); michael@0: const ResourceBundle *r = (ResourceBundle *)fData->get(hashKey); michael@0: if(r != NULL) { michael@0: return r; michael@0: } else { michael@0: status = U_MISSING_RESOURCE_ERROR; michael@0: return NULL; michael@0: } michael@0: } michael@0: michael@0: const UnicodeString RBDataMap::getString(const char* key, UErrorCode &status) const michael@0: { michael@0: const ResourceBundle *r = getItem(key, status); michael@0: if(U_SUCCESS(status)) { michael@0: return r->getString(status); michael@0: } else { michael@0: return UnicodeString(); michael@0: } michael@0: } michael@0: michael@0: int32_t michael@0: RBDataMap::getInt28(const char* key, UErrorCode &status) const michael@0: { michael@0: const ResourceBundle *r = getItem(key, status); michael@0: if(U_SUCCESS(status)) { michael@0: return r->getInt(status); michael@0: } else { michael@0: return 0; michael@0: } michael@0: } michael@0: michael@0: uint32_t michael@0: RBDataMap::getUInt28(const char* key, UErrorCode &status) const michael@0: { michael@0: const ResourceBundle *r = getItem(key, status); michael@0: if(U_SUCCESS(status)) { michael@0: return r->getUInt(status); michael@0: } else { michael@0: return 0; michael@0: } michael@0: } michael@0: michael@0: const int32_t * michael@0: RBDataMap::getIntVector(int32_t &length, const char *key, UErrorCode &status) const { michael@0: const ResourceBundle *r = getItem(key, status); michael@0: if(U_SUCCESS(status)) { michael@0: return r->getIntVector(length, status); michael@0: } else { michael@0: return NULL; michael@0: } michael@0: } michael@0: michael@0: const uint8_t * michael@0: RBDataMap::getBinary(int32_t &length, const char *key, UErrorCode &status) const { michael@0: const ResourceBundle *r = getItem(key, status); michael@0: if(U_SUCCESS(status)) { michael@0: return r->getBinary(length, status); michael@0: } else { michael@0: return NULL; michael@0: } michael@0: } michael@0: michael@0: int32_t RBDataMap::getInt(const char* key, UErrorCode &status) const michael@0: { michael@0: UnicodeString r = this->getString(key, status); michael@0: if(U_SUCCESS(status)) { michael@0: return utoi(r); michael@0: } else { michael@0: return 0; michael@0: } michael@0: } michael@0: michael@0: const UnicodeString* RBDataMap::getStringArray(int32_t& count, const char* key, UErrorCode &status) const michael@0: { michael@0: const ResourceBundle *r = getItem(key, status); michael@0: if(U_SUCCESS(status)) { michael@0: int32_t i = 0; michael@0: michael@0: count = r->getSize(); michael@0: if(count <= 0) { michael@0: return NULL; michael@0: } michael@0: michael@0: UnicodeString *result = new UnicodeString[count]; michael@0: for(i = 0; igetStringEx(i, status); michael@0: } michael@0: return result; michael@0: } else { michael@0: return NULL; michael@0: } michael@0: } michael@0: michael@0: const int32_t* RBDataMap::getIntArray(int32_t& count, const char* key, UErrorCode &status) const michael@0: { michael@0: const ResourceBundle *r = getItem(key, status); michael@0: if(U_SUCCESS(status)) { michael@0: int32_t i = 0; michael@0: michael@0: count = r->getSize(); michael@0: if(count <= 0) { michael@0: return NULL; michael@0: } michael@0: michael@0: int32_t *result = new int32_t[count]; michael@0: UnicodeString stringRes; michael@0: for(i = 0; igetStringEx(i, status); michael@0: result[i] = utoi(stringRes); michael@0: } michael@0: return result; michael@0: } else { michael@0: return NULL; michael@0: } michael@0: } michael@0: