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