W3C home > Mailing lists > Public > www-validator-cvs@w3.org > September 2012

2002/css-validator/org/w3c/css/values CssAngle.java,1.11,1.12 CssFrequency.java,1.8,1.9 CssLength.java,1.12,1.13 CssResolution.java,1.9,1.10 CssTime.java,1.8,1.9 CssUnitsCSS2.java,1.2,1.3 CssUnitsCSS21.java,1.2,1.3 CssUnitsCSS3.java,1.2,1.3

From: Yves Lafon via cvs-syncmail <cvsmail@w3.org>
Date: Fri, 07 Sep 2012 20:41:13 +0000
To: www-validator-cvs@w3.org
Message-Id: <E1TA5MX-0002Ze-Ud@lionel-hutz.w3.org>
Update of /sources/public/2002/css-validator/org/w3c/css/values
In directory hutz:/tmp/cvs-serv9862

Modified Files:
	CssAngle.java CssFrequency.java CssLength.java 
	CssResolution.java CssTime.java CssUnitsCSS2.java 
	CssUnitsCSS21.java CssUnitsCSS3.java 
Log Message:
revamped unit check per CSS level, moved remaining float-based values to BigDecimal (need more work to eliminate float testing in the code)

Index: CssUnitsCSS3.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/values/CssUnitsCSS3.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- CssUnitsCSS3.java	7 Sep 2012 14:57:01 -0000	1.2
+++ CssUnitsCSS3.java	7 Sep 2012 20:41:11 -0000	1.3
@@ -8,6 +8,8 @@
 import org.w3c.css.util.ApplContext;
 import org.w3c.css.util.InvalidParamException;
 
+import java.math.BigDecimal;
+
 /**
  * @spec http://www.w3.org/TR/2012/CR-css3-values-20120828/
  */
@@ -23,14 +25,37 @@
 	public static final String[] angle_units = {
 			"deg", "grad", "rad", "turn"
 	};
+	private static final BigDecimal[] angle_mult;
+
+	static {
+		angle_mult = new BigDecimal[angle_units.length];
+		angle_mult[0] = BigDecimal.ONE;
+		angle_mult[1] = BigDecimal.valueOf(9.0 / 10.0);
+		angle_mult[2] = BigDecimal.valueOf(180.0 / Math.PI);
+		angle_mult[3] = BigDecimal.valueOf(360);
+	}
 
 	public static final String[] time_units = {
 			"ms", "s"
 	};
+	private static BigDecimal[] time_mult;
+
+	static {
+		time_mult = new BigDecimal[time_units.length];
+		time_mult[0] = BigDecimal.valueOf(0.001);
+		time_mult[1] = BigDecimal.ONE;
+	}
 
 	public static final String[] frequency_units = {
-			"kHz", "Hz"
+			"khz", "hz"
 	};
+	private static BigDecimal[] frequency_mult;
+
+	static {
+		frequency_mult = new BigDecimal[frequency_units.length];
+		frequency_mult[0] = BigDecimal.valueOf(1000);
+		frequency_mult[1] = BigDecimal.ONE;
+	}
 
 	public static final String[] resolution_units = {
 			"dpi", "dpcm", "ddpx"
@@ -68,4 +93,65 @@
 		}
 		length.unit = matchedUnit;
 	}
