]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-4_4_2-src/main/tests/core/src/com/ibm/icu/dev/test/util/FieldsSet.java
go
[Dictionary.git] / jars / icu4j-4_4_2-src / main / tests / core / src / com / ibm / icu / dev / test / util / FieldsSet.java
1 /*\r
2  *******************************************************************************\r
3  * Copyright (C) 2007, International Business Machines Corporation and         *\r
4  * others. All Rights Reserved.                                                *\r
5  *******************************************************************************\r
6  */\r
7 package com.ibm.icu.dev.test.util;\r
8 \r
9 import com.ibm.icu.impl.Utility;\r
10 \r
11 /**\r
12  * @author srl\r
13  * \r
14  * analog of FieldsSet in C++\r
15  */\r
16 public class FieldsSet {\r
17     public static final int NO_ENUM = -1;\r
18 \r
19     protected FieldsSet(int whichEnum, int fieldsCount) {\r
20         if (fieldsCount <= 0 && whichEnum != NO_ENUM) {\r
21             fieldsCount = DebugUtilities.enumCount(whichEnum);\r
22         }\r
23         fEnum = whichEnum;\r
24         fFieldsCount = fieldsCount;\r
25         if(fieldsCount<0) {\r
26             throw new InternalError("Preposterous field count " + fieldsCount);\r
27         }\r
28         fValues = new int[fFieldsCount];\r
29         fIsSet = new boolean[fFieldsCount];\r
30         clear();\r
31     }\r
32 \r
33     protected int fEnum = NO_ENUM;\r
34 \r
35     protected int fFieldsCount = 0;\r
36 \r
37     protected int fValues[] = null;\r
38 \r
39     protected boolean fIsSet[] = null;\r
40 \r
41     public void clear() {\r
42         for (int i = 0; i < fFieldsCount; i++) {\r
43             clear(i);\r
44         }\r
45     }\r
46 \r
47     public void clear(int field) {\r
48         fValues[field] = -1;\r
49         fIsSet[field] = false;\r
50     }\r
51 \r
52     public void set(int field, int amount) {\r
53         fValues[field] = amount;\r
54         fIsSet[field] = true;\r
55     }\r
56 \r
57     public boolean isSet(int field) {\r
58         return fIsSet[field];\r
59     }\r
60 \r
61     public int get(int field) {\r
62         if (fIsSet[field]) {\r
63             return fValues[field];\r
64         } else {\r
65             return -1;\r
66         }\r
67     }\r
68 \r
69     public boolean isSameType(FieldsSet other) {\r
70         return ((other.fEnum == fEnum) && (other.fFieldsCount == fFieldsCount));\r
71     }\r
72 \r
73     public int fieldCount() {\r
74         return fFieldsCount;\r
75     }\r
76 \r
77     /**\r
78      * @param other  "expected" set to match against\r
79      * @return a formatted string listing which fields are set in this, with the\r
80      *         comparison made agaainst those fields in other, or, 'null' if there is no difference.\r
81      */\r
82     public String diffFrom(FieldsSet other) {\r
83         StringBuffer str = new StringBuffer();\r
84         if(!isSameType(other)) {\r
85             throw new IllegalArgumentException("U_ILLEGAL_ARGUMENT_ERROR: FieldsSet of a different type!");\r
86         }\r
87         for (int i=0; i<fieldCount(); i++) {\r
88             if (isSet(i)) {\r
89                 int myVal = get(i);\r
90                 int theirVal = other.get(i);\r
91                 \r
92                 if(fEnum != NO_ENUM) {\r
93                     String fieldName = DebugUtilities.enumString(fEnum, i);\r
94                     \r
95                     String aval = Integer.toString(myVal);\r
96                     String bval = Integer.toString(theirVal);\r
97 \r
98                     str.append(fieldName +"="+aval+" not "+bval+", ");\r
99                 } else {\r
100                     str.append(Integer.toString(i) + "=" + myVal+" not " + theirVal+", ");\r
101                 }\r
102             }\r
103         }\r
104         if(str.length()==0) {\r
105             return null;\r
106         }\r
107         return str.toString();\r
108     }\r
109 \r
110     /**\r
111      * @param str string to parse\r
112      * @param status formatted string for status\r
113      */\r
114     public int parseFrom(String str) {\r
115         return parseFrom(str, null);\r
116     }\r
117 \r
118     public int parseFrom(String str, FieldsSet inheritFrom) {\r
119         int goodFields = 0;\r
120         \r
121         String[] fields = Utility.split(str, ',');\r
122         for(int i=0;i<fields.length;i++) {\r
123             String fieldStr = fields[i];\r
124             String kv[] = Utility.split(fieldStr, '=');\r
125             if(kv.length < 1 || kv.length > 2) {\r
126                 throw new InternalError("split around '=' failed: " + fieldStr);\r
127             }\r
128             String key = kv[0];\r
129             String value = "";\r
130             if(kv.length>1) {\r
131                 value = kv[1];\r
132             }\r
133             \r
134             int field = handleParseName(inheritFrom, key, value);\r
135             if(field != -1) {\r
136                 handleParseValue(inheritFrom, field, value);\r
137                 goodFields++;\r
138             }\r
139         }\r
140 \r
141         return goodFields;\r
142     }\r
143 \r
144     /**\r
145      * Callback interface for subclass. This function is called when parsing a\r
146      * field name, such as "MONTH" in "MONTH=4". Base implementation is to\r
147      * lookup the enum value using udbg_* utilities, or else as an integer if\r
148      * enum is not available.\r
149      * \r
150      * If there is a special directive, the implementer can catch it here and\r
151      * return -1 after special processing completes.\r
152      * \r
153      * @param inheritFrom  the set inheriting from - may be null.\r
154      * @param name  the field name (key side)\r
155      * @param substr  the string in question (value side)\r
156      * @param status  error status - set to error for failure.\r
157      * @return field number, or negative if field should be skipped.\r
158      */\r
159     protected int handleParseName(FieldsSet inheritFrom, String name,\r
160             String substr) {\r
161         int field = -1;\r
162         if(fEnum != NO_ENUM) {\r
163             field = DebugUtilities.enumByString(fEnum, name);\r
164         }\r
165         if(field < 0) {\r
166             field = Integer.parseInt(name);\r
167         }\r
168         return field;\r
169     }\r
170 \r
171     /**\r
172      * Callback interface for subclass. Base implementation is to call\r
173      * parseValueDefault(...)\r
174      * \r
175      * @param inheritFrom  the set inheriting from - may be null.\r
176      * @param field   which field is being parsed\r
177      * @param substr  the string in question (value side)\r
178      * @param status  error status - set to error for failure.\r
179      * @see parseValueDefault\r
180      */\r
181     protected void handleParseValue(FieldsSet inheritFrom, int field,\r
182             String substr) {\r
183         parseValueDefault(inheritFrom, field, substr);\r
184     }\r
185 \r
186     /**\r
187      * the default implementation for handleParseValue. Base implementation is\r
188      * to parse a decimal integer value, or inherit from inheritFrom if the\r
189      * string is 0-length. Implementations of this function should call\r
190      * set(field,...) on successful parse.\r
191      * \r
192      * @see handleParseValue\r
193      */\r
194     protected void parseValueDefault(FieldsSet inheritFrom, int field,\r
195             String substr) {\r
196         if(substr.length()==0) {\r
197             if(inheritFrom == null) {\r
198                 throw new InternalError("Trying to inherit from field " + field + " but inheritFrom is null");\r
199             }\r
200             if(!inheritFrom.isSet(field)) {\r
201                 throw new InternalError("Trying to inherit from field " + field + " but inheritFrom["+field+"] is  not set");\r
202             }\r
203             set(field,inheritFrom.get(field));\r
204         } else {\r
205             int value = Integer.parseInt(substr);\r
206             set(field, value);\r
207         }\r
208     }\r
209 \r
210     /**\r
211      * convenience implementation for handleParseValue attempt to load a value\r
212      * from an enum value using udbg_enumByString() if fails, will call\r
213      * parseValueDefault()\r
214      * \r
215      * @see handleParseValue\r
216      */\r
217     protected void parseValueEnum(int type, FieldsSet inheritFrom, int field,\r
218             String substr) {\r
219         int value = DebugUtilities.enumByString(type, substr);\r
220         if(value>=0) {\r
221             set(field,value);\r
222             return;\r
223         }\r
224         parseValueDefault(inheritFrom, field, substr);\r
225     }\r
226     \r
227     public String fieldName(int field) {\r
228         return (fEnum!=NO_ENUM)?DebugUtilities.enumString(fEnum, field):Integer.toString(field);\r
229     }\r
230     \r
231     public String toString() {\r
232         String str = getClass().getName()+" ["+fFieldsCount+","\r
233         +(fEnum!=NO_ENUM?DebugUtilities.typeString(fEnum):Integer.toString(fEnum))+"]: ";\r
234         for(int i=0;i<fFieldsCount;i++) {\r
235             if(isSet(i)) {\r
236                 str = str + fieldName(i)+"="+get(i)+",";\r
237             }\r
238         }\r
239         return str; \r
240     }\r
241 }\r