Javolution 6.0.0 java
TypeFormat.java
Go to the documentation of this file.
1 /*
2  * Javolution - Java(TM) Solution for Real-Time and Embedded Systems
3  * Copyright (C) 2012 - Javolution (http://javolution.org/)
4  * All rights reserved.
5  *
6  * Permission to use, copy, modify, and distribute this software is
7  * freely granted, provided that this notice is preserved.
8  */
9 package javolution.text;
10 
11 import java.io.IOException;
12 import javolution.lang.MathLib;
13 import javolution.lang.Realtime;
14 
42 @Realtime
43 public final class TypeFormat {
44 
48  private TypeFormat() {}
49 
51  // PARSING //
53 
65  public static boolean parseBoolean(CharSequence csq, Cursor cursor) {
66  int start = cursor.getIndex();
67  int end = csq.length();
68  if ((end >= start + 5)
69  && (csq.charAt(start) == 'f' || csq.charAt(start) == 'F')) { // False.
70  if ((csq.charAt(++start) == 'a' || csq.charAt(start) == 'A')
71  && (csq.charAt(++start) == 'l' || csq.charAt(start) == 'L')
72  && (csq.charAt(++start) == 's' || csq.charAt(start) == 'S')
73  && (csq.charAt(++start) == 'e' || csq.charAt(start) == 'E')) {
74  cursor.increment(5);
75  return false;
76  }
77  } else if ((end >= start + 4)
78  && (csq.charAt(start) == 't' || csq.charAt(start) == 'T')) // True.
79  if ((csq.charAt(++start) == 'r' || csq.charAt(start) == 'R')
80  && (csq.charAt(++start) == 'u' || csq.charAt(start) == 'U')
81  && (csq.charAt(++start) == 'e' || csq.charAt(start) == 'E')) {
82  cursor.increment(4);
83  return true;
84  }
85  throw new IllegalArgumentException("Invalid boolean representation");
86  }
87 
96  public static boolean parseBoolean(CharSequence csq) {
97  Cursor cursor = new Cursor();
98  boolean result = parseBoolean(csq, cursor);
99  if (!cursor.atEnd(csq))
100  throw new IllegalArgumentException("Extraneous characters \""
101  + cursor.tail(csq) + "\"");
102  return result;
103  }
104 
116  public static byte parseByte(CharSequence csq, int radix, Cursor cursor) {
117  int i = parseInt(csq, radix, cursor);
118  if ((i < Byte.MIN_VALUE) || (i > Byte.MAX_VALUE))
119  throw new NumberFormatException("Overflow");
120  return (byte) i;
121  }
122 
134  public static byte parseByte(CharSequence csq, int radix) {
135  Cursor cursor = new Cursor();
136  byte result = parseByte(csq, radix, cursor);
137  if (!cursor.atEnd(csq))
138  throw new IllegalArgumentException("Extraneous characters \""
139  + cursor.tail(csq) + "\"");
140  return result;
141  }
142 
153  public static byte parseByte(CharSequence csq, Cursor cursor) {
154  return parseByte(csq, 10, cursor);
155  }
156 
167  public static byte parseByte(CharSequence csq) {
168  return parseByte(csq, 10);
169  }
170 
182  public static short parseShort(CharSequence csq, int radix, Cursor cursor) {
183  int i = parseInt(csq, radix, cursor);
184  if ((i < Short.MIN_VALUE) || (i > Short.MAX_VALUE))
185  throw new NumberFormatException("Overflow");
186  return (short) i;
187  }
188 
200  public static short parseShort(CharSequence csq, int radix) {
201  Cursor cursor = new Cursor();
202  short result = parseShort(csq, radix, cursor);
203  if (!cursor.atEnd(csq))
204  throw new IllegalArgumentException("Extraneous characters \""
205  + cursor.tail(csq) + "\"");
206  return result;
207  }
208 
219  public static short parseShort(CharSequence csq, Cursor cursor) {
220  return parseShort(csq, 10, cursor);
221  }
222 
233  public static short parseShort(CharSequence csq) {
234  return parseShort(csq, 10);
235  }
236 
248  public static int parseInt(CharSequence csq, int radix, Cursor cursor) {
249  int start = cursor.getIndex();
250  int end = csq.length();
251  boolean isNegative = false;
252  int result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
253  int i = start;
254  for (; i < end; i++) {
255  char c = csq.charAt(i);
256  int digit = (c <= '9') ? c - '0'
257  : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
258  : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
259  if ((digit >= 0) && (digit < radix)) {
260  int newResult = result * radix - digit;
261  if (newResult > result)
262  throw new NumberFormatException("Overflow parsing "
263  + csq.subSequence(start, end));
264  result = newResult;
265  } else if ((c == '-') && (i == start))
266  isNegative = true;
267  else if ((c == '+') && (i == start)) {
268  // Ok.
269  } else
270  break;
271  }
272  // Requires one valid digit character and checks for opposite overflow.
273  if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
274  throw new NumberFormatException(
275  "Invalid integer representation for "
276  + csq.subSequence(start, end));
277  if ((result == Integer.MIN_VALUE) && !isNegative)
278  throw new NumberFormatException("Overflow parsing "
279  + csq.subSequence(start, end));
280  cursor.increment(i - start);
281  return isNegative ? result : -result;
282  }
283 
295  public static int parseInt(CharSequence csq, int radix) {
296  Cursor cursor = new Cursor();
297  int result = parseInt(csq, radix, cursor);
298  if (!cursor.atEnd(csq))
299  throw new IllegalArgumentException("Extraneous characters \""
300  + cursor.tail(csq) + "\"");
301  return result;
302  }
303 
314  public static int parseInt(CharSequence csq, Cursor cursor) {
315  return parseInt(csq, 10, cursor);
316  }
317 
328  public static int parseInt(CharSequence csq) {
329  return parseInt(csq, 10);
330  }
331 
343  public static long parseLong(CharSequence csq, int radix, Cursor cursor) {
344  final int start = cursor.getIndex();
345  final int end = csq.length();
346  boolean isNegative = false;
347  long result = 0; // Accumulates negatively (avoid MIN_VALUE overflow).
348  int i = start;
349  for (; i < end; i++) {
350  char c = csq.charAt(i);
351  int digit = (c <= '9') ? c - '0'
352  : ((c <= 'Z') && (c >= 'A')) ? c - 'A' + 10
353  : ((c <= 'z') && (c >= 'a')) ? c - 'a' + 10 : -1;
354  if ((digit >= 0) && (digit < radix)) {
355  long newResult = result * radix - digit;
356  if (newResult > result)
357  throw new NumberFormatException("Overflow parsing "
358  + csq.subSequence(start, end));
359  result = newResult;
360  } else if ((c == '-') && (i == start))
361  isNegative = true;
362  else if ((c == '+') && (i == start)) {
363  // Ok.
364  } else
365  break;
366  }
367  // Requires one valid digit character and checks for opposite overflow.
368  if ((result == 0) && ((end == 0) || (csq.charAt(i - 1) != '0')))
369  throw new NumberFormatException(
370  "Invalid integer representation for "
371  + csq.subSequence(start, end));
372  if ((result == Long.MIN_VALUE) && !isNegative)
373  throw new NumberFormatException("Overflow parsing "
374  + csq.subSequence(start, end));
375  cursor.increment(i - start);
376  return isNegative ? result : -result;
377  }
378 
390  public static long parseLong(CharSequence csq, int radix) {
391  Cursor cursor = new Cursor();
392  long result = parseLong(csq, radix, cursor);
393  if (!cursor.atEnd(csq))
394  throw new IllegalArgumentException("Extraneous characters \""
395  + cursor.tail(csq) + "\"");
396  return result;
397  }
398 
409  public static long parseLong(CharSequence csq, Cursor cursor) {
410  return parseLong(csq, 10, cursor);
411  }
412 
423  public static long parseLong(CharSequence csq) {
424  return parseLong(csq, 10);
425  }
426 
436  public static float parseFloat(CharSequence csq, Cursor cursor) {
437  return (float) parseDouble(csq, cursor);
438  }
439 
449  public static float parseFloat(CharSequence csq) {
450  return (float) parseDouble(csq);
451  }
452 
464  public static double parseDouble(CharSequence csq, Cursor cursor)
465  throws NumberFormatException {
466  final int start = cursor.getIndex();
467  final int end = csq.length();
468  int i = start;
469  char c = csq.charAt(i);
470 
471  // Checks for NaN.
472  if ((c == 'N') && match("NaN", csq, i, end)) {
473  cursor.increment(3);
474  return Double.NaN;
475  }
476 
477  // Reads sign.
478  boolean isNegative = (c == '-');
479  if ((isNegative || (c == '+')) && (++i < end))
480  c = csq.charAt(i);
481 
482  // Checks for Infinity.
483  if ((c == 'I') && match("Infinity", csq, i, end)) {
484  cursor.increment(i + 8 - start);
485  return isNegative ? Double.NEGATIVE_INFINITY
486  : Double.POSITIVE_INFINITY;
487  }
488 
489  // At least one digit or a '.' required.
490  if (((c < '0') || (c > '9')) && (c != '.'))
491  throw new NumberFormatException("Digit or '.' required");
492 
493  // Reads decimal and fraction (both merged to a long).
494  long decimal = 0;
495  int decimalPoint = -1;
496  while (true) {
497  int digit = c - '0';
498  if ((digit >= 0) && (digit < 10)) {
499  long tmp = decimal * 10 + digit;
500  if ((decimal > LONG_MAX_DIV10) || (tmp < decimal))
501  throw new NumberFormatException(
502  "Too many digits - Overflow");
503  decimal = tmp;
504  } else if ((c == '.') && (decimalPoint < 0))
505  decimalPoint = i;
506  else
507  break;
508  if (++i >= end)
509  break;
510  c = csq.charAt(i);
511  }
512  if (isNegative)
513  decimal = -decimal;
514  int fractionLength = (decimalPoint >= 0) ? i - decimalPoint - 1 : 0;
515 
516  // Reads exponent.
517  int exp = 0;
518  if ((i < end) && ((c == 'E') || (c == 'e'))) {
519  c = csq.charAt(++i);
520  boolean isNegativeExp = (c == '-');
521  if ((isNegativeExp || (c == '+')) && (++i < end))
522  c = csq.charAt(i);
523  if ((c < '0') || (c > '9')) // At least one digit required.
524  throw new NumberFormatException("Invalid exponent");
525  while (true) {
526  int digit = c - '0';
527  if ((digit >= 0) && (digit < 10)) {
528  int tmp = exp * 10 + digit;
529  if ((exp > INT_MAX_DIV10) || (tmp < exp))
530  throw new NumberFormatException("Exponent Overflow");
531  exp = tmp;
532  } else
533  break;
534  if (++i >= end)
535  break;
536  c = csq.charAt(i);
537  }
538  if (isNegativeExp)
539  exp = -exp;
540  }
541  cursor.increment(i - start);
542  return javolution.lang.MathLib.toDoublePow10(decimal, exp
543  - fractionLength);
544  }
545  private static final int INT_MAX_DIV10 = Integer.MAX_VALUE / 10;
546  private static final long LONG_MAX_DIV10 = Long.MAX_VALUE / 10;
547 
559  public static double parseDouble(CharSequence csq)
560  throws NumberFormatException {
561  Cursor cursor = new Cursor();
562  double result = parseDouble(csq, cursor);
563  if (!cursor.atEnd(csq))
564  throw new IllegalArgumentException("Extraneous characters \""
565  + cursor.tail(csq) + "\"");
566  return result;
567  }
568 
569  static boolean match(String str, CharSequence csq, int start, int length) {
570  for (int i = 0; i < str.length(); i++) {
571  if ((start + i >= length) || csq.charAt(start + i) != str.charAt(i))
572  return false;
573  }
574  return true;
575  }
576 
577  static boolean match(String str, String csq, int start, int length) {
578  for (int i = 0; i < str.length(); i++) {
579  if ((start + i >= length) || csq.charAt(start + i) != str.charAt(i))
580  return false;
581  }
582  return true;
583  }
584 
586  // FORMATTING //
588 
597  public static Appendable format(boolean b, Appendable a) throws IOException {
598  return b ? a.append("true") : a.append("false");
599  }
600 
611  public static Appendable format(int i, Appendable a) throws IOException {
612  if (a instanceof TextBuilder)
613  return ((TextBuilder) a).append(i);
614  TextBuilder tb = new TextBuilder();
615  tb.append(i);
616  return a.append(tb);
617  }
618 
630  public static Appendable format(int i, int radix, Appendable a)
631  throws IOException {
632  if (a instanceof TextBuilder)
633  return ((TextBuilder) a).append(i, radix);
634  TextBuilder tb = new TextBuilder();
635  tb.append(i, radix);
636  return a.append(tb);
637  }
638 
649  public static Appendable format(long l, Appendable a) throws IOException {
650  if (a instanceof TextBuilder)
651  return ((TextBuilder) a).append(l);
652  TextBuilder tb = new TextBuilder();
653  tb.append(l);
654  return a.append(tb);
655  }
656 
669  public static Appendable format(long l, int radix, Appendable a)
670  throws IOException {
671  if (a instanceof TextBuilder)
672  return ((TextBuilder) a).append(l, radix);
673  TextBuilder tb = new TextBuilder();
674  tb.append(l, radix);
675  return a.append(tb);
676  }
677 
686  public static Appendable format(float f, Appendable a) throws IOException {
687  return TypeFormat.format(f, 10,
688  (MathLib.abs(f) >= 1E7) || (MathLib.abs(f) < 0.001), false, a);
689  }
690 
700  public static Appendable format(double d, Appendable a) throws IOException {
701  return TypeFormat.format(d, -1,
702  (MathLib.abs(d) >= 1E7) || (MathLib.abs(d) < 0.001), false, a);
703  }
704 
723  public static Appendable format(double d, int digits, boolean scientific,
724  boolean showZero, Appendable a) throws IOException {
725  if (a instanceof TextBuilder)
726  return ((TextBuilder) a).append(d, digits, scientific, showZero);
727  TextBuilder tb = new TextBuilder();
728  tb.append(d, digits, scientific, showZero);
729  return a.append(tb);
730  }
731 
732 }
javolution.text.TypeFormat.format
static Appendable format(long l, int radix, Appendable a)
Definition: TypeFormat.java:669
javolution.text.TypeFormat.parseInt
static int parseInt(CharSequence csq, Cursor cursor)
Definition: TypeFormat.java:314
javolution.text.TypeFormat.parseByte
static byte parseByte(CharSequence csq, int radix, Cursor cursor)
Definition: TypeFormat.java:116
javolution.text.TypeFormat.parseByte
static byte parseByte(CharSequence csq, int radix)
Definition: TypeFormat.java:134
javolution.text.TypeFormat.parseByte
static byte parseByte(CharSequence csq)
Definition: TypeFormat.java:167
javolution
javolution.text.TypeFormat.format
static Appendable format(double d, Appendable a)
Definition: TypeFormat.java:700
javolution.text.TextBuilder.append
final TextBuilder append(char c)
Definition: TextBuilder.java:202
javolution.lang.MathLib
Definition: MathLib.java:20
javolution.text.TextBuilder
Definition: TextBuilder.java:29
javolution.text.TypeFormat.parseByte
static byte parseByte(CharSequence csq, Cursor cursor)
Definition: TypeFormat.java:153
javolution.text.TypeFormat.parseDouble
static double parseDouble(CharSequence csq, Cursor cursor)
Definition: TypeFormat.java:464
javolution.text.TypeFormat.parseLong
static long parseLong(CharSequence csq)
Definition: TypeFormat.java:423
javolution.text.TypeFormat.format
static Appendable format(double d, int digits, boolean scientific, boolean showZero, Appendable a)
Definition: TypeFormat.java:723
javolution.text.TypeFormat.INT_MAX_DIV10
static final int INT_MAX_DIV10
Definition: TypeFormat.java:545
javolution.text.TypeFormat.parseLong
static long parseLong(CharSequence csq, int radix)
Definition: TypeFormat.java:390
javolution.text.TypeFormat.parseBoolean
static boolean parseBoolean(CharSequence csq, Cursor cursor)
Definition: TypeFormat.java:65
javolution.text.TypeFormat.parseLong
static long parseLong(CharSequence csq, Cursor cursor)
Definition: TypeFormat.java:409
javolution.text.Cursor.getIndex
final int getIndex()
Definition: Cursor.java:61
javolution.text.Cursor
Definition: Cursor.java:44
javolution.lang
Definition: Configurable.java:9
javolution.text.TypeFormat.format
static Appendable format(long l, Appendable a)
Definition: TypeFormat.java:649
javolution.text.TypeFormat.parseBoolean
static boolean parseBoolean(CharSequence csq)
Definition: TypeFormat.java:96
javolution.text.TypeFormat.parseInt
static int parseInt(CharSequence csq)
Definition: TypeFormat.java:328
javolution.text.TypeFormat.parseInt
static int parseInt(CharSequence csq, int radix)
Definition: TypeFormat.java:295
javolution.text.TypeFormat
Definition: TypeFormat.java:43
javolution.text.TypeFormat.LONG_MAX_DIV10
static final long LONG_MAX_DIV10
Definition: TypeFormat.java:546
javolution.text.TypeFormat.parseDouble
static double parseDouble(CharSequence csq)
Definition: TypeFormat.java:559
javolution.text.TypeFormat.TypeFormat
TypeFormat()
Definition: TypeFormat.java:48
javolution.text.TypeFormat.parseLong
static long parseLong(CharSequence csq, int radix, Cursor cursor)
Definition: TypeFormat.java:343
javolution.lang.Realtime
Definition: Realtime.java:59
javolution.text.TypeFormat.parseShort
static short parseShort(CharSequence csq, int radix, Cursor cursor)
Definition: TypeFormat.java:182
javolution.lang.MathLib.toDoublePow10
static double toDoublePow10(long m, int n)
Definition: MathLib.java:240
javolution.text.TypeFormat.format
static Appendable format(boolean b, Appendable a)
Definition: TypeFormat.java:597
javolution.text.Cursor.tail
final CharSequence tail(CharSequence csq)
Definition: Cursor.java:339
javolution.text.Cursor.increment
final Cursor increment()
Definition: Cursor.java:348
javolution.text.TypeFormat.format
static Appendable format(int i, Appendable a)
Definition: TypeFormat.java:611
javolution.lang.MathLib.abs
static int abs(int i)
Definition: MathLib.java:921
javolution.text.TypeFormat.parseShort
static short parseShort(CharSequence csq, int radix)
Definition: TypeFormat.java:200
javolution.text.TypeFormat.format
static Appendable format(float f, Appendable a)
Definition: TypeFormat.java:686
javolution.text.TypeFormat.parseShort
static short parseShort(CharSequence csq)
Definition: TypeFormat.java:233
javolution.text.TypeFormat.parseShort
static short parseShort(CharSequence csq, Cursor cursor)
Definition: TypeFormat.java:219
javolution.text.TypeFormat.parseFloat
static float parseFloat(CharSequence csq, Cursor cursor)
Definition: TypeFormat.java:436
javolution.text.TypeFormat.match
static boolean match(String str, CharSequence csq, int start, int length)
Definition: TypeFormat.java:569
javolution.text.TypeFormat.parseFloat
static float parseFloat(CharSequence csq)
Definition: TypeFormat.java:449
javolution.text.Cursor.atEnd
final boolean atEnd(CharSequence csq)
Definition: Cursor.java:81
javolution.text.TypeFormat.format
static Appendable format(int i, int radix, Appendable a)
Definition: TypeFormat.java:630
javolution.text.TypeFormat.match
static boolean match(String str, String csq, int start, int length)
Definition: TypeFormat.java:577
javolution.text.TypeFormat.parseInt
static int parseInt(CharSequence csq, int radix, Cursor cursor)
Definition: TypeFormat.java:248