001: // Copyright (c) 2000 Per M.A. Bothner.
002: // This is free software; for terms and warranty disclaimer see ./COPYING.
003:
004: package gnu.math;
005:
006: import java.io.*;
007:
008: /** A Unit that has a name. */
009:
010: public class NamedUnit extends Unit implements Externalizable {
011: /** The interned name of this Unit, for example "cm". */
012: String name;
013:
014: /** The value of this Unit is scale*base.
015: * The value of this.factor is scale*base.factor, so scale is
016: * redundant - were it not for rounding error concerns. */
017: double scale;
018:
019: /** The value this was initialized from. */
020: Unit base;
021:
022: /** Next NamedUnit in table bucket. */
023: NamedUnit chain;
024:
025: public NamedUnit() {
026: }
027:
028: public NamedUnit(String name, DQuantity value) {
029: this .name = name.intern();
030: scale = value.factor;
031: base = value.unt;
032: init();
033: }
034:
035: public NamedUnit(String name, double factor, Unit base) {
036: this .name = name;
037: this .base = base;
038: scale = factor;
039: init();
040: }
041:
042: protected void init() {
043: factor = scale * base.factor;
044: dims = base.dims;
045: name = name.intern();
046: int hash = name.hashCode();
047: int index = (hash & 0x7FFFFFFF) % table.length;
048: chain = table[index];
049: table[index] = this ;
050: }
051:
052: public String getName() {
053: return name;
054: }
055:
056: public static NamedUnit lookup(String name) {
057: name = name.intern();
058: int hash = name.hashCode();
059: int index = (hash & 0x7FFFFFFF) % table.length;
060: for (NamedUnit unit = table[index]; unit != null; unit = unit.chain) {
061: if (unit.name == name)
062: return unit;
063: }
064: return null;
065: }
066:
067: public static NamedUnit lookup(String name, double scale, Unit base) {
068: name = name.intern();
069: int hash = name.hashCode();
070: int index = (hash & 0x7FFFFFFF) % table.length;
071: for (NamedUnit unit = table[index]; unit != null; unit = unit.chain) {
072: if (unit.name == name && unit.scale == scale
073: && unit.base == base)
074: return unit;
075: }
076: return null;
077: }
078:
079: public static NamedUnit make(String name, double scale, Unit base) {
080: NamedUnit old = lookup(name, scale, base);
081: return old == null ? new NamedUnit(name, scale, base) : old;
082: }
083:
084: public static NamedUnit make(String name, Quantity value) {
085: double scale;
086: if (value instanceof DQuantity)
087: scale = ((DQuantity) value).factor;
088: else if (value.imValue() != 0.0)
089: throw new ArithmeticException("defining " + name
090: + " using complex value");
091: else
092: scale = value.re().doubleValue();
093: Unit base = value.unit();
094: NamedUnit old = lookup(name, scale, base);
095: return old == null ? new NamedUnit(name, scale, base) : old;
096: }
097:
098: /**
099: * @serialData Write the unit name (using writeUTF), followed by
100: * the definition (value) of this unit as a scale followed by a base.
101: */
102:
103: public void writeExternal(ObjectOutput out) throws IOException {
104: out.writeUTF(name);
105: out.writeDouble(scale);
106: out.writeObject(base);
107: }
108:
109: public void readExternal(ObjectInput in) throws IOException,
110: ClassNotFoundException {
111: name = in.readUTF();
112: scale = in.readDouble();
113: base = (Unit) in.readObject();
114: }
115:
116: public Object readResolve() throws ObjectStreamException {
117: NamedUnit unit = lookup(name, scale, base);
118: if (unit != null)
119: return unit;
120: init();
121: return this;
122: }
123: }
|