2 *******************************************************************************
\r
3 * Copyright (C) 2007, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
7 package com.ibm.icu.dev.test.util;
\r
9 import com.ibm.icu.impl.Utility;
\r
14 * analog of FieldsSet in C++
\r
16 public class FieldsSet {
\r
17 public static final int NO_ENUM = -1;
\r
19 protected FieldsSet(int whichEnum, int fieldsCount) {
\r
20 if (fieldsCount <= 0 && whichEnum != NO_ENUM) {
\r
21 fieldsCount = DebugUtilities.enumCount(whichEnum);
\r
24 fFieldsCount = fieldsCount;
\r
26 throw new InternalError("Preposterous field count " + fieldsCount);
\r
28 fValues = new int[fFieldsCount];
\r
29 fIsSet = new boolean[fFieldsCount];
\r
33 protected int fEnum = NO_ENUM;
\r
35 protected int fFieldsCount = 0;
\r
37 protected int fValues[] = null;
\r
39 protected boolean fIsSet[] = null;
\r
41 public void clear() {
\r
42 for (int i = 0; i < fFieldsCount; i++) {
\r
47 public void clear(int field) {
\r
48 fValues[field] = -1;
\r
49 fIsSet[field] = false;
\r
52 public void set(int field, int amount) {
\r
53 fValues[field] = amount;
\r
54 fIsSet[field] = true;
\r
57 public boolean isSet(int field) {
\r
58 return fIsSet[field];
\r
61 public int get(int field) {
\r
62 if (fIsSet[field]) {
\r
63 return fValues[field];
\r
69 public boolean isSameType(FieldsSet other) {
\r
70 return ((other.fEnum == fEnum) && (other.fFieldsCount == fFieldsCount));
\r
73 public int fieldCount() {
\r
74 return fFieldsCount;
\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
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
87 for (int i=0; i<fieldCount(); i++) {
\r
90 int theirVal = other.get(i);
\r
92 if(fEnum != NO_ENUM) {
\r
93 String fieldName = DebugUtilities.enumString(fEnum, i);
\r
95 String aval = Integer.toString(myVal);
\r
96 String bval = Integer.toString(theirVal);
\r
98 str.append(fieldName +"="+aval+" not "+bval+", ");
\r
100 str.append(Integer.toString(i) + "=" + myVal+" not " + theirVal+", ");
\r
104 if(str.length()==0) {
\r
107 return str.toString();
\r
111 * @param str string to parse
\r
112 * @param status formatted string for status
\r
114 public int parseFrom(String str) {
\r
115 return parseFrom(str, null);
\r
118 public int parseFrom(String str, FieldsSet inheritFrom) {
\r
119 int goodFields = 0;
\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
128 String key = kv[0];
\r
134 int field = handleParseName(inheritFrom, key, value);
\r
136 handleParseValue(inheritFrom, field, value);
\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
150 * If there is a special directive, the implementer can catch it here and
\r
151 * return -1 after special processing completes.
\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
159 protected int handleParseName(FieldsSet inheritFrom, String name,
\r
162 if(fEnum != NO_ENUM) {
\r
163 field = DebugUtilities.enumByString(fEnum, name);
\r
166 field = Integer.parseInt(name);
\r
172 * Callback interface for subclass. Base implementation is to call
\r
173 * parseValueDefault(...)
\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
181 protected void handleParseValue(FieldsSet inheritFrom, int field,
\r
183 parseValueDefault(inheritFrom, field, substr);
\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
192 * @see handleParseValue
\r
194 protected void parseValueDefault(FieldsSet inheritFrom, int field,
\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
200 if(!inheritFrom.isSet(field)) {
\r
201 throw new InternalError("Trying to inherit from field " + field + " but inheritFrom["+field+"] is not set");
\r
203 set(field,inheritFrom.get(field));
\r
205 int value = Integer.parseInt(substr);
\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
215 * @see handleParseValue
\r
217 protected void parseValueEnum(int type, FieldsSet inheritFrom, int field,
\r
219 int value = DebugUtilities.enumByString(type, substr);
\r
224 parseValueDefault(inheritFrom, field, substr);
\r
227 public String fieldName(int field) {
\r
228 return (fEnum!=NO_ENUM)?DebugUtilities.enumString(fEnum, field):Integer.toString(field);
\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
236 str = str + fieldName(i)+"="+get(i)+",";
\r