// base256 decoder, i.e. ASCII // // derived from B64Decoder.java // // R. Perry, December 2015 import java.io.*; // for testing, in main() /** * Decode ASCII strings into a byte array. *

* This class is designed using internal buffers so that * the caller can decode strings, presumably read line-by-line * from an input file, then obtain the final * decoded result using the flush() method. *

* Example usage (from main(), for testing): *

 *   Base256.Decoder b256 = new Base256.Decoder();
 *
 *   BufferedReader f = new BufferedReader( new InputStreamReader( System.in));
 *
 *   String line;
 * 
 *   while( (line = f.readLine()) != null)
 *     b256.decode( line);
 * 
 *   byte[] r = b256.flush();
 * 
 *   System.out.write( r);
 * 
 *   System.out.close();
 * 
* * @author Rick Perry * @version 19 December 2015 */ public class B256Decoder { /** * Decoded output array. */ private byte[] out; /** * Decoded output current length. */ private int outlen; /** * Size of decoded output array. */ private int maxlen; /** * Construct a new Decoder. */ public B256Decoder() { maxlen = 4096; out = new byte[maxlen]; reset(); } /** * reset the Decoder. */ public void reset() { outlen = 0; } /** * Append a byte to the output array. *

* The output array size is automatically increased as needed. * * @param b the byte to be appended. */ private void append( int b) { if( outlen == maxlen) // increase size { maxlen *= 1.5; byte[] x = new byte[maxlen]; System.arraycopy( out, 0, x, 0, outlen); out = x; } out[outlen++] = (byte) b; } /** * Decode a string. *

* The string is decoded into an internal buffer. *

* No syntax or error checking is performed, so invalid strings * (like "\xgg") will generally produce an exception. * * @param s the string to be decoded. */ public void decode( String s) { for( int i = 0; i < s.length(); ++i) { int c = s.charAt(i); if( c != '\\') // not a backslash { append(c); continue; } // process the chars following the backslash // ++i; c = s.charAt(i); if( c == '_') // blank, special case { append( ' '); continue; } if( c == 'x') // hex escape sequence { append( Integer.parseInt( s.substring( i+1, i+3), 16)); i += 2; continue; } switch( c) // escape sequence { case 'a': append(7); break; // Java doesn't support \a or \v case 'v': append(11); break; case 'b': append('\b'); break; case 't': append('\t'); break; case 'n': append('\n'); break; case 'f': append('\f'); break; case 'r': append('\r'); break; case '\\': append('\\'); break; default: append(c); break; } } } /** * Return decoded output. *

* The decoder internal buffer is reset after this call is made. * * @return the decoded output byte array. */ public byte[] flush() { byte[] r = new byte[outlen]; System.arraycopy( out, 0, r, 0, outlen); reset(); return r; } /** * Just for testing. */ public static void main( String args[]) throws Exception { byte[] b = new byte[4096]; B256Decoder b256 = new B256Decoder(); BufferedReader f = new BufferedReader( new InputStreamReader( System.in)); String line; while( (line = f.readLine()) != null) b256.decode( line); byte[] r = b256.flush(); System.out.write( r); System.out.close(); } }