/* This file is part of VoltDB.
* Copyright (C) 2008-2010 VoltDB L.L.C.
*
* VoltDB is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* VoltDB is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with VoltDB. If not, see <http://www.gnu.org/licenses/>.
*/
package org.voltdb.utils;
import java.io.ByteArrayOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.zip.GZIPOutputStream;
/**
* Encode and decode strings and byte arrays to/from hexidecimal
* string values. This was originally added so binary values could
* be added to the VoltDB catalogs.
*
*/
public class Encoder {
private static final int caseDiff = ('a' - 'A');
/**
*
* @param data A binary array of bytes.
* @return A hex-encoded string with double length.
*/
public static String hexEncode(byte[] data) {
StringBuilder sb = new StringBuilder();
for (byte b : data) {
// hex encoding same way as java.net.URLEncoder.
char ch = Character.forDigit((b >> 4) & 0xF, 16);
// to uppercase
if (Character.isLetter(ch)) {
ch -= caseDiff;
}
sb.append(ch);
ch = Character.forDigit(b & 0xF, 16);
if (Character.isLetter(ch)) {
ch -= caseDiff;
}
sb.append(ch);
}
return sb.toString();
}
/**
*
* @param string A (latin) string to be hex encoded.
* @return The double-length hex encoded string.
*/
public static String hexEncode(String string) {
byte[] strbytes = {};
try {
// this will need to be less "western" in the future
strbytes = string.getBytes("ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return hexEncode(strbytes);
}
/**
*
* @param hexString An (even-length) hexidecimal string to be decoded.
* @return The binary byte array value for the string (half length).
*/
public static byte[] hexDecode(String hexString) {
assert (hexString.length() % 2) == 0;
hexString = hexString.toUpperCase();
byte[] retval = new byte[hexString.length() / 2];
for (int i = 0; i < retval.length; i++) {
retval[i] = (byte) Integer.parseInt(hexString.substring(2 * i, 2 * i + 2), 16);
}
return retval;
}
/**
*
* @param hexString A string of hexidecimal chars of even length.
* @return A string value de-hexed from the input.
*/
public static String hexDecodeToString(String hexString) {
byte[] decodedValue = hexDecode(hexString);
String retval = null;
try {
retval = new String(decodedValue, "ISO-8859-1");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return retval;
}
public static String compressAndBase64Encode(String string) {
try {
byte[] inBytes = string.getBytes("UTF-8");
ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(string.length() * 0.7));
GZIPOutputStream gzos = new GZIPOutputStream(baos);
gzos.write(inBytes);
gzos.close();
byte[] outBytes = baos.toByteArray();
return Base64.encodeBytes(outBytes);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static byte[] compressAndBase64EncodeToBytes(String string) {
try {
byte[] inBytes = string.getBytes("UTF-8");
ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(string.length() * 0.7));
GZIPOutputStream gzos = new GZIPOutputStream(baos);
gzos.write(inBytes);
gzos.close();
byte[] outBytes = baos.toByteArray();
return Base64.encodeBytesToBytes(outBytes);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static byte[] compressAndBase64EncodeToBytes(byte inBytes[]) {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream((int)(inBytes.length * .7));
GZIPOutputStream gzos = new GZIPOutputStream(baos);
gzos.write(inBytes);
gzos.close();
byte[] outBytes = baos.toByteArray();
return Base64.encodeBytesToBytes(outBytes);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static String base64Encode(String string) {
try {
final byte[] inBytes = string.getBytes("UTF-8");
return Base64.encodeBytes(inBytes);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static byte[] base64EncodeToBytes(String string) {
try {
final byte[] inBytes = string.getBytes("UTF-8");
return Base64.encodeBytesToBytes(inBytes);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static byte[] base64EncodeToBytes(byte bytes[]) {
try {
return Base64.encodeBytesToBytes(bytes);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static String decodeBase64AndDecompress(String string) {
try {
byte[] bytes = Base64.decode(string);
return new String(bytes, "UTF-8");
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static byte[] decodeBase64AndDecompressToBytes(byte inbytes[]) {
try {
return Base64.decodeAndGUnzip(inbytes);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static byte[] decodeBase64AndDecompressToBytes(String string) {
try {
return Base64.decode(string);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static String decodeBase64(String string) {
try {
return new String(Base64.decode(string, Base64.DONT_GUNZIP), "UTF-8");
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static byte[] decodeBase64ToBytes(String string) {
try {
return Base64.decode(string, Base64.DONT_GUNZIP);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static byte[] decodeBase64ToBytes(byte bytes[]) {
try {
return Base64.decode(bytes);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}