1 /* 2 * Copyright 2001-2004 The Apache Software Foundation. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package org.apache.commons.codec.binary; 18 19 import org.apache.commons.codec.BinaryDecoder; 20 import org.apache.commons.codec.BinaryEncoder; 21 import org.apache.commons.codec.DecoderException; 22 import org.apache.commons.codec.EncoderException; 23 24 /** 25 * Translates between byte arrays and strings of "0"s and "1"s. 26 * 27 * <b>TODO:</b> may want to add more bit vector functions like and/or/xor/nand. 28 * <B>TODO:</b> also might be good to generate boolean[] 29 * from byte[] et. cetera. 30 * 31 * @author Apache Software Foundation 32 * @since 1.3 33 * @version $Id $ 34 * 35 * @deprecated Please use {@link java.net.URL#openConnection} instead. 36 * Please visit <a href="http://android-developers.blogspot.com/2011/09/androids-http-clients.html">this webpage</a> 37 * for further details. 38 */ 39 @Deprecated 40 public class BinaryCodec implements BinaryDecoder, BinaryEncoder { 41 /* 42 * tried to avoid using ArrayUtils to minimize dependencies while using these empty arrays - dep is just not worth 43 * it. 44 */ 45 /** Empty char array. */ 46 private static final char[] EMPTY_CHAR_ARRAY = new char[0]; 47 48 /** Empty byte array. */ 49 private static final byte[] EMPTY_BYTE_ARRAY = new byte[0]; 50 51 /** Mask for bit 0 of a byte. */ 52 private static final int BIT_0 = 1; 53 54 /** Mask for bit 1 of a byte. */ 55 private static final int BIT_1 = 0x02; 56 57 /** Mask for bit 2 of a byte. */ 58 private static final int BIT_2 = 0x04; 59 60 /** Mask for bit 3 of a byte. */ 61 private static final int BIT_3 = 0x08; 62 63 /** Mask for bit 4 of a byte. */ 64 private static final int BIT_4 = 0x10; 65 66 /** Mask for bit 5 of a byte. */ 67 private static final int BIT_5 = 0x20; 68 69 /** Mask for bit 6 of a byte. */ 70 private static final int BIT_6 = 0x40; 71 72 /** Mask for bit 7 of a byte. */ 73 private static final int BIT_7 = 0x80; 74 75 private static final int[] BITS = {BIT_0, BIT_1, BIT_2, BIT_3, BIT_4, BIT_5, BIT_6, BIT_7}; 76 77 /** 78 * Converts an array of raw binary data into an array of ascii 0 and 1 characters. 79 * 80 * @param raw 81 * the raw binary data to convert 82 * @return 0 and 1 ascii character bytes one for each bit of the argument 83 * @see org.apache.commons.codec.BinaryEncoder#encode(byte[]) 84 */ encode(byte[] raw)85 public byte[] encode(byte[] raw) { 86 return toAsciiBytes(raw); 87 } 88 89 /** 90 * Converts an array of raw binary data into an array of ascii 0 and 1 chars. 91 * 92 * @param raw 93 * the raw binary data to convert 94 * @return 0 and 1 ascii character chars one for each bit of the argument 95 * @throws EncoderException 96 * if the argument is not a byte[] 97 * @see org.apache.commons.codec.Encoder#encode(java.lang.Object) 98 */ encode(Object raw)99 public Object encode(Object raw) throws EncoderException { 100 if (!(raw instanceof byte[])) { 101 throw new EncoderException("argument not a byte array"); 102 } 103 return toAsciiChars((byte[]) raw); 104 } 105 106 /** 107 * Decodes a byte array where each byte represents an ascii '0' or '1'. 108 * 109 * @param ascii 110 * each byte represents an ascii '0' or '1' 111 * @return the raw encoded binary where each bit corresponds to a byte in the byte array argument 112 * @throws DecoderException 113 * if argument is not a byte[], char[] or String 114 * @see org.apache.commons.codec.Decoder#decode(java.lang.Object) 115 */ decode(Object ascii)116 public Object decode(Object ascii) throws DecoderException { 117 if (ascii == null) { 118 return EMPTY_BYTE_ARRAY; 119 } 120 if (ascii instanceof byte[]) { 121 return fromAscii((byte[]) ascii); 122 } 123 if (ascii instanceof char[]) { 124 return fromAscii((char[]) ascii); 125 } 126 if (ascii instanceof String) { 127 return fromAscii(((String) ascii).toCharArray()); 128 } 129 throw new DecoderException("argument not a byte array"); 130 } 131 132 /** 133 * Decodes a byte array where each byte represents an ascii '0' or '1'. 134 * 135 * @param ascii 136 * each byte represents an ascii '0' or '1' 137 * @return the raw encoded binary where each bit corresponds to a byte in the byte array argument 138 * @see org.apache.commons.codec.Decoder#decode(Object) 139 */ decode(byte[] ascii)140 public byte[] decode(byte[] ascii) { 141 return fromAscii(ascii); 142 } 143 144 /** 145 * Decodes a String where each char of the String represents an ascii '0' or '1'. 146 * 147 * @param ascii 148 * String of '0' and '1' characters 149 * @return the raw encoded binary where each bit corresponds to a byte in the byte array argument 150 * @see org.apache.commons.codec.Decoder#decode(Object) 151 */ toByteArray(String ascii)152 public byte[] toByteArray(String ascii) { 153 if (ascii == null) { 154 return EMPTY_BYTE_ARRAY; 155 } 156 return fromAscii(ascii.toCharArray()); 157 } 158 159 // ------------------------------------------------------------------------ 160 // 161 // static codec operations 162 // 163 // ------------------------------------------------------------------------ 164 /** 165 * Decodes a byte array where each char represents an ascii '0' or '1'. 166 * 167 * @param ascii 168 * each char represents an ascii '0' or '1' 169 * @return the raw encoded binary where each bit corresponds to a char in the char array argument 170 */ fromAscii(char[] ascii)171 public static byte[] fromAscii(char[] ascii) { 172 if (ascii == null || ascii.length == 0) { 173 return EMPTY_BYTE_ARRAY; 174 } 175 // get length/8 times bytes with 3 bit shifts to the right of the length 176 byte[] l_raw = new byte[ascii.length >> 3]; 177 /* 178 * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the 179 * loop. 180 */ 181 for (int ii = 0, jj = ascii.length - 1; ii < l_raw.length; ii++, jj -= 8) { 182 for (int bits = 0; bits < BITS.length; ++bits) { 183 if (ascii[jj - bits] == '1') { 184 l_raw[ii] |= BITS[bits]; 185 } 186 } 187 } 188 return l_raw; 189 } 190 191 /** 192 * Decodes a byte array where each byte represents an ascii '0' or '1'. 193 * 194 * @param ascii 195 * each byte represents an ascii '0' or '1' 196 * @return the raw encoded binary where each bit corresponds to a byte in the byte array argument 197 */ fromAscii(byte[] ascii)198 public static byte[] fromAscii(byte[] ascii) { 199 if (ascii == null || ascii.length == 0) { 200 return EMPTY_BYTE_ARRAY; 201 } 202 // get length/8 times bytes with 3 bit shifts to the right of the length 203 byte[] l_raw = new byte[ascii.length >> 3]; 204 /* 205 * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the 206 * loop. 207 */ 208 for (int ii = 0, jj = ascii.length - 1; ii < l_raw.length; ii++, jj -= 8) { 209 for (int bits = 0; bits < BITS.length; ++bits) { 210 if (ascii[jj - bits] == '1') { 211 l_raw[ii] |= BITS[bits]; 212 } 213 } 214 } 215 return l_raw; 216 } 217 218 /** 219 * Converts an array of raw binary data into an array of ascii 0 and 1 character bytes - each byte is a truncated 220 * char. 221 * 222 * @param raw 223 * the raw binary data to convert 224 * @return an array of 0 and 1 character bytes for each bit of the argument 225 * @see org.apache.commons.codec.BinaryEncoder#encode(byte[]) 226 */ toAsciiBytes(byte[] raw)227 public static byte[] toAsciiBytes(byte[] raw) { 228 if (raw == null || raw.length == 0) { 229 return EMPTY_BYTE_ARRAY; 230 } 231 // get 8 times the bytes with 3 bit shifts to the left of the length 232 byte[] l_ascii = new byte[raw.length << 3]; 233 /* 234 * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the 235 * loop. 236 */ 237 for (int ii = 0, jj = l_ascii.length - 1; ii < raw.length; ii++, jj -= 8) { 238 for (int bits = 0; bits < BITS.length; ++bits) { 239 if ((raw[ii] & BITS[bits]) == 0) { 240 l_ascii[jj - bits] = '0'; 241 } else { 242 l_ascii[jj - bits] = '1'; 243 } 244 } 245 } 246 return l_ascii; 247 } 248 249 /** 250 * Converts an array of raw binary data into an array of ascii 0 and 1 characters. 251 * 252 * @param raw 253 * the raw binary data to convert 254 * @return an array of 0 and 1 characters for each bit of the argument 255 * @see org.apache.commons.codec.BinaryEncoder#encode(byte[]) 256 */ toAsciiChars(byte[] raw)257 public static char[] toAsciiChars(byte[] raw) { 258 if (raw == null || raw.length == 0) { 259 return EMPTY_CHAR_ARRAY; 260 } 261 // get 8 times the bytes with 3 bit shifts to the left of the length 262 char[] l_ascii = new char[raw.length << 3]; 263 /* 264 * We decr index jj by 8 as we go along to not recompute indices using multiplication every time inside the 265 * loop. 266 */ 267 for (int ii = 0, jj = l_ascii.length - 1; ii < raw.length; ii++, jj -= 8) { 268 for (int bits = 0; bits < BITS.length; ++bits) { 269 if ((raw[ii] & BITS[bits]) == 0) { 270 l_ascii[jj - bits] = '0'; 271 } else { 272 l_ascii[jj - bits] = '1'; 273 } 274 } 275 } 276 return l_ascii; 277 } 278 279 /** 280 * Converts an array of raw binary data into a String of ascii 0 and 1 characters. 281 * 282 * @param raw 283 * the raw binary data to convert 284 * @return a String of 0 and 1 characters representing the binary data 285 * @see org.apache.commons.codec.BinaryEncoder#encode(byte[]) 286 */ toAsciiString(byte[] raw)287 public static String toAsciiString(byte[] raw) { 288 return new String(toAsciiChars(raw)); 289 } 290 } 291