001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.lang;
024:
025: import java.io.StringReader;
026: import java.io.StringWriter;
027: import java.io.IOException;
028:
029: public final class ByteUtils {
030: public final static short UNSIGNED_MAX_VALUE = (Byte.MAX_VALUE * 2) + 1;
031:
032: public static short toUnsigned(byte b) {
033: return (short) (b < 0 ? (UNSIGNED_MAX_VALUE + 1) + b : b);
034: }
035:
036: public static String toHexAscii(byte b) {
037: StringWriter sw = new StringWriter(2);
038: addHexAscii(b, sw);
039: return sw.toString();
040: }
041:
042: public static String toHexAscii(byte[] bytes) {
043: int len = bytes.length;
044: StringWriter sw = new StringWriter(len * 2);
045: for (int i = 0; i < len; ++i)
046: addHexAscii(bytes[i], sw);
047: return sw.toString();
048: }
049:
050: public static byte[] fromHexAscii(String s)
051: throws NumberFormatException {
052: try {
053: int len = s.length();
054: if ((len % 2) != 0)
055: throw new NumberFormatException(
056: "Hex ascii must be exactly two digits per byte.");
057:
058: int out_len = len / 2;
059: byte[] out = new byte[out_len];
060: int i = 0;
061: StringReader sr = new StringReader(s);
062: while (i < out_len) {
063: int val = (16 * fromHexDigit(sr.read()))
064: + fromHexDigit(sr.read());
065: out[i++] = (byte) val;
066: }
067: return out;
068: } catch (IOException e) {
069: throw new InternalError(
070: "IOException reading from StringReader?!?!");
071: }
072: }
073:
074: static void addHexAscii(byte b, StringWriter sw) {
075: short ub = toUnsigned(b);
076: int h1 = ub / 16;
077: int h2 = ub % 16;
078: sw.write(toHexDigit(h1));
079: sw.write(toHexDigit(h2));
080: }
081:
082: private static int fromHexDigit(int c) throws NumberFormatException {
083: if (c >= 0x30 && c < 0x3A)
084: return c - 0x30;
085: else if (c >= 0x41 && c < 0x47)
086: return c - 0x37;
087: else if (c >= 0x61 && c < 0x67)
088: return c - 0x57;
089: else
090: throw new NumberFormatException('\'' + c
091: + "' is not a valid hexadecimal digit.");
092: }
093:
094: /* note: we do no arg. checking, because */
095: /* we only ever call this from addHexAscii() */
096: /* above, and we are sure the args are okay */
097: private static char toHexDigit(int h) {
098: char out;
099: if (h <= 9)
100: out = (char) (h + 0x30);
101: else
102: out = (char) (h + 0x37);
103: //System.err.println(h + ": " + out);
104: return out;
105: }
106:
107: private ByteUtils() {
108: }
109: }
|