1 package com.sharkysoft.printf;
2
3 import java.io.IOException;
4 import java.io.Writer;
5
6 /***
7 * Main Printf For Java interface.
8 *
9 * <p><b>Details:</b> <code>Printf</code> is the primary interface to Printf For
10 * Java. This singleton class includes methods for outputing
11 * printf-<wbr>formatted text and data to the console, file streams, and
12 * buffers.</p>
13 *
14 * <p>The formatting template for a printf request must be given as a
15 * <code>String</code> or a {@link PrintfTemplate}. The data to format in a
16 * printf request must be given as an <code>Object</code> array or a
17 * {@link PrintfData}.</p>
18 *
19 * <p>For more information on both of these data structures, see the
20 * <a href="doc-files/specification.htm">Printf for Java Specification
21 * 2.0</a>.</p>
22 *
23 * <p>Any of the formating methods in this class may throw the following
24 * exceptions:</p>
25 *
26 * <ul>
27 * <li>{@link PrintfTemplateException} - If the format template is invalid. Or,
28 * if the format template includes a variable width or precision, and the
29 * value supplied is negative.</li>
30 * <li>{@link ClassCastException} - If a converstion type requires a certain
31 * type of data, but the wrong data type is offered.</li>
32 * <li>{@link NullPointerException} - If the data vector is <code>null</code>,
33 * but the format template calls for data. Or, if a conversion type
34 * requires non-<wbr><code>null</code> data, but the data being converted is
35 * <code>null</code>.</li>
36 * </ul>
37 *
38 * <p><b>Quick tip for C programmers:</b> Programmers familiar with
39 * <code>printf</code> in C may find the following idiom translations
40 * useful.</p>
41 *
42 * <table border=1>
43 * <tr>
44 * <th>C idiom</th>
45 * <th>Printf for Java idiom</th>
46 * </tr>
47 * <tr>
48 * <td><code>printf(fmt, arg1, arg2, ...)</code></td>
49 * <td><code>Printf.out(fmt, new Object[] {arg1, arg2, ...})</code></td>
50 * </tr>
51 * <tr>
52 * <td><code>sprintf(buff, fmt, arg1, arg2, ...)</code></td>
53 * <td><code>buff = Printf.format(fmt, new Object[] {arg1, arg2, ...})</code></td>
54 * </tr>
55 * <tr>
56 * <td><code>fprintf(out, fmt, arg1, arg2, ...)</code></td>
57 * <td><code>Printf.write(out, fmt, new Object[] {arg1, arg2, ...})</code></td>
58 * </tr>
59 * </table>
60 *
61 * @author Sharky
62 */
63 public final class Printf
64 {
65
66 /***
67 * Reserved.
68 */
69 private Printf()
70 {
71 }
72
73
74
75
76
77
78
79 /***
80 * Formats data to string.
81 *
82 * <p><b>Details:</b> <code>format</code> converts the given data into a
83 * string using the provided template. Elements in the data vector may be
84 * overwritten if the character counting format specifier is used. The
85 * template is pre-<wbr>compiled for efficiency.</p>
86 *
87 * @param ipTemplate the template
88 * @param ioapData the data
89 * @return the formatted string
90 *
91 * @see #format(String, Object[])
92 * @see #format(String, PrintfData)
93 */
94 public static String format(final PrintfTemplate ipTemplate, final Object[] ioapData)
95 {
96 final PrintfState vpState = new PrintfState();
97 vpState.mpOutput = new StringBuffer();
98 vpState.mapArgs = ioapData;
99 vpState.mnArgIndex = 0;
100
101 for (int vnI = 0; vnI < ipTemplate.mapComponents.length; ++vnI)
102 ipTemplate.mapComponents[vnI].format(vpState);
103 return vpState.mpOutput.toString();
104 }
105
106 /***
107 * Formats data to string.
108 *
109 * <p><b>Details:</b> <code>format</code> converts the given data into a
110 * string using the provided template. Elements in the data vector may be
111 * overwritten if the character counting format specifier is used.</p>
112 *
113 * @param isTemplate the template
114 * @param ioapData the data
115 * @return the formatted text
116 *
117 * @see #format(PrintfTemplate, Object[])
118 * @see #format(String, PrintfData)
119 */
120 public static String format(final String isTemplate, final Object[] ioapData)
121 {
122 return format(new PrintfTemplate(isTemplate), ioapData);
123 }
124
125 /***
126 * Formats data to string.
127 *
128 * <p><b>Details:</b> <code>format</code> converts the given data into a
129 * string using the provided template. The data is given in a growable vector
130 * for convenience.</p>
131 *
132 * @param isTemplate the template
133 * @param ipData the data
134 * @return the formatted string
135 *
136 * @see #format(PrintfTemplate, Object[])
137 * @see #format(String, Object[])
138 */
139 public static String format(final String isTemplate, final PrintfData ipData)
140 {
141 return format(new PrintfTemplate(isTemplate), ipData.done());
142 }
143
144 /***
145 * Formats template to stdout.
146 *
147 * <p><b>Details:</b> <code>format</code> converts the given template to a
148 * string. Only format strings which do not require a data vector can be used
149 * with this method.</p>
150 *
151 * @param isTemplate the template
152 * @return the formatted string
153 *
154 * @see #format(PrintfTemplate, Object[])
155 * @see #format(String, Object[])
156 * @see #format(String, PrintfData)
157 */
158 public static String format(final String isTemplate)
159 {
160 return format(isTemplate, (Object[]) null);
161 }
162
163
164
165
166
167
168
169 /***
170 * Formats data to stdout.
171 *
172 * <p><b>Details:</b> <code>format</code> converts the given data into a
173 * string using the provided template and then outputs it to
174 * <code>System.out</code>, which is usually the console. The number of
175 * characters output is returned. Elements in the data vector may be
176 * overwritten if the character counting format specifier is used. The
177 * template is pre-<wbr>compiled for efficiency.</p>
178 *
179 * @param ipTemplate the template
180 * @param ioapData the data
181 * @return the number of characters output
182 *
183 * @see #out(String, Object[])
184 * @see #out(String, PrintfData)
185 * @see #out(String)
186 */
187 public static int out(final PrintfTemplate ipTemplate, final Object[] ioapData)
188 {
189 final String vsOut = format(ipTemplate, ioapData);
190 System.out.print(vsOut);
191 return vsOut.length();
192 }
193
194 /***
195 * Formats data to stdout.
196 *
197 * <p><b>Details:</b> <code>format</code> converts the given data into a
198 * string using the provided template and then outputs it to
199 * <code>System.out</code>, which is usually the console. The number of
200 * characters output is returned. Elements in the data vector may be
201 * overwritten if the character counting format specifier is used.</p>
202 *
203 * @param isTemplate the template
204 * @param ioapData the data
205 * @return the number of characters output
206 *
207 * @see #out(PrintfTemplate, Object[])
208 * @see #out(String, PrintfData)
209 * @see #out(String)
210 */
211 public static int out(final String isTemplate, final Object[] ioapData)
212 {
213 return out(new PrintfTemplate(isTemplate), ioapData);
214 }
215
216 /***
217 * Formats data to stdout.
218 *
219 * <p><b>Details:</b> <code>format</code> converts the given data into a
220 * string using the provided template and then outputs it to
221 * <code>System.out</code>, which is usually the console. The number of
222 * characters output is returned. The data is given in a growable vector for
223 * convenience.</p>
224 *
225 * @param isTemplate the template
226 * @param ipData the data
227 * @return the number of characters output
228 *
229 * @see #out(PrintfTemplate, Object[])
230 * @see #out(String, Object[])
231 * @see #out(String)
232 */
233 public static int out(final String isTemplate, final PrintfData ipData)
234 {
235 return out(isTemplate, ipData.done());
236 }
237
238 /***
239 * Formats template to stdout.
240 *
241 * <p><b>Details:</b> <code>format</code> converts the given template to a
242 * string and then outputs it to <code>System.out</code>, which is usually the
243 * console. The number of characters output is returned. Only format strings
244 * which do not require a data vector can be used with this method.</p>
245 *
246 * @param isTemplate the template
247 * @return the number of characters output
248 *
249 * @see #out(PrintfTemplate, Object[])
250 * @see #out(String, Object[])
251 * @see #out(String, PrintfData)
252 */
253 public static int out(final String isTemplate)
254 {
255 return out(isTemplate, (Object[]) null);
256 }
257
258
259
260
261
262
263
264 /***
265 * Formats data to stream.
266 *
267 * <p><b>Details:</b> <code>write</code> converts the given data into a string
268 * using the provided template and then writes it to the given stream. The
269 * number of characters output is returned. Elements in the data vector may
270 * be overwritten if the character counting format specifier is used. The
271 * template is pre-<wbr>compiled for efficiency.</p>
272 *
273 * @param ipWriter the stream
274 * @param ipTemplate the template
275 * @param ioapData the data
276 * @return the number of characters output
277 * @throws IOException if writing to the stream causes an IOException
278 *
279 * @see #write(Writer, String, Object[])
280 * @see #write(Writer, String, PrintfData)
281 * @see #write(Writer, String)
282 */
283 public static int write
284 ( final Writer ipWriter,
285 final PrintfTemplate ipTemplate,
286 final Object[] ioapData
287 ) throws IOException
288 {
289 final String vsOut = format(ipTemplate, ioapData);
290 ipWriter.write(vsOut);
291 return vsOut.length();
292 }
293
294 /***
295 * Formats data to stream.
296 *
297 * <p><b>Details:</b> <code>write</code> converts the given data into a string
298 * using the provided template and then outputs it to the given stream. The
299 * number of characters output is returned. Elements in the data vector may
300 * be overwritten if the character counting format specifier is used.</p>
301 *
302 * @param ipWriter the stream
303 * @param isTemplate the template
304 * @param ioapData the data
305 * @return the number of characters output
306 * @throws IOException if writing to the stream causes an IOException
307 *
308 * @see #write(Writer, PrintfTemplate, Object[])
309 * @see #write(Writer, String, PrintfData)
310 * @see #write(Writer, String)
311 */
312 public static int write
313 ( final Writer ipWriter,
314 final String isTemplate,
315 final Object[] ioapData
316 ) throws IOException
317 {
318 return write(ipWriter, new PrintfTemplate(isTemplate), ioapData);
319 }
320
321 /***
322 * Formats data to stream.
323 *
324 * <p><b>Details:</b> <code>write</code> converts the given data into a string
325 * using the provided template and then outputs it to the given stream. The
326 * number of characters output is returned. The data is given in a growable
327 * vector for convenience.</p>
328 *
329 * @param ipWriter the stream
330 * @param isTemplate the template
331 * @param ipData the data
332 * @return the number of characters output
333 * @throws IOException if writing to the stream causes an IOException
334 *
335 * @see #write(Writer, PrintfTemplate, Object[])
336 * @see #write(Writer, String, Object[])
337 * @see #write(Writer, String)
338 */
339 public static int write
340 ( final Writer ipWriter,
341 final String isTemplate,
342 final PrintfData ipData
343 ) throws IOException
344 {
345 return write(ipWriter, isTemplate, ipData.done());
346 }
347
348 /***
349 * Formats template to stream.
350 *
351 * <p><b>Details:</b> <code>write</code> converts the given template into a
352 * string and then outputs it to the given stream. The number of characters
353 * output is returned. Only format strings which do not require a data vector
354 * can be used with this method.</p>
355 *
356 * @param ipWriter the stream
357 * @param isTemplate the template
358 * @return the number of characters output
359 * @throws IOException if writing to the stream causes an IOException
360 *
361 * @see #write(Writer, PrintfTemplate, Object[])
362 * @see #write(Writer, String, Object[])
363 * @see #write(Writer, String, PrintfData)
364 */
365 public static int write(final Writer ipWriter, final String isTemplate) throws IOException
366 {
367 return write(ipWriter, isTemplate, (Object[]) null);
368 }
369
370 }
371