import java.io.*; import java.net.*; import java.lang.*; class CodecInfo { String coderName = ""; String coderType = ""; String fileName = null; int rawLen=0,compLen=0; double ratio=0,bpb=0; public String toString() { return("Codec: " + coderName + ": " + coderType + ": " + rawLen + " -> " + compLen); }; public String cIndicator() { return(fileName + " : " + coderName + ": " + coderType + ": " + rawLen + " -> " + compLen + " = " + ratio + ":1 = " + bpb + " bpb"); }; public CodecInfo(String n,String t,int r,int c) { coderName=n; coderType=t; rawLen=r;compLen=c; ratio=r/c;bpb = c*8/r; } public CodecInfo(String n) { coderName=n; } public CodecInfo() { } }; abstract class Codec { public static byte[] pack(byte[] raw) { return(null); } public static byte[] unpack(byte[] packed) throws IOException { return(null); } public static boolean recognize(byte[] packed) { return(false); } public static CodecInfo info(byte[] packed) { return(null); } public static CodecInfo info() { return(null); } }; /************************************/ final class CodecUU extends Codec { private static CodecInfo myInfo = new CodecInfo("UU"); public static byte[] pack(byte[] in) { return(null); }; public static byte[] unpack(byte[] in) throws IOException { DataInputStream sin = new DataInputStream( new ByteArrayInputStream(in) ); String curstr; do { curstr = sin.readLine(); if ( curstr == null ) return( new byte[0] ); } while ( ! curstr.regionMatches(0,"begin ",0,6) ); return( unpackStream(sin,in.length) ); }; public static byte[] unpackResume(byte[] in) throws IOException { DataInputStream sin = new DataInputStream( new ByteArrayInputStream(in) ); String curstr; return( unpackStream(sin,in.length) ); } public static byte[] unpackStream(DataInputStream sin,int maxlen) throws IOException { byte[] result; byte[] out = new byte[maxlen]; byte[] inline = new byte[91]; int outi,ini; int inlinelen,curoutlen; String curstr; int A,B,C,D; outi = 0; curoutlen = 0; do { if ( (curstr = sin.readLine()) == null ) return( new byte[0] ); } while( curstr.length() < 2 || curstr.charAt(0) != 'M' ); do { if ( (inlinelen = curstr.length()) > 1 ) { if ( inlinelen > 90 ) inlinelen = 90; curstr.getBytes(0,inlinelen,inline,0); curoutlen = inline[0] - 0x20; ini = 1; if ( curoutlen >= 0x40 ) break; while( curoutlen >= 3 ) { A = (inline[ini++] - 0x20) & 0x3F; B = (inline[ini++] - 0x20) & 0x3F; C = (inline[ini++] - 0x20) & 0x3F; D = (inline[ini++] - 0x20) & 0x3F; out[outi++] = (byte)( (A<<2) + (B>>4) ); out[outi++] = (byte)( ((B<<4) + (C>>2)) & 0xFF ); out[outi++] = (byte)( ((C<<6) + D) & 0xFF ); curoutlen -= 3; } switch(curoutlen) { case 0: break; case 1: A = (inline[ini++] - 0x20) & 0x3F; B = (inline[ini++] - 0x20) & 0x3F; out[outi++] = (byte)( (A<<2) + (B>>4)); break; case 2: A = (inline[ini++] - 0x20) & 0x3F; B = (inline[ini++] - 0x20) & 0x3F; C = (inline[ini++] - 0x20) & 0x3F; out[outi++] = (byte)( (A<<2) + (B>>4) ); out[outi++] = (byte)( ((B<<4) + (C>>2)) & 0xFF ); break; } } } while( (curstr = sin.readLine()) != null ); result = new byte[outi]; System.arraycopy(out,0,result,0,outi); out = null; return(result); }; public static boolean recognize(byte[] in) { String curline; int lines=0; DataInputStream sin = new DataInputStream( new ByteArrayInputStream(in) ); try { while( (curline = sin.readLine()) != null & lines < 100 ) { lines ++; if ( curline.regionMatches(0,"begin ",0,6) ) return(true); } } catch ( IOException e ) { } return(false); }; public static CodecInfo info(byte[] in) { CodecInfo newinfo = new CodecInfo(); newinfo.coderName = myInfo.coderName; newinfo.coderType = ""; newinfo.fileName = null; newinfo.compLen = in.length; newinfo.rawLen = ((in.length/61)*60*3)/4; /* rough estimate */ newinfo.ratio = newinfo.rawLen / newinfo.compLen; newinfo.bpb = newinfo.compLen * 8.0 / newinfo.rawLen; try { String curline; int lines=0; DataInputStream sin = new DataInputStream( new ByteArrayInputStream(in) ); while( (curline = sin.readLine()) != null & lines < 100 ) { lines ++; if ( curline.regionMatches(0,"begin ",0,6) ) { newinfo.fileName = curline.substring(10); return(newinfo); } } } catch ( IOException e ) { } return(newinfo); }; public static CodecInfo info() { return(myInfo); } }; final class CodecMaster extends Codec { private static CodecInfo myInfo = new CodecInfo("Master"); public static byte[] pack(byte[] in) { return(null); } public static byte[] unpack(byte[] in) throws IOException { if ( CodecUU.recognize(in) ) return( CodecUU.unpack(in) ); return(null); }; public static boolean recognize(byte[] in) { if ( CodecUU.recognize(in) ) return(true); return(false); } public static CodecInfo info(byte[] in) { if ( CodecUU.recognize(in) ) return( CodecUU.info(in) ); return( info() ); } public static CodecInfo info() { return(myInfo); } };