PageRenderTime 25ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/client/android/src/org/xmlrpc/android/Base64Coder.java

http://eztally.googlecode.com/
Java | 307 lines | 135 code | 18 blank | 154 comment | 33 complexity | 687682e6408cf3a1719336d66b86c63c MD5 | raw file
Possible License(s): Apache-2.0
  1. // Copyright 2003-2010 Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland
  2. // www.source-code.biz, www.inventec.ch/chdh
  3. //
  4. // This module is multi-licensed and may be used under the terms
  5. // of any of the following licenses:
  6. //
  7. // EPL, Eclipse Public License, http://www.eclipse.org/legal
  8. // LGPL, GNU Lesser General Public License, http://www.gnu.org/licenses/lgpl.html
  9. // AL, Apache License, http://www.apache.org/licenses
  10. // BSD, BSD License, http://www.opensource.org/licenses/bsd-license.php
  11. //
  12. // Please contact the author if you need another license.
  13. // This module is provided "as is", without warranties of any kind.
  14. package org.xmlrpc.android;
  15. /**
  16. * A Base64 encoder/decoder.
  17. *
  18. * <p>
  19. * This class is used to encode and decode data in Base64 format as described in
  20. * RFC 1521.
  21. *
  22. * <p>
  23. * Project home page: <a
  24. * href="http://www.source-code.biz/base64coder/java/">www.
  25. * source-code.biz/base64coder/java</a><br>
  26. * Author: Christian d'Heureuse, Inventec Informatik AG, Zurich, Switzerland<br>
  27. * Multi-licensed: EPL / LGPL / AL / BSD.
  28. */
  29. public class Base64Coder {
  30. // The line separator string of the operating system.
  31. private static final String systemLineSeparator = System
  32. .getProperty("line.separator");
  33. // Mapping table from 6-bit nibbles to Base64 characters.
  34. private static char[] map1 = new char[64];
  35. static {
  36. int i = 0;
  37. for (char c = 'A'; c <= 'Z'; c++)
  38. map1[i++] = c;
  39. for (char c = 'a'; c <= 'z'; c++)
  40. map1[i++] = c;
  41. for (char c = '0'; c <= '9'; c++)
  42. map1[i++] = c;
  43. map1[i++] = '+';
  44. map1[i++] = '/';
  45. }
  46. // Mapping table from Base64 characters to 6-bit nibbles.
  47. private static byte[] map2 = new byte[128];
  48. static {
  49. for (int i = 0; i < map2.length; i++)
  50. map2[i] = -1;
  51. for (int i = 0; i < 64; i++)
  52. map2[map1[i]] = (byte) i;
  53. }
  54. /**
  55. * Encodes a string into Base64 format. No blanks or line breaks are
  56. * inserted.
  57. *
  58. * @param s
  59. * A String to be encoded.
  60. * @return A String containing the Base64 encoded data.
  61. */
  62. public static String encodeString(String s) {
  63. return new String(encode(s.getBytes()));
  64. }
  65. /**
  66. * Encodes a byte array into Base 64 format and breaks the output into lines
  67. * of 76 characters. This method is compatible with
  68. * <code>sun.misc.BASE64Encoder.encodeBuffer(byte[])</code>.
  69. *
  70. * @param in
  71. * An array containing the data bytes to be encoded.
  72. * @return A String containing the Base64 encoded data, broken into lines.
  73. */
  74. public static String encodeLines(byte[] in) {
  75. return encodeLines(in, 0, in.length, 76, systemLineSeparator);
  76. }
  77. /**
  78. * Encodes a byte array into Base 64 format and breaks the output into
  79. * lines.
  80. *
  81. * @param in
  82. * An array containing the data bytes to be encoded.
  83. * @param iOff
  84. * Offset of the first byte in <code>in</code> to be processed.
  85. * @param iLen
  86. * Number of bytes to be processed in <code>in</code>, starting
  87. * at <code>iOff</code>.
  88. * @param lineLen
  89. * Line length for the output data. Should be a multiple of 4.
  90. * @param lineSeparator
  91. * The line separator to be used to separate the output lines.
  92. * @return A String containing the Base64 encoded data, broken into lines.
  93. */
  94. public static String encodeLines(byte[] in, int iOff, int iLen,
  95. int lineLen, String lineSeparator) {
  96. int blockLen = (lineLen * 3) / 4;
  97. if (blockLen <= 0)
  98. throw new IllegalArgumentException();
  99. int lines = (iLen + blockLen - 1) / blockLen;
  100. int bufLen = ((iLen + 2) / 3) * 4 + lines * lineSeparator.length();
  101. StringBuilder buf = new StringBuilder(bufLen);
  102. int ip = 0;
  103. while (ip < iLen) {
  104. int l = Math.min(iLen - ip, blockLen);
  105. buf.append(encode(in, iOff + ip, l));
  106. buf.append(lineSeparator);
  107. ip += l;
  108. }
  109. return buf.toString();
  110. }
  111. /**
  112. * Encodes a byte array into Base64 format. No blanks or line breaks are
  113. * inserted in the output.
  114. *
  115. * @param in
  116. * An array containing the data bytes to be encoded.
  117. * @return A character array containing the Base64 encoded data.
  118. */
  119. public static char[] encode(byte[] in) {
  120. return encode(in, 0, in.length);
  121. }
  122. /**
  123. * Encodes a byte array into Base64 format. No blanks or line breaks are
  124. * inserted in the output.
  125. *
  126. * @param in
  127. * An array containing the data bytes to be encoded.
  128. * @param iLen
  129. * Number of bytes to process in <code>in</code>.
  130. * @return A character array containing the Base64 encoded data.
  131. */
  132. public static char[] encode(byte[] in, int iLen) {
  133. return encode(in, 0, iLen);
  134. }
  135. /**
  136. * Encodes a byte array into Base64 format. No blanks or line breaks are
  137. * inserted in the output.
  138. *
  139. * @param in
  140. * An array containing the data bytes to be encoded.
  141. * @param iOff
  142. * Offset of the first byte in <code>in</code> to be processed.
  143. * @param iLen
  144. * Number of bytes to process in <code>in</code>, starting at
  145. * <code>iOff</code>.
  146. * @return A character array containing the Base64 encoded data.
  147. */
  148. public static char[] encode(byte[] in, int iOff, int iLen) {
  149. int oDataLen = (iLen * 4 + 2) / 3; // output length without padding
  150. int oLen = ((iLen + 2) / 3) * 4; // output length including padding
  151. char[] out = new char[oLen];
  152. int ip = iOff;
  153. int iEnd = iOff + iLen;
  154. int op = 0;
  155. while (ip < iEnd) {
  156. int i0 = in[ip++] & 0xff;
  157. int i1 = ip < iEnd ? in[ip++] & 0xff : 0;
  158. int i2 = ip < iEnd ? in[ip++] & 0xff : 0;
  159. int o0 = i0 >>> 2;
  160. int o1 = ((i0 & 3) << 4) | (i1 >>> 4);
  161. int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6);
  162. int o3 = i2 & 0x3F;
  163. out[op++] = map1[o0];
  164. out[op++] = map1[o1];
  165. out[op] = op < oDataLen ? map1[o2] : '=';
  166. op++;
  167. out[op] = op < oDataLen ? map1[o3] : '=';
  168. op++;
  169. }
  170. return out;
  171. }
  172. /**
  173. * Decodes a string from Base64 format. No blanks or line breaks are allowed
  174. * within the Base64 encoded input data.
  175. *
  176. * @param s
  177. * A Base64 String to be decoded.
  178. * @return A String containing the decoded data.
  179. * @throws IllegalArgumentException
  180. * If the input is not valid Base64 encoded data.
  181. */
  182. public static String decodeString(String s) {
  183. return new String(decode(s));
  184. }
  185. /**
  186. * Decodes a byte array from Base64 format and ignores line separators, tabs
  187. * and blanks. CR, LF, Tab and Space characters are ignored in the input
  188. * data. This method is compatible with
  189. * <code>sun.misc.BASE64Decoder.decodeBuffer(String)</code>.
  190. *
  191. * @param s
  192. * A Base64 String to be decoded.
  193. * @return An array containing the decoded data bytes.
  194. * @throws IllegalArgumentException
  195. * If the input is not valid Base64 encoded data.
  196. */
  197. public static byte[] decodeLines(String s) {
  198. char[] buf = new char[s.length()];
  199. int p = 0;
  200. for (int ip = 0; ip < s.length(); ip++) {
  201. char c = s.charAt(ip);
  202. if (c != ' ' && c != '\r' && c != '\n' && c != '\t')
  203. buf[p++] = c;
  204. }
  205. return decode(buf, 0, p);
  206. }
  207. /**
  208. * Decodes a byte array from Base64 format. No blanks or line breaks are
  209. * allowed within the Base64 encoded input data.
  210. *
  211. * @param s
  212. * A Base64 String to be decoded.
  213. * @return An array containing the decoded data bytes.
  214. * @throws IllegalArgumentException
  215. * If the input is not valid Base64 encoded data.
  216. */
  217. public static byte[] decode(String s) {
  218. return decode(s.toCharArray());
  219. }
  220. /**
  221. * Decodes a byte array from Base64 format. No blanks or line breaks are
  222. * allowed within the Base64 encoded input data.
  223. *
  224. * @param in
  225. * A character array containing the Base64 encoded data.
  226. * @return An array containing the decoded data bytes.
  227. * @throws IllegalArgumentException
  228. * If the input is not valid Base64 encoded data.
  229. */
  230. public static byte[] decode(char[] in) {
  231. return decode(in, 0, in.length);
  232. }
  233. /**
  234. * Decodes a byte array from Base64 format. No blanks or line breaks are
  235. * allowed within the Base64 encoded input data.
  236. *
  237. * @param in
  238. * A character array containing the Base64 encoded data.
  239. * @param iOff
  240. * Offset of the first character in <code>in</code> to be
  241. * processed.
  242. * @param iLen
  243. * Number of characters to process in <code>in</code>, starting
  244. * at <code>iOff</code>.
  245. * @return An array containing the decoded data bytes.
  246. * @throws IllegalArgumentException
  247. * If the input is not valid Base64 encoded data.
  248. */
  249. public static byte[] decode(char[] in, int iOff, int iLen) {
  250. if (iLen % 4 != 0)
  251. throw new IllegalArgumentException(
  252. "Length of Base64 encoded input string is not a multiple of 4.");
  253. while (iLen > 0 && in[iOff + iLen - 1] == '=')
  254. iLen--;
  255. int oLen = (iLen * 3) / 4;
  256. byte[] out = new byte[oLen];
  257. int ip = iOff;
  258. int iEnd = iOff + iLen;
  259. int op = 0;
  260. while (ip < iEnd) {
  261. int i0 = in[ip++];
  262. int i1 = in[ip++];
  263. int i2 = ip < iEnd ? in[ip++] : 'A';
  264. int i3 = ip < iEnd ? in[ip++] : 'A';
  265. if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127)
  266. throw new IllegalArgumentException(
  267. "Illegal character in Base64 encoded data.");
  268. int b0 = map2[i0];
  269. int b1 = map2[i1];
  270. int b2 = map2[i2];
  271. int b3 = map2[i3];
  272. if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0)
  273. throw new IllegalArgumentException(
  274. "Illegal character in Base64 encoded data.");
  275. int o0 = (b0 << 2) | (b1 >>> 4);
  276. int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2);
  277. int o2 = ((b2 & 3) << 6) | b3;
  278. out[op++] = (byte) o0;
  279. if (op < oLen)
  280. out[op++] = (byte) o1;
  281. if (op < oLen)
  282. out[op++] = (byte) o2;
  283. }
  284. return out;
  285. }
  286. // Dummy constructor.
  287. private Base64Coder() {
  288. }
  289. } // end class Base64Coder