1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 2015-2016, International Business Machines
6 * Corporation and others.  All Rights Reserved.
7 *******************************************************************************
8 * resource.h
9 *
10 * created on: 2015nov04
11 * created by: Markus W. Scherer
12 */
13 
14 #ifndef __URESOURCE_H__
15 #define __URESOURCE_H__
16 
17 /**
18  * \file
19  * \brief ICU resource bundle key and value types.
20  */
21 
22 // Note: Ported from ICU4J class UResource and its nested classes,
23 // but the C++ classes are separate, not nested.
24 
25 // We use the Resource prefix for C++ classes, as usual.
26 // The UResource prefix would be used for C types.
27 
28 #include "unicode/utypes.h"
29 #include "unicode/unistr.h"
30 #include "unicode/ures.h"
31 #include "restrace.h"
32 
33 struct ResourceData;
34 
35 U_NAMESPACE_BEGIN
36 
37 class ResourceValue;
38 
39 // Note: In C++, we use const char * pointers for keys,
40 // rather than an abstraction like Java UResource.Key.
41 
42 /**
43  * Interface for iterating over a resource bundle array resource.
44  */
45 class U_COMMON_API ResourceArray {
46 public:
47     /** Constructs an empty array object. */
ResourceArray()48     ResourceArray() : items16(NULL), items32(NULL), length(0) {}
49 
50     /** Only for implementation use. @internal */
ResourceArray(const uint16_t * i16,const uint32_t * i32,int32_t len,const ResourceTracer & traceInfo)51     ResourceArray(const uint16_t *i16, const uint32_t *i32, int32_t len,
52                   const ResourceTracer& traceInfo) :
53             items16(i16), items32(i32), length(len),
54             fTraceInfo(traceInfo) {}
55 
56     /**
57      * @return The number of items in the array resource.
58      */
getSize()59     int32_t getSize() const { return length; }
60     /**
61      * @param i Array item index.
62      * @param value Output-only, receives the value of the i'th item.
63      * @return true if i is non-negative and less than getSize().
64      */
65     UBool getValue(int32_t i, ResourceValue &value) const;
66 
67     /** Only for implementation use. @internal */
68     uint32_t internalGetResource(const ResourceData *pResData, int32_t i) const;
69 
70 private:
71     const uint16_t *items16;
72     const uint32_t *items32;
73     int32_t length;
74     ResourceTracer fTraceInfo;
75 };
76 
77 /**
78  * Interface for iterating over a resource bundle table resource.
79  */
80 class U_COMMON_API ResourceTable {
81 public:
82     /** Constructs an empty table object. */
ResourceTable()83     ResourceTable() : keys16(NULL), keys32(NULL), items16(NULL), items32(NULL), length(0) {}
84 
85     /** Only for implementation use. @internal */
ResourceTable(const uint16_t * k16,const int32_t * k32,const uint16_t * i16,const uint32_t * i32,int32_t len,const ResourceTracer & traceInfo)86     ResourceTable(const uint16_t *k16, const int32_t *k32,
87                   const uint16_t *i16, const uint32_t *i32, int32_t len,
88                   const ResourceTracer& traceInfo) :
89             keys16(k16), keys32(k32), items16(i16), items32(i32), length(len),
90             fTraceInfo(traceInfo) {}
91 
92     /**
93      * @return The number of items in the array resource.
94      */
getSize()95     int32_t getSize() const { return length; }
96     /**
97      * @param i Table item index.
98      * @param key Output-only, receives the key of the i'th item.
99      * @param value Output-only, receives the value of the i'th item.
100      * @return true if i is non-negative and less than getSize().
101      */
102     UBool getKeyAndValue(int32_t i, const char *&key, ResourceValue &value) const;
103 
104     /**
105      * @param key Key string to find in the table.
106      * @param value Output-only, receives the value of the item with that key.
107      * @return true if the table contains the key.
108      */
109     UBool findValue(const char *key, ResourceValue &value) const;
110 
111 private:
112     const uint16_t *keys16;
113     const int32_t *keys32;
114     const uint16_t *items16;
115     const uint32_t *items32;
116     int32_t length;
117     ResourceTracer fTraceInfo;
118 };
119 
120 /**
121  * Represents a resource bundle item's value.
122  * Avoids object creations as much as possible.
123  * Mutable, not thread-safe.
124  */
125 class U_COMMON_API ResourceValue : public UObject {
126 public:
127     virtual ~ResourceValue();
128 
129     /**
130      * @return ICU resource type, for example, URES_STRING
131      */
132     virtual UResType getType() const = 0;
133 
134     /**
135      * Sets U_RESOURCE_TYPE_MISMATCH if this is not a string resource.
136      *
137      * @see ures_getString()
138      */
139     virtual const UChar *getString(int32_t &length, UErrorCode &errorCode) const = 0;
140 
getUnicodeString(UErrorCode & errorCode)141     inline UnicodeString getUnicodeString(UErrorCode &errorCode) const {
142         int32_t len = 0;
143         const UChar *r = getString(len, errorCode);
144         return UnicodeString(true, r, len);
145     }
146 
147     /**
148      * Sets U_RESOURCE_TYPE_MISMATCH if this is not an alias resource.
149      */
150     virtual const UChar *getAliasString(int32_t &length, UErrorCode &errorCode) const = 0;
151 
getAliasUnicodeString(UErrorCode & errorCode)152     inline UnicodeString getAliasUnicodeString(UErrorCode &errorCode) const {
153         int32_t len = 0;
154         const UChar *r = getAliasString(len, errorCode);
155         return UnicodeString(true, r, len);
156     }
157 
158     /**
159      * Sets U_RESOURCE_TYPE_MISMATCH if this is not an integer resource.
160      *
161      * @see ures_getInt()
162      */
163     virtual int32_t getInt(UErrorCode &errorCode) const = 0;
164 
165     /**
166      * Sets U_RESOURCE_TYPE_MISMATCH if this is not an integer resource.
167      *
168      * @see ures_getUInt()
169      */
170     virtual uint32_t getUInt(UErrorCode &errorCode) const = 0;
171 
172     /**
173      * Sets U_RESOURCE_TYPE_MISMATCH if this is not an intvector resource.
174      *
175      * @see ures_getIntVector()
176      */
177     virtual const int32_t *getIntVector(int32_t &length, UErrorCode &errorCode) const = 0;
178 
179     /**
180      * Sets U_RESOURCE_TYPE_MISMATCH if this is not a binary-blob resource.
181      *
182      * @see ures_getBinary()
183      */
184     virtual const uint8_t *getBinary(int32_t &length, UErrorCode &errorCode) const = 0;
185 
186     /**
187      * Sets U_RESOURCE_TYPE_MISMATCH if this is not an array resource
188      */
189     virtual ResourceArray getArray(UErrorCode &errorCode) const = 0;
190 
191     /**
192      * Sets U_RESOURCE_TYPE_MISMATCH if this is not a table resource
193      */
194     virtual ResourceTable getTable(UErrorCode &errorCode) const = 0;
195 
196     /**
197      * Is this a no-fallback/no-inheritance marker string?
198      * Such a marker is used for
199      * CLDR no-fallback data values of (three empty-set symbols)=={2205, 2205, 2205}
200      * when enumerating tables with fallback from the specific resource bundle to root.
201      *
202      * @return true if this is a no-inheritance marker string
203      */
204     virtual UBool isNoInheritanceMarker() const = 0;
205 
206     /**
207      * Sets the dest strings from the string values in this array resource.
208      *
209      * @return the number of strings in this array resource.
210      *     If greater than capacity, then an overflow error is set.
211      *
212      * Sets U_RESOURCE_TYPE_MISMATCH if this is not an array resource
213      *     or if any of the array items is not a string
214      */
215     virtual int32_t getStringArray(UnicodeString *dest, int32_t capacity,
216                                    UErrorCode &errorCode) const = 0;
217 
218     /**
219      * Same as
220      * <pre>
221      * if (getType() == URES_STRING) {
222      *     return new String[] { getString(); }
223      * } else {
224      *     return getStringArray();
225      * }
226      * </pre>
227      *
228      * Sets U_RESOURCE_TYPE_MISMATCH if this is
229      *     neither a string resource nor an array resource containing strings
230      * @see getString()
231      * @see getStringArray()
232      */
233     virtual int32_t getStringArrayOrStringAsArray(UnicodeString *dest, int32_t capacity,
234                                                   UErrorCode &errorCode) const = 0;
235 
236     /**
237      * Same as
238      * <pre>
239      * if (getType() == URES_STRING) {
240      *     return getString();
241      * } else {
242      *     return getStringArray()[0];
243      * }
244      * </pre>
245      *
246      * Sets U_RESOURCE_TYPE_MISMATCH if this is
247      *     neither a string resource nor an array resource containing strings
248      * @see getString()
249      * @see getStringArray()
250      */
251     virtual UnicodeString getStringOrFirstOfArray(UErrorCode &errorCode) const = 0;
252 
253 protected:
ResourceValue()254     ResourceValue() {}
255 
256 private:
257     ResourceValue(const ResourceValue &);  // no copy constructor
258     ResourceValue &operator=(const ResourceValue &);  // no assignment operator
259 };
260 
261 /**
262  * Sink for ICU resource bundle contents.
263  */
264 class U_COMMON_API ResourceSink : public UObject {
265 public:
ResourceSink()266     ResourceSink() {}
267     virtual ~ResourceSink();
268 
269     /**
270      * Called once for each bundle (child-parent-...-root).
271      * The value is normally an array or table resource,
272      * and implementations of this method normally iterate over the
273      * tree of resource items stored there.
274      *
275      * @param key The key string of the enumeration-start resource.
276      *     Empty if the enumeration starts at the top level of the bundle.
277      * @param value Call getArray() or getTable() as appropriate. Then reuse for
278      *     output values from Array and Table getters. Note: ResourceTable and
279      *     ResourceArray instances must outlive the ResourceValue instance for
280      *     ResourceTracer to be happy.
281      * @param noFallback true if the bundle has no parent;
282      *     that is, its top-level table has the nofallback attribute,
283      *     or it is the root bundle of a locale tree.
284      */
285     virtual void put(const char *key, ResourceValue &value, UBool noFallback,
286                      UErrorCode &errorCode) = 0;
287 
288 private:
289     ResourceSink(const ResourceSink &);  // no copy constructor
290     ResourceSink &operator=(const ResourceSink &);  // no assignment operator
291 };
292 
293 U_NAMESPACE_END
294 
295 #endif
296