Source Code Cross Referenced for PrintfFormat.java in  » Content-Management-System » opencms » org » opencms » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Content Management System » opencms » org.opencms.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * File   : $Source: /usr/local/cvs/opencms/src/org/opencms/util/PrintfFormat.java,v $
0003:         * Date   : $Date: 2008-02-27 12:05:36 $
0004:         * Version: $Revision: 1.12 $
0005:         *
0006:         * This library is part of OpenCms -
0007:         * the Open Source Content Management System
0008:         *
0009:         * Copyright (c) 2002 - 2008 Alkacon Software GmbH (http://www.alkacon.com)
0010:         *
0011:         * This library is free software; you can redistribute it and/or
0012:         * modify it under the terms of the GNU Lesser General Public
0013:         * License as published by the Free Software Foundation; either
0014:         * version 2.1 of the License, or (at your option) any later version.
0015:         *
0016:         * This library is distributed in the hope that it will be useful,
0017:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
0018:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0019:         * Lesser General Public License for more details.
0020:         *
0021:         * For further information about Alkacon Software GmbH, please see the
0022:         * company website: http://www.alkacon.com
0023:         *
0024:         * For further information about OpenCms, please see the
0025:         * project website: http://www.opencms.org
0026:         * 
0027:         * You should have received a copy of the GNU Lesser General Public
0028:         * License along with this library; if not, write to the Free Software
0029:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
0030:         */
0031:
0032:        //
0033:        // (c) 2000 Sun Microsystems, Inc.
0034:        // ALL RIGHTS RESERVED
0035:        // 
0036:        // License Grant-
0037:        // 
0038:        // 
0039:        // Permission to use, copy, modify, and distribute this Software and its 
0040:        // documentation for NON-COMMERCIAL or COMMERCIAL purposes and without fee is 
0041:        // hereby granted.  
0042:        // 
0043:        // This Software is provided "AS IS".  All express warranties, including any 
0044:        // implied warranty of merchantability, satisfactory quality, fitness for a 
0045:        // particular purpose, or non-infringement, are disclaimed, except to the extent 
0046:        // that such disclaimers are held to be legally invalid.
0047:        // 
0048:        // You acknowledge that Software is not designed, licensed or intended for use in 
0049:        // the design, construction, operation or maintenance of any nuclear facility 
0050:        // ("High Risk Activities").  Sun disclaims any express or implied warranty of 
0051:        // fitness for such uses.  
0052:        //
0053:        // Please refer to the file http://www.sun.com/policies/trademarks/ for further 
0054:        // important trademark information and to 
0055:        // http://java.sun.com/nav/business/index.html for further important licensing 
0056:        // information for the Java Technology.
0057:        //
0058:        package org.opencms.util;
0059:
0060:        import org.opencms.main.CmsIllegalArgumentException;
0061:
0062:        import java.text.DecimalFormatSymbols;
0063:        import java.util.Enumeration;
0064:        import java.util.Locale;
0065:        import java.util.Vector;
0066:
0067:        /**
0068:         * PrintfFormat allows the formatting of an array of
0069:         * objects embedded within a string.  Primitive types
0070:         * must be passed using wrapper types.  The formatting
0071:         * is controlled by a control string.
0072:         *<p>
0073:         * A control string is a Java string that contains a
0074:         * control specification.  The control specification
0075:         * starts at the first percent sign (%) in the string,
0076:         * provided that this percent sign
0077:         *<ol>
0078:         *<li>is not escaped protected by a matching % or is
0079:         * not an escape % character,
0080:         *<li>is not at the end of the format string, and
0081:         *<li>precedes a sequence of characters that parses as
0082:         * a valid control specification.
0083:         *</ol>
0084:         *</p><p>
0085:         * A control specification usually takes the form:
0086:         *<pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
0087:         *                { [hlL] }+ [idfgGoxXeEcs]
0088:         *</pre>
0089:         * There are variants of this basic form that are
0090:         * discussed below.</p>
0091:         *<p>
0092:         * The format is composed of zero or more directives
0093:         * defined as follows:
0094:         *<ul>
0095:         *<li>ordinary characters, which are simply copied to
0096:         * the output stream;
0097:         *<li>escape sequences, which represent non-graphic
0098:         * characters; and
0099:         *<li>conversion specifications,  each of which
0100:         * results in the fetching of zero or more arguments.
0101:         *</ul></p>
0102:         *<p>
0103:         * The results are undefined if there are insufficient
0104:         * arguments for the format.  Usually an unchecked
0105:         * exception will be thrown.  If the format is
0106:         * exhausted while arguments remain, the excess
0107:         * arguments are evaluated but are otherwise ignored.
0108:         * In format strings containing the % form of
0109:         * conversion specifications, each argument in the
0110:         * argument list is used exactly once.</p>
0111:         * <p>
0112:         * Conversions can be applied to the <code>n</code>th
0113:         * argument after the format in the argument list,
0114:         * rather than to the next unused argument.  In this
0115:         * case, the conversion characer % is replaced by the
0116:         * sequence %<code>n</code>$, where <code>n</code> is
0117:         * a decimal integer giving the position of the
0118:         * argument in the argument list.</p>
0119:         * <p>
0120:         * In format strings containing the %<code>n</code>$
0121:         * form of conversion specifications, each argument
0122:         * in the argument list is used exactly once.</p>
0123:         *
0124:         *<h4>Escape Sequences</h4>
0125:         *<p>
0126:         * The following table lists escape sequences and
0127:         * associated actions on display devices capable of
0128:         * the action.
0129:         *<table>
0130:         *<tr><th align=left>Sequence</th>
0131:         *    <th align=left>Name</th>
0132:         *    <th align=left>Description</th></tr>
0133:         *<tr><td>\\</td><td>backlash</td><td>None.
0134:         *</td></tr>
0135:         *<tr><td>\a</td><td>alert</td><td>Attempts to alert
0136:         *          the user through audible or visible
0137:         *          notification.
0138:         *</td></tr>
0139:         *<tr><td>\b</td><td>backspace</td><td>Moves the
0140:         *          printing position to one column before
0141:         *          the current position, unless the
0142:         *          current position is the start of a line.
0143:         *</td></tr>
0144:         *<tr><td>\f</td><td>form-feed</td><td>Moves the
0145:         *          printing position to the initial 
0146:         *          printing position of the next logical
0147:         *          page.
0148:         *</td></tr>
0149:         *<tr><td>\n</td><td>newline</td><td>Moves the
0150:         *          printing position to the start of the
0151:         *          next line.
0152:         *</td></tr>
0153:         *<tr><td>\r</td><td>carriage-return</td><td>Moves
0154:         *          the printing position to the start of
0155:         *          the current line.
0156:         *</td></tr>
0157:         *<tr><td>\t</td><td>tab</td><td>Moves the printing
0158:         *          position to the next implementation-
0159:         *          defined horizontal tab position.
0160:         *</td></tr>
0161:         *<tr><td>\v</td><td>vertical-tab</td><td>Moves the
0162:         *          printing position to the start of the
0163:         *          next implementation-defined vertical
0164:         *          tab position.
0165:         *</td></tr>
0166:         *</table></p>
0167:         *<h4>Conversion Specifications</h4>
0168:         *<p>
0169:         * Each conversion specification is introduced by
0170:         * the percent sign character (%).  After the character
0171:         * %, the following appear in sequence:</p>
0172:         *<p>
0173:         * Zero or more flags (in any order), which modify the
0174:         * meaning of the conversion specification.</p>
0175:         *<p>
0176:         * An optional minimum field width.  If the converted
0177:         * value has fewer characters than the field width, it
0178:         * will be padded with spaces by default on the left;
0179:         * t will be padded on the right, if the left-
0180:         * adjustment flag (-), described below, is given to
0181:         * the field width.  The field width takes the form
0182:         * of a decimal integer.  If the conversion character
0183:         * is s, the field width is the the minimum number of
0184:         * characters to be printed.</p>
0185:         *<p>
0186:         * An optional precision that gives the minumum number
0187:         * of digits to appear for the d, i, o, x or X
0188:         * conversions (the field is padded with leading
0189:         * zeros); the number of digits to appear after the
0190:         * radix character for the e, E, and f conversions,
0191:         * the maximum number of significant digits for the g
0192:         * and G conversions; or the maximum number of
0193:         * characters to be written from a string is s and S
0194:         * conversions.  The precision takes the form of an
0195:         * optional decimal digit string, where a null digit
0196:         * string is treated as 0.  If a precision appears
0197:         * with a c conversion character the precision is
0198:         * ignored.
0199:         * </p>
0200:         *<p>
0201:         * An optional h specifies that a following d, i, o,
0202:         * x, or X conversion character applies to a type 
0203:         * short argument (the argument will be promoted
0204:         * according to the integral promotions and its value
0205:         * converted to type short before printing).</p>
0206:         *<p>
0207:         * An optional l (ell) specifies that a following
0208:         * d, i, o, x, or X conversion character applies to a
0209:         * type long argument.</p>
0210:         *<p>
0211:         * A field width or precision may be indicated by an
0212:         * asterisk (*) instead of a digit string.  In this
0213:         * case, an integer argument supplised the field width
0214:         * precision.  The argument that is actually converted
0215:         * is not fetched until the conversion letter is seen,
0216:         * so the the arguments specifying field width or
0217:         * precision must appear before the argument (if any)
0218:         * to be converted.  If the precision argument is
0219:         * negative, it will be changed to zero.  A negative
0220:         * field width argument is taken as a - flag, followed
0221:         * by a positive field width.</p>
0222:         * <p>
0223:         * In format strings containing the %<code>n</code>$
0224:         * form of a conversion specification, a field width
0225:         * or precision may be indicated by the sequence
0226:         * *<code>m</code>$, where m is a decimal integer
0227:         * giving the position in the argument list (after the
0228:         * format argument) of an integer argument containing
0229:         * the field width or precision.</p>
0230:         * <p>
0231:         * The format can contain either numbered argument
0232:         * specifications (that is, %<code>n</code>$ and
0233:         * *<code>m</code>$), or unnumbered argument
0234:         * specifications (that is % and *), but normally not
0235:         * both.  The only exception to this is that %% can
0236:         * be mixed with the %<code>n</code>$ form.  The
0237:         * results of mixing numbered and unnumbered argument
0238:         * specifications in a format string are undefined.</p>
0239:         *
0240:         *<h4>Flag Characters</h4>
0241:         *<p>
0242:         * The flags and their meanings are:</p>
0243:         *<dl>
0244:         * <dt>'<dd> integer portion of the result of a
0245:         *      decimal conversion (%i, %d, %f, %g, or %G) will
0246:         *      be formatted with thousands' grouping
0247:         *      characters.  For other conversions the flag
0248:         *      is ignored.  The non-monetary grouping
0249:         *      character is used.
0250:         * <dt>-<dd> result of the conversion is left-justified
0251:         *      within the field.  (It will be right-justified
0252:         *      if this flag is not specified).
0253:         * <dt>+<dd> result of a signed conversion always
0254:         *      begins with a sign (+ or -).  (It will begin
0255:         *      with a sign only when a negative value is
0256:         *      converted if this flag is not specified.)
0257:         * <dt>&lt;space&gt;<dd> If the first character of a
0258:         *      signed conversion is not a sign, a space
0259:         *      character will be placed before the result.
0260:         *      This means that if the space character and +
0261:         *      flags both appear, the space flag will be
0262:         *      ignored.
0263:         * <dt>#<dd> value is to be converted to an alternative
0264:         *      form.  For c, d, i, and s conversions, the flag
0265:         *      has no effect.  For o conversion, it increases
0266:         *      the precision to force the first digit of the
0267:         *      result to be a zero.  For x or X conversion, a
0268:         *      non-zero result has 0x or 0X prefixed to it,
0269:         *      respectively.  For e, E, f, g, and G
0270:         *      conversions, the result always contains a radix
0271:         *      character, even if no digits follow the radix
0272:         *      character (normally, a decimal point appears in
0273:         *      the result of these conversions only if a digit
0274:         *      follows it).  For g and G conversions, trailing
0275:         *      zeros will not be removed from the result as
0276:         *      they normally are.
0277:         * <dt>0<dd> d, i, o, x, X, e, E, f, g, and G
0278:         *      conversions, leading zeros (following any
0279:         *      indication of sign or base) are used to pad to
0280:         *      the field width;  no space padding is
0281:         *      performed.  If the 0 and - flags both appear,
0282:         *      the 0 flag is ignored.  For d, i, o, x, and X
0283:         *      conversions, if a precision is specified, the
0284:         *      0 flag will be ignored. For c conversions,
0285:         *      the flag is ignored.
0286:         *</dl>
0287:         *
0288:         *<h4>Conversion Characters</h4>
0289:         *<p>
0290:         * Each conversion character results in fetching zero
0291:         * or more arguments.  The results are undefined if
0292:         * there are insufficient arguments for the format.
0293:         * Usually, an unchecked exception will be thrown.
0294:         * If the format is exhausted while arguments remain,
0295:         * the excess arguments are ignored.</p>
0296:         *
0297:         *<p>
0298:         * The conversion characters and their meanings are:
0299:         *</p>
0300:         *<dl>
0301:         * <dt>d,i<dd>The int argument is converted to a
0302:         *        signed decimal in the style [-]dddd.  The
0303:         *        precision specifies the minimum number of
0304:         *        digits to appear;  if the value being
0305:         *        converted can be represented in fewer
0306:         *        digits, it will be expanded with leading
0307:         *        zeros.  The default precision is 1.  The
0308:         *        result of converting 0 with an explicit
0309:         *        precision of 0 is no characters.
0310:         * <dt>o<dd> The int argument is converted to unsigned
0311:         *        octal format in the style ddddd.  The
0312:         *        precision specifies the minimum number of
0313:         *        digits to appear;  if the value being
0314:         *        converted can be represented in fewer
0315:         *        digits, it will be expanded with leading
0316:         *        zeros.  The default precision is 1.  The
0317:         *        result of converting 0 with an explicit
0318:         *        precision of 0 is no characters.
0319:         * <dt>x<dd> The int argument is converted to unsigned
0320:         *        hexadecimal format in the style dddd;  the
0321:         *        letters abcdef are used.  The precision
0322:         *        specifies the minimum numberof digits to
0323:         *        appear; if the value being converted can be
0324:         *        represented in fewer digits, it will be
0325:         *        expanded with leading zeros.  The default
0326:         *        precision is 1.  The result of converting 0
0327:         *        with an explicit precision of 0 is no
0328:         *        characters.
0329:         * <dt>X<dd> Behaves the same as the x conversion
0330:         *        character except that letters ABCDEF are
0331:         *        used instead of abcdef.
0332:         * <dt>f<dd> The floating point number argument is
0333:         *        written in decimal notation in the style
0334:         *        [-]ddd.ddd, where the number of digits after
0335:         *        the radix character (shown here as a decimal
0336:         *        point) is equal to the precision
0337:         *        specification.  A Locale is used to determine
0338:         *        the radix character to use in this format.
0339:         *        If the precision is omitted from the
0340:         *        argument, six digits are written after the
0341:         *        radix character;  if the precision is
0342:         *        explicitly 0 and the # flag is not specified,
0343:         *        no radix character appears.  If a radix
0344:         *        character appears, at least 1 digit appears
0345:         *        before it.  The value is rounded to the
0346:         *        appropriate number of digits.
0347:         * <dt>e,E<dd>The floating point number argument is
0348:         *        written in the style [-]d.ddde{+-}dd
0349:         *        (the symbols {+-} indicate either a plus or
0350:         *        minus sign), where there is one digit before
0351:         *        the radix character (shown here as a decimal
0352:         *        point) and the number of digits after it is
0353:         *        equal to the precision.  A Locale is used to
0354:         *        determine the radix character to use in this
0355:         *        format.  When the precision is missing, six
0356:         *        digits are written after the radix character;
0357:         *        if the precision is 0 and the # flag is not
0358:         *        specified, no radix character appears.  The
0359:         *        E conversion will produce a number with E
0360:         *        instead of e introducing the exponent.  The
0361:         *        exponent always contains at least two digits.
0362:         *        However, if the value to be written requires
0363:         *        an exponent greater than two digits,
0364:         *        additional exponent digits are written as
0365:         *        necessary.  The value is rounded to the
0366:         *        appropriate number of digits.
0367:         * <dt>g,G<dd>The floating point number argument is
0368:         *        written in style f or e (or in sytle E in the
0369:         *        case of a G conversion character), with the
0370:         *        precision specifying the number of
0371:         *        significant digits.  If the precision is
0372:         *        zero, it is taken as one.  The style used
0373:         *        depends on the value converted:  style e
0374:         *        (or E) will be used only if the exponent
0375:         *        resulting from the conversion is less than
0376:         *        -4 or greater than or equal to the precision.
0377:         *        Trailing zeros are removed from the result.
0378:         *        A radix character appears only if it is
0379:         *        followed by a digit.
0380:         * <dt>c,C<dd>The integer argument is converted to a
0381:         *        char and the result is written.
0382:         *
0383:         * <dt>s,S<dd>The argument is taken to be a string and
0384:         *        bytes from the string are written until the
0385:         *        end of the string or the number of bytes 
0386:         *        indicated by the precision specification of
0387:         *        the argument is reached.  If the precision
0388:         *        is omitted from the argument, it is taken to
0389:         *        be infinite, so all characters up to the end
0390:         *        of the string are written.
0391:         * <dt>%<dd>Write a % character;  no argument is
0392:         *        converted.
0393:         *</dl>
0394:         *<p>
0395:         * If a conversion specification does not match one of
0396:         * the above forms, an IllegalArgumentException is
0397:         * thrown and the instance of PrintfFormat is not
0398:         * created.</p>
0399:         *<p>
0400:         * If a floating point value is the internal
0401:         * representation for infinity, the output is
0402:         * [+]Infinity, where Infinity is either Infinity or
0403:         * Inf, depending on the desired output string length.
0404:         * Printing of the sign follows the rules described
0405:         * above.</p>
0406:         *<p>
0407:         * If a floating point value is the internal
0408:         * representation for "not-a-number," the output is
0409:         * [+]NaN.  Printing of the sign follows the rules
0410:         * described above.</p>
0411:         *<p>
0412:         * In no case does a non-existent or small field width
0413:         * cause truncation of a field;  if the result of a
0414:         * conversion is wider than the field width, the field
0415:         * is simply expanded to contain the conversion result.
0416:         *</p>
0417:         *<p>
0418:         * The behavior is like printf.  One exception is that
0419:         * the minimum number of exponent digits is 3 instead
0420:         * of 2 for e and E formats when the optional L is used
0421:         * before the e, E, g, or G conversion character.  The
0422:         * optional L does not imply conversion to a long long
0423:         * double. </p>
0424:         * <p>
0425:         * The biggest divergence from the C printf
0426:         * specification is in the use of 16 bit characters.
0427:         * This allows the handling of characters beyond the
0428:         * small ASCII character set and allows the utility to
0429:         * interoperate correctly with the rest of the Java
0430:         * runtime environment.</p>
0431:         *<p>
0432:         * Omissions from the C printf specification are
0433:         * numerous.  All the known omissions are present
0434:         * because Java never uses bytes to represent
0435:         * characters and does not have pointers:</p>
0436:         *<ul>
0437:         * <li>%c is the same as %C.
0438:         * <li>%s is the same as %S.
0439:         * <li>u, p, and n conversion characters. 
0440:         * <li>%ws format.
0441:         * <li>h modifier applied to an n conversion character.
0442:         * <li>l (ell) modifier applied to the c, n, or s
0443:         * conversion characters.
0444:         * <li>ll (ell ell) modifier to d, i, o, u, x, or X
0445:         * conversion characters.
0446:         * <li>ll (ell ell) modifier to an n conversion
0447:         * character.
0448:         * <li>c, C, d,i,o,u,x, and X conversion characters
0449:         * apply to Byte, Character, Short, Integer, Long
0450:         * types.
0451:         * <li>f, e, E, g, and G conversion characters apply
0452:         * to Float and Double types.
0453:         * <li>s and S conversion characters apply to String
0454:         * types.
0455:         * <li>All other reference types can be formatted
0456:         * using the s or S conversion characters only.
0457:         *</ul>
0458:         * <p>
0459:         * Most of this specification is quoted from the Unix
0460:         * man page for the sprintf utility.</p>
0461:         *
0462:         * @author Allan Jacobs
0463:         * 
0464:         * @version $Revision: 1.12 $ 
0465:         * 
0466:         * @since 6.0.0 
0467:         */
0468:        public class PrintfFormat {
0469:
0470:            /**
0471:             *<p>
0472:             * ConversionSpecification allows the formatting of
0473:             * a single primitive or object embedded within a
0474:             * string.  The formatting is controlled by a
0475:             * format string.  Only one Java primitive or
0476:             * object can be formatted at a time.
0477:             *<p>
0478:             * A format string is a Java string that contains
0479:             * a control string.  The control string starts at
0480:             * the first percent sign (%) in the string,
0481:             * provided that this percent sign
0482:             *<ol>
0483:             *<li>is not escaped protected by a matching % or
0484:             *     is not an escape % character,
0485:             *<li>is not at the end of the format string, and
0486:             *<li>precedes a sequence of characters that parses
0487:             *     as a valid control string.
0488:             *</ol>
0489:             *<p>
0490:             * A control string takes the form:
0491:             *<pre> % ['-+ #0]* [0..9]* { . [0..9]* }+
0492:             *                { [hlL] }+ [idfgGoxXeEcs]
0493:             *</pre>
0494:             *<p>
0495:             * The behavior is like printf.  One (hopefully the
0496:             * only) exception is that the minimum number of
0497:             * exponent digits is 3 instead of 2 for e and E
0498:             * formats when the optional L is used before the
0499:             * e, E, g, or G conversion character.  The 
0500:             * optional L does not imply conversion to a long
0501:             * long double.
0502:             */
0503:            private final class ConversionSpecification {
0504:
0505:                /** Default precision. */
0506:                private static final int DEFAULT_DIGITS = 6;
0507:
0508:                /**
0509:                 * For an o conversion, increase the precision to
0510:                 * force the first digit of the result to be a
0511:                 * zero.  For x (or X) conversions, a non-zero
0512:                 * result will have 0x (or 0X) prepended to it.
0513:                 * For e, E, f, g, or G conversions, the result
0514:                 * will always contain a radix character, even if
0515:                 * no digits follow the point.  For g and G
0516:                 * conversions, trailing zeros will not be removed
0517:                 * from the result.
0518:                 */
0519:                private boolean m_alternateForm;
0520:
0521:                /** Internal variable. */
0522:                private int m_argumentPosition;
0523:
0524:                /** Internal variable. */
0525:                private int m_argumentPositionForFieldWidth;
0526:
0527:                /** Internal variable. */
0528:                private int m_argumentPositionForPrecision;
0529:
0530:                /** Control string type. */
0531:                private char m_conversionCharacter;
0532:
0533:                /**
0534:                 * If the converted value has fewer bytes than the
0535:                 * field width, it will be padded with spaces or
0536:                 * zeroes.
0537:                 */
0538:                private int m_fieldWidth;
0539:
0540:                /**
0541:                 * Flag indicating whether or not the field width
0542:                 * has been set.
0543:                 */
0544:                private boolean m_fieldWidthSet;
0545:
0546:                /** Literal or control format string. */
0547:                private String m_fmt;
0548:
0549:                /**
0550:                 * The result of a signed conversion will always
0551:                 * begin with a sign (+ or -).
0552:                 */
0553:                private boolean m_leadingSign;
0554:
0555:                /**
0556:                 * Flag indicating that left padding with spaces is
0557:                 * specified.
0558:                 */
0559:                private boolean m_leadingSpace;
0560:
0561:                /**
0562:                 * Flag indicating that left padding with zeroes is
0563:                 * specified.
0564:                 */
0565:                private boolean m_leadingZeros;
0566:
0567:                /**
0568:                 * The result of the conversion will be
0569:                 * left-justified within the field.
0570:                 */
0571:                private boolean m_leftJustify;
0572:
0573:                /**
0574:                 * Flag specifying that a following d, i, o, u, x,
0575:                 * or X conversion character applies to a type
0576:                 * short int.
0577:                 */
0578:                private boolean m_optionalh;
0579:
0580:                /**
0581:                 * Flag specifying that a following d, i, o, u, x,
0582:                 * or X conversion character applies to a type lont
0583:                 * int argument.
0584:                 */
0585:                private boolean m_optionall;
0586:
0587:                /**
0588:                 * Flag specifying that a following e, E, f, g, or
0589:                 * G conversion character applies to a type double
0590:                 * argument.  This is a noop in Java.
0591:                 */
0592:                private boolean m_optionalL;
0593:
0594:                /**
0595:                 * Position within the control string.  Used by
0596:                 * the constructor.
0597:                 */
0598:                private int m_pos;
0599:
0600:                /** Internal variable. */
0601:                private boolean m_positionalFieldWidth;
0602:
0603:                /** Internal variable. */
0604:                private boolean m_positionalPrecision;
0605:
0606:                /** Internal variable. */
0607:                private boolean m_positionalSpecification;
0608:
0609:                /**
0610:                 * The minimum number of digits to appear for the
0611:                 * d, i, o, u, x, or X conversions.  The number of
0612:                 * digits to appear after the radix character for
0613:                 * the e, E, and f conversions.  The maximum number
0614:                 *  of significant digits for the g and G 
0615:                 * conversions.  The maximum number of bytes to be
0616:                 * printed from a string in s and S conversions.
0617:                 */
0618:                private int m_precision;
0619:
0620:                /**
0621:                 * Flag indicating whether or not the precision has
0622:                 * been set.
0623:                 */
0624:                private boolean m_precisionSet;
0625:
0626:                /**
0627:                 * The integer portion of the result of a decimal
0628:                 * conversion (i, d, u, f, g, or G) will be
0629:                 * formatted with thousands' grouping characters.
0630:                 * For other conversions the flag is ignored.
0631:                 */
0632:                private boolean m_thousands;
0633:
0634:                /**
0635:                 * Flag indicating that the field width is *.
0636:                 */
0637:                private boolean m_variableFieldWidth;
0638:
0639:                /**
0640:                 * Flag indicating that the precision is *.
0641:                 */
0642:                private boolean m_variablePrecision;
0643:
0644:                /**
0645:                 * Constructor.  Used to prepare an instance
0646:                 * to hold a literal, not a control string.
0647:                 */
0648:                ConversionSpecification() {
0649:
0650:                    // empty
0651:                }
0652:
0653:                /**
0654:                 * Constructor for a conversion specification.
0655:                 * The argument must begin with a % and end
0656:                 * with the conversion character for the
0657:                 * conversion specification.
0658:                 * @param fmtArg  String specifying the
0659:                 *     conversion specification.
0660:                 * @exception CmsIllegalArgumentException if the
0661:                 *     input string is null, zero length, or
0662:                 *     otherwise malformed.
0663:                 */
0664:                ConversionSpecification(String fmtArg)
0665:                        throws CmsIllegalArgumentException {
0666:
0667:                    if (fmtArg == null) {
0668:                        throw new NullPointerException();
0669:                    }
0670:                    if (fmtArg.length() == 0) {
0671:                        throw new CmsIllegalArgumentException(
0672:                                Messages.get().container(
0673:                                        Messages.ERR_CONTROL_STRING_LENGTH_0));
0674:                    }
0675:                    if (fmtArg.charAt(0) == '%') {
0676:                        m_fmt = fmtArg;
0677:                        m_pos = 1;
0678:                        setArgPosition();
0679:                        setFlagCharacters();
0680:                        setFieldWidth();
0681:                        setPrecision();
0682:                        setOptionalHL();
0683:                        if (setConversionCharacter()) {
0684:                            if (m_pos == fmtArg.length()) {
0685:                                if (m_leadingZeros && m_leftJustify) {
0686:                                    m_leadingZeros = false;
0687:                                }
0688:                                if (m_precisionSet && m_leadingZeros) {
0689:                                    if ((m_conversionCharacter == 'd')
0690:                                            || (m_conversionCharacter == 'i')
0691:                                            || (m_conversionCharacter == 'o')
0692:                                            || (m_conversionCharacter == 'x')) {
0693:                                        m_leadingZeros = false;
0694:                                    }
0695:                                }
0696:                            } else {
0697:                                throw new CmsIllegalArgumentException(
0698:                                        Messages
0699:                                                .get()
0700:                                                .container(
0701:                                                        Messages.ERR_INVALID_CONVERSION_SPEC_1,
0702:                                                        fmtArg));
0703:                            }
0704:                        } else {
0705:                            throw new CmsIllegalArgumentException(
0706:                                    Messages
0707:                                            .get()
0708:                                            .container(
0709:                                                    Messages.ERR_INVALID_CONVERSION_SPEC_1,
0710:                                                    fmtArg));
0711:                        }
0712:                    } else {
0713:                        throw new CmsIllegalArgumentException(Messages.get()
0714:                                .container(Messages.ERR_CONTROL_STRING_START_0));
0715:                    }
0716:                }
0717:
0718:                /**
0719:                 * Internal helper.<p>
0720:                 * 
0721:                 * @return the result
0722:                 */
0723:                int getArgumentPosition() {
0724:
0725:                    return m_argumentPosition;
0726:                }
0727:
0728:                /**
0729:                 * Internal helper.<p> 
0730:                 * 
0731:                 * @return the result
0732:                 */
0733:                int getArgumentPositionForFieldWidth() {
0734:
0735:                    return m_argumentPositionForFieldWidth;
0736:                }
0737:
0738:                /**
0739:                 * Internal helper.<p>
0740:                 * 
0741:                 * @return the result
0742:                 */
0743:                int getArgumentPositionForPrecision() {
0744:
0745:                    return m_argumentPositionForPrecision;
0746:                }
0747:
0748:                /**
0749:                 * Get the conversion character that tells what
0750:                 * type of control character this instance has.
0751:                 *
0752:                 * @return the conversion character.
0753:                 */
0754:                char getConversionCharacter() {
0755:
0756:                    return m_conversionCharacter;
0757:                }
0758:
0759:                /**
0760:                 * Get the String for this instance.  Translate
0761:                 * any escape sequences.
0762:                 *
0763:                 * @return s the stored String.
0764:                 */
0765:                String getLiteral() {
0766:
0767:                    StringBuffer sb = new StringBuffer();
0768:                    int i = 0;
0769:                    while (i < m_fmt.length()) {
0770:                        if (m_fmt.charAt(i) == '\\') {
0771:                            i++;
0772:                            if (i < m_fmt.length()) {
0773:                                char c = m_fmt.charAt(i);
0774:                                switch (c) {
0775:                                case 'a':
0776:                                    sb.append((char) 0x07);
0777:                                    break;
0778:                                case 'b':
0779:                                    sb.append('\b');
0780:                                    break;
0781:                                case 'f':
0782:                                    sb.append('\f');
0783:                                    break;
0784:                                case 'n':
0785:                                    sb.append(System
0786:                                            .getProperty("line.separator"));
0787:                                    break;
0788:                                case 'r':
0789:                                    sb.append('\r');
0790:                                    break;
0791:                                case 't':
0792:                                    sb.append('\t');
0793:                                    break;
0794:                                case 'v':
0795:                                    sb.append((char) 0x0b);
0796:                                    break;
0797:                                case '\\':
0798:                                    sb.append('\\');
0799:                                    break;
0800:                                default:
0801:                                    // noop
0802:                                }
0803:                                i++;
0804:                            } else {
0805:                                sb.append('\\');
0806:                            }
0807:                        } else {
0808:                            i++;
0809:                        }
0810:                    }
0811:                    return m_fmt;
0812:                }
0813:
0814:                /**
0815:                 * Format a double argument using this conversion
0816:                 * specification.
0817:                 * @param s the double to format.
0818:                 * @return the formatted String.
0819:                 * @exception CmsIllegalArgumentException if the
0820:                 *     conversion character is c, C, s, S, i, d,
0821:                 *     x, X, or o.
0822:                 */
0823:                String internalsprintf(double s)
0824:                        throws CmsIllegalArgumentException {
0825:
0826:                    String s2 = "";
0827:                    switch (m_conversionCharacter) {
0828:                    case 'f':
0829:                        s2 = printFFormat(s);
0830:                        break;
0831:                    case 'E':
0832:                    case 'e':
0833:                        s2 = printEFormat(s);
0834:                        break;
0835:                    case 'G':
0836:                    case 'g':
0837:                        s2 = printGFormat(s);
0838:                        break;
0839:                    default:
0840:                        throw new CmsIllegalArgumentException(Messages.get()
0841:                                .container(
0842:                                        Messages.ERR_INVALID_DOUBLE_FMT_CHAR_2,
0843:                                        "double",
0844:                                        new Character(m_conversionCharacter)));
0845:                    }
0846:                    return s2;
0847:                }
0848:
0849:                /**
0850:                 * Format an int argument using this conversion
0851:                 * specification.
0852:                 * @param s the int to format.
0853:                 * @return the formatted String.
0854:                 * @exception CmsIllegalArgumentException if the
0855:                 *     conversion character is f, e, E, g, or G.
0856:                 */
0857:                String internalsprintf(int s)
0858:                        throws CmsIllegalArgumentException {
0859:
0860:                    String s2 = "";
0861:                    switch (m_conversionCharacter) {
0862:                    case 'd':
0863:                    case 'i':
0864:                        if (m_optionalh) {
0865:                            s2 = printDFormat((short) s);
0866:                        } else if (m_optionall) {
0867:                            s2 = printDFormat((long) s);
0868:                        } else {
0869:                            s2 = printDFormat(s);
0870:                        }
0871:                        break;
0872:                    case 'x':
0873:                    case 'X':
0874:                        if (m_optionalh) {
0875:                            s2 = printXFormat((short) s);
0876:                        } else if (m_optionall) {
0877:                            s2 = printXFormat((long) s);
0878:                        } else {
0879:                            s2 = printXFormat(s);
0880:                        }
0881:                        break;
0882:                    case 'o':
0883:                        if (m_optionalh) {
0884:                            s2 = printOFormat((short) s);
0885:                        } else if (m_optionall) {
0886:                            s2 = printOFormat((long) s);
0887:                        } else {
0888:                            s2 = printOFormat(s);
0889:                        }
0890:                        break;
0891:                    case 'c':
0892:                    case 'C':
0893:                        s2 = printCFormat((char) s);
0894:                        break;
0895:                    default:
0896:                        throw new CmsIllegalArgumentException(Messages.get()
0897:                                .container(
0898:                                        Messages.ERR_INVALID_DOUBLE_FMT_CHAR_2,
0899:                                        "int",
0900:                                        new Character(m_conversionCharacter)));
0901:                    }
0902:                    return s2;
0903:                }
0904:
0905:                /**
0906:                 * Format a long argument using this conversion
0907:                 * specification.
0908:                 * @param s the long to format.
0909:                 * @return the formatted String.
0910:                 * @exception CmsIllegalArgumentException if the
0911:                 *     conversion character is f, e, E, g, or G.
0912:                 */
0913:                String internalsprintf(long s)
0914:                        throws CmsIllegalArgumentException {
0915:
0916:                    String s2 = "";
0917:                    switch (m_conversionCharacter) {
0918:                    case 'd':
0919:                    case 'i':
0920:                        if (m_optionalh) {
0921:                            s2 = printDFormat((short) s);
0922:                        } else if (m_optionall) {
0923:                            s2 = printDFormat(s);
0924:                        } else {
0925:                            s2 = printDFormat((int) s);
0926:                        }
0927:                        break;
0928:                    case 'x':
0929:                    case 'X':
0930:                        if (m_optionalh) {
0931:                            s2 = printXFormat((short) s);
0932:                        } else if (m_optionall) {
0933:                            s2 = printXFormat(s);
0934:                        } else {
0935:                            s2 = printXFormat((int) s);
0936:                        }
0937:                        break;
0938:                    case 'o':
0939:                        if (m_optionalh) {
0940:                            s2 = printOFormat((short) s);
0941:                        } else if (m_optionall) {
0942:                            s2 = printOFormat(s);
0943:                        } else {
0944:                            s2 = printOFormat((int) s);
0945:                        }
0946:                        break;
0947:                    case 'c':
0948:                    case 'C':
0949:                        s2 = printCFormat((char) s);
0950:                        break;
0951:                    default:
0952:                        throw new CmsIllegalArgumentException(Messages.get()
0953:                                .container(
0954:                                        Messages.ERR_INVALID_DOUBLE_FMT_CHAR_2,
0955:                                        "long",
0956:                                        new Character(m_conversionCharacter)));
0957:                    }
0958:                    return s2;
0959:                }
0960:
0961:                /**
0962:                 * Format an Object argument using this conversion
0963:                 * specification.
0964:                 * @param s the Object to format.
0965:                 * @return the formatted String.
0966:                 * @exception CmsIllegalArgumentException if the
0967:                 *     conversion character is neither s nor S.
0968:                 */
0969:                String internalsprintf(Object s)
0970:                        throws CmsIllegalArgumentException {
0971:
0972:                    String s2 = "";
0973:                    if ((m_conversionCharacter == 's')
0974:                            || (m_conversionCharacter == 'S')) {
0975:                        s2 = printSFormat(s.toString());
0976:                    } else {
0977:                        throw new CmsIllegalArgumentException(Messages.get()
0978:                                .container(
0979:                                        Messages.ERR_INVALID_DOUBLE_FMT_CHAR_2,
0980:                                        "String",
0981:                                        new Character(m_conversionCharacter)));
0982:                    }
0983:                    return s2;
0984:                }
0985:
0986:                /**
0987:                 * Format a String argument using this conversion
0988:                 * specification.
0989:                 * @param s the String to format.
0990:                 * @return the formatted String.
0991:                 * @exception CmsIllegalArgumentException if the
0992:                 *   conversion character is neither s nor S.
0993:                 */
0994:                String internalsprintf(String s)
0995:                        throws CmsIllegalArgumentException {
0996:
0997:                    String s2 = "";
0998:                    if ((m_conversionCharacter == 's')
0999:                            || (m_conversionCharacter == 'S')) {
1000:                        s2 = printSFormat(s);
1001:                    } else {
1002:                        throw new CmsIllegalArgumentException(Messages.get()
1003:                                .container(
1004:                                        Messages.ERR_INVALID_DOUBLE_FMT_CHAR_2,
1005:                                        "String",
1006:                                        new Character(m_conversionCharacter)));
1007:                    }
1008:                    return s2;
1009:                }
1010:
1011:                /**
1012:                 * Internal helper.<p>
1013:                 * 
1014:                 * @return the result
1015:                 */
1016:                boolean isPositionalFieldWidth() {
1017:
1018:                    return m_positionalFieldWidth;
1019:                }
1020:
1021:                /**
1022:                 * Internal helper.<p>
1023:                 * 
1024:                 * @return the result
1025:                 */
1026:                boolean isPositionalPrecision() {
1027:
1028:                    return m_positionalPrecision;
1029:                }
1030:
1031:                /**
1032:                 * Internal helper.<p> 
1033:                 * 
1034:                 * @return the result
1035:                 */
1036:                boolean isPositionalSpecification() {
1037:
1038:                    return m_positionalSpecification;
1039:                }
1040:
1041:                /**
1042:                 * Check whether the specifier has a variable
1043:                 * field width that is going to be set by an
1044:                 * argument.
1045:                 * @return <code>true</code> if the conversion
1046:                 *   uses an * field width; otherwise
1047:                 *   <code>false</code>.
1048:                 */
1049:                boolean isVariableFieldWidth() {
1050:
1051:                    return m_variableFieldWidth;
1052:                }
1053:
1054:                /**
1055:                 * Check whether the specifier has a variable
1056:                 * precision that is going to be set by an
1057:                 * argument.
1058:                 * @return <code>true</code> if the conversion
1059:                 *   uses an * precision; otherwise
1060:                 *   <code>false</code>.
1061:                 */
1062:                boolean isVariablePrecision() {
1063:
1064:                    return m_variablePrecision;
1065:                }
1066:
1067:                /**
1068:                 * Set the field width with an argument.  A
1069:                 * negative field width is taken as a - flag
1070:                 * followed by a positive field width.
1071:                 * @param fw the field width.
1072:                 */
1073:                void setFieldWidthWithArg(int fw) {
1074:
1075:                    if (fw < 0) {
1076:                        m_leftJustify = true;
1077:                    }
1078:                    m_fieldWidthSet = true;
1079:                    m_fieldWidth = Math.abs(fw);
1080:                }
1081:
1082:                /**
1083:                 * Set the String for this instance.
1084:                 * @param s the String to store.
1085:                 */
1086:                void setLiteral(String s) {
1087:
1088:                    m_fmt = s;
1089:                }
1090:
1091:                /**
1092:                 * Set the precision with an argument.  A
1093:                 * negative precision will be changed to zero.
1094:                 * @param pr the precision.
1095:                 */
1096:                void setPrecisionWithArg(int pr) {
1097:
1098:                    m_precisionSet = true;
1099:                    m_precision = Math.max(pr, 0);
1100:                }
1101:
1102:                /**
1103:                 * Apply zero or blank, left or right padding.
1104:                 * @param ca4 array of characters before padding is
1105:                 *     finished
1106:                 * @param noDigits NaN or signed Inf
1107:                 * @return a padded array of characters
1108:                 */
1109:                private char[] applyFloatPadding(char[] ca4, boolean noDigits) {
1110:
1111:                    char[] ca5 = ca4;
1112:                    if (m_fieldWidthSet) {
1113:                        int i, j, nBlanks;
1114:                        if (m_leftJustify) {
1115:                            nBlanks = m_fieldWidth - ca4.length;
1116:                            if (nBlanks > 0) {
1117:                                ca5 = new char[ca4.length + nBlanks];
1118:                                for (i = 0; i < ca4.length; i++) {
1119:                                    ca5[i] = ca4[i];
1120:                                }
1121:                                for (j = 0; j < nBlanks; j++, i++) {
1122:                                    ca5[i] = ' ';
1123:                                }
1124:                            }
1125:                        } else if (!m_leadingZeros || noDigits) {
1126:                            nBlanks = m_fieldWidth - ca4.length;
1127:                            if (nBlanks > 0) {
1128:                                ca5 = new char[ca4.length + nBlanks];
1129:                                for (i = 0; i < nBlanks; i++) {
1130:                                    ca5[i] = ' ';
1131:                                }
1132:                                for (j = 0; j < ca4.length; i++, j++) {
1133:                                    ca5[i] = ca4[j];
1134:                                }
1135:                            }
1136:                        } else if (m_leadingZeros) {
1137:                            nBlanks = m_fieldWidth - ca4.length;
1138:                            if (nBlanks > 0) {
1139:                                ca5 = new char[ca4.length + nBlanks];
1140:                                i = 0;
1141:                                j = 0;
1142:                                if (ca4[0] == '-') {
1143:                                    ca5[0] = '-';
1144:                                    i++;
1145:                                    j++;
1146:                                }
1147:                                for (int k = 0; k < nBlanks; i++, k++) {
1148:                                    ca5[i] = '0';
1149:                                }
1150:                                for (; j < ca4.length; i++, j++) {
1151:                                    ca5[i] = ca4[j];
1152:                                }
1153:                            }
1154:                        }
1155:                    }
1156:                    return ca5;
1157:                }
1158:
1159:                /**
1160:                 * Check to see if the digits that are going to
1161:                 * be truncated because of the precision should
1162:                 * force a round in the preceding digits.
1163:                 * @param ca1 the array of digits
1164:                 * @param icarry the index of the first digit that
1165:                 *     is to be truncated from the print
1166:                 * @return <code>true</code> if the truncation forces
1167:                 *     a round that will change the print
1168:                 */
1169:                private boolean checkForCarry(char[] ca1, int icarry) {
1170:
1171:                    boolean carry = false;
1172:                    if (icarry < ca1.length) {
1173:                        if ((ca1[icarry] == '6') || (ca1[icarry] == '7')
1174:                                || (ca1[icarry] == '8') || (ca1[icarry] == '9')) {
1175:                            carry = true;
1176:                        } else if (ca1[icarry] == '5') {
1177:                            int ii = icarry + 1;
1178:                            for (; ii < ca1.length; ii++) {
1179:                                if (ca1[ii] != '0') {
1180:                                    break;
1181:                                }
1182:                            }
1183:                            carry = ii < ca1.length;
1184:                            if (!carry && (icarry > 0)) {
1185:                                carry = ((ca1[icarry - 1] == '1')
1186:                                        || (ca1[icarry - 1] == '3')
1187:                                        || (ca1[icarry - 1] == '5')
1188:                                        || (ca1[icarry - 1] == '7') || (ca1[icarry - 1] == '9'));
1189:                            }
1190:                        }
1191:                    }
1192:                    return carry;
1193:                }
1194:
1195:                /**
1196:                 * For e format, the flag character '-', means that
1197:                 * the output should be left justified within the
1198:                 * field.  The default is to pad with blanks on the
1199:                 * left.  '+' character means that the conversion
1200:                 * will always begin with a sign (+ or -).  The
1201:                 * blank flag character means that a non-negative
1202:                 * input will be preceded with a blank.  If both a
1203:                 * '+' and a ' ' are specified, the blank flag is
1204:                 * ignored.  The '0' flag character implies that
1205:                 * padding to the field width will be done with
1206:                 * zeros instead of blanks.
1207:                 *
1208:                 * The field width is treated as the minimum number
1209:                 * of characters to be printed.  The default is to
1210:                 * add no padding.  Padding is with blanks by
1211:                 * default.
1212:                 *
1213:                 * The precision, if set, is the minimum number of
1214:                 * digits to appear after the radix character.
1215:                 * Padding is with trailing 0s.
1216:                 *
1217:                 * The behavior is like printf.  One (hopefully the
1218:                 * only) exception is that the minimum number of
1219:                 * exponent digits is 3 instead of 2 for e and E
1220:                 * formats when the optional L is used before the
1221:                 * e, E, g, or G conversion character. The optional
1222:                 * L does not imply conversion to a long long
1223:                 * double.
1224:                 * 
1225:                 * @param x the x parameter
1226:                 * @param eChar the eChar parameter
1227:                 * @return the result
1228:                 */
1229:                private char[] eFormatDigits(double x, char eChar) {
1230:
1231:                    char[] ca1, ca2, ca3;
1232:                    // int defaultDigits=6;
1233:                    String sx;
1234:                    int i, j, k, p;
1235:                    int expon = 0;
1236:                    int ePos, rPos, eSize;
1237:                    boolean minusSign = false;
1238:                    if (x > 0.0) {
1239:                        sx = Double.toString(x);
1240:                    } else if (x < 0.0) {
1241:                        sx = Double.toString(-x);
1242:                        minusSign = true;
1243:                    } else {
1244:                        sx = Double.toString(x);
1245:                        if (sx.charAt(0) == '-') {
1246:                            minusSign = true;
1247:                            sx = sx.substring(1);
1248:                        }
1249:                    }
1250:                    ePos = sx.indexOf('E');
1251:                    if (ePos == -1) {
1252:                        ePos = sx.indexOf('e');
1253:                    }
1254:                    rPos = sx.indexOf('.');
1255:                    if (ePos != -1) {
1256:                        int ie = ePos + 1;
1257:                        expon = 0;
1258:                        if (sx.charAt(ie) == '-') {
1259:                            for (++ie; ie < sx.length(); ie++) {
1260:                                if (sx.charAt(ie) != '0') {
1261:                                    break;
1262:                                }
1263:                            }
1264:                            if (ie < sx.length()) {
1265:                                expon = -Integer.parseInt(sx.substring(ie));
1266:                            }
1267:                        } else {
1268:                            if (sx.charAt(ie) == '+') {
1269:                                ++ie;
1270:                            }
1271:                            for (; ie < sx.length(); ie++) {
1272:                                if (sx.charAt(ie) != '0') {
1273:                                    break;
1274:                                }
1275:                            }
1276:                            if (ie < sx.length()) {
1277:                                expon = Integer.parseInt(sx.substring(ie));
1278:                            }
1279:                        }
1280:                    }
1281:                    if (rPos != -1) {
1282:                        expon += rPos - 1;
1283:                    }
1284:                    if (m_precisionSet) {
1285:                        p = m_precision;
1286:                    } else {
1287:                        p = DEFAULT_DIGITS - 1;
1288:                    }
1289:                    if ((rPos != -1) && (ePos != -1)) {
1290:                        ca1 = (sx.substring(0, rPos) + sx.substring(rPos + 1,
1291:                                ePos)).toCharArray();
1292:                    } else if (rPos != -1) {
1293:                        ca1 = (sx.substring(0, rPos) + sx.substring(rPos + 1))
1294:                                .toCharArray();
1295:                    } else if (ePos != -1) {
1296:                        ca1 = sx.substring(0, ePos).toCharArray();
1297:                    } else {
1298:                        ca1 = sx.toCharArray();
1299:                    }
1300:                    boolean carry = false;
1301:                    int i0 = 0;
1302:                    if (ca1[0] != '0') {
1303:                        i0 = 0;
1304:                    } else {
1305:                        for (i0 = 0; i0 < ca1.length; i0++) {
1306:                            if (ca1[i0] != '0') {
1307:                                break;
1308:                            }
1309:                        }
1310:                    }
1311:                    if (i0 + p < ca1.length - 1) {
1312:                        carry = checkForCarry(ca1, i0 + p + 1);
1313:                        if (carry) {
1314:                            carry = startSymbolicCarry(ca1, i0 + p, i0);
1315:                        }
1316:                        if (carry) {
1317:                            ca2 = new char[i0 + p + 1];
1318:                            ca2[i0] = '1';
1319:                            for (j = 0; j < i0; j++) {
1320:                                ca2[j] = '0';
1321:                            }
1322:                            for (i = i0, j = i0 + 1; j < p + 1; i++, j++) {
1323:                                ca2[j] = ca1[i];
1324:                            }
1325:                            expon++;
1326:                            ca1 = ca2;
1327:                        }
1328:                    }
1329:                    if ((Math.abs(expon) < 100) && !m_optionalL) {
1330:                        eSize = 4;
1331:                    } else {
1332:                        eSize = 5;
1333:                    }
1334:                    if (m_alternateForm || !m_precisionSet
1335:                            || (m_precision != 0)) {
1336:                        ca2 = new char[2 + p + eSize];
1337:                    } else {
1338:                        ca2 = new char[1 + eSize];
1339:                    }
1340:                    if (ca1[0] != '0') {
1341:                        ca2[0] = ca1[0];
1342:                        j = 1;
1343:                    } else {
1344:                        for (j = 1; j < (ePos == -1 ? ca1.length : ePos); j++) {
1345:                            if (ca1[j] != '0') {
1346:                                break;
1347:                            }
1348:                        }
1349:                        if (((ePos != -1) && (j < ePos))
1350:                                || ((ePos == -1) && (j < ca1.length))) {
1351:                            ca2[0] = ca1[j];
1352:                            expon -= j;
1353:                            j++;
1354:                        } else {
1355:                            ca2[0] = '0';
1356:                            j = 2;
1357:                        }
1358:                    }
1359:                    if (m_alternateForm || !m_precisionSet
1360:                            || (m_precision != 0)) {
1361:                        ca2[1] = '.';
1362:                        i = 2;
1363:                    } else {
1364:                        i = 1;
1365:                    }
1366:                    for (k = 0; (k < p) && (j < ca1.length); j++, i++, k++) {
1367:                        ca2[i] = ca1[j];
1368:                    }
1369:                    for (; i < ca2.length - eSize; i++) {
1370:                        ca2[i] = '0';
1371:                    }
1372:                    ca2[i++] = eChar;
1373:                    if (expon < 0) {
1374:                        ca2[i++] = '-';
1375:                    } else {
1376:                        ca2[i++] = '+';
1377:                    }
1378:                    expon = Math.abs(expon);
1379:                    if (expon >= 100) {
1380:                        switch (expon / 100) {
1381:                        case 1:
1382:                            ca2[i] = '1';
1383:                            break;
1384:                        case 2:
1385:                            ca2[i] = '2';
1386:                            break;
1387:                        case 3:
1388:                            ca2[i] = '3';
1389:                            break;
1390:                        case 4:
1391:                            ca2[i] = '4';
1392:                            break;
1393:                        case 5:
1394:                            ca2[i] = '5';
1395:                            break;
1396:                        case 6:
1397:                            ca2[i] = '6';
1398:                            break;
1399:                        case 7:
1400:                            ca2[i] = '7';
1401:                            break;
1402:                        case 8:
1403:                            ca2[i] = '8';
1404:                            break;
1405:                        case 9:
1406:                            ca2[i] = '9';
1407:                            break;
1408:                        default:
1409:                            // noop
1410:                        }
1411:                        i++;
1412:                    }
1413:                    switch ((expon % 100) / 10) {
1414:                    case 0:
1415:                        ca2[i] = '0';
1416:                        break;
1417:                    case 1:
1418:                        ca2[i] = '1';
1419:                        break;
1420:                    case 2:
1421:                        ca2[i] = '2';
1422:                        break;
1423:                    case 3:
1424:                        ca2[i] = '3';
1425:                        break;
1426:                    case 4:
1427:                        ca2[i] = '4';
1428:                        break;
1429:                    case 5:
1430:                        ca2[i] = '5';
1431:                        break;
1432:                    case 6:
1433:                        ca2[i] = '6';
1434:                        break;
1435:                    case 7:
1436:                        ca2[i] = '7';
1437:                        break;
1438:                    case 8:
1439:                        ca2[i] = '8';
1440:                        break;
1441:                    case 9:
1442:                        ca2[i] = '9';
1443:                        break;
1444:                    default:
1445:                        // noop
1446:                    }
1447:                    i++;
1448:                    switch (expon % 10) {
1449:                    case 0:
1450:                        ca2[i] = '0';
1451:                        break;
1452:                    case 1:
1453:                        ca2[i] = '1';
1454:                        break;
1455:                    case 2:
1456:                        ca2[i] = '2';
1457:                        break;
1458:                    case 3:
1459:                        ca2[i] = '3';
1460:                        break;
1461:                    case 4:
1462:                        ca2[i] = '4';
1463:                        break;
1464:                    case 5:
1465:                        ca2[i] = '5';
1466:                        break;
1467:                    case 6:
1468:                        ca2[i] = '6';
1469:                        break;
1470:                    case 7:
1471:                        ca2[i] = '7';
1472:                        break;
1473:                    case 8:
1474:                        ca2[i] = '8';
1475:                        break;
1476:                    case 9:
1477:                        ca2[i] = '9';
1478:                        break;
1479:                    default:
1480:                        // noop
1481:                    }
1482:                    int nZeros = 0;
1483:                    if (!m_leftJustify && m_leadingZeros) {
1484:                        int xThousands = 0;
1485:                        if (m_thousands) {
1486:                            int xlead = 0;
1487:                            if ((ca2[0] == '+') || (ca2[0] == '-')
1488:                                    || (ca2[0] == ' ')) {
1489:                                xlead = 1;
1490:                            }
1491:                            int xdp = xlead;
1492:                            for (; xdp < ca2.length; xdp++) {
1493:                                if (ca2[xdp] == '.') {
1494:                                    break;
1495:                                }
1496:                            }
1497:                            xThousands = (xdp - xlead) / 3;
1498:                        }
1499:                        if (m_fieldWidthSet) {
1500:                            nZeros = m_fieldWidth - ca2.length;
1501:                        }
1502:                        if ((!minusSign && (m_leadingSign || m_leadingSpace))
1503:                                || minusSign) {
1504:                            nZeros--;
1505:                        }
1506:                        nZeros -= xThousands;
1507:                        if (nZeros < 0) {
1508:                            nZeros = 0;
1509:                        }
1510:                    }
1511:                    j = 0;
1512:                    if ((!minusSign && (m_leadingSign || m_leadingSpace))
1513:                            || minusSign) {
1514:                        ca3 = new char[ca2.length + nZeros + 1];
1515:                        j++;
1516:                    } else {
1517:                        ca3 = new char[ca2.length + nZeros];
1518:                    }
1519:                    if (!minusSign) {
1520:                        if (m_leadingSign) {
1521:                            ca3[0] = '+';
1522:                        }
1523:                        if (m_leadingSpace) {
1524:                            ca3[0] = ' ';
1525:                        }
1526:                    } else {
1527:                        ca3[0] = '-';
1528:                    }
1529:                    for (k = 0; k < nZeros; j++, k++) {
1530:                        ca3[j] = '0';
1531:                    }
1532:                    for (i = 0; (i < ca2.length) && (j < ca3.length); i++, j++) {
1533:                        ca3[j] = ca2[i];
1534:                    }
1535:
1536:                    int lead = 0;
1537:                    if ((ca3[0] == '+') || (ca3[0] == '-') || (ca3[0] == ' ')) {
1538:                        lead = 1;
1539:                    }
1540:                    int dp = lead;
1541:                    for (; dp < ca3.length; dp++) {
1542:                        if (ca3[dp] == '.') {
1543:                            break;
1544:                        }
1545:                    }
1546:                    int nThousands = dp / 3;
1547:                    // Localize the decimal point.
1548:                    if (dp < ca3.length) {
1549:                        ca3[dp] = m_dfs.getDecimalSeparator();
1550:                    }
1551:                    char[] ca4 = ca3;
1552:                    if (m_thousands && (nThousands > 0)) {
1553:                        ca4 = new char[ca3.length + nThousands + lead];
1554:                        ca4[0] = ca3[0];
1555:                        for (i = lead, k = lead; i < dp; i++) {
1556:                            if ((i > 0) && ((dp - i) % 3 == 0)) {
1557:                                // ca4[k]=',';
1558:                                ca4[k] = m_dfs.getGroupingSeparator();
1559:                                ca4[k + 1] = ca3[i];
1560:                                k += 2;
1561:                            } else {
1562:                                ca4[k] = ca3[i];
1563:                                k++;
1564:                            }
1565:                        }
1566:                        for (; i < ca3.length; i++, k++) {
1567:                            ca4[k] = ca3[i];
1568:                        }
1569:                    }
1570:                    return ca4;
1571:                }
1572:
1573:                /**
1574:                 * An intermediate routine on the way to creating
1575:                 * an e format String.  The method decides whether
1576:                 * the input double value is an infinity,
1577:                 * not-a-number, or a finite double and formats
1578:                 * each type of input appropriately.
1579:                 * @param x the double value to be formatted.
1580:                 * @param eChar an 'e' or 'E' to use in the
1581:                 *     converted double value.
1582:                 * @return the converted double value.
1583:                 */
1584:                private String eFormatString(double x, char eChar) {
1585:
1586:                    char[] ca4, ca5;
1587:                    if (Double.isInfinite(x)) {
1588:                        if (x == Double.POSITIVE_INFINITY) {
1589:                            if (m_leadingSign) {
1590:                                ca4 = "+Inf".toCharArray();
1591:                            } else if (m_leadingSpace) {
1592:                                ca4 = " Inf".toCharArray();
1593:                            } else {
1594:                                ca4 = "Inf".toCharArray();
1595:                            }
1596:                        } else {
1597:                            ca4 = "-Inf".toCharArray();
1598:                        }
1599:                    } else if (Double.isNaN(x)) {
1600:                        if (m_leadingSign) {
1601:                            ca4 = "+NaN".toCharArray();
1602:                        } else if (m_leadingSpace) {
1603:                            ca4 = " NaN".toCharArray();
1604:                        } else {
1605:                            ca4 = "NaN".toCharArray();
1606:                        }
1607:                    } else {
1608:                        ca4 = eFormatDigits(x, eChar);
1609:                    }
1610:                    ca5 = applyFloatPadding(ca4, false);
1611:                    return new String(ca5);
1612:                }
1613:
1614:                /**
1615:                 * For f format, the flag character '-', means that
1616:                 * the output should be left justified within the
1617:                 * field.  The default is to pad with blanks on the
1618:                 * left.  '+' character means that the conversion
1619:                 * will always begin with a sign (+ or -).  The
1620:                 * blank flag character means that a non-negative
1621:                 * input will be preceded with a blank.  If both
1622:                 * a '+' and a ' ' are specified, the blank flag
1623:                 * is ignored.  The '0' flag character implies that
1624:                 * padding to the field width will be done with
1625:                 * zeros instead of blanks.
1626:                 *
1627:                 * The field width is treated as the minimum number
1628:                 * of characters to be printed.  The default is to
1629:                 * add no padding.  Padding is with blanks by
1630:                 * default.
1631:                 *
1632:                 * The precision, if set, is the number of digits
1633:                 * to appear after the radix character.  Padding is
1634:                 * with trailing 0s.
1635:                 * 
1636:                 * @param x the paramater
1637:                 * @return the result
1638:                 */
1639:                private char[] fFormatDigits(double x) {
1640:
1641:                    // int defaultDigits=6;
1642:                    String sx;
1643:                    int i, j, k;
1644:                    int n1In, n2In;
1645:                    int expon = 0;
1646:                    boolean minusSign = false;
1647:                    if (x > 0.0) {
1648:                        sx = Double.toString(x);
1649:                    } else if (x < 0.0) {
1650:                        sx = Double.toString(-x);
1651:                        minusSign = true;
1652:                    } else {
1653:                        sx = Double.toString(x);
1654:                        if (sx.charAt(0) == '-') {
1655:                            minusSign = true;
1656:                            sx = sx.substring(1);
1657:                        }
1658:                    }
1659:                    int ePos = sx.indexOf('E');
1660:                    int rPos = sx.indexOf('.');
1661:                    if (rPos != -1) {
1662:                        n1In = rPos;
1663:                    } else if (ePos != -1) {
1664:                        n1In = ePos;
1665:                    } else {
1666:                        n1In = sx.length();
1667:                    }
1668:                    if (rPos != -1) {
1669:                        if (ePos != -1) {
1670:                            n2In = ePos - rPos - 1;
1671:                        } else {
1672:                            n2In = sx.length() - rPos - 1;
1673:                        }
1674:                    } else {
1675:                        n2In = 0;
1676:                    }
1677:                    if (ePos != -1) {
1678:                        int ie = ePos + 1;
1679:                        expon = 0;
1680:                        if (sx.charAt(ie) == '-') {
1681:                            for (++ie; ie < sx.length(); ie++) {
1682:                                if (sx.charAt(ie) != '0') {
1683:                                    break;
1684:                                }
1685:                            }
1686:                            if (ie < sx.length()) {
1687:                                expon = -Integer.parseInt(sx.substring(ie));
1688:                            }
1689:                        } else {
1690:                            if (sx.charAt(ie) == '+') {
1691:                                ++ie;
1692:                            }
1693:                            for (; ie < sx.length(); ie++) {
1694:                                if (sx.charAt(ie) != '0') {
1695:                                    break;
1696:                                }
1697:                            }
1698:                            if (ie < sx.length()) {
1699:                                expon = Integer.parseInt(sx.substring(ie));
1700:                            }
1701:                        }
1702:                    }
1703:                    int p;
1704:                    if (m_precisionSet) {
1705:                        p = m_precision;
1706:                    } else {
1707:                        p = DEFAULT_DIGITS - 1;
1708:                    }
1709:                    char[] ca1 = sx.toCharArray();
1710:                    char[] ca2 = new char[n1In + n2In];
1711:                    char[] ca3, ca4, ca5;
1712:                    for (j = 0; j < n1In; j++) {
1713:                        ca2[j] = ca1[j];
1714:                    }
1715:                    i = j + 1;
1716:                    for (k = 0; k < n2In; j++, i++, k++) {
1717:                        ca2[j] = ca1[i];
1718:                    }
1719:                    if (n1In + expon <= 0) {
1720:                        ca3 = new char[-expon + n2In];
1721:                        for (j = 0, k = 0; k < (-n1In - expon); k++, j++) {
1722:                            ca3[j] = '0';
1723:                        }
1724:                        for (i = 0; i < (n1In + n2In); i++, j++) {
1725:                            ca3[j] = ca2[i];
1726:                        }
1727:                    } else {
1728:                        ca3 = ca2;
1729:                    }
1730:                    boolean carry = false;
1731:                    if (p < -expon + n2In) {
1732:                        if (expon < 0) {
1733:                            i = p;
1734:                        } else {
1735:                            i = p + n1In;
1736:                        }
1737:                        carry = checkForCarry(ca3, i);
1738:                        if (carry) {
1739:                            carry = startSymbolicCarry(ca3, i - 1, 0);
1740:                        }
1741:                    }
1742:                    if (n1In + expon <= 0) {
1743:                        ca4 = new char[2 + p];
1744:                        if (!carry) {
1745:                            ca4[0] = '0';
1746:                        } else {
1747:                            ca4[0] = '1';
1748:                        }
1749:                        if (m_alternateForm || !m_precisionSet
1750:                                || (m_precision != 0)) {
1751:                            ca4[1] = '.';
1752:                            for (i = 0, j = 2; i < Math.min(p, ca3.length); i++, j++) {
1753:                                ca4[j] = ca3[i];
1754:                            }
1755:                            for (; j < ca4.length; j++) {
1756:                                ca4[j] = '0';
1757:                            }
1758:                        }
1759:                    } else {
1760:                        if (!carry) {
1761:                            if (m_alternateForm || !m_precisionSet
1762:                                    || (m_precision != 0)) {
1763:                                ca4 = new char[n1In + expon + p + 1];
1764:                            } else {
1765:                                ca4 = new char[n1In + expon];
1766:                            }
1767:                            j = 0;
1768:                        } else {
1769:                            if (m_alternateForm || !m_precisionSet
1770:                                    || (m_precision != 0)) {
1771:                                ca4 = new char[n1In + expon + p + 2];
1772:                            } else {
1773:                                ca4 = new char[n1In + expon + 1];
1774:                            }
1775:                            ca4[0] = '1';
1776:                            j = 1;
1777:                        }
1778:                        for (i = 0; i < Math.min(n1In + expon, ca3.length); i++, j++) {
1779:                            ca4[j] = ca3[i];
1780:                        }
1781:                        for (; i < n1In + expon; i++, j++) {
1782:                            ca4[j] = '0';
1783:                        }
1784:                        if (m_alternateForm || !m_precisionSet
1785:                                || (m_precision != 0)) {
1786:                            ca4[j] = '.';
1787:                            j++;
1788:                            for (k = 0; (i < ca3.length) && (k < p); i++, j++, k++) {
1789:                                ca4[j] = ca3[i];
1790:                            }
1791:                            for (; j < ca4.length; j++) {
1792:                                ca4[j] = '0';
1793:                            }
1794:                        }
1795:                    }
1796:                    int nZeros = 0;
1797:                    if (!m_leftJustify && m_leadingZeros) {
1798:                        int xThousands = 0;
1799:                        if (m_thousands) {
1800:                            int xlead = 0;
1801:                            if ((ca4[0] == '+') || (ca4[0] == '-')
1802:                                    || (ca4[0] == ' ')) {
1803:                                xlead = 1;
1804:                            }
1805:                            int xdp = xlead;
1806:                            for (; xdp < ca4.length; xdp++) {
1807:                                if (ca4[xdp] == '.') {
1808:                                    break;
1809:                                }
1810:                            }
1811:                            xThousands = (xdp - xlead) / 3;
1812:                        }
1813:                        if (m_fieldWidthSet) {
1814:                            nZeros = m_fieldWidth - ca4.length;
1815:                        }
1816:                        if ((!minusSign && (m_leadingSign || m_leadingSpace))
1817:                                || minusSign) {
1818:                            nZeros--;
1819:                        }
1820:                        nZeros -= xThousands;
1821:                        if (nZeros < 0) {
1822:                            nZeros = 0;
1823:                        }
1824:                    }
1825:                    j = 0;
1826:                    if ((!minusSign && (m_leadingSign || m_leadingSpace))
1827:                            || minusSign) {
1828:                        ca5 = new char[ca4.length + nZeros + 1];
1829:                        j++;
1830:                    } else {
1831:                        ca5 = new char[ca4.length + nZeros];
1832:                    }
1833:                    if (!minusSign) {
1834:                        if (m_leadingSign) {
1835:                            ca5[0] = '+';
1836:                        }
1837:                        if (m_leadingSpace) {
1838:                            ca5[0] = ' ';
1839:                        }
1840:                    } else {
1841:                        ca5[0] = '-';
1842:                    }
1843:                    for (i = 0; i < nZeros; i++, j++) {
1844:                        ca5[j] = '0';
1845:                    }
1846:                    for (i = 0; i < ca4.length; i++, j++) {
1847:                        ca5[j] = ca4[i];
1848:                    }
1849:                    int lead = 0;
1850:                    if ((ca5[0] == '+') || (ca5[0] == '-') || (ca5[0] == ' ')) {
1851:                        lead = 1;
1852:                    }
1853:                    int dp = lead;
1854:                    for (; dp < ca5.length; dp++) {
1855:                        if (ca5[dp] == '.') {
1856:                            break;
1857:                        }
1858:                    }
1859:                    int nThousands = (dp - lead) / 3;
1860:                    // Localize the decimal point.
1861:                    if (dp < ca5.length) {
1862:                        ca5[dp] = m_dfs.getDecimalSeparator();
1863:                    }
1864:                    char[] ca6 = ca5;
1865:                    if (m_thousands && (nThousands > 0)) {
1866:                        ca6 = new char[ca5.length + nThousands + lead];
1867:                        ca6[0] = ca5[0];
1868:                        for (i = lead, k = lead; i < dp; i++) {
1869:                            if ((i > 0) && ((dp - i) % 3 == 0)) {
1870:                                // ca6[k]=',';
1871:                                ca6[k] = m_dfs.getGroupingSeparator();
1872:                                ca6[k + 1] = ca5[i];
1873:                                k += 2;
1874:                            } else {
1875:                                ca6[k] = ca5[i];
1876:                                k++;
1877:                            }
1878:                        }
1879:                        for (; i < ca5.length; i++, k++) {
1880:                            ca6[k] = ca5[i];
1881:                        }
1882:                    }
1883:                    return ca6;
1884:                }
1885:
1886:                /**
1887:                 * An intermediate routine on the way to creating
1888:                 * an f format String.  The method decides whether
1889:                 * the input double value is an infinity,
1890:                 * not-a-number, or a finite double and formats
1891:                 * each type of input appropriately.
1892:                 * @param x the double value to be formatted.
1893:                 * @return the converted double value.
1894:                 */
1895:                private String fFormatString(double x) {
1896:
1897:                    char[] ca6, ca7;
1898:                    if (Double.isInfinite(x)) {
1899:                        if (x == Double.POSITIVE_INFINITY) {
1900:                            if (m_leadingSign) {
1901:                                ca6 = "+Inf".toCharArray();
1902:                            } else if (m_leadingSpace) {
1903:                                ca6 = " Inf".toCharArray();
1904:                            } else {
1905:                                ca6 = "Inf".toCharArray();
1906:                            }
1907:                        } else {
1908:                            ca6 = "-Inf".toCharArray();
1909:                        }
1910:                    } else if (Double.isNaN(x)) {
1911:                        if (m_leadingSign) {
1912:                            ca6 = "+NaN".toCharArray();
1913:                        } else if (m_leadingSpace) {
1914:                            ca6 = " NaN".toCharArray();
1915:                        } else {
1916:                            ca6 = "NaN".toCharArray();
1917:                        }
1918:                    } else {
1919:                        ca6 = fFormatDigits(x);
1920:                    }
1921:                    ca7 = applyFloatPadding(ca6, false);
1922:                    return new String(ca7);
1923:                }
1924:
1925:                /**
1926:                 * Format method for the c conversion character and
1927:                 * char argument.
1928:                 *
1929:                 * The only flag character that affects c format is
1930:                 * the '-', meaning that the output should be left
1931:                 * justified within the field.  The default is to
1932:                 * pad with blanks on the left.
1933:                 *
1934:                 * The field width is treated as the minimum number
1935:                 * of characters to be printed.  Padding is with
1936:                 * blanks by default.  The default width is 1.
1937:                 *
1938:                 * The precision, if set, is ignored.
1939:                 * @param x the char to format.
1940:                 * @return the formatted String.
1941:                 */
1942:                private String printCFormat(char x) {
1943:
1944:                    int nPrint = 1;
1945:                    int width = m_fieldWidth;
1946:                    if (!m_fieldWidthSet) {
1947:                        width = nPrint;
1948:                    }
1949:                    char[] ca = new char[width];
1950:                    int i = 0;
1951:                    if (m_leftJustify) {
1952:                        ca[0] = x;
1953:                        for (i = 1; i <= width - nPrint; i++) {
1954:                            ca[i] = ' ';
1955:                        }
1956:                    } else {
1957:                        for (i = 0; i < width - nPrint; i++) {
1958:                            ca[i] = ' ';
1959:                        }
1960:                        ca[i] = x;
1961:                    }
1962:                    return new String(ca);
1963:                }
1964:
1965:                /**
1966:                 * Format method for the d conversion character and
1967:                 * int argument.
1968:                 *
1969:                 * For d format, the flag character '-', means that
1970:                 * the output should be left justified within the
1971:                 * field.  The default is to pad with blanks on the
1972:                 * left.  A '+' character means that the conversion
1973:                 * will always begin with a sign (+ or -).  The
1974:                 * blank flag character means that a non-negative
1975:                 * input will be preceded with a blank.  If both a
1976:                 * '+' and a ' ' are specified, the blank flag is
1977:                 * ignored.  The '0' flag character implies that
1978:                 * padding to the field width will be done with
1979:                 * zeros instead of blanks.
1980:                 *
1981:                 * The field width is treated as the minimum number
1982:                 * of characters to be printed.  The default is to
1983:                 * add no padding.  Padding is with blanks by
1984:                 * default.
1985:                 *
1986:                 * The precision, if set, is the minimum number of
1987:                 * digits to appear.  Padding is with leading 0s.
1988:                 * @param x the int to format.
1989:                 * @return the formatted String.
1990:                 */
1991:                private String printDFormat(int x) {
1992:
1993:                    return printDFormat(Integer.toString(x));
1994:                }
1995:
1996:                /**
1997:                 * Format method for the d conversion character and
1998:                 * long argument.
1999:                 *
2000:                 * For d format, the flag character '-', means that
2001:                 * the output should be left justified within the
2002:                 * field.  The default is to pad with blanks on the
2003:                 * left.  A '+' character means that the conversion
2004:                 * will always begin with a sign (+ or -).  The
2005:                 * blank flag character means that a non-negative
2006:                 * input will be preceded with a blank.  If both a
2007:                 * '+' and a ' ' are specified, the blank flag is
2008:                 * ignored.  The '0' flag character implies that
2009:                 * padding to the field width will be done with
2010:                 * zeros instead of blanks.
2011:                 *
2012:                 * The field width is treated as the minimum number
2013:                 * of characters to be printed.  The default is to
2014:                 * add no padding.  Padding is with blanks by
2015:                 * default.
2016:                 *
2017:                 * The precision, if set, is the minimum number of
2018:                 * digits to appear.  Padding is with leading 0s.
2019:                 * @param x the long to format.
2020:                 * @return the formatted String.
2021:                 */
2022:                private String printDFormat(long x) {
2023:
2024:                    return printDFormat(Long.toString(x));
2025:                }
2026:
2027:                /**
2028:                 * Format method for the d conversion specifer and
2029:                 * short argument.
2030:                 *
2031:                 * For d format, the flag character '-', means that
2032:                 * the output should be left justified within the
2033:                 * field.  The default is to pad with blanks on the
2034:                 * left.  A '+' character means that the conversion
2035:                 * will always begin with a sign (+ or -).  The
2036:                 * blank flag character means that a non-negative
2037:                 * input will be preceded with a blank.  If both a
2038:                 * '+' and a ' ' are specified, the blank flag is
2039:                 * ignored.  The '0' flag character implies that
2040:                 * padding to the field width will be done with
2041:                 * zeros instead of blanks.
2042:                 *
2043:                 * The field width is treated as the minimum number
2044:                 * of characters to be printed.  The default is to
2045:                 * add no padding.  Padding is with blanks by
2046:                 * default.
2047:                 *
2048:                 * The precision, if set, is the minimum number of
2049:                 * digits to appear.  Padding is with leading 0s.
2050:                 * @param x the short to format.
2051:                 * @return the formatted String.
2052:                 */
2053:                private String printDFormat(short x) {
2054:
2055:                    return printDFormat(Short.toString(x));
2056:                }
2057:
2058:                /**
2059:                 * Utility method for formatting using the d
2060:                 * conversion character.
2061:                 * @param sx the String to format, the result of
2062:                 *     converting a short, int, or long to a
2063:                 *     String.
2064:                 * @return the formatted String.
2065:                 */
2066:                private String printDFormat(String sx) {
2067:
2068:                    int nLeadingZeros = 0;
2069:                    int nBlanks = 0, n = 0;
2070:                    int i = 0, jFirst = 0;
2071:                    boolean neg = sx.charAt(0) == '-';
2072:                    if (sx.equals("0") && m_precisionSet && (m_precision == 0)) {
2073:                        sx = "";
2074:                    }
2075:                    if (!neg) {
2076:                        if (m_precisionSet && (sx.length() < m_precision)) {
2077:                            nLeadingZeros = m_precision - sx.length();
2078:                        }
2079:                    } else {
2080:                        if (m_precisionSet && ((sx.length() - 1) < m_precision)) {
2081:                            nLeadingZeros = m_precision - sx.length() + 1;
2082:                        }
2083:                    }
2084:                    if (nLeadingZeros < 0) {
2085:                        nLeadingZeros = 0;
2086:                    }
2087:                    if (m_fieldWidthSet) {
2088:                        nBlanks = m_fieldWidth - nLeadingZeros - sx.length();
2089:                        if (!neg && (m_leadingSign || m_leadingSpace)) {
2090:                            nBlanks--;
2091:                        }
2092:                    }
2093:                    if (nBlanks < 0) {
2094:                        nBlanks = 0;
2095:                    }
2096:                    if (m_leadingSign) {
2097:                        n++;
2098:                    } else if (m_leadingSpace) {
2099:                        n++;
2100:                    }
2101:                    n += nBlanks;
2102:                    n += nLeadingZeros;
2103:                    n += sx.length();
2104:                    char[] ca = new char[n];
2105:                    if (m_leftJustify) {
2106:                        if (neg) {
2107:                            ca[i++] = '-';
2108:                        } else if (m_leadingSign) {
2109:                            ca[i++] = '+';
2110:                        } else if (m_leadingSpace) {
2111:                            ca[i++] = ' ';
2112:                        }
2113:                        char[] csx = sx.toCharArray();
2114:                        jFirst = neg ? 1 : 0;
2115:                        for (int j = 0; j < nLeadingZeros; i++, j++) {
2116:                            ca[i] = '0';
2117:                        }
2118:                        for (int j = jFirst; j < csx.length; j++, i++) {
2119:                            ca[i] = csx[j];
2120:                        }
2121:                        for (int j = 0; j < nBlanks; i++, j++) {
2122:                            ca[i] = ' ';
2123:                        }
2124:                    } else {
2125:                        if (!m_leadingZeros) {
2126:                            for (i = 0; i < nBlanks; i++) {
2127:                                ca[i] = ' ';
2128:                            }
2129:                            if (neg) {
2130:                                ca[i++] = '-';
2131:                            } else if (m_leadingSign) {
2132:                                ca[i++] = '+';
2133:                            } else if (m_leadingSpace) {
2134:                                ca[i++] = ' ';
2135:                            }
2136:                        } else {
2137:                            if (neg) {
2138:                                ca[i++] = '-';
2139:                            } else if (m_leadingSign) {
2140:                                ca[i++] = '+';
2141:                            } else if (m_leadingSpace) {
2142:                                ca[i++] = ' ';
2143:                            }
2144:                            for (int j = 0; j < nBlanks; j++, i++) {
2145:                                ca[i] = '0';
2146:                            }
2147:                        }
2148:                        for (int j = 0; j < nLeadingZeros; j++, i++) {
2149:                            ca[i] = '0';
2150:                        }
2151:                        char[] csx = sx.toCharArray();
2152:                        jFirst = neg ? 1 : 0;
2153:                        for (int j = jFirst; j < csx.length; j++, i++) {
2154:                            ca[i] = csx[j];
2155:                        }
2156:                    }
2157:                    return new String(ca);
2158:                }
2159:
2160:                /**
2161:                 * Format method for the e or E conversion
2162:                 * character.
2163:                 * @param x the double to format.
2164:                 * @return the formatted String.
2165:                 */
2166:                private String printEFormat(double x) {
2167:
2168:                    if (m_conversionCharacter == 'e') {
2169:                        return eFormatString(x, 'e');
2170:                    } else {
2171:                        return eFormatString(x, 'E');
2172:                    }
2173:                }
2174:
2175:                /**
2176:                 * Format method for the f conversion character.
2177:                 * @param x the double to format.
2178:                 * @return the formatted String.
2179:                 */
2180:                private String printFFormat(double x) {
2181:
2182:                    return fFormatString(x);
2183:                }
2184:
2185:                /**
2186:                 * Format method for the g conversion character.
2187:                 *
2188:                 * For g format, the flag character '-', means that
2189:                 *  the output should be left justified within the
2190:                 * field.  The default is to pad with blanks on the
2191:                 * left.  '+' character means that the conversion
2192:                 * will always begin with a sign (+ or -).  The
2193:                 * blank flag character means that a non-negative
2194:                 * input will be preceded with a blank.  If both a
2195:                 * '+' and a ' ' are specified, the blank flag is
2196:                 * ignored.  The '0' flag character implies that
2197:                 * padding to the field width will be done with
2198:                 * zeros instead of blanks.
2199:                 *
2200:                 * The field width is treated as the minimum number
2201:                 * of characters to be printed.  The default is to
2202:                 * add no padding.  Padding is with blanks by
2203:                 * default.
2204:                 *
2205:                 * The precision, if set, is the minimum number of
2206:                 * digits to appear after the radix character.
2207:                 * Padding is with trailing 0s.
2208:                 * @param x the double to format.
2209:                 * @return the formatted String.
2210:                 */
2211:                private String printGFormat(double x) {
2212:
2213:                    String sx, sy, sz, ret;
2214:                    int savePrecision = m_precision;
2215:                    int i;
2216:                    char[] ca4, ca5;
2217:                    if (Double.isInfinite(x)) {
2218:                        if (x == Double.POSITIVE_INFINITY) {
2219:                            if (m_leadingSign) {
2220:                                ca4 = "+Inf".toCharArray();
2221:                            } else if (m_leadingSpace) {
2222:                                ca4 = " Inf".toCharArray();
2223:                            } else {
2224:                                ca4 = "Inf".toCharArray();
2225:                            }
2226:                        } else {
2227:                            ca4 = "-Inf".toCharArray();
2228:                        }
2229:                    } else if (Double.isNaN(x)) {
2230:                        if (m_leadingSign) {
2231:                            ca4 = "+NaN".toCharArray();
2232:                        } else if (m_leadingSpace) {
2233:                            ca4 = " NaN".toCharArray();
2234:                        } else {
2235:                            ca4 = "NaN".toCharArray();
2236:                        }
2237:                    } else {
2238:                        if (!m_precisionSet) {
2239:                            m_precision = DEFAULT_DIGITS;
2240:                        }
2241:                        if (m_precision == 0) {
2242:                            m_precision = 1;
2243:                        }
2244:                        int ePos = -1;
2245:                        if (m_conversionCharacter == 'g') {
2246:                            sx = eFormatString(x, 'e').trim();
2247:                            ePos = sx.indexOf('e');
2248:                        } else {
2249:                            sx = eFormatString(x, 'E').trim();
2250:                            ePos = sx.indexOf('E');
2251:                        }
2252:                        i = ePos + 1;
2253:                        int expon = 0;
2254:                        if (sx.charAt(i) == '-') {
2255:                            for (++i; i < sx.length(); i++) {
2256:                                if (sx.charAt(i) != '0') {
2257:                                    break;
2258:                                }
2259:                            }
2260:                            if (i < sx.length()) {
2261:                                expon = -Integer.parseInt(sx.substring(i));
2262:                            }
2263:                        } else {
2264:                            if (sx.charAt(i) == '+') {
2265:                                ++i;
2266:                            }
2267:                            for (; i < sx.length(); i++) {
2268:                                if (sx.charAt(i) != '0') {
2269:                                    break;
2270:                                }
2271:                            }
2272:                            if (i < sx.length()) {
2273:                                expon = Integer.parseInt(sx.substring(i));
2274:                            }
2275:                        }
2276:                        // Trim trailing zeros.
2277:                        // If the radix character is not followed by
2278:                        // a digit, trim it, too.
2279:                        if (!m_alternateForm) {
2280:                            if ((expon >= -4) && (expon < m_precision)) {
2281:                                sy = fFormatString(x).trim();
2282:                            } else {
2283:                                sy = sx.substring(0, ePos);
2284:                            }
2285:                            i = sy.length() - 1;
2286:                            for (; i >= 0; i--) {
2287:                                if (sy.charAt(i) != '0') {
2288:                                    break;
2289:                                }
2290:                            }
2291:                            if ((i >= 0) && (sy.charAt(i) == '.')) {
2292:                                i--;
2293:                            }
2294:                            if (i == -1) {
2295:                                sz = "0";
2296:                            } else if (!Character.isDigit(sy.charAt(i))) {
2297:                                sz = sy.substring(0, i + 1) + "0";
2298:                            } else {
2299:                                sz = sy.substring(0, i + 1);
2300:                            }
2301:                            if ((expon >= -4) && (expon < m_precision)) {
2302:                                ret = sz;
2303:                            } else {
2304:                                ret = sz + sx.substring(ePos);
2305:                            }
2306:                        } else {
2307:                            if ((expon >= -4) && (expon < m_precision)) {
2308:                                ret = fFormatString(x).trim();
2309:                            } else {
2310:                                ret = sx;
2311:                            }
2312:                        }
2313:                        // leading space was trimmed off during
2314:                        // construction
2315:                        if (m_leadingSpace) {
2316:                            if (x >= 0) {
2317:                                ret = " " + ret;
2318:                            }
2319:                        }
2320:                        ca4 = ret.toCharArray();
2321:                    }
2322:                    // Pad with blanks or zeros.
2323:                    ca5 = applyFloatPadding(ca4, false);
2324:                    m_precision = savePrecision;
2325:                    return new String(ca5);
2326:                }
2327:
2328:                /**
2329:                 * Format method for the o conversion character and
2330:                 * int argument.
2331:                 *
2332:                 * For o format, the flag character '-', means that
2333:                 * the output should be left justified within the
2334:                 * field.  The default is to pad with blanks on the
2335:                 * left.  The '#' flag character means that the
2336:                 * output begins with a leading 0 and the precision
2337:                 * is increased by 1.
2338:                 *
2339:                 * The field width is treated as the minimum number
2340:                 * of characters to be printed.  The default is to
2341:                 * add no padding.  Padding is with blanks by
2342:                 * default.
2343:                 *
2344:                 * The precision, if set, is the minimum number of
2345:                 * digits to appear.  Padding is with leading 0s.
2346:                 * @param x the int to format.
2347:                 * @return the formatted String.
2348:                 */
2349:                private String printOFormat(int x) {
2350:
2351:                    String sx = null;
2352:                    if (x == Integer.MIN_VALUE) {
2353:                        sx = "20000000000";
2354:                    } else if (x < 0) {
2355:                        String t = Integer.toString((~(-x - 1))
2356:                                ^ Integer.MIN_VALUE, 8);
2357:                        switch (t.length()) {
2358:                        case 1:
2359:                            sx = "2000000000" + t;
2360:                            break;
2361:                        case 2:
2362:                            sx = "200000000" + t;
2363:                            break;
2364:                        case 3:
2365:                            sx = "20000000" + t;
2366:                            break;
2367:                        case 4:
2368:                            sx = "2000000" + t;
2369:                            break;
2370:                        case 5:
2371:                            sx = "200000" + t;
2372:                            break;
2373:                        case 6:
2374:                            sx = "20000" + t;
2375:                            break;
2376:                        case 7:
2377:                            sx = "2000" + t;
2378:                            break;
2379:                        case 8:
2380:                            sx = "200" + t;
2381:                            break;
2382:                        case 9:
2383:                            sx = "20" + t;
2384:                            break;
2385:                        case 10:
2386:                            sx = "2" + t;
2387:                            break;
2388:                        case 11:
2389:                            sx = "3" + t.substring(1);
2390:                            break;
2391:                        default:
2392:                            // noop
2393:                        }
2394:                    } else {
2395:                        sx = Integer.toString(x, 8);
2396:                    }
2397:                    return printOFormat(sx);
2398:                }
2399:
2400:                /**
2401:                 * Format method for the o conversion character and
2402:                 * long argument.
2403:                 *
2404:                 * For o format, the flag character '-', means that
2405:                 * the output should be left justified within the
2406:                 * field.  The default is to pad with blanks on the 
2407:                 * left.  The '#' flag character means that the
2408:                 * output begins with a leading 0 and the precision
2409:                 * is increased by 1.
2410:                 *
2411:                 * The field width is treated as the minimum number
2412:                 * of characters to be printed.  The default is to
2413:                 * add no padding.  Padding is with blanks by
2414:                 * default.
2415:                 *
2416:                 * The precision, if set, is the minimum number of
2417:                 * digits to appear.  Padding is with leading 0s.
2418:                 * @param x the long to format.
2419:                 * @return the formatted String.
2420:                 */
2421:                private String printOFormat(long x) {
2422:
2423:                    String sx = null;
2424:                    if (x == Long.MIN_VALUE) {
2425:                        sx = "1000000000000000000000";
2426:                    } else if (x < 0) {
2427:                        String t = Long.toString((~(-x - 1)) ^ Long.MIN_VALUE,
2428:                                8);
2429:                        switch (t.length()) {
2430:                        case 1:
2431:                            sx = "100000000000000000000" + t;
2432:                            break;
2433:                        case 2:
2434:                            sx = "10000000000000000000" + t;
2435:                            break;
2436:                        case 3:
2437:                            sx = "1000000000000000000" + t;
2438:                            break;
2439:                        case 4:
2440:                            sx = "100000000000000000" + t;
2441:                            break;
2442:                        case 5:
2443:                            sx = "10000000000000000" + t;
2444:                            break;
2445:                        case 6:
2446:                            sx = "1000000000000000" + t;
2447:                            break;
2448:                        case 7:
2449:                            sx = "100000000000000" + t;
2450:                            break;
2451:                        case 8:
2452:                            sx = "10000000000000" + t;
2453:                            break;
2454:                        case 9:
2455:                            sx = "1000000000000" + t;
2456:                            break;
2457:                        case 10:
2458:                            sx = "100000000000" + t;
2459:                            break;
2460:                        case 11:
2461:                            sx = "10000000000" + t;
2462:                            break;
2463:                        case 12:
2464:                            sx = "1000000000" + t;
2465:                            break;
2466:                        case 13:
2467:                            sx = "100000000" + t;
2468:                            break;
2469:                        case 14:
2470:                            sx = "10000000" + t;
2471:                            break;
2472:                        case 15:
2473:                            sx = "1000000" + t;
2474:                            break;
2475:                        case 16:
2476:                            sx = "100000" + t;
2477:                            break;
2478:                        case 17:
2479:                            sx = "10000" + t;
2480:                            break;
2481:                        case 18:
2482:                            sx = "1000" + t;
2483:                            break;
2484:                        case 19:
2485:                            sx = "100" + t;
2486:                            break;
2487:                        case 20:
2488:                            sx = "10" + t;
2489:                            break;
2490:                        case 21:
2491:                            sx = "1" + t;
2492:                            break;
2493:                        default:
2494:                            // noop
2495:                        }
2496:                    } else {
2497:                        sx = Long.toString(x, 8);
2498:                    }
2499:                    return printOFormat(sx);
2500:                }
2501:
2502:                /**
2503:                 * Format method for the o conversion character and
2504:                 * short argument.
2505:                 *
2506:                 * For o format, the flag character '-', means that
2507:                 * the output should be left justified within the
2508:                 * field.  The default is to pad with blanks on the 
2509:                 * left.  The '#' flag character means that the
2510:                 * output begins with a leading 0 and the precision
2511:                 * is increased by 1.
2512:                 *
2513:                 * The field width is treated as the minimum number
2514:                 * of characters to be printed.  The default is to
2515:                 * add no padding.  Padding is with blanks by
2516:                 * default.
2517:                 *
2518:                 * The precision, if set, is the minimum number of
2519:                 * digits to appear.  Padding is with leading 0s.
2520:                 * @param x the short to format.
2521:                 * @return the formatted String.
2522:                 */
2523:                private String printOFormat(short x) {
2524:
2525:                    String sx = null;
2526:                    if (x == Short.MIN_VALUE) {
2527:                        sx = "100000";
2528:                    } else if (x < 0) {
2529:                        String t = Integer.toString((~(-x - 1))
2530:                                ^ Short.MIN_VALUE, 8);
2531:                        switch (t.length()) {
2532:                        case 1:
2533:                            sx = "10000" + t;
2534:                            break;
2535:                        case 2:
2536:                            sx = "1000" + t;
2537:                            break;
2538:                        case 3:
2539:                            sx = "100" + t;
2540:                            break;
2541:                        case 4:
2542:                            sx = "10" + t;
2543:                            break;
2544:                        case 5:
2545:                            sx = "1" + t;
2546:                            break;
2547:                        default:
2548:                            // noop
2549:                        }
2550:                    } else {
2551:                        sx = Integer.toString(x, 8);
2552:                    }
2553:                    return printOFormat(sx);
2554:                }
2555:
2556:                /**
2557:                 * Utility method for formatting using the o
2558:                 * conversion character.
2559:                 * @param sx the String to format, the result of
2560:                 *     converting a short, int, or long to a
2561:                 *     String.
2562:                 * @return the formatted String.
2563:                 */
2564:                private String printOFormat(String sx) {
2565:
2566:                    int nLeadingZeros = 0;
2567:                    int nBlanks = 0;
2568:                    if (sx.equals("0") && m_precisionSet && (m_precision == 0)) {
2569:                        sx = "";
2570:                    }
2571:                    if (m_precisionSet) {
2572:                        nLeadingZeros = m_precision - sx.length();
2573:                    }
2574:                    if (m_alternateForm) {
2575:                        nLeadingZeros++;
2576:                    }
2577:                    if (nLeadingZeros < 0) {
2578:                        nLeadingZeros = 0;
2579:                    }
2580:                    if (m_fieldWidthSet) {
2581:                        nBlanks = m_fieldWidth - nLeadingZeros - sx.length();
2582:                    }
2583:                    if (nBlanks < 0) {
2584:                        nBlanks = 0;
2585:                    }
2586:                    int n = nLeadingZeros + sx.length() + nBlanks;
2587:                    char[] ca = new char[n];
2588:                    int i;
2589:                    if (m_leftJustify) {
2590:                        for (i = 0; i < nLeadingZeros; i++) {
2591:                            ca[i] = '0';
2592:                        }
2593:                        char[] csx = sx.toCharArray();
2594:                        for (int j = 0; j < csx.length; j++, i++) {
2595:                            ca[i] = csx[j];
2596:                        }
2597:                        for (int j = 0; j < nBlanks; j++, i++) {
2598:                            ca[i] = ' ';
2599:                        }
2600:                    } else {
2601:                        if (m_leadingZeros) {
2602:                            for (i = 0; i < nBlanks; i++) {
2603:                                ca[i] = '0';
2604:                            }
2605:                        } else {
2606:                            for (i = 0; i < nBlanks; i++) {
2607:                                ca[i] = ' ';
2608:                            }
2609:                        }
2610:                        for (int j = 0; j < nLeadingZeros; j++, i++) {
2611:                            ca[i] = '0';
2612:                        }
2613:                        char[] csx = sx.toCharArray();
2614:                        for (int j = 0; j < csx.length; j++, i++) {
2615:                            ca[i] = csx[j];
2616:                        }
2617:                    }
2618:                    return new String(ca);
2619:                }
2620:
2621:                /**
2622:                 * Format method for the s conversion character and
2623:                 * String argument.
2624:                 *
2625:                 * The only flag character that affects s format is
2626:                 * the '-', meaning that the output should be left
2627:                 * justified within the field.  The default is to
2628:                 * pad with blanks on the left.
2629:                 *
2630:                 * The field width is treated as the minimum number
2631:                 * of characters to be printed.  The default is the
2632:                 * smaller of the number of characters in the the
2633:                 * input and the precision.  Padding is with blanks
2634:                 * by default.
2635:                 *
2636:                 * The precision, if set, specifies the maximum
2637:                 * number of characters to be printed from the
2638:                 * string.  A null digit string is treated
2639:                 * as a 0.  The default is not to set a maximum
2640:                 * number of characters to be printed.
2641:                 * @param x the String to format.
2642:                 * @return the formatted String.
2643:                 */
2644:                private String printSFormat(String x) {
2645:
2646:                    int nPrint = x.length();
2647:                    int width = m_fieldWidth;
2648:                    if (m_precisionSet && (nPrint > m_precision)) {
2649:                        nPrint = m_precision;
2650:                    }
2651:                    if (!m_fieldWidthSet) {
2652:                        width = nPrint;
2653:                    }
2654:                    int n = 0;
2655:                    if (width > nPrint) {
2656:                        n += width - nPrint;
2657:                    }
2658:                    if (nPrint >= x.length()) {
2659:                        n += x.length();
2660:                    } else {
2661:                        n += nPrint;
2662:                    }
2663:                    char[] ca = new char[n];
2664:                    int i = 0;
2665:                    if (m_leftJustify) {
2666:                        if (nPrint >= x.length()) {
2667:                            char[] csx = x.toCharArray();
2668:                            for (i = 0; i < x.length(); i++) {
2669:                                ca[i] = csx[i];
2670:                            }
2671:                        } else {
2672:                            char[] csx = x.substring(0, nPrint).toCharArray();
2673:                            for (i = 0; i < nPrint; i++) {
2674:                                ca[i] = csx[i];
2675:                            }
2676:                        }
2677:                        for (int j = 0; j < width - nPrint; j++, i++) {
2678:                            ca[i] = ' ';
2679:                        }
2680:                    } else {
2681:                        for (i = 0; i < width - nPrint; i++) {
2682:                            ca[i] = ' ';
2683:                        }
2684:                        if (nPrint >= x.length()) {
2685:                            char[] csx = x.toCharArray();
2686:                            for (int j = 0; j < x.length(); i++, j++) {
2687:                                ca[i] = csx[j];
2688:                            }
2689:                        } else {
2690:                            char[] csx = x.substring(0, nPrint).toCharArray();
2691:                            for (int j = 0; j < nPrint; i++, j++) {
2692:                                ca[i] = csx[j];
2693:                            }
2694:                        }
2695:                    }
2696:                    return new String(ca);
2697:                }
2698:
2699:                /**
2700:                 * Format method for the x conversion character and
2701:                 * int argument.
2702:                 *
2703:                 * For x format, the flag character '-', means that
2704:                 * the output should be left justified within the
2705:                 * field.  The default is to pad with blanks on the
2706:                 * left.  The '#' flag character means to lead with
2707:                 * '0x'.
2708:                 *
2709:                 * The field width is treated as the minimum number
2710:                 * of characters to be printed.  The default is to
2711:                 * add no padding.  Padding is with blanks by
2712:                 * default.
2713:                 *
2714:                 * The precision, if set, is the minimum number of
2715:                 * digits to appear.  Padding is with leading 0s.
2716:                 * @param x the int to format.
2717:                 * @return the formatted String.
2718:                 */
2719:                private String printXFormat(int x) {
2720:
2721:                    String sx = null;
2722:                    if (x == Integer.MIN_VALUE) {
2723:                        sx = "80000000";
2724:                    } else if (x < 0) {
2725:                        String t = Integer.toString((~(-x - 1))
2726:                                ^ Integer.MIN_VALUE, 16);
2727:                        switch (t.length()) {
2728:                        case 1:
2729:                            sx = "8000000" + t;
2730:                            break;
2731:                        case 2:
2732:                            sx = "800000" + t;
2733:                            break;
2734:                        case 3:
2735:                            sx = "80000" + t;
2736:                            break;
2737:                        case 4:
2738:                            sx = "8000" + t;
2739:                            break;
2740:                        case 5:
2741:                            sx = "800" + t;
2742:                            break;
2743:                        case 6:
2744:                            sx = "80" + t;
2745:                            break;
2746:                        case 7:
2747:                            sx = "8" + t;
2748:                            break;
2749:                        case 8:
2750:                            switch (t.charAt(0)) {
2751:                            case '1':
2752:                                sx = "9" + t.substring(1, 8);
2753:                                break;
2754:                            case '2':
2755:                                sx = "a" + t.substring(1, 8);
2756:                                break;
2757:                            case '3':
2758:                                sx = "b" + t.substring(1, 8);
2759:                                break;
2760:                            case '4':
2761:                                sx = "c" + t.substring(1, 8);
2762:                                break;
2763:                            case '5':
2764:                                sx = "d" + t.substring(1, 8);
2765:                                break;
2766:                            case '6':
2767:                                sx = "e" + t.substring(1, 8);
2768:                                break;
2769:                            case '7':
2770:                                sx = "f" + t.substring(1, 8);
2771:                                break;
2772:                            default:
2773:                                // noop
2774:                            }
2775:                            break;
2776:                        default:
2777:                            // noop
2778:                        }
2779:                    } else {
2780:                        sx = Integer.toString(x, 16);
2781:                    }
2782:                    return printXFormat(sx);
2783:                }
2784:
2785:                /**
2786:                 * Format method for the x conversion character and
2787:                 * long argument.
2788:                 *
2789:                 * For x format, the flag character '-', means that
2790:                 * the output should be left justified within the
2791:                 * field.  The default is to pad with blanks on the
2792:                 * left.  The '#' flag character means to lead with
2793:                 * '0x'.
2794:                 *
2795:                 * The field width is treated as the minimum number
2796:                 * of characters to be printed.  The default is to
2797:                 * add no padding.  Padding is with blanks by
2798:                 * default.
2799:                 *
2800:                 * The precision, if set, is the minimum number of
2801:                 * digits to appear.  Padding is with leading 0s.
2802:                 * @param x the long to format.
2803:                 * @return the formatted String.
2804:                 */
2805:                private String printXFormat(long x) {
2806:
2807:                    String sx = null;
2808:                    if (x == Long.MIN_VALUE) {
2809:                        sx = "8000000000000000";
2810:                    } else if (x < 0) {
2811:                        String t = Long.toString((~(-x - 1)) ^ Long.MIN_VALUE,
2812:                                16);
2813:                        switch (t.length()) {
2814:                        case 1:
2815:                            sx = "800000000000000" + t;
2816:                            break;
2817:                        case 2:
2818:                            sx = "80000000000000" + t;
2819:                            break;
2820:                        case 3:
2821:                            sx = "8000000000000" + t;
2822:                            break;
2823:                        case 4:
2824:                            sx = "800000000000" + t;
2825:                            break;
2826:                        case 5:
2827:                            sx = "80000000000" + t;
2828:                            break;
2829:                        case 6:
2830:                            sx = "8000000000" + t;
2831:                            break;
2832:                        case 7:
2833:                            sx = "800000000" + t;
2834:                            break;
2835:                        case 8:
2836:                            sx = "80000000" + t;
2837:                            break;
2838:                        case 9:
2839:                            sx = "8000000" + t;
2840:                            break;
2841:                        case 10:
2842:                            sx = "800000" + t;
2843:                            break;
2844:                        case 11:
2845:                            sx = "80000" + t;
2846:                            break;
2847:                        case 12:
2848:                            sx = "8000" + t;
2849:                            break;
2850:                        case 13:
2851:                            sx = "800" + t;
2852:                            break;
2853:                        case 14:
2854:                            sx = "80" + t;
2855:                            break;
2856:                        case 15:
2857:                            sx = "8" + t;
2858:                            break;
2859:                        case 16:
2860:                            switch (t.charAt(0)) {
2861:                            case '1':
2862:                                sx = "9" + t.substring(1, 16);
2863:                                break;
2864:                            case '2':
2865:                                sx = "a" + t.substring(1, 16);
2866:                                break;
2867:                            case '3':
2868:                                sx = "b" + t.substring(1, 16);
2869:                                break;
2870:                            case '4':
2871:                                sx = "c" + t.substring(1, 16);
2872:                                break;
2873:                            case '5':
2874:                                sx = "d" + t.substring(1, 16);
2875:                                break;
2876:                            case '6':
2877:                                sx = "e" + t.substring(1, 16);
2878:                                break;
2879:                            case '7':
2880:                                sx = "f" + t.substring(1, 16);
2881:                                break;
2882:                            default:
2883:                                // noop
2884:                            }
2885:                            break;
2886:                        default:
2887:                            // noop
2888:                        }
2889:                    } else {
2890:                        sx = Long.toString(x, 16);
2891:                    }
2892:                    return printXFormat(sx);
2893:                }
2894:
2895:                /**
2896:                 * Format method for the x conversion character and
2897:                 * short argument.
2898:                 *
2899:                 * For x format, the flag character '-', means that
2900:                 * the output should be left justified within the
2901:                 * field.  The default is to pad with blanks on the
2902:                 * left.  The '#' flag character means to lead with
2903:                 * '0x'.
2904:                 *
2905:                 * The field width is treated as the minimum number
2906:                 * of characters to be printed.  The default is to
2907:                 * add no padding.  Padding is with blanks by
2908:                 * default.
2909:                 *
2910:                 * The precision, if set, is the minimum number of
2911:                 * digits to appear.  Padding is with leading 0s.
2912:                 * @param x the short to format.
2913:                 * @return the formatted String.
2914:                 */
2915:                private String printXFormat(short x) {
2916:
2917:                    String sx = null;
2918:                    if (x == Short.MIN_VALUE) {
2919:                        sx = "8000";
2920:                    } else if (x < 0) {
2921:                        String t;
2922:                        if (x == Short.MIN_VALUE) {
2923:                            t = "0";
2924:                        } else {
2925:                            t = Integer.toString((~(-x - 1)) ^ Short.MIN_VALUE,
2926:                                    16);
2927:                            if ((t.charAt(0) == 'F') || (t.charAt(0) == 'f')) {
2928:                                t = t.substring(16, 32);
2929:                            }
2930:                        }
2931:                        switch (t.length()) {
2932:                        case 1:
2933:                            sx = "800" + t;
2934:                            break;
2935:                        case 2:
2936:                            sx = "80" + t;
2937:                            break;
2938:                        case 3:
2939:                            sx = "8" + t;
2940:                            break;
2941:                        case 4:
2942:                            switch (t.charAt(0)) {
2943:                            case '1':
2944:                                sx = "9" + t.substring(1, 4);
2945:                                break;
2946:                            case '2':
2947:                                sx = "a" + t.substring(1, 4);
2948:                                break;
2949:                            case '3':
2950:                                sx = "b" + t.substring(1, 4);
2951:                                break;
2952:                            case '4':
2953:                                sx = "c" + t.substring(1, 4);
2954:                                break;
2955:                            case '5':
2956:                                sx = "d" + t.substring(1, 4);
2957:                                break;
2958:                            case '6':
2959:                                sx = "e" + t.substring(1, 4);
2960:                                break;
2961:                            case '7':
2962:                                sx = "f" + t.substring(1, 4);
2963:                                break;
2964:                            default:
2965:                                // noop
2966:                            }
2967:                            break;
2968:                        default:
2969:                            // noop
2970:                        }
2971:                    } else {
2972:                        sx = Integer.toString(x, 16);
2973:                    }
2974:                    return printXFormat(sx);
2975:                }
2976:
2977:                /**
2978:                 * Utility method for formatting using the x
2979:                 * conversion character.
2980:                 * @param sx the String to format, the result of
2981:                 *     converting a short, int, or long to a
2982:                 *     String.
2983:                 * @return the formatted String.
2984:                 */
2985:                private String printXFormat(String sx) {
2986:
2987:                    int nLeadingZeros = 0;
2988:                    int nBlanks = 0;
2989:                    if (sx.equals("0") && m_precisionSet && (m_precision == 0)) {
2990:                        sx = "";
2991:                    }
2992:                    if (m_precisionSet) {
2993:                        nLeadingZeros = m_precision - sx.length();
2994:                    }
2995:                    if (nLeadingZeros < 0) {
2996:                        nLeadingZeros = 0;
2997:                    }
2998:                    if (m_fieldWidthSet) {
2999:                        nBlanks = m_fieldWidth - nLeadingZeros - sx.length();
3000:                        if (m_alternateForm) {
3001:                            nBlanks = nBlanks - 2;
3002:                        }
3003:                    }
3004:                    if (nBlanks < 0) {
3005:                        nBlanks = 0;
3006:                    }
3007:                    int n = 0;
3008:                    if (m_alternateForm) {
3009:                        n += 2;
3010:                    }
3011:                    n += nLeadingZeros;
3012:                    n += sx.length();
3013:                    n += nBlanks;
3014:                    char[] ca = new char[n];
3015:                    int i = 0;
3016:                    if (m_leftJustify) {
3017:                        if (m_alternateForm) {
3018:                            ca[i++] = '0';
3019:                            ca[i++] = 'x';
3020:                        }
3021:                        for (int j = 0; j < nLeadingZeros; j++, i++) {
3022:                            ca[i] = '0';
3023:                        }
3024:                        char[] csx = sx.toCharArray();
3025:                        for (int j = 0; j < csx.length; j++, i++) {
3026:                            ca[i] = csx[j];
3027:                        }
3028:                        for (int j = 0; j < nBlanks; j++, i++) {
3029:                            ca[i] = ' ';
3030:                        }
3031:                    } else {
3032:                        if (!m_leadingZeros) {
3033:                            for (int j = 0; j < nBlanks; j++, i++) {
3034:                                ca[i] = ' ';
3035:                            }
3036:                        }
3037:                        if (m_alternateForm) {
3038:                            ca[i++] = '0';
3039:                            ca[i++] = 'x';
3040:                        }
3041:                        if (m_leadingZeros) {
3042:                            for (int j = 0; j < nBlanks; j++, i++) {
3043:                                ca[i] = '0';
3044:                            }
3045:                        }
3046:                        for (int j = 0; j < nLeadingZeros; j++, i++) {
3047:                            ca[i] = '0';
3048:                        }
3049:                        char[] csx = sx.toCharArray();
3050:                        for (int j = 0; j < csx.length; j++, i++) {
3051:                            ca[i] = csx[j];
3052:                        }
3053:                    }
3054:                    String caReturn = new String(ca);
3055:                    if (m_conversionCharacter == 'X') {
3056:                        caReturn = caReturn.toUpperCase();
3057:                    }
3058:                    return caReturn;
3059:                }
3060:
3061:                /**
3062:                 * Store the digits <code>n</code> in %n$ forms.
3063:                 */
3064:                private void setArgPosition() {
3065:
3066:                    int xPos;
3067:                    for (xPos = m_pos; xPos < m_fmt.length(); xPos++) {
3068:                        if (!Character.isDigit(m_fmt.charAt(xPos))) {
3069:                            break;
3070:                        }
3071:                    }
3072:                    if ((xPos > m_pos) && (xPos < m_fmt.length())) {
3073:                        if (m_fmt.charAt(xPos) == '$') {
3074:                            m_positionalSpecification = true;
3075:                            m_argumentPosition = Integer.parseInt(m_fmt
3076:                                    .substring(m_pos, xPos));
3077:                            m_pos = xPos + 1;
3078:                        }
3079:                    }
3080:                }
3081:
3082:                /**
3083:                 * Check for a conversion character.  If it is
3084:                 * there, store it.
3085:                 * @return <code>true</code> if the conversion
3086:                 *     character is there, and
3087:                 *     <code>false</code> otherwise.
3088:                 */
3089:                private boolean setConversionCharacter() {
3090:
3091:                    /* idfgGoxXeEcs */
3092:                    boolean ret = false;
3093:                    m_conversionCharacter = '\0';
3094:                    if (m_pos < m_fmt.length()) {
3095:                        char c = m_fmt.charAt(m_pos);
3096:                        if ((c == 'i') || (c == 'd') || (c == 'f')
3097:                                || (c == 'g') || (c == 'G') || (c == 'o')
3098:                                || (c == 'x') || (c == 'X') || (c == 'e')
3099:                                || (c == 'E') || (c == 'c') || (c == 's')
3100:                                || (c == '%')) {
3101:                            m_conversionCharacter = c;
3102:                            m_pos++;
3103:                            ret = true;
3104:                        }
3105:                    }
3106:                    return ret;
3107:                }
3108:
3109:                /**
3110:                 * Set the field width.
3111:                 */
3112:                private void setFieldWidth() {
3113:
3114:                    int firstPos = m_pos;
3115:                    m_fieldWidth = 0;
3116:                    m_fieldWidthSet = false;
3117:                    if ((m_pos < m_fmt.length())
3118:                            && (m_fmt.charAt(m_pos) == '*')) {
3119:                        m_pos++;
3120:                        if (!setFieldWidthArgPosition()) {
3121:                            m_variableFieldWidth = true;
3122:                            m_fieldWidthSet = true;
3123:                        }
3124:                    } else {
3125:                        while (m_pos < m_fmt.length()) {
3126:                            char c = m_fmt.charAt(m_pos);
3127:                            if (Character.isDigit(c)) {
3128:                                m_pos++;
3129:                            } else {
3130:                                break;
3131:                            }
3132:                        }
3133:                        if ((firstPos < m_pos) && (firstPos < m_fmt.length())) {
3134:                            String sz = m_fmt.substring(firstPos, m_pos);
3135:                            m_fieldWidth = Integer.parseInt(sz);
3136:                            m_fieldWidthSet = true;
3137:                        }
3138:                    }
3139:                }
3140:
3141:                /**
3142:                 * Store the digits <code>n</code> in *n$ forms.
3143:                 * 
3144:                 * @return the result
3145:                 */
3146:                private boolean setFieldWidthArgPosition() {
3147:
3148:                    boolean ret = false;
3149:                    int xPos;
3150:                    for (xPos = m_pos; xPos < m_fmt.length(); xPos++) {
3151:                        if (!Character.isDigit(m_fmt.charAt(xPos))) {
3152:                            break;
3153:                        }
3154:                    }
3155:                    if ((xPos > m_pos) && (xPos < m_fmt.length())) {
3156:                        if (m_fmt.charAt(xPos) == '$') {
3157:                            m_positionalFieldWidth = true;
3158:                            m_argumentPositionForFieldWidth = Integer
3159:                                    .parseInt(m_fmt.substring(m_pos, xPos));
3160:                            m_pos = xPos + 1;
3161:                            ret = true;
3162:                        }
3163:                    }
3164:                    return ret;
3165:                }
3166:
3167:                /**
3168:                 * Set flag characters, one of '-+#0 or a space.
3169:                 */
3170:                private void setFlagCharacters() {
3171:
3172:                    /* '-+ #0 */
3173:                    m_thousands = false;
3174:                    m_leftJustify = false;
3175:                    m_leadingSign = false;
3176:                    m_leadingSpace = false;
3177:                    m_alternateForm = false;
3178:                    m_leadingZeros = false;
3179:                    for (; m_pos < m_fmt.length(); m_pos++) {
3180:                        char c = m_fmt.charAt(m_pos);
3181:                        if (c == '\'') {
3182:                            m_thousands = true;
3183:                        } else if (c == '-') {
3184:                            m_leftJustify = true;
3185:                            m_leadingZeros = false;
3186:                        } else if (c == '+') {
3187:                            m_leadingSign = true;
3188:                            m_leadingSpace = false;
3189:                        } else if (c == ' ') {
3190:                            if (!m_leadingSign) {
3191:                                m_leadingSpace = true;
3192:                            }
3193:                        } else if (c == '#') {
3194:                            m_alternateForm = true;
3195:                        } else if (c == '0') {
3196:                            if (!m_leftJustify) {
3197:                                m_leadingZeros = true;
3198:                            }
3199:                        } else {
3200:                            break;
3201:                        }
3202:                    }
3203:                }
3204:
3205:                /**
3206:                 * Check for an h, l, or L in a format.  An L is
3207:                 * used to control the minimum number of digits
3208:                 * in an exponent when using floating point
3209:                 * formats.  An l or h is used to control
3210:                 * conversion of the input to a long or short,
3211:                 * respectively, before formatting.  If any of
3212:                 * these is present, store them.
3213:                 */
3214:                private void setOptionalHL() {
3215:
3216:                    m_optionalh = false;
3217:                    m_optionall = false;
3218:                    m_optionalL = false;
3219:                    if (m_pos < m_fmt.length()) {
3220:                        char c = m_fmt.charAt(m_pos);
3221:                        if (c == 'h') {
3222:                            m_optionalh = true;
3223:                            m_pos++;
3224:                        } else if (c == 'l') {
3225:                            m_optionall = true;
3226:                            m_pos++;
3227:                        } else if (c == 'L') {
3228:                            m_optionalL = true;
3229:                            m_pos++;
3230:                        }
3231:                    }
3232:                }
3233:
3234:                /**
3235:                 * Set the precision.
3236:                 */
3237:                private void setPrecision() {
3238:
3239:                    int firstPos = m_pos;
3240:                    m_precisionSet = false;
3241:                    if ((m_pos < m_fmt.length())
3242:                            && (m_fmt.charAt(m_pos) == '.')) {
3243:                        m_pos++;
3244:                        if ((m_pos < m_fmt.length())
3245:                                && (m_fmt.charAt(m_pos) == '*')) {
3246:                            m_pos++;
3247:                            if (!setPrecisionArgPosition()) {
3248:                                m_variablePrecision = true;
3249:                                m_precisionSet = true;
3250:                            }
3251:                            return;
3252:                        } else {
3253:                            while (m_pos < m_fmt.length()) {
3254:                                char c = m_fmt.charAt(m_pos);
3255:                                if (Character.isDigit(c)) {
3256:                                    m_pos++;
3257:                                } else {
3258:                                    break;
3259:                                }
3260:                            }
3261:                            if (m_pos > firstPos + 1) {
3262:                                String sz = m_fmt
3263:                                        .substring(firstPos + 1, m_pos);
3264:                                m_precision = Integer.parseInt(sz);
3265:                                m_precisionSet = true;
3266:                            }
3267:                        }
3268:                    }
3269:                }
3270:
3271:                /**
3272:                 * Store the digits <code>n</code> in *n$ forms.
3273:                 * 
3274:                 * @return the result
3275:                 */
3276:                private boolean setPrecisionArgPosition() {
3277:
3278:                    boolean ret = false;
3279:                    int xPos;
3280:                    for (xPos = m_pos; xPos < m_fmt.length(); xPos++) {
3281:                        if (!Character.isDigit(m_fmt.charAt(xPos))) {
3282:                            break;
3283:                        }
3284:                    }
3285:                    if ((xPos > m_pos) && (xPos < m_fmt.length())) {
3286:                        if (m_fmt.charAt(xPos) == '$') {
3287:                            m_positionalPrecision = true;
3288:                            m_argumentPositionForPrecision = Integer
3289:                                    .parseInt(m_fmt.substring(m_pos, xPos));
3290:                            m_pos = xPos + 1;
3291:                            ret = true;
3292:                        }
3293:                    }
3294:                    return ret;
3295:                }
3296:
3297:                /**
3298:                 * Start the symbolic carry process.  The process
3299:                 * is not quite finished because the symbolic
3300:                 * carry may change the length of the string and
3301:                 * change the exponent (in e format).
3302:                 * @param cLast index of the last digit changed
3303:                 *     by the round
3304:                 * @param cFirst index of the first digit allowed
3305:                 *     to be changed by this phase of the round
3306:                 * @param ca the ca parameter
3307:                 * @return <code>true</code> if the carry forces
3308:                 *     a round that will change the print still
3309:                 *     more
3310:                 */
3311:                private boolean startSymbolicCarry(char[] ca, int cLast,
3312:                        int cFirst) {
3313:
3314:                    boolean carry = true;
3315:                    for (int i = cLast; carry && (i >= cFirst); i--) {
3316:                        carry = false;
3317:                        switch (ca[i]) {
3318:                        case '0':
3319:                            ca[i] = '1';
3320:                            break;
3321:                        case '1':
3322:                            ca[i] = '2';
3323:                            break;
3324:                        case '2':
3325:                            ca[i] = '3';
3326:                            break;
3327:                        case '3':
3328:                            ca[i] = '4';
3329:                            break;
3330:                        case '4':
3331:                            ca[i] = '5';
3332:                            break;
3333:                        case '5':
3334:                            ca[i] = '6';
3335:                            break;
3336:                        case '6':
3337:                            ca[i] = '7';
3338:                            break;
3339:                        case '7':
3340:                            ca[i] = '8';
3341:                            break;
3342:                        case '8':
3343:                            ca[i] = '9';
3344:                            break;
3345:                        case '9':
3346:                            ca[i] = '0';
3347:                            carry = true;
3348:                            break;
3349:                        default:
3350:                            // noop
3351:                        }
3352:                    }
3353:                    return carry;
3354:                }
3355:            }
3356:
3357:            /** Character position. Used by the constructor. */
3358:            DecimalFormatSymbols m_dfs;
3359:
3360:            /** Character position. Used by the constructor. */
3361:            private int m_cPos;
3362:
3363:            /** Vector of control strings and format literals. */
3364:            private Vector m_vFmt = new Vector();
3365:
3366:            /**
3367:             * Constructs an array of control specifications
3368:             * possibly preceded, separated, or followed by
3369:             * ordinary strings.  Control strings begin with
3370:             * unpaired percent signs.  A pair of successive
3371:             * percent signs designates a single percent sign in
3372:             * the format.
3373:             * @param locale the locale
3374:             * @param fmtArg  Control string.
3375:             * @exception CmsIllegalArgumentException if the control
3376:             * string is null, zero length, or otherwise
3377:             * malformed.
3378:             */
3379:            public PrintfFormat(Locale locale, String fmtArg)
3380:                    throws CmsIllegalArgumentException {
3381:
3382:                m_dfs = new DecimalFormatSymbols(locale);
3383:                int ePos = 0;
3384:                ConversionSpecification sFmt = null;
3385:                String unCS = this .nonControl(fmtArg, 0);
3386:                if (unCS != null) {
3387:                    sFmt = new ConversionSpecification();
3388:                    sFmt.setLiteral(unCS);
3389:                    m_vFmt.addElement(sFmt);
3390:                }
3391:                while ((m_cPos != -1) && (m_cPos < fmtArg.length())) {
3392:                    for (ePos = m_cPos + 1; ePos < fmtArg.length(); ePos++) {
3393:                        char c = 0;
3394:                        c = fmtArg.charAt(ePos);
3395:                        if (c == 'i') {
3396:                            break;
3397:                        }
3398:                        if (c == 'd') {
3399:                            break;
3400:                        }
3401:                        if (c == 'f') {
3402:                            break;
3403:                        }
3404:                        if (c == 'g') {
3405:                            break;
3406:                        }
3407:                        if (c == 'G') {
3408:                            break;
3409:                        }
3410:                        if (c == 'o') {
3411:                            break;
3412:                        }
3413:                        if (c == 'x') {
3414:                            break;
3415:                        }
3416:                        if (c == 'X') {
3417:                            break;
3418:                        }
3419:                        if (c == 'e') {
3420:                            break;
3421:                        }
3422:                        if (c == 'E') {
3423:                            break;
3424:                        }
3425:                        if (c == 'c') {
3426:                            break;
3427:                        }
3428:                        if (c == 's') {
3429:                            break;
3430:                        }
3431:                        if (c == '%') {
3432:                            break;
3433:                        }
3434:                    }
3435:                    ePos = Math.min(ePos + 1, fmtArg.length());
3436:                    sFmt = new ConversionSpecification(fmtArg.substring(m_cPos,
3437:                            ePos));
3438:                    m_vFmt.addElement(sFmt);
3439:                    unCS = this .nonControl(fmtArg, ePos);
3440:                    if (unCS != null) {
3441:                        sFmt = new ConversionSpecification();
3442:                        sFmt.setLiteral(unCS);
3443:                        m_vFmt.addElement(sFmt);
3444:                    }
3445:                }
3446:            }
3447:
3448:            /**
3449:             * Constructs an array of control specifications
3450:             * possibly preceded, separated, or followed by
3451:             * ordinary strings.  Control strings begin with
3452:             * unpaired percent signs.  A pair of successive
3453:             * percent signs designates a single percent sign in
3454:             * the format.
3455:             * @param fmtArg  Control string.
3456:             * @exception IllegalArgumentException if the control
3457:             * string is null, zero length, or otherwise
3458:             * malformed.
3459:             */
3460:            public PrintfFormat(String fmtArg) throws IllegalArgumentException {
3461:
3462:                this (Locale.getDefault(), fmtArg);
3463:            }
3464:
3465:            /**
3466:             * Format nothing.  Just use the control string.
3467:             * @return  the formatted String.
3468:             */
3469:            public String sprintf() {
3470:
3471:                Enumeration e = m_vFmt.elements();
3472:                ConversionSpecification cs = null;
3473:                char c = 0;
3474:                StringBuffer sb = new StringBuffer();
3475:                while (e.hasMoreElements()) {
3476:                    cs = (ConversionSpecification) e.nextElement();
3477:                    c = cs.getConversionCharacter();
3478:                    if (c == '\0') {
3479:                        sb.append(cs.getLiteral());
3480:                    } else if (c == '%') {
3481:                        sb.append("%");
3482:                    }
3483:                }
3484:                return sb.toString();
3485:            }
3486:
3487:            /**
3488:             * Format a double.
3489:             * @param x The double to format.
3490:             * @return  The formatted String.
3491:             * @exception CmsIllegalArgumentException if the
3492:             *     conversion character is c, C, s, S,
3493:             *     d, d, x, X, or o.
3494:             */
3495:            public String sprintf(double x) throws CmsIllegalArgumentException {
3496:
3497:                Enumeration e = m_vFmt.elements();
3498:                ConversionSpecification cs = null;
3499:                char c = 0;
3500:                StringBuffer sb = new StringBuffer();
3501:                while (e.hasMoreElements()) {
3502:                    cs = (ConversionSpecification) e.nextElement();
3503:                    c = cs.getConversionCharacter();
3504:                    if (c == '\0') {
3505:                        sb.append(cs.getLiteral());
3506:                    } else if (c == '%') {
3507:                        sb.append("%");
3508:                    } else {
3509:                        sb.append(cs.internalsprintf(x));
3510:                    }
3511:                }
3512:                return sb.toString();
3513:            }
3514:
3515:            /**
3516:             * Format an int.
3517:             * @param x The int to format.
3518:             * @return  The formatted String.
3519:             * @exception CmsIllegalArgumentException if the
3520:             *     conversion character is f, e, E, g, G, s,
3521:             *     or S.
3522:             */
3523:            public String sprintf(int x) throws CmsIllegalArgumentException {
3524:
3525:                Enumeration e = m_vFmt.elements();
3526:                ConversionSpecification cs = null;
3527:                char c = 0;
3528:                StringBuffer sb = new StringBuffer();
3529:                while (e.hasMoreElements()) {
3530:                    cs = (ConversionSpecification) e.nextElement();
3531:                    c = cs.getConversionCharacter();
3532:                    if (c == '\0') {
3533:                        sb.append(cs.getLiteral());
3534:                    } else if (c == '%') {
3535:                        sb.append("%");
3536:                    } else {
3537:                        sb.append(cs.internalsprintf(x));
3538:                    }
3539:                }
3540:                return sb.toString();
3541:            }
3542:
3543:            /**
3544:             * Format an long.
3545:             * @param x The long to format.
3546:             * @return  The formatted String.
3547:             * @exception CmsIllegalArgumentException if the
3548:             *     conversion character is f, e, E, g, G, s,
3549:             *     or S.
3550:             */
3551:            public String sprintf(long x) throws CmsIllegalArgumentException {
3552:
3553:                Enumeration e = m_vFmt.elements();
3554:                ConversionSpecification cs = null;
3555:                char c = 0;
3556:                StringBuffer sb = new StringBuffer();
3557:                while (e.hasMoreElements()) {
3558:                    cs = (ConversionSpecification) e.nextElement();
3559:                    c = cs.getConversionCharacter();
3560:                    if (c == '\0') {
3561:                        sb.append(cs.getLiteral());
3562:                    } else if (c == '%') {
3563:                        sb.append("%");
3564:                    } else {
3565:                        sb.append(cs.internalsprintf(x));
3566:                    }
3567:                }
3568:                return sb.toString();
3569:            }
3570:
3571:            /**
3572:             * Format an Object.  Convert wrapper types to
3573:             * their primitive equivalents and call the
3574:             * appropriate internal formatting method. Convert
3575:             * Strings using an internal formatting method for
3576:             * Strings. Otherwise use the default formatter
3577:             * (use toString).
3578:             * @param x the Object to format.
3579:             * @return  the formatted String.
3580:             * @exception CmsIllegalArgumentException if the
3581:             *    conversion character is inappropriate for
3582:             *    formatting an unwrapped value.
3583:             */
3584:            public String sprintf(Object x) throws CmsIllegalArgumentException {
3585:
3586:                Enumeration e = m_vFmt.elements();
3587:                ConversionSpecification cs = null;
3588:                char c = 0;
3589:                StringBuffer sb = new StringBuffer();
3590:                while (e.hasMoreElements()) {
3591:                    cs = (ConversionSpecification) e.nextElement();
3592:                    c = cs.getConversionCharacter();
3593:                    if (c == '\0') {
3594:                        sb.append(cs.getLiteral());
3595:                    } else if (c == '%') {
3596:                        sb.append("%");
3597:                    } else {
3598:                        if (x instanceof  Byte) {
3599:                            sb.append(cs
3600:                                    .internalsprintf(((Byte) x).byteValue()));
3601:                        } else if (x instanceof  Short) {
3602:                            sb.append(cs.internalsprintf(((Short) x)
3603:                                    .shortValue()));
3604:                        } else if (x instanceof  Integer) {
3605:                            sb.append(cs.internalsprintf(((Integer) x)
3606:                                    .intValue()));
3607:                        } else if (x instanceof  Long) {
3608:                            sb.append(cs
3609:                                    .internalsprintf(((Long) x).longValue()));
3610:                        } else if (x instanceof  Float) {
3611:                            sb.append(cs.internalsprintf(((Float) x)
3612:                                    .floatValue()));
3613:                        } else if (x instanceof  Double) {
3614:                            sb.append(cs.internalsprintf(((Double) x)
3615:                                    .doubleValue()));
3616:                        } else if (x instanceof  Character) {
3617:                            sb.append(cs.internalsprintf(((Character) x)
3618:                                    .charValue()));
3619:                        } else if (x instanceof  String) {
3620:                            sb.append(cs.internalsprintf((String) x));
3621:                        } else {
3622:                            sb.append(cs.internalsprintf(x));
3623:                        }
3624:                    }
3625:                }
3626:                return sb.toString();
3627:            }
3628:
3629:            /**
3630:             * Format an array of objects.  Byte, Short,
3631:             * Integer, Long, Float, Double, and Character
3632:             * arguments are treated as wrappers for primitive
3633:             * types.
3634:             * @param o The array of objects to format.
3635:             * @return  The formatted String.
3636:             */
3637:            public String sprintf(Object[] o) {
3638:
3639:                Enumeration e = m_vFmt.elements();
3640:                ConversionSpecification cs = null;
3641:                char c = 0;
3642:                int i = 0;
3643:                StringBuffer sb = new StringBuffer();
3644:                while (e.hasMoreElements()) {
3645:                    cs = (ConversionSpecification) e.nextElement();
3646:                    c = cs.getConversionCharacter();
3647:                    if (c == '\0') {
3648:                        sb.append(cs.getLiteral());
3649:                    } else if (c == '%') {
3650:                        sb.append("%");
3651:                    } else {
3652:                        if (cs.isPositionalSpecification()) {
3653:                            i = cs.getArgumentPosition() - 1;
3654:                            if (cs.isPositionalFieldWidth()) {
3655:                                int ifw = cs.getArgumentPositionForFieldWidth() - 1;
3656:                                cs.setFieldWidthWithArg(((Integer) o[ifw])
3657:                                        .intValue());
3658:                            }
3659:                            if (cs.isPositionalPrecision()) {
3660:                                int ipr = cs.getArgumentPositionForPrecision() - 1;
3661:                                cs.setPrecisionWithArg(((Integer) o[ipr])
3662:                                        .intValue());
3663:                            }
3664:                        } else {
3665:                            if (cs.isVariableFieldWidth()) {
3666:                                cs.setFieldWidthWithArg(((Integer) o[i])
3667:                                        .intValue());
3668:                                i++;
3669:                            }
3670:                            if (cs.isVariablePrecision()) {
3671:                                cs.setPrecisionWithArg(((Integer) o[i])
3672:                                        .intValue());
3673:                                i++;
3674:                            }
3675:                        }
3676:                        if (o[i] instanceof  Byte) {
3677:                            sb.append(cs.internalsprintf(((Byte) o[i])
3678:                                    .byteValue()));
3679:                        } else if (o[i] instanceof  Short) {
3680:                            sb.append(cs.internalsprintf(((Short) o[i])
3681:                                    .shortValue()));
3682:                        } else if (o[i] instanceof  Integer) {
3683:                            sb.append(cs.internalsprintf(((Integer) o[i])
3684:                                    .intValue()));
3685:                        } else if (o[i] instanceof  Long) {
3686:                            sb.append(cs.internalsprintf(((Long) o[i])
3687:                                    .longValue()));
3688:                        } else if (o[i] instanceof  Float) {
3689:                            sb.append(cs.internalsprintf(((Float) o[i])
3690:                                    .floatValue()));
3691:                        } else if (o[i] instanceof  Double) {
3692:                            sb.append(cs.internalsprintf(((Double) o[i])
3693:                                    .doubleValue()));
3694:                        } else if (o[i] instanceof  Character) {
3695:                            sb.append(cs.internalsprintf(((Character) o[i])
3696:                                    .charValue()));
3697:                        } else if (o[i] instanceof  String) {
3698:                            sb.append(cs.internalsprintf((String) o[i]));
3699:                        } else {
3700:                            sb.append(cs.internalsprintf(o[i]));
3701:                        }
3702:                        if (!cs.isPositionalSpecification()) {
3703:                            i++;
3704:                        }
3705:                    }
3706:                }
3707:                return sb.toString();
3708:            }
3709:
3710:            /**
3711:             * Format a String.
3712:             * @param x The String to format.
3713:             * @return  The formatted String.
3714:             * @exception CmsIllegalArgumentException if the
3715:             *   conversion character is neither s nor S.
3716:             */
3717:            public String sprintf(String x) throws CmsIllegalArgumentException {
3718:
3719:                Enumeration e = m_vFmt.elements();
3720:                ConversionSpecification cs = null;
3721:                char c = 0;
3722:                StringBuffer sb = new StringBuffer();
3723:                while (e.hasMoreElements()) {
3724:                    cs = (ConversionSpecification) e.nextElement();
3725:                    c = cs.getConversionCharacter();
3726:                    if (c == '\0') {
3727:                        sb.append(cs.getLiteral());
3728:                    } else if (c == '%') {
3729:                        sb.append("%");
3730:                    } else {
3731:                        sb.append(cs.internalsprintf(x));
3732:                    }
3733:                }
3734:                return sb.toString();
3735:            }
3736:
3737:            /**
3738:             * Return a substring starting at
3739:             * <code>start</code> and ending at either the end
3740:             * of the String <code>s</code>, the next unpaired
3741:             * percent sign, or at the end of the String if the
3742:             * last character is a percent sign.
3743:             * @param s  Control string.
3744:             * @param start Position in the string
3745:             *     <code>s</code> to begin looking for the start
3746:             *     of a control string.
3747:             * @return the substring from the start position
3748:             *     to the beginning of the control string.
3749:             */
3750:            private String nonControl(String s, int start) {
3751:
3752:                m_cPos = s.indexOf("%", start);
3753:                if (m_cPos == -1) {
3754:                    m_cPos = s.length();
3755:                }
3756:                return s.substring(start, m_cPos);
3757:            }
3758:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.