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