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