PageRenderTime 68ms CodeModel.GetById 38ms RepoModel.GetById 1ms app.codeStats 0ms

/java/obsolete/gwt2_2/dtai/util/Format.java

https://bitbucket.org/Mr_Tines/scrapbook
Java | 551 lines | 358 code | 64 blank | 129 comment | 216 complexity | 81fdb736e537f4abc3807cf50bdf4797 MD5 | raw file
Possible License(s): LGPL-2.0
  1. /*
  2. * Gary Cornell and Cay S. Horstmann, Core Java (Book/CD-ROM)
  3. * Published By SunSoft Press/Prentice-Hall
  4. * Copyright (C) 1996 Sun Microsystems Inc.
  5. * All Rights Reserved. ISBN 0-13-565755-5
  6. *
  7. * Permission to use, copy, modify, and distribute this
  8. * software and its documentation for NON-COMMERCIAL purposes
  9. * and without fee is hereby granted provided that this
  10. * copyright notice appears in all copies.
  11. *
  12. * THE AUTHORS AND PUBLISHER MAKE NO REPRESENTATIONS OR
  13. * WARRANTIES ABOUT THE SUITABILITY OF THE SOFTWARE, EITHER
  14. * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  16. * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. THE AUTHORS
  17. * AND PUBLISHER SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED
  18. * BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  19. * THIS SOFTWARE OR ITS DERIVATIVES.
  20. */
  21. /**
  22. * A class for formatting numbers that follows printf conventions.
  23. * Also implements C-like atoi and atof functions
  24. * @version 1.01 15 Feb 1996
  25. * @author Cay Horstmann
  26. */
  27. package dtai.util;
  28. import java.io.*;
  29. public class Format
  30. { /**
  31. * Formats the number following printf conventions.
  32. * Main limitation: Can only handle one format parameter at a time
  33. * Use multiple Format objects to format more than one number
  34. * @param s the format string following printf conventions
  35. * The string has a prefix, a format code and a suffix. The prefix and suffix
  36. * become part of the formatted output. The format code directs the
  37. * formatting of the (single) parameter to be formatted. The code has the
  38. * following structure
  39. * <ul>
  40. * <li> a % (required)
  41. * <li> a modifier (optional)
  42. * <dl>
  43. * <dt> + <dd> forces display of + for positive numbers
  44. * <dt> 0 <dd> show leading zeroes
  45. * <dt> - <dd> align left in the field
  46. * <dt> space <dd> prepend a space in front of positive numbers
  47. * <dt> # <dd> use "alternate" format. Add 0 or 0x for octal or hexadecimal numbers. Don't suppress trailing zeroes in general floating point format.
  48. * </dl>
  49. * <li> an integer denoting field width (optional)
  50. * <li> a period followed by an integer denoting precision (optional)
  51. * <li> a format descriptor (required)
  52. * <dl>
  53. * <dt>f <dd> floating point number in fixed format
  54. * <dt>e, E <dd> floating point number in exponential notation (scientific format). The E format results in an uppercase E for the exponent (1.14130E+003), the e format in a lowercase e.
  55. * <dt>g, G <dd> floating point number in general format (fixed format for small numbers, exponential format for large numbers). Trailing zeroes are suppressed. The G format results in an uppercase E for the exponent (if any), the g format in a lowercase e.
  56. * <dt>d, i <dd> integer in decimal
  57. * <dt>x <dd> integer in hexadecimal
  58. * <dt>o <dd> integer in octal
  59. * <dt>s <dd> string
  60. * <dt>c <dd> character
  61. * </dl>
  62. * </ul>
  63. * @exception IllegalArgumentException if bad format
  64. */
  65. /**
  66. * Format constructor
  67. * @param s a string
  68. */
  69. public Format(String s)
  70. { width = 0;
  71. precision = -1;
  72. pre = "";
  73. post = "";
  74. leading_zeroes = false;
  75. show_plus = false;
  76. alternate = false;
  77. show_space = false;
  78. left_align = false;
  79. fmt = ' ';
  80. int state = 0;
  81. int length = s.length();
  82. int parse_state = 0;
  83. // 0 = prefix, 1 = flags, 2 = width, 3 = precision,
  84. // 4 = format, 5 = end
  85. int i = 0;
  86. while (parse_state == 0)
  87. { if (i >= length) parse_state = 5;
  88. else if (s.charAt(i) == '%')
  89. { if (i < length - 1)
  90. { if (s.charAt(i + 1) == '%')
  91. { pre = pre + '%';
  92. i++;
  93. }
  94. else
  95. parse_state = 1;
  96. }
  97. else throw new java.lang.IllegalArgumentException();
  98. }
  99. else
  100. pre = pre + s.charAt(i);
  101. i++;
  102. }
  103. while (parse_state == 1)
  104. { if (i >= length) parse_state = 5;
  105. else if (s.charAt(i) == ' ') show_space = true;
  106. else if (s.charAt(i) == '-') left_align = true;
  107. else if (s.charAt(i) == '+') show_plus = true;
  108. else if (s.charAt(i) == '0') leading_zeroes = true;
  109. else if (s.charAt(i) == '#') alternate = true;
  110. else { parse_state = 2; i--; }
  111. i++;
  112. }
  113. while (parse_state == 2)
  114. { if (i >= length) parse_state = 5;
  115. else if ('0' <= s.charAt(i) && s.charAt(i) <= '9')
  116. { width = width * 10 + s.charAt(i) - '0';
  117. i++;
  118. }
  119. else if (s.charAt(i) == '.')
  120. { parse_state = 3;
  121. precision = 0;
  122. i++;
  123. }
  124. else
  125. parse_state = 4;
  126. }
  127. while (parse_state == 3)
  128. { if (i >= length) parse_state = 5;
  129. else if ('0' <= s.charAt(i) && s.charAt(i) <= '9')
  130. { precision = precision * 10 + s.charAt(i) - '0';
  131. i++;
  132. }
  133. else
  134. parse_state = 4;
  135. }
  136. if (parse_state == 4)
  137. { if (i >= length) parse_state = 5;
  138. else fmt = s.charAt(i);
  139. i++;
  140. }
  141. if (i < length)
  142. post = s.substring(i, length);
  143. }
  144. /**
  145. * prints a formatted number following printf conventions
  146. * @param s a PrintStream
  147. * @param fmt the format string
  148. * @param x the double to print
  149. */
  150. public static void print(java.io.PrintStream s, String fmt, double x)
  151. { s.print(new Format(fmt).form(x));
  152. }
  153. /**
  154. * prints a formatted number following printf conventions
  155. * @param s a PrintStream
  156. * @param fmt the format string
  157. * @param x the long to print
  158. */
  159. public static void print(java.io.PrintStream s, String fmt, long x)
  160. { s.print(new Format(fmt).form(x));
  161. }
  162. /**
  163. * prints a formatted number following printf conventions
  164. * @param s a PrintStream
  165. * @param fmt the format string
  166. * @param x the character to
  167. */
  168. public static void print(java.io.PrintStream s, String fmt, char x)
  169. { s.print(new Format(fmt).form(x));
  170. }
  171. /**
  172. * prints a formatted number following printf conventions
  173. * @param s a PrintStream, fmt the format string
  174. * @param x a string that represents the digits to print
  175. */
  176. public static void print(java.io.PrintStream s, String fmt, String x)
  177. { s.print(new Format(fmt).form(x));
  178. }
  179. /**
  180. * Converts a string of digits (decimal, octal or hex) to an integer
  181. * @param s a string
  182. * @return the numeric value of the prefix of s representing a base 10 integer
  183. */
  184. public static int atoi(String s)
  185. { return (int)atol(s);
  186. }
  187. /**
  188. * Converts a string of digits (decimal, octal or hex) to a long integer
  189. * @param s a string
  190. * @return the numeric value of the prefix of s representing a base 10 integer
  191. */
  192. public static long atol(String s)
  193. { int i = 0;
  194. while (i < s.length() && Character.isSpace(s.charAt(i))) i++;
  195. if (i < s.length() && s.charAt(i) == '0')
  196. { if (i + 1 < s.length() && (s.charAt(i + 1) == 'x' || s.charAt(i + 1) == 'X'))
  197. return parseLong(s.substring(i + 2), 16);
  198. else return parseLong(s, 8);
  199. }
  200. else return parseLong(s, 10);
  201. }
  202. private static long parseLong(String s, int base)
  203. { int i = 0;
  204. int sign = 1;
  205. long r = 0;
  206. while (i < s.length() && Character.isSpace(s.charAt(i))) i++;
  207. if (i < s.length() && s.charAt(i) == '-') { sign = -1; i++; }
  208. else if (i < s.length() && s.charAt(i) == '+') { i++; }
  209. while (i < s.length())
  210. { char ch = s.charAt(i);
  211. if ('0' <= ch && ch < '0' + base)
  212. r = r * base + ch - '0';
  213. else if ('A' <= ch && ch < 'A' + base - 10)
  214. r = r * base + ch - 'A' + 10 ;
  215. else if ('a' <= ch && ch < 'a' + base - 10)
  216. r = r * base + ch - 'a' + 10 ;
  217. else
  218. return r * sign;
  219. i++;
  220. }
  221. return r * sign;
  222. }
  223. /**
  224. * Converts a string of digits to an double
  225. * @param s a string
  226. */
  227. public static double atof(String s)
  228. { int i = 0;
  229. int sign = 1;
  230. double r = 0; // integer part
  231. double f = 0; // fractional part
  232. double p = 1; // exponent of fractional part
  233. int state = 0; // 0 = int part, 1 = frac part
  234. while (i < s.length() && Character.isSpace(s.charAt(i))) i++;
  235. if (i < s.length() && s.charAt(i) == '-') { sign = -1; i++; }
  236. else if (i < s.length() && s.charAt(i) == '+') { i++; }
  237. while (i < s.length())
  238. { char ch = s.charAt(i);
  239. if ('0' <= ch && ch <= '9')
  240. { if (state == 0)
  241. r = r * 10 + ch - '0';
  242. else if (state == 1)
  243. { p = p / 10;
  244. r = r + p * (ch - '0');
  245. }
  246. }
  247. else if (ch == '.')
  248. { if (state == 0) state = 1;
  249. else return sign * r;
  250. }
  251. else if (ch == 'e' || ch == 'E')
  252. { long e = (int)parseLong(s.substring(i + 1), 10);
  253. return sign * r * Math.pow(10, e);
  254. }
  255. else return sign * r;
  256. i++;
  257. }
  258. return sign * r;
  259. }
  260. /**
  261. * Formats a double into a string (like sprintf in C)
  262. * @param x the number to format
  263. * @return the formatted string
  264. * @exception IllegalArgumentException if bad argument
  265. */
  266. public String form(double x)
  267. { String r;
  268. if (precision < 0) precision = 6;
  269. int s = 1;
  270. if (x < 0) { x = -x; s = -1; }
  271. if (fmt == 'f')
  272. r = fixed_format(x);
  273. else if (fmt == 'e' || fmt == 'E' || fmt == 'g' || fmt == 'G')
  274. r = exp_format(x);
  275. else throw new java.lang.IllegalArgumentException();
  276. return pad(sign(s, r));
  277. }
  278. /**
  279. * Formats a long integer into a string (like sprintf in C)
  280. * @param x the number to format
  281. * @return the formatted string
  282. */
  283. public String form(long x)
  284. { String r;
  285. int s = 0;
  286. if (fmt == 'd' || fmt == 'i')
  287. { s = 1;
  288. if (x < 0) { x = -x; s = -1; }
  289. r = "" + x;
  290. }
  291. else if (fmt == 'o')
  292. r = convert(x, 3, 7, "01234567");
  293. else if (fmt == 'x')
  294. r = convert(x, 4, 15, "0123456789abcdef");
  295. else if (fmt == 'X')
  296. r = convert(x, 4, 15, "0123456789ABCDEF");
  297. else throw new java.lang.IllegalArgumentException();
  298. return pad(sign(s, r));
  299. }
  300. /**
  301. * Formats a character into a string (like sprintf in C)
  302. * @param x the value to format
  303. * @return the formatted string
  304. */
  305. public String form(char c)
  306. { if (fmt != 'c')
  307. throw new java.lang.IllegalArgumentException();
  308. String r = "" + c;
  309. return pad(r);
  310. }
  311. /**
  312. * Formats a string into a larger string (like sprintf in C)
  313. * @param x the value to format
  314. * @return the formatted string
  315. */
  316. public String form(String s)
  317. { if (fmt != 's')
  318. throw new java.lang.IllegalArgumentException();
  319. if (precision >= 0) s = s.substring(0, precision);
  320. return pad(s);
  321. }
  322. /**
  323. * a test stub for the format class
  324. */
  325. public static void main(String[] a)
  326. { double x = 1.23456789012;
  327. double y = 123;
  328. double z = 1.2345e30;
  329. double w = 1.02;
  330. double u = 1.234e-5;
  331. int d = 0xCAFE;
  332. Format.print(System.out, "x = |%f|\n", x);
  333. Format.print(System.out, "u = |%20f|\n", u);
  334. Format.print(System.out, "x = |% .5f|\n", x);
  335. Format.print(System.out, "w = |%20.5f|\n", w);
  336. Format.print(System.out, "x = |%020.5f|\n", x);
  337. Format.print(System.out, "x = |%+20.5f|\n", x);
  338. Format.print(System.out, "x = |%+020.5f|\n", x);
  339. Format.print(System.out, "x = |% 020.5f|\n", x);
  340. Format.print(System.out, "y = |%#+20.5f|\n", y);
  341. Format.print(System.out, "y = |%-+20.5f|\n", y);
  342. Format.print(System.out, "z = |%20.5f|\n", z);
  343. Format.print(System.out, "x = |%e|\n", x);
  344. Format.print(System.out, "u = |%20e|\n", u);
  345. Format.print(System.out, "x = |% .5e|\n", x);
  346. Format.print(System.out, "w = |%20.5e|\n", w);
  347. Format.print(System.out, "x = |%020.5e|\n", x);
  348. Format.print(System.out, "x = |%+20.5e|\n", x);
  349. Format.print(System.out, "x = |%+020.5e|\n", x);
  350. Format.print(System.out, "x = |% 020.5e|\n", x);
  351. Format.print(System.out, "y = |%#+20.5e|\n", y);
  352. Format.print(System.out, "y = |%-+20.5e|\n", y);
  353. Format.print(System.out, "x = |%g|\n", x);
  354. Format.print(System.out, "z = |%g|\n", z);
  355. Format.print(System.out, "w = |%g|\n", w);
  356. Format.print(System.out, "u = |%g|\n", u);
  357. Format.print(System.out, "y = |%.2g|\n", y);
  358. Format.print(System.out, "y = |%#.2g|\n", y);
  359. Format.print(System.out, "d = |%d|\n", d);
  360. Format.print(System.out, "d = |%20d|\n", d);
  361. Format.print(System.out, "d = |%020d|\n", d);
  362. Format.print(System.out, "d = |%+20d|\n", d);
  363. Format.print(System.out, "d = |% 020d|\n", d);
  364. Format.print(System.out, "d = |%-20d|\n", d);
  365. Format.print(System.out, "d = |%20.8d|\n", d);
  366. Format.print(System.out, "d = |%x|\n", d);
  367. Format.print(System.out, "d = |%20X|\n", d);
  368. Format.print(System.out, "d = |%#20x|\n", d);
  369. Format.print(System.out, "d = |%020X|\n", d);
  370. Format.print(System.out, "d = |%20.8x|\n", d);
  371. Format.print(System.out, "d = |%o|\n", d);
  372. Format.print(System.out, "d = |%020o|\n", d);
  373. Format.print(System.out, "d = |%#20o|\n", d);
  374. Format.print(System.out, "d = |%#020o|\n", d);
  375. Format.print(System.out, "d = |%20.12o|\n", d);
  376. Format.print(System.out, "s = |%-20s|\n", "Hello");
  377. Format.print(System.out, "s = |%-20c|\n", '!');
  378. }
  379. private static String repeat(char c, int n)
  380. { if (n <= 0) return "";
  381. StringBuffer s = new StringBuffer(n);
  382. for (int i = 0; i < n; i++) s.append(c);
  383. return s.toString();
  384. }
  385. private static String convert(long x, int n, int m, String d)
  386. { if (x == 0) return "0";
  387. String r = "";
  388. while (x != 0)
  389. { r = d.charAt((int)(x & m)) + r;
  390. x = x >>> n;
  391. }
  392. return r;
  393. }
  394. private String pad(String r)
  395. { String p = repeat(' ', width - r.length());
  396. if (left_align) return pre + r + p + post;
  397. else return pre + p + r + post;
  398. }
  399. private String sign(int s, String r)
  400. { String p = "";
  401. if (s < 0) p = "-";
  402. else if (s > 0)
  403. { if (show_plus) p = "+";
  404. else if (show_space) p = " ";
  405. }
  406. else
  407. { if (fmt == 'o' && alternate && r.length() > 0 && r.charAt(0) != '0') p = "0";
  408. else if (fmt == 'x' && alternate) p = "0x";
  409. else if (fmt == 'X' && alternate) p = "0X";
  410. }
  411. int w = 0;
  412. if (leading_zeroes)
  413. w = width;
  414. else if ((fmt == 'd' || fmt == 'i' || fmt == 'x' || fmt == 'X' || fmt == 'o')
  415. && precision > 0) w = precision;
  416. return p + repeat('0', w - p.length() - r.length()) + r;
  417. }
  418. private String fixed_format(double d)
  419. { String f = "";
  420. if (d > 0x7FFFFFFFFFFFFFFFL) return exp_format(d);
  421. long l = (long)(precision == 0 ? d + 0.5 : d);
  422. f = f + l;
  423. double fr = d - l; // fractional part
  424. if (fr >= 1 || fr < 0) return exp_format(d);
  425. return f + frac_part(fr);
  426. }
  427. private String frac_part(double fr)
  428. // precondition: 0 <= fr < 1
  429. { String z = "";
  430. if (precision > 0)
  431. { double factor = 1;
  432. String leading_zeroes = "";
  433. for (int i = 1; i <= precision && factor <= 0x7FFFFFFFFFFFFFFFL; i++)
  434. { factor *= 10;
  435. leading_zeroes = leading_zeroes + "0";
  436. }
  437. long l = (long) (factor * fr + 0.5);
  438. z = leading_zeroes + l;
  439. z = z.substring(z.length() - precision, z.length());
  440. }
  441. if (precision > 0 || alternate) z = "." + z;
  442. if ((fmt == 'G' || fmt == 'g') && !alternate)
  443. // remove trailing zeroes and decimal point
  444. { int t = z.length() - 1;
  445. while (t >= 0 && z.charAt(t) == '0') t--;
  446. if (t >= 0 && z.charAt(t) == '.') t--;
  447. z = z.substring(0, t + 1);
  448. }
  449. return z;
  450. }
  451. private String exp_format(double d)
  452. { String f = "";
  453. int e = 0;
  454. double dd = d;
  455. double factor = 1;
  456. while (dd > 10) { e++; factor /= 10; dd = dd / 10; }
  457. while (dd < 1) { e--; factor *= 10; dd = dd * 10; }
  458. if ((fmt == 'g' || fmt == 'G') && e >= -4 && e < precision)
  459. return fixed_format(d);
  460. d = d * factor;
  461. f = f + fixed_format(d);
  462. if (fmt == 'e' || fmt == 'g')
  463. f = f + "e";
  464. else
  465. f = f + "E";
  466. String p = "000";
  467. if (e >= 0)
  468. { f = f + "+";
  469. p = p + e;
  470. }
  471. else
  472. { f = f + "-";
  473. p = p + (-e);
  474. }
  475. return f + p.substring(p.length() - 3, p.length());
  476. }
  477. private int width;
  478. private int precision;
  479. private String pre;
  480. private String post;
  481. private boolean leading_zeroes;
  482. private boolean show_plus;
  483. private boolean alternate;
  484. private boolean show_space;
  485. private boolean left_align;
  486. private char fmt; // one of cdeEfgGiosxXos
  487. }