1 // 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /******************************************************************** 4 * COPYRIGHT: 5 * Copyright (c) 2002-2006, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ********************************************************************/ 8 9 /* Created by weiv 05/09/2002 */ 10 11 #include "unicode/datamap.h" 12 #include "unicode/resbund.h" 13 #include "unicode/unistr.h" 14 #include "hash.h" 15 #include <stdlib.h> 16 17 DataMap::~DataMap() {} 18 DataMap::DataMap() {} 19 20 int32_t 21 DataMap::utoi(const UnicodeString &s) const 22 { 23 char ch[256]; 24 const UChar *u = toUCharPtr(s.getBuffer()); 25 int32_t len = s.length(); 26 u_UCharsToChars(u, ch, len); 27 ch[len] = 0; /* include terminating \0 */ 28 return atoi(ch); 29 } 30 31 U_CDECL_BEGIN 32 void U_CALLCONV 33 deleteResBund(void *obj) { 34 delete (ResourceBundle *)obj; 35 } 36 U_CDECL_END 37 38 39 RBDataMap::~RBDataMap() 40 { 41 delete fData; 42 } 43 44 RBDataMap::RBDataMap() 45 { 46 UErrorCode status = U_ZERO_ERROR; 47 fData = new Hashtable(TRUE, status); 48 fData->setValueDeleter(deleteResBund); 49 } 50 51 // init from table resource 52 // will put stuff in hashtable according to 53 // keys. 54 RBDataMap::RBDataMap(UResourceBundle *data, UErrorCode &status) 55 { 56 fData = new Hashtable(TRUE, status); 57 fData->setValueDeleter(deleteResBund); 58 init(data, status); 59 } 60 61 // init from headers and resource 62 // with checking the whether the size of resource matches 63 // header size 64 RBDataMap::RBDataMap(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status) 65 { 66 fData = new Hashtable(TRUE, status); 67 fData->setValueDeleter(deleteResBund); 68 init(headers, data, status); 69 } 70 71 72 void RBDataMap::init(UResourceBundle *data, UErrorCode &status) { 73 int32_t i = 0; 74 fData->removeAll(); 75 UResourceBundle *t = NULL; 76 for(i = 0; i < ures_getSize(data); i++) { 77 t = ures_getByIndex(data, i, t, &status); 78 fData->put(UnicodeString(ures_getKey(t), -1, US_INV), new ResourceBundle(t, status), status); 79 } 80 ures_close(t); 81 } 82 83 void RBDataMap::init(UResourceBundle *headers, UResourceBundle *data, UErrorCode &status) 84 { 85 int32_t i = 0; 86 fData->removeAll(); 87 UResourceBundle *t = NULL; 88 const UChar *key = NULL; 89 int32_t keyLen = 0; 90 if(ures_getSize(headers) == ures_getSize(data)) { 91 for(i = 0; i < ures_getSize(data); i++) { 92 t = ures_getByIndex(data, i, t, &status); 93 key = ures_getStringByIndex(headers, i, &keyLen, &status); 94 fData->put(UnicodeString(key, keyLen), new ResourceBundle(t, status), status); 95 } 96 } else { 97 // error 98 status = U_INVALID_FORMAT_ERROR; 99 } 100 ures_close(t); 101 } 102 103 const ResourceBundle *RBDataMap::getItem(const char* key, UErrorCode &status) const 104 { 105 if(U_FAILURE(status)) { 106 return NULL; 107 } 108 109 UnicodeString hashKey(key, -1, US_INV); 110 const ResourceBundle *r = (ResourceBundle *)fData->get(hashKey); 111 if(r != NULL) { 112 return r; 113 } else { 114 status = U_MISSING_RESOURCE_ERROR; 115 return NULL; 116 } 117 } 118 119 const UnicodeString RBDataMap::getString(const char* key, UErrorCode &status) const 120 { 121 const ResourceBundle *r = getItem(key, status); 122 if(U_SUCCESS(status)) { 123 return r->getString(status); 124 } else { 125 return UnicodeString(); 126 } 127 } 128 129 int32_t 130 RBDataMap::getInt28(const char* key, UErrorCode &status) const 131 { 132 const ResourceBundle *r = getItem(key, status); 133 if(U_SUCCESS(status)) { 134 return r->getInt(status); 135 } else { 136 return 0; 137 } 138 } 139 140 uint32_t 141 RBDataMap::getUInt28(const char* key, UErrorCode &status) const 142 { 143 const ResourceBundle *r = getItem(key, status); 144 if(U_SUCCESS(status)) { 145 return r->getUInt(status); 146 } else { 147 return 0; 148 } 149 } 150 151 const int32_t * 152 RBDataMap::getIntVector(int32_t &length, const char *key, UErrorCode &status) const { 153 const ResourceBundle *r = getItem(key, status); 154 if(U_SUCCESS(status)) { 155 return r->getIntVector(length, status); 156 } else { 157 return NULL; 158 } 159 } 160 161 const uint8_t * 162 RBDataMap::getBinary(int32_t &length, const char *key, UErrorCode &status) const { 163 const ResourceBundle *r = getItem(key, status); 164 if(U_SUCCESS(status)) { 165 return r->getBinary(length, status); 166 } else { 167 return NULL; 168 } 169 } 170 171 int32_t RBDataMap::getInt(const char* key, UErrorCode &status) const 172 { 173 UnicodeString r = this->getString(key, status); 174 if(U_SUCCESS(status)) { 175 return utoi(r); 176 } else { 177 return 0; 178 } 179 } 180 181 const UnicodeString* RBDataMap::getStringArray(int32_t& count, const char* key, UErrorCode &status) const 182 { 183 const ResourceBundle *r = getItem(key, status); 184 if(U_SUCCESS(status)) { 185 int32_t i = 0; 186 187 count = r->getSize(); 188 if(count <= 0) { 189 return NULL; 190 } 191 192 UnicodeString *result = new UnicodeString[count]; 193 for(i = 0; i<count; i++) { 194 result[i] = r->getStringEx(i, status); 195 } 196 return result; 197 } else { 198 return NULL; 199 } 200 } 201 202 const int32_t* RBDataMap::getIntArray(int32_t& count, const char* key, UErrorCode &status) const 203 { 204 const ResourceBundle *r = getItem(key, status); 205 if(U_SUCCESS(status)) { 206 int32_t i = 0; 207 208 count = r->getSize(); 209 if(count <= 0) { 210 return NULL; 211 } 212 213 int32_t *result = new int32_t[count]; 214 UnicodeString stringRes; 215 for(i = 0; i<count; i++) { 216 stringRes = r->getStringEx(i, status); 217 result[i] = utoi(stringRes); 218 } 219 return result; 220 } else { 221 return NULL; 222 } 223 } 224 225