+
+	protected static void parseAngleUnit(String unit, CssAngle angle, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < angle_units.length; i++) {
+			if (angle_units[i].equals(unit)) {
+				matchedUnit = angle_units[i];
+				angle.factor = angle_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		angle.unit = matchedUnit;
+	}
+
+	protected static void parseFrequencyUnit(String unit, CssFrequency frequency, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < frequency_units.length; i++) {
+			if (frequency_units[i].equals(unit)) {
+				matchedUnit = frequency_units[i];
+				frequency.factor = frequency_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		frequency.unit = matchedUnit;
+	}
+
+
+	protected static void parseTimeUnit(String unit, CssTime time, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < time_units.length; i++) {
+			if (time_units[i].equals(unit)) {
+				matchedUnit = time_units[i];
+				time.factor = time_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		time.unit = matchedUnit;
+	}
+
+	protected static void parseResolutionUnit(String unit, CssResolution time, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (String s : resolution_units) {
+			if (s.equals(unit)) {
+				time.unit = s;
+				return;
+			}
+		}
+		throw new InvalidParamException("unit", unit, ac);
+	}
 }

Index: CssResolution.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/values/CssResolution.java,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- CssResolution.java	22 Oct 2011 13:36:23 -0000	1.9
+++ CssResolution.java	7 Sep 2012 20:41:11 -0000	1.10
@@ -8,126 +8,119 @@
 package org.w3c.css.values;
 
 import org.w3c.css.util.ApplContext;
-import org.w3c.css.util.CssVersion;
 import org.w3c.css.util.InvalidParamException;
-import org.w3c.css.util.Util;
+
+import java.math.BigDecimal;
 
 /**
- * @since CSS3
  * @spec http://www.w3.org/TR/2010/CR-css3-mediaqueries-20100727/#values
+ * @since CSS3
  */
 public class CssResolution extends CssValue {
 
-    public static final int type = CssTypes.CSS_RESOLUTION;
-
-    public final int getType() {
-        return type;
-    }
-
-    private Float value;
-    private String unit;
-    boolean isInt;
-
-    /**
-     * Create a new CssResolution
-     */
-    public CssResolution() {
-    }
+	public static final int type = CssTypes.CSS_RESOLUTION;
 
-    private void setValue(String s) {
-        try {
-            new Integer(s);
-            isInt = true;
-        } catch (NumberFormatException e) {
-            isInt = false;
-        } finally {
-            value = new Float(s);
-        }
-    }
+	public final int getType() {
+		return type;
+	}
 
-    /**
-     * Set the value of this Resolution.
-     *
-     * @param s  the string representation of the Resolution.
-     * @param ac For errors and warnings reports.
-     * @throws InvalidParamException The unit is incorrect
-     */
-    public void set(String s, ApplContext ac) throws InvalidParamException {
+	private BigDecimal value;
+	protected String unit;
+	private boolean isInt = false;
 
-        s = s.toLowerCase();
-        int length = s.length();
-        String unit = "";
-        if (s.contains("dpi")) {
-            unit = s.substring(length - 3, length);
-            setValue(s.substring(0, length - 3));
-            if (unit.equals("dpi")) {
-                this.unit = unit;
-            }
-            return;
-        } else if (s.contains("dpcm")) {
-            unit = s.substring(length - 4, length);
-            setValue(s.substring(0, length - 4));
-            if (unit.equals("dpcm")) {
-                this.unit = unit;
-            }
-            return;
-        }
+	/**
+	 * Create a new CssResolution
+	 */
+	public CssResolution() {
+	}
 
-        if (ac.getCssVersion().compareTo(CssVersion.CSS3) < 0) {
-            throw new InvalidParamException("unit", unit, ac);
-        }
+	private void setValue(String s) {
+		value = new BigDecimal(s);
+		try {
+			value.toBigIntegerExact();
+			isInt = true;
+		} catch (ArithmeticException e) {
+			isInt = false;
+		}
+	}
 
-        throw new InvalidParamException("unit", unit, ac);
-    }
+	/**
+	 * Set the value of this Resolution.
+	 *
+	 * @param s  the string representation of the Resolution.
+	 * @param ac For errors and warnings reports.
+	 * @throws InvalidParamException The unit is incorrect
+	 */
+	public void set(String s, ApplContext ac) throws InvalidParamException {
+		String low_s = s.toLowerCase();
+		int length = low_s.length();
+		int unitIdx = length - 1;
+		char c = low_s.charAt(unitIdx);
+		while (unitIdx > 0 && c <= 'z' && c >= 'a') {
+			c = low_s.charAt(--unitIdx);
+		}
+		if (unitIdx == length - 1) {
+			throw new InvalidParamException("unit", s, ac);
+		}
+		// we go back to the beginning of the unit
+		unitIdx++;
+		String unit_str = low_s.substring(unitIdx, length);
+		// let's test the unit
+		switch (ac.getCssVersion()) {
+			case CSS3:
+				CssUnitsCSS3.parseResolutionUnit(unit_str, this, ac);
+				break;
+			default:
+				throw new InvalidParamException("unit", s, ac);
+		}
+		try {
+			setValue(low_s.substring(0, unitIdx));
+		} catch (NumberFormatException nex) {
+			throw new InvalidParamException("invalid-number",
+					low_s.substring(0, unitIdx), ac);
+		}
+	}
 
-    /**
-     * Returns the current value
-     */
-    public Object get() {
-        if (isInt) {
-            return new Integer(value.intValue());
-        }
-        return value;
-    }
+	/**
+	 * Returns the current value
+	 */
+	public Object get() {
+		if (isInt) {
+			return new Integer(value.intValue());
+		}
+		return value;
+	}
 
-    /**
-     * @return a float
-     *
-     */
-    public float getFloatValue() {
-        return value.floatValue();
-    }
+	/**
+	 * @return a float
+	 */
+	public float getFloatValue() {
+		return value.floatValue();
+	}
 
-    /**
-     * @return the current value
-     */
-    public String getUnit() {
-        return unit;
-    }
+	/**
+	 * @return the current value
+	 */
+	public String getUnit() {
+		return unit;
+	}
 
-    /**
-     * Returns a string representation of the object.
-     */
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        if (isInt) {
-           sb.append(Integer.toString(value.intValue()));
-        } else {
-            sb.append(Util.displayFloat(value));
-        }
-        sb.append(unit);
-        return sb.toString();
-    }
+	/**
+	 * Returns a string representation of the object.
+	 */
+	public String toString() {
+		return value.toPlainString() + ((BigDecimal.ZERO.equals(value)) ? "dpi" : unit);
+	}
 
-    /**
-     * Compares two values for equality.
-     *
-     * @param value The other value.
-     */
-    public boolean equals(Object value) {
-        return (value instanceof CssResolution &&
-                this.value.equals(((CssResolution) value).value) &&
-                unit.equals(((CssResolution) value).unit));
-    }
+	/**
+	 * Compares two values for equality.
+	 *
+	 * @param value The other value.
+	 */
+	public boolean equals(Object value) {
+		return (value instanceof CssResolution &&
+				this.value.equals(((CssResolution) value).value) &&
+				unit.equals(((CssResolution) value).unit));
+	}
 }
 

Index: CssUnitsCSS2.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/values/CssUnitsCSS2.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- CssUnitsCSS2.java	7 Sep 2012 14:57:01 -0000	1.2
+++ CssUnitsCSS2.java	7 Sep 2012 20:41:11 -0000	1.3
@@ -8,6 +8,8 @@
 import org.w3c.css.util.ApplContext;
 import org.w3c.css.util.InvalidParamException;
 
+import java.math.BigDecimal;
+
 /**
  * @spec http://www.w3.org/TR/2008/REC-CSS2-20080411/syndata.html#values
  */
@@ -23,14 +25,36 @@
 	private static final String[] angle_units = {
 			"deg", "grad", "rad"
 	};
+	private static final BigDecimal[] angle_mult;
+
+	static {
+		angle_mult = new BigDecimal[angle_units.length];
+		angle_mult[0] = BigDecimal.ONE;
+		angle_mult[1] = BigDecimal.valueOf(9.0 / 10.0);
+		angle_mult[2] = BigDecimal.valueOf(180.0 / Math.PI);
+	}
 
 	private static final String[] time_units = {
 			"ms", "s"
 	};
+	private static BigDecimal[] time_mult;
+
+	static {
+		time_mult = new BigDecimal[time_units.length];
+		time_mult[0] = BigDecimal.valueOf(0.001);
+		time_mult[1] = BigDecimal.ONE;
+	}
 
 	private static final String[] frequency_units = {
-			"kHz", "Hz"
+			"khz", "hz"
 	};
+	private static BigDecimal[] frequency_mult;
+
+	static {
+		frequency_mult = new BigDecimal[frequency_units.length];
+		frequency_mult[0] = BigDecimal.valueOf(1000);
+		frequency_mult[1] = BigDecimal.ONE;
+	}
 
 	protected static String getRelativeLengthUnit(String unit) {
 		for (String s : relative_length_units) {
@@ -64,4 +88,53 @@
 		}
 		length.unit = matchedUnit;
 	}
+
+	protected static void parseAngleUnit(String unit, CssAngle angle, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < angle_units.length; i++) {
+			if (angle_units[i].equals(unit)) {
+				matchedUnit = angle_units[i];
+				angle.factor = angle_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		angle.unit = matchedUnit;
+	}
+
+	protected static void parseFrequencyUnit(String unit, CssFrequency frequency, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < frequency_units.length; i++) {
+			if (frequency_units[i].equals(unit)) {
+				matchedUnit = frequency_units[i];
+				frequency.factor = frequency_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		frequency.unit = matchedUnit;
+	}
+
+
+	protected static void parseTimeUnit(String unit, CssTime time, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < time_units.length; i++) {
+			if (time_units[i].equals(unit)) {
+				matchedUnit = time_units[i];
+				time.factor = time_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		time.unit = matchedUnit;
+	}
 }

Index: CssTime.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/values/CssTime.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- CssTime.java	9 Feb 2012 17:36:33 -0000	1.8
+++ CssTime.java	7 Sep 2012 20:41:11 -0000	1.9
@@ -35,11 +35,15 @@
         return type;
     }
 
+	private BigDecimal value;
+	protected String unit;
+	protected BigDecimal factor = BigDecimal.ONE;
+
     /**
      * Create a new CssTime.
      */
     public CssTime() {
-        value = defaultValue;
+        value = BigDecimal.ZERO;
     }
 
     /**
@@ -54,46 +58,46 @@
     /**
      * Set the value of this time.
      *
-     * @param ts  the string representation of the time.
+     * @param s  the string representation of the time.
      * @param ac For errors and warnings reports.
      * @throws InvalidParamException The unit is incorrect
      */
-    public void set(String ts, ApplContext ac) throws InvalidParamException {
-        String s = ts.toLowerCase();
-        int length = s.length();
-        String unit;
-
-        if (s.charAt(length - 2) == 'm') {
-            unit = s.substring(length - 2, length);
-            this.value = new BigDecimal(s.substring(0, length - 2));
-        } else {
-            unit = s.substring(length - 1, length);
-            this.value = new BigDecimal(s.substring(0, length - 1));
-        }
-
-        if (this.value.signum() == -1) {
-            throw new InvalidParamException("negative-value",
-                    this.value.toString(), ac);
-        }
-
-        this.unit = 1; // there is no unit by default
-
-        if (!BigDecimal.ZERO.equals(this.value)) {
-            int hash = unit.hashCode();
-            int i = 0;
-            while (i < units.length) {
-                if (hash == hash_units[i]) {
-                    this.unit = i;
-                    return;
-                }
-                i++;
-            }
-        } else {
-            return;
-        }
+    public void set(String s, ApplContext ac) throws InvalidParamException {
+		String low_s = s.toLowerCase();
+		int length = low_s.length();
+		int unitIdx = length - 1;
+		char c = low_s.charAt(unitIdx);
+		while (unitIdx > 0 && c <= 'z' && c >= 'a') {
+			c = low_s.charAt(--unitIdx);
+		}
+		if (unitIdx == length - 1) {
+			throw new InvalidParamException("unit", s, ac);
+		}
+		// we go back to the beginning of the unit
+		unitIdx++;
+		String unit_str = low_s.substring(unitIdx, length);
+		// let's test the unit
+		switch (ac.getCssVersion()) {
+			case CSS2:
+				CssUnitsCSS2.parseTimeUnit(unit_str, this, ac);
+				break;
+			case CSS21:
+				CssUnitsCSS21.parseTimeUnit(unit_str, this, ac);
+				break;
+			case CSS3:
+				CssUnitsCSS3.parseTimeUnit(unit_str, this, ac);
+				break;
+			default:
+				throw new InvalidParamException("unit", s, ac);
+		}
+		try {
+			value = new BigDecimal(low_s.substring(0, unitIdx));
+		} catch (NumberFormatException nex) {
+			throw new InvalidParamException("invalid-number",
+					low_s.substring(0, unitIdx), ac);
+		}
 
-        throw new InvalidParamException("unit", unit, ac);
-    }
+	}
 
     /**
      * Returns the current value
@@ -101,17 +105,15 @@
      * TODO move to a BigDecimal
      */
     public Object get() {
-        if (unit == 1) {
-            return new Float(value.floatValue() * 1000);
-        }
-        return value;
-    }
+		return value.multiply(factor).floatValue();
+
+	}
 
     /**
      * Returns the current value
      */
     public String getUnit() {
-        return units[unit];
+        return unit;
     }
 
     /**
@@ -121,29 +123,21 @@
         if (BigDecimal.ZERO.equals(value)) {
             return value.toPlainString();
         }
-        return value.toPlainString() + getUnit();
+        return value.toPlainString() + unit;
     }
 
     /**
      * Compares two values for equality.
      *
-     * @param value The other value.
+     * @param other The other value.
      */
-    public boolean equals(Object value) {
-        return (value instanceof CssTime && this.value.equals(((CssTime) value).value) &&
-                unit == ((CssTime) value).unit);
-    }
+    public boolean equals(Object other) {
+		if (((CssValue)other).getType() == getType()) {
+			return get().equals(((CssValue)other).get());
+		}
+		return false;
+	}
 
-    private BigDecimal value;
-    private int unit;
-    private static String[] units = {"ms", "s"};
-    private static int[] hash_units;
-    private static BigDecimal defaultValue = BigDecimal.ZERO;
 
-    static {
-        hash_units = new int[units.length];
-        for (int i = 0; i < units.length; i++)
-            hash_units[i] = units[i].hashCode();
-    }
 }
 

