1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 ************************************************************************
5 * Copyright (c) 2007-2010, International Business Machines
6 * Corporation and others.  All Rights Reserved.
7 ************************************************************************
8 */
9 #ifndef FLDSET_H_
10 #define FLDSET_H_
11 
12 #include "unicode/utypes.h"
13 
14 #if !UCONFIG_NO_FORMATTING
15 #include "unicode/calendar.h"
16 #include "unicode/ucal.h"
17 #include "unicode/udat.h"
18 #include "udbgutil.h"
19 #include "dbgutil.h"
20 #include "unicode/unistr.h"
21 
22 #define U_FIELDS_SET_MAX  64
23 
24 /**
25  * This class represents a collection of integer values (fields), each designated by
26  * one of a particular set of enum values.  Each integer value (int32_t) is optional and
27  * may or may not be set.
28  *
29  * @internal ICU 3.8
30  */
31 class FieldsSet {
32     protected:
33         /**
34          * subclass interface - construct the FieldsSet to reference one of the standard
35          * enumerations.
36          * @param whichEnum which enumaration value goes with this set. Will be used to calculate string
37          * values and also enum size.
38          * @see UDebugEnumType
39          */
40         FieldsSet(UDebugEnumType whichEnum);
41 
42         /**
43          * subclass interface - construct the FieldsSet without using a standard enum type.
44          * @param fieldCount how many fields this object can hold.
45          */
46         FieldsSet(int32_t fieldsCount);
47 
48     public:
49 
50       /**
51        * Compare two sets. In typical test usage, 'this' is the resul of
52        * a tested operation, and 'other' is the predefined expected value.
53        *
54        * @param other the set to compare against.
55        * @param status will return U_ILLEGAL_ARGUMENT_ERROR if sets are not the same size
56        * @return a formatted string listing which fields are set in
57        *   this, with the comparison made agaainst those fields in other.
58        */
59       U_NAMESPACE_QUALIFIER UnicodeString diffFrom(const FieldsSet& other, UErrorCode &status) const;
60 
61     public:
62       /**
63        * Fill-in fields from a specified string, such as "NAME1=VALUE1,NAME2=VALUE2", etc.
64        * @param str string to parse
65        * @param status status of parse
66        * @return the number of valid parsed fields on success, or a negative number on failure.
67        */
parseFrom(const U_NAMESPACE_QUALIFIER UnicodeString & str,UErrorCode & status)68       int32_t parseFrom(const U_NAMESPACE_QUALIFIER UnicodeString& str, UErrorCode& status) {
69           return parseFrom(str,NULL,status);
70       }
71 
72       /**
73        * Fill-in fields from a specified string, such as "NAME1=VALUE1,NAME2=VALUE2", etc.
74        * @param inheritFrom if a field's value is given as 0-length, such as NAME1 in "NAME1=,NAME2=VALUE2",
75        * the specified FieldsSet's value for NAME1 will be copied into this.
76        * @param str string to parse
77        * @param status status of parse
78        * @return the number of valid parsed fields on success, or a negative number on failure.
79        */
parseFrom(const U_NAMESPACE_QUALIFIER UnicodeString & str,const FieldsSet & inheritFrom,UErrorCode & status)80       int32_t parseFrom(const U_NAMESPACE_QUALIFIER UnicodeString& str,
81                         const FieldsSet& inheritFrom,
82                         UErrorCode& status) {
83           return parseFrom(str, &inheritFrom, status);
84       }
85 
86       /**
87        * Fill-in fields from a specified string, such as "NAME1=VALUE1,NAME2=VALUE2", etc.
88        * @param inheritFrom if a field's value is given as 0-length, such as NAME1 in "NAME1=,NAME2=VALUE2",
89        * the specified FieldsSet's value for NAME1 will be copied into this.
90        * @param str string to parse
91        * @param status status of parse
92        * @return the number of valid parsed fields on success, or a negative number on failure.
93        */
94       int32_t parseFrom(const U_NAMESPACE_QUALIFIER UnicodeString& str,
95                         const FieldsSet* inheritFrom,
96                         UErrorCode& status);
97 
98     protected:
99       /**
100        * Callback interface for subclass.
101        * This function is called when parsing a field name, such as "MONTH"  in "MONTH=4".
102        * Base implementation is to lookup the enum value using udbg_* utilities, or else as an integer if
103        * enum is not available.
104        *
105        * If there is a special directive, the implementer can catch it here and return -1 after special processing completes.
106        *
107        * @param inheritFrom the set inheriting from - may be null.
108        * @param name the field name (key side)
109        * @param substr the string in question (value side)
110        * @param status error status - set to error for failure.
111        * @return field number, or negative if field should be skipped.
112        */
113       virtual int32_t handleParseName(const FieldsSet* inheritFrom,
114                                       const U_NAMESPACE_QUALIFIER UnicodeString& name,
115                                       const U_NAMESPACE_QUALIFIER UnicodeString& substr,
116                                       UErrorCode& status);
117 
118       /**
119        * Callback interface for subclass.
120        * Base implementation is to call parseValueDefault(...)
121        * @param inheritFrom the set inheriting from - may be null.
122        * @param field which field is being parsed
123        * @param substr the string in question (value side)
124        * @param status error status - set to error for failure.
125        * @see parseValueDefault
126        */
127       virtual void handleParseValue(const FieldsSet* inheritFrom,
128                                     int32_t field,
129                                     const U_NAMESPACE_QUALIFIER UnicodeString& substr,
130                                     UErrorCode& status);
131 
132       /**
133        * the default implementation for handleParseValue.
134        * Base implementation is to parse a decimal integer value, or inherit from inheritFrom if the string is 0-length.
135        * Implementations of this function should call set(field,...) on successful parse.
136        * @see handleParseValue
137        */
138       void parseValueDefault(const FieldsSet* inheritFrom,
139                              int32_t field,
140                              const U_NAMESPACE_QUALIFIER UnicodeString& substr,
141                              UErrorCode& status);
142 
143 
144       /**
145        * convenience implementation for handleParseValue
146        * attempt to load a value from an enum value using udbg_enumByString()
147        * if fails, will call parseValueDefault()
148        * @see handleParseValue
149        */
150       void parseValueEnum(UDebugEnumType type,
151                           const FieldsSet* inheritFrom,
152                           int32_t field,
153                           const U_NAMESPACE_QUALIFIER UnicodeString& substr,
154                           UErrorCode& status);
155 
156     private:
157       /**
158        * Not callable - construct a default FieldsSet
159        * @internal
160        */
161       FieldsSet();
162 
163       /**
164        * construct the object.
165        * @internal
166        */
167       void construct(UDebugEnumType whichEnum, int32_t fieldCount);
168 
169     public:
170     /**
171      * destructor
172      */
173      virtual ~FieldsSet();
174 
175     /**
176      * Mark all fields as unset
177      */
178     void clear();
179 
180     /**
181      * Mark a specific field as unset
182      * @param field the field to unset
183      */
184     void clear(int32_t field);
185 
186     /**
187      * Set a specific field
188      * @param field the field to set (i.e. enum value)
189      * @param value the field's value
190      */
191     void set(int32_t field, int32_t value);
192 
193     UBool isSet(int32_t field) const;
194 
195     /**
196      * Return the field's value
197      * @param field which field
198      * @return field's value, or -1 if unset.
199      */
200     int32_t get(int32_t field) const;
201 
202     /**
203      * Return true if both FieldsSet objects either are based on the same enum, or have the same number of fields.
204      */
205     UBool isSameType(const FieldsSet& other) const;
206 
207     /**
208      * @return the number of fields
209      */
210     int32_t fieldCount() const;
211 
212     protected:
213        int32_t fValue[U_FIELDS_SET_MAX];
214        UBool fIsSet[U_FIELDS_SET_MAX];
215     protected:
216        int32_t fFieldCount;
217        UDebugEnumType fEnum;
218 };
219 
220 /**
221  * A subclass of FieldsSet representing the fields in a Calendar
222  * @see Calendar
223  */
224 class CalendarFieldsSet : public FieldsSet {
225 public:
226     CalendarFieldsSet();
227     virtual ~CalendarFieldsSet();
228 
229 //        void clear(UCalendarDateFields field) { clear((int32_t)field); }
230 //        void set(UCalendarDateFields field, int32_t amount) { set ((int32_t)field, amount); }
231 
232 //        UBool isSet(UCalendarDateFields field) const { return isSet((int32_t)field); }
233 //        int32_t get(UCalendarDateFields field) const { return get((int32_t)field); }
234 
235     /**
236      * @param matches fillin to hold any fields different. Will have the calendar's value set on them.
237      * @return true if the calendar matches in these fields.
238      */
239     UBool matches(U_NAMESPACE_QUALIFIER Calendar *cal,
240                   CalendarFieldsSet &diffSet,
241                   UErrorCode& status) const;
242 
243     /**
244      * For each set field, set the same field on this Calendar.
245      * Doesn't clear the Calendar first.
246      * @param cal Calendar to modify
247      * @param status Contains any errors propagated by the Calendar.
248      */
249     void setOnCalendar(U_NAMESPACE_QUALIFIER Calendar *cal, UErrorCode& status) const;
250 
251 protected:
252     /**
253      * subclass override
254      */
255     void handleParseValue(const FieldsSet* inheritFrom,
256                           int32_t field,
257                           const U_NAMESPACE_QUALIFIER UnicodeString& substr,
258                           UErrorCode& status);
259 };
260 
261 /**
262  * This class simply implements a set of date and time styles
263  * such as DATE=SHORT  or TIME=SHORT,DATE=LONG, such as would be passed
264  * to DateFormat::createInstance()
265  * @see DateFormat
266  */
267 class DateTimeStyleSet : public FieldsSet {
268     public:
269         DateTimeStyleSet();
270         virtual ~DateTimeStyleSet();
271 
272         /**
273          * @return the date style, or UDAT_NONE if not set
274          */
275         UDateFormatStyle getDateStyle() const;
276 
277         /**
278          * @return the time style, or UDAT_NONE if not set
279          */
280         UDateFormatStyle getTimeStyle() const;
281     protected:
282         void handleParseValue(const FieldsSet* inheritFrom,
283                               int32_t field,
284                               const U_NAMESPACE_QUALIFIER UnicodeString& substr,
285                               UErrorCode& status);
286         int32_t handleParseName(const FieldsSet* inheritFrom,
287                                 const U_NAMESPACE_QUALIFIER UnicodeString& name,
288                                 const U_NAMESPACE_QUALIFIER UnicodeString& substr,
289                                 UErrorCode& status);
290 };
291 
292 
293 #endif /*!UCONFIG_NO_FORMAT*/
294 #endif /*FLDSET_H_*/
295