/* ******************************************************************************* * Copyright (C) 2007, International Business Machines Corporation and * * others. All Rights Reserved. * ******************************************************************************* */ package com.ibm.icu.dev.test.util; import com.ibm.icu.impl.Utility; /** * @author srl * * analog of FieldsSet in C++ */ public class FieldsSet { public static final int NO_ENUM = -1; protected FieldsSet(int whichEnum, int fieldsCount) { if (fieldsCount <= 0 && whichEnum != NO_ENUM) { fieldsCount = DebugUtilities.enumCount(whichEnum); } fEnum = whichEnum; fFieldsCount = fieldsCount; if(fieldsCount<0) { throw new InternalError("Preposterous field count " + fieldsCount); } fValues = new int[fFieldsCount]; fIsSet = new boolean[fFieldsCount]; clear(); } protected int fEnum = NO_ENUM; protected int fFieldsCount = 0; protected int fValues[] = null; protected boolean fIsSet[] = null; public void clear() { for (int i = 0; i < fFieldsCount; i++) { clear(i); } } public void clear(int field) { fValues[field] = -1; fIsSet[field] = false; } public void set(int field, int amount) { fValues[field] = amount; fIsSet[field] = true; } public boolean isSet(int field) { return fIsSet[field]; } public int get(int field) { if (fIsSet[field]) { return fValues[field]; } else { return -1; } } public boolean isSameType(FieldsSet other) { return ((other.fEnum == fEnum) && (other.fFieldsCount == fFieldsCount)); } public int fieldCount() { return fFieldsCount; } /** * @param other "expected" set to match against * @return a formatted string listing which fields are set in this, with the * comparison made agaainst those fields in other, or, 'null' if there is no difference. */ public String diffFrom(FieldsSet other) { StringBuffer str = new StringBuffer(); if(!isSameType(other)) { throw new IllegalArgumentException("U_ILLEGAL_ARGUMENT_ERROR: FieldsSet of a different type!"); } for (int i=0; i1) { value = kv[1]; } int field = handleParseName(inheritFrom, key, value); if(field != -1) { handleParseValue(inheritFrom, field, value); goodFields++; } } return goodFields; } /** * Callback interface for subclass. This function is called when parsing a * field name, such as "MONTH" in "MONTH=4". Base implementation is to * lookup the enum value using udbg_* utilities, or else as an integer if * enum is not available. * * If there is a special directive, the implementer can catch it here and * return -1 after special processing completes. * * @param inheritFrom the set inheriting from - may be null. * @param name the field name (key side) * @param substr the string in question (value side) * @param status error status - set to error for failure. * @return field number, or negative if field should be skipped. */ protected int handleParseName(FieldsSet inheritFrom, String name, String substr) { int field = -1; if(fEnum != NO_ENUM) { field = DebugUtilities.enumByString(fEnum, name); } if(field < 0) { field = Integer.parseInt(name); } return field; } /** * Callback interface for subclass. Base implementation is to call * parseValueDefault(...) * * @param inheritFrom the set inheriting from - may be null. * @param field which field is being parsed * @param substr the string in question (value side) * @param status error status - set to error for failure. * @see parseValueDefault */ protected void handleParseValue(FieldsSet inheritFrom, int field, String substr) { parseValueDefault(inheritFrom, field, substr); } /** * the default implementation for handleParseValue. Base implementation is * to parse a decimal integer value, or inherit from inheritFrom if the * string is 0-length. Implementations of this function should call * set(field,...) on successful parse. * * @see handleParseValue */ protected void parseValueDefault(FieldsSet inheritFrom, int field, String substr) { if(substr.length()==0) { if(inheritFrom == null) { throw new InternalError("Trying to inherit from field " + field + " but inheritFrom is null"); } if(!inheritFrom.isSet(field)) { throw new InternalError("Trying to inherit from field " + field + " but inheritFrom["+field+"] is not set"); } set(field,inheritFrom.get(field)); } else { int value = Integer.parseInt(substr); set(field, value); } } /** * convenience implementation for handleParseValue attempt to load a value * from an enum value using udbg_enumByString() if fails, will call * parseValueDefault() * * @see handleParseValue */ protected void parseValueEnum(int type, FieldsSet inheritFrom, int field, String substr) { int value = DebugUtilities.enumByString(type, substr); if(value>=0) { set(field,value); return; } parseValueDefault(inheritFrom, field, substr); } public String fieldName(int field) { return (fEnum!=NO_ENUM)?DebugUtilities.enumString(fEnum, field):Integer.toString(field); } public String toString() { String str = getClass().getName()+" ["+fFieldsCount+"," +(fEnum!=NO_ENUM?DebugUtilities.typeString(fEnum):Integer.toString(fEnum))+"]: "; for(int i=0;i