Index: CssFrequency.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/values/CssFrequency.java,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- CssFrequency.java	9 Feb 2012 17:36:33 -0000	1.8
+++ CssFrequency.java	7 Sep 2012 20:41:11 -0000	1.9
@@ -36,16 +36,9 @@
     }
 
     private BigDecimal value;
-    private int unit;
-    private static String[] units = {"Hz", "kHz"};
-    private static int[] hash_units;
-    private static BigDecimal defaultValue = BigDecimal.ZERO;
-
-    static {
-        hash_units = new int[units.length];
-        for (int i = 0; i < units.length; i++)
-            hash_units[i] = units[i].toLowerCase().hashCode();
-    }
+	protected String unit;
+	protected BigDecimal factor = BigDecimal.ONE;
+	private static BigDecimal defaultValue = BigDecimal.ZERO;
 
     /**
      * Create a new CssFrequency
@@ -71,34 +64,40 @@
      * @throws InvalidParamException The unit is incorrect
      */
     public void set(String s, ApplContext ac) throws InvalidParamException {
-        s = s.toLowerCase();
-        int length = s.length();
-        String unit;
-        BigDecimal v;
-        if (s.charAt(length - 3) == 'k') {
-            unit = s.substring(length - 3, length);
-            v = new BigDecimal(s.substring(0, length - 3));
-        } else {
-            unit = s.substring(length - 2, length);
-            v = new BigDecimal(s.substring(0, length - 2));
-        }
-        int hash = unit.hashCode();
-
-
-        int i = 0;
-        while (i < units.length) {
-            if (hash == hash_units[i]) {
-                this.unit = i;
-                break;
-            }
-            i++;
-        }
-
-        if (i == units.length) {
-            throw new InvalidParamException("unit", unit, ac);
-        }
-
-        this.value = v;
+		String low_s = s.toLowerCase();
+		int length = low_s.length();
+		int unitIdx = length - 1;
+		char c = low_s.charAt(unitIdx);
+		while (unitIdx > 0 && c <= 'z' && c >= 'a') {
+			c = low_s.charAt(--unitIdx);
+		}
+		if (unitIdx == length - 1) {
+			throw new InvalidParamException("unit", s, ac);
+		}
+		// we go back to the beginning of the unit
+		unitIdx++;
+		String unit_str = low_s.substring(unitIdx, length);
+		// let's test the unit
+		switch (ac.getCssVersion()) {
+			case CSS2:
+				CssUnitsCSS2.parseFrequencyUnit(unit_str, this, ac);
+				break;
+			case CSS21:
+				CssUnitsCSS21.parseFrequencyUnit(unit_str, this, ac);
+				break;
+			case CSS3:
+				CssUnitsCSS3.parseFrequencyUnit(unit_str, this, ac);
+				break;
+			case CSS1:
+			default:
+				throw new InvalidParamException("unit", s, ac);
+		}
+		try {
+			value = new BigDecimal(low_s.substring(0, unitIdx));
+		} catch (NumberFormatException nex) {
+			throw new InvalidParamException("invalid-number",
+					low_s.substring(0, unitIdx), ac);
+		}
 
     }
 
