PageRenderTime 61ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 1ms

/projects/jre-1.6.0/src/com/sun/org/apache/xerces/internal/impl/dv/xs/DoubleDV.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 247 lines | 152 code | 24 blank | 71 comment | 80 complexity | 541fecd2d93989da2e1f99253d439d06 MD5 | raw file
  1. /*
  2. * Copyright 2001-2005 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package com.sun.org.apache.xerces.internal.impl.dv.xs;
  17. import com.sun.org.apache.xerces.internal.impl.dv.InvalidDatatypeValueException;
  18. import com.sun.org.apache.xerces.internal.impl.dv.ValidationContext;
  19. import com.sun.org.apache.xerces.internal.xs.datatypes.XSDouble;
  20. /**
  21. * Represent the schema type "double"
  22. *
  23. * @xerces.internal
  24. *
  25. * @author Neeraj Bajaj, Sun Microsystems, inc.
  26. * @author Sandy Gao, IBM
  27. *
  28. * @version $Id: DoubleDV.java,v 1.4 2007/07/19 04:38:33 ofung Exp $
  29. */
  30. public class DoubleDV extends TypeValidator {
  31. public short getAllowedFacets(){
  32. return ( XSSimpleTypeDecl.FACET_PATTERN | XSSimpleTypeDecl.FACET_WHITESPACE | XSSimpleTypeDecl.FACET_ENUMERATION |XSSimpleTypeDecl.FACET_MAXINCLUSIVE |XSSimpleTypeDecl.FACET_MININCLUSIVE | XSSimpleTypeDecl.FACET_MAXEXCLUSIVE | XSSimpleTypeDecl.FACET_MINEXCLUSIVE );
  33. }//getAllowedFacets()
  34. //convert a String to Double form, we have to take care of cases specified in spec like INF, -INF and NaN
  35. public Object getActualValue(String content, ValidationContext context) throws InvalidDatatypeValueException {
  36. try{
  37. return new XDouble(content);
  38. } catch (NumberFormatException ex){
  39. throw new InvalidDatatypeValueException("cvc-datatype-valid.1.2.1", new Object[]{content, "double"});
  40. }
  41. }//getActualValue()
  42. // Can't call Double#compareTo method, because it's introduced in jdk 1.2
  43. public int compare(Object value1, Object value2) {
  44. return ((XDouble)value1).compareTo((XDouble)value2);
  45. }//compare()
  46. //distinguishes between identity and equality for double datatype
  47. //0.0 is equal but not identical to -0.0
  48. public boolean isIdentical (Object value1, Object value2) {
  49. if (value2 instanceof XDouble) {
  50. return ((XDouble)value1).isIdentical((XDouble)value2);
  51. }
  52. return false;
  53. }//isIdentical()
  54. /**
  55. * Returns true if it's possible that the given
  56. * string represents a valid floating point value
  57. * (excluding NaN, INF and -INF).
  58. */
  59. static boolean isPossibleFP(String val) {
  60. final int length = val.length();
  61. for (int i = 0; i < length; ++i) {
  62. char c = val.charAt(i);
  63. if (!(c >= '0' && c <= '9' || c == '.' ||
  64. c == '-' || c == '+' || c == 'E' || c == 'e')) {
  65. return false;
  66. }
  67. }
  68. return true;
  69. }
  70. private static final class XDouble implements XSDouble {
  71. private double value;
  72. public XDouble(String s) throws NumberFormatException {
  73. if (isPossibleFP(s)) {
  74. value = Double.parseDouble(s);
  75. }
  76. else if ( s.equals("INF") ) {
  77. value = Double.POSITIVE_INFINITY;
  78. }
  79. else if ( s.equals("-INF") ) {
  80. value = Double.NEGATIVE_INFINITY;
  81. }
  82. else if ( s.equals("NaN" ) ) {
  83. value = Double.NaN;
  84. }
  85. else {
  86. throw new NumberFormatException(s);
  87. }
  88. }
  89. public boolean equals(Object val) {
  90. if (val == this)
  91. return true;
  92. if (!(val instanceof XDouble))
  93. return false;
  94. XDouble oval = (XDouble)val;
  95. // NOTE: we don't distinguish 0.0 from -0.0
  96. if (value == oval.value)
  97. return true;
  98. if (value != value && oval.value != oval.value)
  99. return true;
  100. return false;
  101. }
  102. // NOTE: 0.0 is equal but not identical to -0.0
  103. public boolean isIdentical (XDouble val) {
  104. if (val == this) {
  105. return true;
  106. }
  107. if (value == val.value) {
  108. return (value != 0.0d ||
  109. (Double.doubleToLongBits(value) == Double.doubleToLongBits(val.value)));
  110. }
  111. if (value != value && val.value != val.value)
  112. return true;
  113. return false;
  114. }
  115. private int compareTo(XDouble val) {
  116. double oval = val.value;
  117. // this < other
  118. if (value < oval)
  119. return -1;
  120. // this > other
  121. if (value > oval)
  122. return 1;
  123. // this == other
  124. // NOTE: we don't distinguish 0.0 from -0.0
  125. if (value == oval)
  126. return 0;
  127. // one of the 2 values or both is/are NaN(s)
  128. if (value != value) {
  129. // this = NaN = other
  130. if (oval != oval)
  131. return 0;
  132. // this is NaN <> other
  133. return INDETERMINATE;
  134. }
  135. // other is NaN <> this
  136. return INDETERMINATE;
  137. }
  138. private String canonical;
  139. public synchronized String toString() {
  140. if (canonical == null) {
  141. if (value == Double.POSITIVE_INFINITY)
  142. canonical = "INF";
  143. else if (value == Double.NEGATIVE_INFINITY)
  144. canonical = "-INF";
  145. else if (value != value)
  146. canonical = "NaN";
  147. // NOTE: we don't distinguish 0.0 from -0.0
  148. else if (value == 0)
  149. canonical = "0.0E1";
  150. else {
  151. // REVISIT: use the java algorithm for now, because we
  152. // don't know what to output for 1.1d (which is no
  153. // actually 1.1)
  154. canonical = Double.toString(value);
  155. // if it contains 'E', then it should be a valid schema
  156. // canonical representation
  157. if (canonical.indexOf('E') == -1) {
  158. int len = canonical.length();
  159. // at most 3 longer: E, -, 9
  160. char[] chars = new char[len+3];
  161. canonical.getChars(0, len, chars, 0);
  162. // expected decimal point position
  163. int edp = chars[0] == '-' ? 2 : 1;
  164. // for non-zero integer part
  165. if (value >= 1 || value <= -1) {
  166. // decimal point position
  167. int dp = canonical.indexOf('.');
  168. // move the digits: ddd.d --> d.ddd
  169. for (int i = dp; i > edp; i--) {
  170. chars[i] = chars[i-1];
  171. }
  172. chars[edp] = '.';
  173. // trim trailing zeros: d00.0 --> d.000 --> d.
  174. while (chars[len-1] == '0')
  175. len--;
  176. // add the last zero if necessary: d. --> d.0
  177. if (chars[len-1] == '.')
  178. len++;
  179. // append E: d.dd --> d.ddE
  180. chars[len++] = 'E';
  181. // how far we shifted the decimal point
  182. int shift = dp - edp;
  183. // append the exponent --> d.ddEd
  184. // the exponent is at most 7
  185. chars[len++] = (char)(shift + '0');
  186. }
  187. else {
  188. // non-zero digit point
  189. int nzp = edp + 1;
  190. // skip zeros: 0.003
  191. while (chars[nzp] == '0')
  192. nzp++;
  193. // put the first non-zero digit to the left of '.'
  194. chars[edp-1] = chars[nzp];
  195. chars[edp] = '.';
  196. // move other digits (non-zero) to the right of '.'
  197. for (int i = nzp+1, j = edp+1; i < len; i++, j++)
  198. chars[j] = chars[i];
  199. // adjust the length
  200. len -= nzp - edp;
  201. // append 0 if nessary: 0.03 --> 3. --> 3.0
  202. if (len == edp + 1)
  203. chars[len++] = '0';
  204. // append E-: d.dd --> d.ddE-
  205. chars[len++] = 'E';
  206. chars[len++] = '-';
  207. // how far we shifted the decimal point
  208. int shift = nzp - edp;
  209. // append the exponent --> d.ddEd
  210. // the exponent is at most 3
  211. chars[len++] = (char)(shift + '0');
  212. }
  213. canonical = new String(chars, 0, len);
  214. }
  215. }
  216. }
  217. return canonical;
  218. }
  219. public double getValue() {
  220. return value;
  221. }
  222. }
  223. } // class DoubleDV