001 package railo.runtime.coder; 002 003 import java.text.StringCharacterIterator; 004 005 /** 006 * Unix Coding for java 007 */ 008 public final class UUCoder { 009 010 /** 011 * encodes a byte array to a String 012 * @param barr 013 * @return encoded String 014 */ 015 public static String encode(byte barr[]) { 016 StringBuffer rtn = new StringBuffer(); 017 int len = barr.length; 018 int read = 0; 019 boolean stop = false; 020 byte b = 0; 021 int offset = 0; 022 023 do { 024 int left=len-read; 025 if(left==0) stop=true; 026 027 if(left<=45) b=(byte)left; 028 else b=45; 029 030 rtn.append(_enc(b)); 031 for(int i = 0; i < b; i += 3) { 032 if(len - offset < 3) { 033 byte padding[] = new byte[3]; 034 for(int z = 0; offset + z < len; z++) padding[z] = barr[offset + z]; 035 encodeBytes(padding, 0, rtn); 036 } else { 037 encodeBytes(barr, offset, rtn); 038 } 039 offset += 3; 040 } 041 042 rtn.append('\n'); 043 read += b; 044 if(b < 45) stop=true; 045 } 046 while(!stop); 047 return rtn.toString(); 048 } 049 050 /** 051 * decodes back a String to a byte array 052 * @param b 053 * @return decoded byte array 054 */ 055 public static byte[] decode(String str) throws CoderException { 056 byte out[] = new byte[str.length()]; 057 int len = 0; 058 int offset = 0; 059 //int current = 0; 060 byte b = 0; 061 boolean stop = false; 062 StringCharacterIterator it = new StringCharacterIterator(str); 063 do { 064 b = _dec(it.current()); 065 it.next(); 066 if(b>45) throw new CoderException("can't decode string ["+str+"]"); 067 if(b<45) stop=true; 068 len += b; 069 for(; b > 0; b -= 3) { 070 decodeChars(it, out, offset); 071 offset += 3; 072 } 073 it.next(); 074 } 075 while(!stop); 076 byte rtn[] = new byte[len]; 077 for(int i = 0; i < len; i++) 078 rtn[i] = out[i]; 079 080 return rtn; 081 } 082 083 private static void encodeBytes(byte in[], int off, StringBuffer out) { 084 out.append(_enc((byte)(in[off] >>> 2))); 085 out.append(_enc((byte)(in[off] << 4 & 0x30 | in[off + 1] >>> 4 & 0xf))); 086 out.append(_enc((byte)(in[off + 1] << 2 & 0x3c | in[off + 2] >>> 6 & 3))); 087 out.append(_enc((byte)(in[off + 2] & 0x3f))); 088 } 089 090 private static void decodeChars(StringCharacterIterator it, byte out[], int off) { 091 byte b1 = _dec(it.current()); 092 byte b2 = _dec(it.next()); 093 byte b3 = _dec(it.next()); 094 byte b4 = _dec(it.next()); 095 it.next(); 096 byte b5 = (byte)(b1 << 2 | b2 >> 4); 097 byte b6 = (byte)(b2 << 4 | b3 >> 2); 098 byte b7 = (byte)(b3 << 6 | b4); 099 out[off] = b5; 100 out[off + 1] = b6; 101 out[off + 2] = b7; 102 } 103 104 private static char _enc(byte c) { 105 return (char)((c & 0x3f) + 32); 106 } 107 108 private static byte _dec(char c) { 109 return (byte)(c - 32 & 0x3f); 110 } 111 }