@@ -107,17 +106,14 @@
      */
     public Object get() {
         // TODO FIXME should not be a Float...
-        if (unit == 1) {
-            return new Float(value.floatValue() * 1000);
-        }
-        return value.floatValue();
+        return value.multiply(factor).floatValue();
     }
 
     /**
      * Returns the current value
      */
     public String getUnit() {
-        return units[unit];
+        return unit;
     }
 
     /**
@@ -127,7 +123,7 @@
         if (BigDecimal.ZERO.equals(value)) {
             return value.toPlainString();
         }
-        return value.toPlainString() + getUnit();
+        return value.toPlainString() + unit;
     }
 
     /**
@@ -138,7 +134,7 @@
     public boolean equals(Object value) {
         return (value instanceof CssFrequency
                 && this.value.equals(((CssFrequency) value).value)
-                && unit == ((CssFrequency) value).unit);
+                && unit.equals(((CssFrequency) value).unit));
     }
 
 

Index: CssUnitsCSS21.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/values/CssUnitsCSS21.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- CssUnitsCSS21.java	7 Sep 2012 14:57:01 -0000	1.2
+++ CssUnitsCSS21.java	7 Sep 2012 20:41:11 -0000	1.3
@@ -8,6 +8,8 @@
 import org.w3c.css.util.ApplContext;
 import org.w3c.css.util.InvalidParamException;
 
+import java.math.BigDecimal;
+
 /**
  * @spec http://www.w3.org/TR/2011/REC-CSS2-20110607/syndata.html#values
  */
