View Javadoc

1   package com.sharkysoft.printf;
2   
3   import com.sharkysoft.printf.engine.IntegerFormatter;
4   import com.sharkysoft.printf.engine.StringFormatter;
5   
6   final class Formatter_c extends Formatter_Field
7   {
8   
9   	private static final IntegerFormatter gpUnicodeFmt = new IntegerFormatter();
10  
11  	private static final IntegerFormatter gpAsciiFmt = new IntegerFormatter();
12  
13  	static 
14  	{
15  		gpUnicodeFmt.setMinDigits(4);
16  		gpUnicodeFmt.setRadix(16);
17  		gpUnicodeFmt.setZeroPrefix("//u");
18  		gpUnicodeFmt.setPosPrefix("//u");
19  		gpAsciiFmt.setMinDigits(3);
20  		gpAsciiFmt.setRadix(8);
21  		gpAsciiFmt.setZeroPrefix("//");
22  		gpAsciiFmt.setPosPrefix("//");
23  	}
24  
25  	private final boolean mzAlternate;
26  
27  	Formatter_c(final FormatSpecifier mpPfs)
28  	{
29  		super(mpPfs, new StringFormatter());
30  		mzAlternate = mpPfs.mcAlternate == FormatSpecifier.ALTERNATE_ON;
31  	}
32  
33  	void format(final PrintfState ipState)
34  	{
35  		adjustWidth(ipState);
36  		final char vcC = ((Character) ipState.mapArgs[ipState.mnArgIndex++]).charValue();
37  		final String vsOutput;
38  		if (mzAlternate)
39  			switch (vcC)
40  			{
41  			case '"' :
42  				vsOutput = "//\"";
43  				break;
44  			case '\'' :
45  				vsOutput = "//'";
46  				break;
47  			case '\n' :
48  				vsOutput = "//n";
49  				break;
50  			case '\r' :
51  				vsOutput = "//r";
52  				break;
53  			case '\b' :
54  				vsOutput = "//b";
55  				break;
56  			case '\t' :
57  				vsOutput = "//t";
58  				break;
59  			case '\f' :
60  				vsOutput = "//f";
61  				break;
62  			default :
63  				if (isprint(vcC))
64  					vsOutput = "" + vcC;
65  				else if (vcC < 256)
66  					vsOutput = gpAsciiFmt.format((int) vcC);
67  				else
68  					vsOutput = gpUnicodeFmt.format((int) vcC);
69  			}
70  		else
71  			vsOutput = "" + vcC;
72  		ipState.mpOutput.append(mpFormatter.format(vsOutput));
73  	}
74  
75  	final int argsRequired()
76  	{
77  		return 1 + (mzVariableWidth ? 1 : 0);
78  	}
79  
80  	/***
81  	 * <p><b>Details:</b> Returns <code>true</code> if c is a printing character.  
82  	 * For ASCII values, c is a printing character if and only if c is in 
83  	 * {32..127}.  This method does not support Unicode values, but it may in the 
84  	 * future.
85  	 */
86  	static boolean isprint(int c)
87  	{
88  		if (c > 255)
89  			throw new com.sharkysoft.util.NotImplementedException("c=" + c);
90  		return 32 <= c && c <= 126;
91  	}
92  
93      final Class[] argTypes() {
94          if (mzVariableWidth) {
95              return new Class[] { Number.class, Character.class };
96          } else {
97              return new Class[] { Character.class };
98          }
99      }
100 }
101