1 7 8 20 21 package java.text; 22 23 import java.io.InvalidObjectException ; 24 import java.io.IOException ; 25 import java.io.ObjectInputStream ; 26 import sun.text.Utility; 27 28 150 public class ChoiceFormat extends NumberFormat { 151 152 private static final long serialVersionUID = 1795184449645032964L; 154 155 159 public void applyPattern(String newPattern) { 160 StringBuffer [] segments = new StringBuffer [2]; 161 for (int i = 0; i < segments.length; ++i) { 162 segments[i] = new StringBuffer (); 163 } 164 double[] newChoiceLimits = new double[30]; 165 String [] newChoiceFormats = new String [30]; 166 int count = 0; 167 int part = 0; 168 double startValue = 0; 169 double oldStartValue = Double.NaN; 170 boolean inQuote = false; 171 for (int i = 0; i < newPattern.length(); ++i) { 172 char ch = newPattern.charAt(i); 173 if (ch=='\'') { 174 if ((i+1)<newPattern.length() && newPattern.charAt(i+1)==ch) { 176 segments[part].append(ch); 177 ++i; 178 } else { 179 inQuote = !inQuote; 180 } 181 } else if (inQuote) { 182 segments[part].append(ch); 183 } else if (ch == '<' || ch == '#' || ch == '\u2264') { 184 if (segments[0].equals("")) { 185 throw new IllegalArgumentException (); 186 } 187 try { 188 String tempBuffer = segments[0].toString(); 189 if (tempBuffer.equals("\u221E")) { 190 startValue = Double.POSITIVE_INFINITY; 191 } else if (tempBuffer.equals("-\u221E")) { 192 startValue = Double.NEGATIVE_INFINITY; 193 } else { 194 startValue = Double.valueOf(segments[0].toString()).doubleValue(); 195 } 196 } catch (Exception e) { 197 throw new IllegalArgumentException (); 198 } 199 if (ch == '<' && startValue != Double.POSITIVE_INFINITY && 200 startValue != Double.NEGATIVE_INFINITY) { 201 startValue = nextDouble(startValue); 202 } 203 if (startValue <= oldStartValue) { 204 throw new IllegalArgumentException (); 205 } 206 segments[0].setLength(0); 207 part = 1; 208 } else if (ch == '|') { 209 if (count == newChoiceLimits.length) { 210 newChoiceLimits = doubleArraySize(newChoiceLimits); 211 newChoiceFormats = doubleArraySize(newChoiceFormats); 212 } 213 newChoiceLimits[count] = startValue; 214 newChoiceFormats[count] = segments[1].toString(); 215 ++count; 216 oldStartValue = startValue; 217 segments[1].setLength(0); 218 part = 0; 219 } else { 220 segments[part].append(ch); 221 } 222 } 223 if (part == 1) { 225 if (count == newChoiceLimits.length) { 226 newChoiceLimits = doubleArraySize(newChoiceLimits); 227 newChoiceFormats = doubleArraySize(newChoiceFormats); 228 } 229 newChoiceLimits[count] = startValue; 230 newChoiceFormats[count] = segments[1].toString(); 231 ++count; 232 } 233 choiceLimits = new double[count]; 234 System.arraycopy(newChoiceLimits, 0, choiceLimits, 0, count); 235 choiceFormats = new String [count]; 236 System.arraycopy(newChoiceFormats, 0, choiceFormats, 0, count); 237 } 238 239 242 public String toPattern() { 243 StringBuffer result = new StringBuffer (); 244 for (int i = 0; i < choiceLimits.length; ++i) { 245 if (i != 0) { 246 result.append('|'); 247 } 248 double less = previousDouble(choiceLimits[i]); 252 double tryLessOrEqual = Math.abs(Math.IEEEremainder(choiceLimits[i], 1.0d)); 253 double tryLess = Math.abs(Math.IEEEremainder(less, 1.0d)); 254 255 if (tryLessOrEqual < tryLess) { 256 result.append(""+choiceLimits[i]); 257 result.append('#'); 258 } else { 259 if (choiceLimits[i] == Double.POSITIVE_INFINITY) { 260 result.append("\u221E"); 261 } else if (choiceLimits[i] == Double.NEGATIVE_INFINITY) { 262 result.append("-\u221E"); 263 } else { 264 result.append(""+less); 265 } 266 result.append('<'); 267 } 268 String text = choiceFormats[i]; 271 boolean needQuote = text.indexOf('<') >= 0 272 || text.indexOf('#') >= 0 273 || text.indexOf('\u2264') >= 0 274 || text.indexOf('|') >= 0; 275 if (needQuote) result.append('\''); 276 if (text.indexOf('\'') < 0) result.append(text); 277 else { 278 for (int j=0; j<text.length(); ++j) { 279 char c = text.charAt(j); 280 result.append(c); 281 if (c == '\'') result.append(c); 282 } 283 } 284 if (needQuote) result.append('\''); 285 } 286 return result.toString(); 287 } 288 289 293 public ChoiceFormat(String newPattern) { 294 applyPattern(newPattern); 295 } 296 297 301 public ChoiceFormat(double[] limits, String [] formats) { 302 setChoices(limits, formats); 303 } 304 305 319 public void setChoices(double[] limits, String formats[]) { 320 if (limits.length != formats.length) { 321 throw new IllegalArgumentException ( 322 "Array and limit arrays must be of the same length."); 323 } 324 choiceLimits = limits; 325 choiceFormats = formats; 326 } 327 328 332 public double[] getLimits() { 333 return choiceLimits; 334 } 335 336 340 public Object [] getFormats() { 341 return choiceFormats; 342 } 343 344 346 353 public StringBuffer format(long number, StringBuffer toAppendTo, 354 FieldPosition status) { 355 return format((double)number, toAppendTo, status); 356 } 357 358 364 public StringBuffer format(double number, StringBuffer toAppendTo, 365 FieldPosition status) { 366 int i; 368 for (i = 0; i < choiceLimits.length; ++i) { 369 if (!(number >= choiceLimits[i])) { 370 break; 372 } 373 } 374 --i; 375 if (i < 0) i = 0; 376 return toAppendTo.append(choiceFormats[i]); 378 } 379 380 392 public Number parse(String text, ParsePosition status) { 393 int start = status.index; 395 int furthest = start; 396 double bestNumber = Double.NaN; 397 double tempNumber = 0.0; 398 for (int i = 0; i < choiceFormats.length; ++i) { 399 String tempString = choiceFormats[i]; 400 if (text.regionMatches(start, tempString, 0, tempString.length())) { 401 status.index = start + tempString.length(); 402 tempNumber = choiceLimits[i]; 403 if (status.index > furthest) { 404 furthest = status.index; 405 bestNumber = tempNumber; 406 if (furthest == text.length()) break; 407 } 408 } 409 } 410 status.index = furthest; 411 if (status.index == start) { 412 status.errorIndex = furthest; 413 } 414 return new Double (bestNumber); 415 } 416 417 423 public static final double nextDouble (double d) { 424 return nextDouble(d,true); 425 } 426 427 432 public static final double previousDouble (double d) { 433 return nextDouble(d,false); 434 } 435 436 439 public Object clone() 440 { 441 ChoiceFormat other = (ChoiceFormat ) super.clone(); 442 other.choiceLimits = (double[]) choiceLimits.clone(); 444 other.choiceFormats = (String []) choiceFormats.clone(); 445 return other; 446 } 447 448 451 public int hashCode() { 452 int result = choiceLimits.length; 453 if (choiceFormats.length > 0) { 454 result ^= choiceFormats[choiceFormats.length-1].hashCode(); 456 } 457 return result; 458 } 459 460 463 public boolean equals(Object obj) { 464 if (obj == null) return false; 465 if (this == obj) return true; 467 if (getClass() != obj.getClass()) 468 return false; 469 ChoiceFormat other = (ChoiceFormat ) obj; 470 return (Utility.arrayEquals(choiceLimits,other.choiceLimits) 471 && Utility.arrayEquals(choiceFormats,other.choiceFormats)); 472 } 473 474 479 private void readObject(ObjectInputStream in) throws IOException , ClassNotFoundException { 480 in.defaultReadObject(); 481 if (choiceLimits.length != choiceFormats.length) { 482 throw new InvalidObjectException ( 483 "limits and format arrays of different length."); 484 } 485 } 486 487 489 495 private double[] choiceLimits; 496 497 503 private String [] choiceFormats; 504 505 531 532 static final long SIGN = 0x8000000000000000L; 533 static final long EXPONENT = 0x7FF0000000000000L; 534 static final long POSITIVEINFINITY = 0x7FF0000000000000L; 535 536 547 public static double nextDouble (double d, boolean positive) { 548 549 550 if (Double.isNaN(d)) { 551 return d; 552 } 553 554 555 if (d == 0.0) { 556 double smallestPositiveDouble = Double.longBitsToDouble(1L); 557 if (positive) { 558 return smallestPositiveDouble; 559 } else { 560 return -smallestPositiveDouble; 561 } 562 } 563 564 565 566 567 long bits = Double.doubleToLongBits(d); 568 569 570 long magnitude = bits & ~SIGN; 571 572 573 if ((bits > 0) == positive) { 574 if (magnitude != POSITIVEINFINITY) { 575 magnitude += 1; 576 } 577 } 578 579 else { 580 magnitude -= 1; 581 } 582 583 584 long signbit = bits & SIGN; 585 return Double.longBitsToDouble (magnitude | signbit); 586 } 587 588 private static double[] doubleArraySize(double[] array) { 589 int oldSize = array.length; 590 double[] newArray = new double[oldSize * 2]; 591 System.arraycopy(array, 0, newArray, 0, oldSize); 592 return newArray; 593 } 594 595 private String [] doubleArraySize(String [] array) { 596 int oldSize = array.length; 597 String [] newArray = new String [oldSize * 2]; 598 System.arraycopy(array, 0, newArray, 0, oldSize); 599 return newArray; 600 } 601 602 } 603 604 | Popular Tags |