@@ -22,17 +24,39 @@
 
 	// defined in Appendix A.2
 	// http://www.w3.org/TR/2011/REC-CSS2-20110607/aural.html#aural-intro
-	public static final String[] angle_units = {
+	private static final String[] angle_units = {
 			"deg", "grad", "rad"
 	};
+	private static final BigDecimal[] angle_mult;
+
+	static {
+		angle_mult = new BigDecimal[angle_units.length];
+		angle_mult[0] = BigDecimal.ONE;
+		angle_mult[1] = BigDecimal.valueOf(9.0 / 10.0);
+		angle_mult[2] = BigDecimal.valueOf(180.0 / Math.PI);
+	}
 
 	public static final String[] time_units = {
 			"ms", "s"
 	};
+	private static BigDecimal[] time_mult;
+
+	static {
+		time_mult = new BigDecimal[time_units.length];
+		time_mult[0] = BigDecimal.valueOf(0.001);
+		time_mult[1] = BigDecimal.ONE;
+	}
 
 	public static final String[] frequency_units = {
-			"kHz", "Hz"
+			"khz", "hz"
 	};
+	private static BigDecimal[] frequency_mult;
+
+	static {
+		frequency_mult = new BigDecimal[frequency_units.length];
+		frequency_mult[0] = BigDecimal.valueOf(1000);
+		frequency_mult[1] = BigDecimal.ONE;
+	}
 
 	protected static String getRelativeLengthUnit(String unit) {
 		for (String s : relative_length_units) {
@@ -66,4 +90,52 @@
 		}
 		length.unit = matchedUnit;
 	}
+
+	protected static void parseAngleUnit(String unit, CssAngle angle, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < angle_units.length; i++) {
+			if (angle_units[i].equals(unit)) {
+				matchedUnit = angle_units[i];
+				angle.factor = angle_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		angle.unit = matchedUnit;
+	}
+
+	protected static void parseFrequencyUnit(String unit, CssFrequency frequency, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < frequency_units.length; i++) {
+			if (frequency_units[i].equals(unit)) {
+				matchedUnit = frequency_units[i];
+				frequency.factor = frequency_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		frequency.unit = matchedUnit;
+	}
+
+	protected static void parseTimeUnit(String unit, CssTime time, ApplContext ac)
+			throws InvalidParamException {
+		String matchedUnit = null;
+		for (int i = 0; i < time_units.length; i++) {
+			if (time_units[i].equals(unit)) {
+				matchedUnit = time_units[i];
+				time.factor = time_mult[i];
+				break;
+			}
+		}
+		if (matchedUnit == null) {
+			throw new InvalidParamException("unit", unit, ac);
+		}
+		time.unit = matchedUnit;
+	}
 }

Index: CssAngle.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/values/CssAngle.java,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- CssAngle.java	14 Sep 2011 16:31:50 -0000	1.11
+++ CssAngle.java	7 Sep 2012 20:41:11 -0000	1.12
@@ -7,9 +7,9 @@
 package org.w3c.css.values;
 
 import org.w3c.css.util.ApplContext;
-import org.w3c.css.util.CssVersion;
 import org.w3c.css.util.InvalidParamException;
-import org.w3c.css.util.Util;
+
+import java.math.BigDecimal;
 
 /**
  * <H3>Angle</H3>
@@ -31,178 +31,135 @@
  */
 public class CssAngle extends CssValue implements CssValueFloat {
 
-    public static final int type = CssTypes.CSS_ANGLE;
-
-    public final int getType() {
-        return type;
-    }
-
-    Float value;
-    String unit;
-
-    static final String deg = "deg";
-    static final String rad = "rad";
-    static final String grad = "grad";
-    static final String turn = "turn"; // CSS3
-    static final String allowed_values[];
-
-    static Float defaultValue = new Float(0);
-
-    static {
-        allowed_values = new String[4];
-        allowed_values[0] = deg;
-        allowed_values[1] = rad;
-        allowed_values[2] = grad;
-        allowed_values[3] = turn;
-    }
-
-    /**
-     * Create a new CssAngle.
-     */
-    public CssAngle() {
-        this(defaultValue);
-    }
-
-    /**
-     * Create a new CssAngle
-     */
-    public CssAngle(float v) {
-        this(new Float(v));
-    }
-
-    /**
-     * Create a new CssAngle
-     */
-    public CssAngle(Float angle) {
-        value = angle;
-    }
+	public static final int type = CssTypes.CSS_ANGLE;
 
-    private String checkUnit(String unitString, ApplContext ac)
-            throws InvalidParamException {
-        for (String s : allowed_values) {
-            if (s.matches(unitString)) {
-                if ((s == turn) && (ac.getCssVersion().compareTo(CssVersion.CSS3) < 0)) {
-                    throw new InvalidParamException("unit", s, ac);
-                }
-                return s;
-            }
-        }
-        throw new InvalidParamException("unit", unitString, ac);
-    }
+	public final int getType() {
+		return type;
+	}
 
-    /**
-     * Set the value of this angle.
-     *
-     * @param s  The string representation of the angle
-     * @param ac For errors and warnings reports
-     * @throws InvalidParamException The unit is incorrect
-     */
-    public void set(String s, ApplContext ac) throws InvalidParamException {
-        s = s.toLowerCase();
-        int length = s.length();
-        // by construction we should receive only valid strings with valid
-        // units however let's check things...
-        // a valid string should be at least [0-9]<3 letter units> so >= 4 chars
-        if (length >= 4) {
-            char c = s.charAt(length - 4);
-            if (c == 't' || c == 'g') {
-                // turn or grad
-                unit = checkUnit(s.substring(length - 4), ac);
-                value = Float.valueOf(s.substring(0, length - 4));
-            } else {
-                // others so deg, rad 3 letters long.
-                unit = checkUnit(s.substring(length - 3), ac);
-                value = Float.valueOf(s.substring(0, length - 3));
-            }
-        } else {
-            throw new InvalidParamException("unit", s, ac);
-        }
-    }
+	private static final BigDecimal deg360;
 
-    /**
-     * Returns the current value
-     */
-    public Object get() {
-        return value;
-    }
+	static {
+		deg360 = BigDecimal.valueOf(360);
+	}
 
-    public float getValue() {
-        return value.floatValue();
-    }
+	private BigDecimal value;
+	protected BigDecimal factor = BigDecimal.ONE;
+	String unit;
 
-    /**
-     * Returns the current value
-     */
-    public String getUnit() {
-        return unit;
-    }
+	/**
+	 * Create a new CssAngle.
+	 */
+	public CssAngle() {
+		this(BigDecimal.ZERO);
+	}
 
-    /**
-     * Returns a string representation of the object.
-     */
-    public String toString() {
-        if (value.floatValue() != 0) {
-            return Util.displayFloat(value) + getUnit();
-        } else {
-            // let's say that 0 is 0deg for sanity.
-            return Util.displayFloat(value) + deg;
-        }
-    }
+	/**
+	 * Create a new CssAngle
+	 */
+	public CssAngle(float v) {
+		this(new BigDecimal(v));
+	}
 
-    /**
-     * Compares two values for equality.
-     *
-     * @param value The other value.
-     */
-    public boolean equals(Object value) {
-        return (value instanceof CssAngle &&
-                this.value.equals(((CssAngle) value).value) &&
-                unit == ((CssAngle) value).unit);
-    }
+	/**
+	 * Create a new CssAngle
+	 */
+	public CssAngle(BigDecimal angle) {
+		value = angle;
+	}
 
-    private float normalize(float degree) {
-        degree %= 360.f;
-        if (degree < 0.f) {
-            degree += 360.f;
-        }
-        return degree;
-    }
+	/**
+	 * Set the value of this angle.
+	 *
+	 * @param s  The string representation of the angle
+	 * @param ac For errors and warnings reports
+	 * @throws InvalidParamException The unit is incorrect
+	 */
+	public void set(String s, ApplContext ac) throws InvalidParamException {
+		String low_s = s.toLowerCase();
+		int length = low_s.length();
+		int unitIdx = length - 1;
+		char c = low_s.charAt(unitIdx);
+		while (unitIdx > 0 && c <= 'z' && c >= 'a') {
+			c = low_s.charAt(--unitIdx);
+		}
+		if (unitIdx == length - 1) {
+			throw new InvalidParamException("unit", s, ac);
+		}
+		// we go back to the beginning of the unit
+		unitIdx++;
+		String unit_str = low_s.substring(unitIdx, length);
+		// let's test the unit
+		switch (ac.getCssVersion()) {
+			case CSS2:
+				CssUnitsCSS2.parseAngleUnit(unit_str, this, ac);
+				break;
+			case CSS21:
+				CssUnitsCSS21.parseAngleUnit(unit_str, this, ac);
+				break;
+			case CSS3:
+				CssUnitsCSS3.parseAngleUnit(unit_str, this, ac);
+				break;
+			default:
+				throw new InvalidParamException("unit", s, ac);
+		}
+		try {
+			value = new BigDecimal(low_s.substring(0, unitIdx));
+		} catch (NumberFormatException nex) {
+			throw new InvalidParamException("invalid-number",
+					low_s.substring(0, unitIdx), ac);
+		}
+	}
 
-    //@@FIXME I should return the remainder for all ...
+	/**
+	 * Returns the current value
+	 */
+	public Object get() {
+		return value;
+	}
 
-    public float getDegree() {
-        float angle = value.floatValue();
-        if (unit == deg) {
-            return normalize(angle);
-        } else if (unit == rad) {
-            return normalize(angle * (180.f / ((float) Math.PI)));
-        } else if (unit == grad) {
-            return normalize(angle * (9.f / 10.f));
-        } else if (unit == turn) {
-            return normalize(angle * 360.f);
-        }
+	public float getValue() {
+		return value.floatValue();
+	}
 
-        System.err.println("[ERROR] in org.w3c.css.values.CssAngle");
-        System.err.println("[ERROR] Please report (" + unit + ")");
-        return (float) 0;
-    }
+	/**
+	 * Returns the current value
+	 */
+	public String getUnit() {
+		return unit;
+	}
 
-    public boolean isDegree() {
-        return unit == deg;
-    }
+	/**
+	 * Returns a string representation of the object.
+	 */
+	public String toString() {
+		return value.toPlainString() + ((BigDecimal.ZERO.equals(value)) ? "deg" : unit);
+	}
 
-    public boolean isGradian() {
-        return unit == grad;
-    }
+	/**
+	 * Compares two values for equality.
+	 *
+	 * @param value The other value.
+	 */
+	public boolean equals(Object value) {
+		return (value instanceof CssAngle &&
+				this.value.equals(((CssAngle) value).value) &&
+				unit.equals(((CssAngle) value).unit));
+	}
 
-    public boolean isRadian() {
-        return unit == rad;
-    }
+	private BigDecimal normalize(BigDecimal degree) {
+		degree = degree.remainder(deg360);
+		if (degree.compareTo(BigDecimal.ZERO) < 0) {
+			degree.add(deg360);
+		}
+		return degree;
+	}
 
-    public boolean isTurn() {
-        return unit == turn;
-    }
+	//@@FIXME I should return the remainder for all ...
 
+	public float getDegree() {
+		return normalize(value.multiply(factor)).floatValue();
+	}
 
 }
 

Index: CssLength.java
===================================================================
RCS file: /sources/public/2002/css-validator/org/w3c/css/values/CssLength.java,v
retrieving revision 1.12
retrieving revision 1.13
diff -u -d -r1.12 -r1.13
--- CssLength.java	7 Sep 2012 15:13:42 -0000	1.12
+++ CssLength.java	7 Sep 2012 20:41:11 -0000	1.13
@@ -130,7 +130,7 @@
 		unitIdx++;
 		String unit_str = low_s.substring(unitIdx, length);
 		// let's test the unit
-		boolean ok = true;
+
 		// TODO check the  if (!BigDecimal.ZERO.equals(value))) test
 		// that was here earlier
 		// seems legit to always test the unit no matter the value
Received on Friday, 7 September 2012 20:41:15 UTC

This archive was generated by hypermail 2.3.1 : Wednesday, 7 January 2015 15:17:51 UTC