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 */
29class 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       */
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       */
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 */
222class CalendarFieldsSet : public FieldsSet {
223public:
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
249protected:
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 */
265class 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