diff options
Diffstat (limited to 'java/src/IceUtil/Base64.java')
-rw-r--r-- | java/src/IceUtil/Base64.java | 274 |
1 files changed, 274 insertions, 0 deletions
diff --git a/java/src/IceUtil/Base64.java b/java/src/IceUtil/Base64.java new file mode 100644 index 00000000000..da56f58cf4a --- /dev/null +++ b/java/src/IceUtil/Base64.java @@ -0,0 +1,274 @@ +// ********************************************************************** +// +// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved. +// +// This copy of Ice is licensed to you under the terms described in the +// ICE_LICENSE file included in this distribution. +// +// ********************************************************************** + +package IceUtil; + +public class Base64 +{ + +public static String +encode(byte[] plainSeq) +{ + if(plainSeq == null || plainSeq.length == 0) + { + return ""; + } + + StringBuffer retval = new StringBuffer(); + int base64Bytes = (((plainSeq.length * 4) / 3) + 1); + int newlineBytes = (((base64Bytes * 2) / 76) + 1); + int totalBytes = base64Bytes + newlineBytes; + + retval.ensureCapacity(totalBytes); + + int by1; + int by2; + int by3; + int by4; + int by5; + int by6; + int by7; + + for(int i = 0; i < plainSeq.length; i += 3) + { + by1 = plainSeq[i] & 0xff; + by2 = 0; + by3 = 0; + + if((i + 1) < plainSeq.length) + { + by2 = plainSeq[i+1] & 0xff; + } + + if((i + 2) < plainSeq.length) + { + by3 = plainSeq[i+2] & 0xff; + } + + by4 = (by1 >> 2) & 0xff; + by5 = (((by1 & 0x3) << 4) | (by2 >> 4)) & 0xff; + by6 = (((by2 & 0xf) << 2) | (by3 >> 6)) & 0xff; + by7 = by3 & 0x3f; + + retval.append(encode((byte)by4)); + retval.append(encode((byte)by5)); + + if((i + 1) < plainSeq.length) + { + retval.append(encode((byte)by6)); + } + else + { + retval.append('='); + } + + if((i + 2) < plainSeq.length) + { + retval.append(encode((byte)by7)); + } + else + { + retval.append('='); + } + } + + StringBuffer outString = new StringBuffer(); + outString.ensureCapacity(totalBytes); + int iter = 0; + + while((retval.length() - iter) > 76) + { + outString.append(retval.substring(iter, 76)); + outString.append("\r\n"); + iter += 76; + } + + outString.append(retval.substring(iter)); + + return outString.toString(); +} + +public static byte[] +decode(String str) +{ + StringBuffer newStr = new StringBuffer(); + + newStr.ensureCapacity(str.length()); + + for(int j = 0; j < str.length(); j++) + { + char c = str.charAt(j); + if(isBase64(c)) + { + newStr.append(c); + } + } + + if(newStr.length() == 0) + { + return null; + } + + // Note: This is how we were previously computing the size of the return + // sequence. The method below is more efficient (and correct). + // size_t lines = str.size() / 78; + // size_t totalBytes = (lines * 76) + (((str.size() - (lines * 78)) * 3) / 4); + + // Figure out how long the final sequence is going to be. + int totalBytes = (newStr.length() * 3 / 4) + 1; + + java.nio.ByteBuffer retval = java.nio.ByteBuffer.allocate(totalBytes); + + int by1; + int by2; + int by3; + int by4; + + char c1, c2, c3, c4; + + int pos = 0; + for(int i = 0; i < newStr.length(); i += 4) + { + c1 = 'A'; + c2 = 'A'; + c3 = 'A'; + c4 = 'A'; + + c1 = newStr.charAt(i); + + if((i + 1) < newStr.length()) + { + c2 = newStr.charAt(i + 1); + } + + if((i + 2) < newStr.length()) + { + c3 = newStr.charAt(i + 2); + } + + if((i + 3) < newStr.length()) + { + c4 = newStr.charAt(i + 3); + } + + by1 = decode(c1) & 0xff; + by2 = decode(c2) & 0xff; + by3 = decode(c3) & 0xff; + by4 = decode(c4) & 0xff; + + retval.put((byte)((by1 << 2) | (by2 >> 4))); + ++pos; + + if(c3 != '=') + { + retval.put((byte)(((by2 & 0xf) << 4) | (by3 >> 2))); + ++pos; + } + + if(c4 != '=') + { + retval.put((byte)(((by3 & 0x3) << 6) | by4)); + ++pos; + } + } + + byte[] arr = new byte[pos]; + System.arraycopy(retval.array(), 0, arr, 0, pos); + return arr; +} + +public static boolean +isBase64(char c) +{ + if(c >= 'A' && c <= 'Z') + { + return true; + } + + if(c >= 'a' && c <= 'z') + { + return true; + } + + if(c >= '0' && c <= '9') + { + return true; + } + + if(c == '+') + { + return true; + } + + if(c == '/') + { + return true; + } + + if(c == '=') + { + return true; + } + + return false; +} + +private static char +encode(byte uc) +{ + if(uc < 26) + { + return (char)('A' + uc); + } + + if(uc < 52) + { + return (char)('a' + (uc - 26)); + } + + if(uc < 62) + { + return (char)('0' + (uc - 52)); + } + + if(uc == 62) + { + return '+'; + } + + return '/'; +} + +private static byte +decode(char c) +{ + if(c >= 'A' && c <= 'Z') + { + return (byte)(c - 'A'); + } + + if(c >= 'a' && c <= 'z') + { + return (byte)(c - 'a' + 26); + } + + if(c >= '0' && c <= '9') + { + return (byte)(c - '0' + 52); + } + + if(c == '+') + { + return 62; + } + + return 63; +} + +} |