rev version
[lwes-java.git] / src / org / lwes / util / NumberCodec.java
blob84284aaf03e53d9917ae6c505e68f0a3a7f1b371
1 package org.lwes.util;
3 import java.math.BigInteger;
5 /**
6 * This is a class to efficiently encode built-in primitive types into
7 * byte arrays and decode them back. While this can be done with a
8 * combination of ByteArrayOutputStreams, DataOutputStreams,
9 * ByteArrayInputStreams, DataInputStreams, merely creating those
10 * objects is quite costly and it is difficult to make them persistent.
11 * As such, this contains code lifted from the guts of the Data*Stream
12 * classes.
14 * Also, this class defines functions to convert primitive types and
15 * byte arrays to and from hexadecimal strings.
17 * Hopefully, support for these operations will be added to
18 * the standard Java API and this class can be retired.
20 * @author Preston Pfarner
21 * @author Michael P. Lum
22 * @version %I%, %G%
23 * @since 0.0.1
25 public final class NumberCodec {
26 public static final int BYTE_BYTES = 1;
27 public static final int SHORT_BYTES = 2;
28 public static final int INT_BYTES = 4;
29 public static final int LONG_BYTES = 8;
31 public static final int BYTE_BITS = 8;
32 public static final int SHORT_BITS = SHORT_BYTES * BYTE_BITS;
33 public static final int INT_BITS = INT_BYTES * BYTE_BITS;
34 public static final int LONG_BITS = LONG_BYTES * BYTE_BITS;
36 public static final short BYTE_MASK = 0xFF;
37 public static final int SHORT_MASK = 0xFFFF;
38 public static final long INT_MASK = 0xFFFFFFFFL;
40 private static final char[] hexCharMap = {
41 '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
44 private static final byte[] hexByteMap = {
45 (byte) '0', (byte) '1', (byte) '2', (byte) '3',
46 (byte) '4', (byte) '5', (byte) '6', (byte) '7',
47 (byte) '8', (byte) '9', (byte) 'A', (byte) 'B',
48 (byte) 'C', (byte) 'D', (byte) 'E', (byte) 'F',
51 /** Prohibited constructor; this is an uninstantiable class. */
52 private NumberCodec() { }
55 /* ***********************************************************************
56 * ENCODING TO BYTE ARRAYS
57 * ***********************************************************************/
58 /**
59 * Encode a byte into a byte-array buffer. <br>
60 * This version does not perform any null or range checks!
61 * @param b the byte to be encoded
62 * @param buffer the byte array into which the encoding should be written
63 * @param offset the position in the array to start writing the encoding
65 public static void encodeByteUnchecked(byte b, byte[] buffer,int offset) {
66 buffer[offset] = b;
69 /**
70 * Encode a byte into a byte-array buffer.
71 * @param b the byte to be encoded
72 * @param buffer the byte array into which the encoding should be written
73 * @param offset the position in the array to start writing the encoding
74 * @param length the maximum number of bytes that may be written
76 public static void encodeByte(byte b, byte[] buffer,int offset,int length)
77 throws IllegalArgumentException {
78 checkRange(BYTE_BYTES, buffer, offset, length);
79 encodeByteUnchecked(b,buffer,offset);
82 /**
83 * Encode a short into a byte-array buffer. <br>
84 * This version does not perform any null or range checks!
85 * @param s the short to be encoded
86 * @param buffer the byte array into which the encoding should be written
87 * @param offset the position in the array to start writing the encoding
89 public static void encodeShortUnchecked(short s, byte[] buffer,int offset) {
90 buffer[offset++] = (byte) ((s >>> (1*BYTE_BITS)) & BYTE_MASK);
91 buffer[offset ] = (byte) ((s >>> (0*BYTE_BITS)) & BYTE_MASK);
94 /**
95 * Encode a short into a byte-array buffer.
96 * @param s the short to be encoded
97 * @param buffer the byte array into which the encoding should be written
98 * @param offset the position in the array to start writing the encoding
99 * @param length the maximum number of bytes that may be written
101 public static void encodeShort(short s, byte[] buffer,int offset,int length)
102 throws IllegalArgumentException {
103 checkRange(SHORT_BYTES, buffer, offset, length);
104 encodeShortUnchecked(s, buffer,offset);
108 * Encode an int into a byte-array buffer. <br>
109 * This version does not perform any null or range checks!
110 * @param i the int to be encoded
111 * @param buffer the byte array into which the encoding should be written
112 * @param offset the position in the array to start writing the encoding
114 public static void encodeIntUnchecked(int i, byte[] buffer,int offset) {
115 buffer[offset++] = (byte) ((i >>> (3*BYTE_BITS)) & BYTE_MASK);
116 buffer[offset++] = (byte) ((i >>> (2*BYTE_BITS)) & BYTE_MASK);
117 buffer[offset++] = (byte) ((i >>> (1*BYTE_BITS)) & BYTE_MASK);
118 buffer[offset ] = (byte) ((i >>> (0*BYTE_BITS)) & BYTE_MASK);
122 * Encode an int into a byte-array buffer.
123 * @param i the int to be encoded
124 * @param buffer the byte array into which the encoding should be written
125 * @param offset the position in the array to start writing the encoding
126 * @param length the maximum number of bytes that may be written
128 public static void encodeInt(int i, byte[] buffer,int offset,int length)
129 throws IllegalArgumentException {
130 checkRange(INT_BYTES, buffer, offset, length);
131 encodeIntUnchecked(i, buffer,offset);
135 * Encode a long into a byte-array buffer.
136 * @param l the long to be encoded
137 * @param buffer the byte array into which the encoding should be written
138 * @param offset the position in the array to start writing the encoding
140 public static void encodeLongUnchecked(long l, byte[] buffer,int offset) {
141 buffer[offset++] = (byte) ((l >>> (7*BYTE_BITS)) & BYTE_MASK);
142 buffer[offset++] = (byte) ((l >>> (6*BYTE_BITS)) & BYTE_MASK);
143 buffer[offset++] = (byte) ((l >>> (5*BYTE_BITS)) & BYTE_MASK);
144 buffer[offset++] = (byte) ((l >>> (4*BYTE_BITS)) & BYTE_MASK);
145 buffer[offset++] = (byte) ((l >>> (3*BYTE_BITS)) & BYTE_MASK);
146 buffer[offset++] = (byte) ((l >>> (2*BYTE_BITS)) & BYTE_MASK);
147 buffer[offset++] = (byte) ((l >>> (1*BYTE_BITS)) & BYTE_MASK);
148 buffer[offset ] = (byte) ((l >>> (0*BYTE_BITS)) & BYTE_MASK);
152 * Encode a long into a byte-array buffer.
153 * @param l the long to be encoded
154 * @param buffer the byte array into which the encoding should be written
155 * @param offset the position in the array to start writing the encoding
156 * @param length the maximum number of bytes that may be written
158 public static void encodeLong(long l, byte[] buffer,int offset,int length)
159 throws IllegalArgumentException {
160 checkRange(LONG_BYTES, buffer, offset, length);
161 encodeLongUnchecked(l, buffer,offset);
164 /* ***********************************************************************
165 * DECODING FROM BYTE ARRAYS
166 * ***********************************************************************/
168 * Extract and decode a byte out of a byte-array buffer. <br>
169 * This version does not perform any null or range checks!
170 * @param buffer the byte array from which the encoded form should be read
171 * @param offset the position in the array to start reading the encoded form
173 public static final byte decodeByteUnchecked(byte[] buffer,int offset) {
174 return buffer[offset];
178 * Decode a byte out of a byte-array buffer.
179 * @param buffer the byte array from which the encoded form should be read
180 * @param offset the position in the array to start reading the encoded form
181 * @param length the maximum number of bytes that may be read
183 public static final byte decodeByte(byte[] buffer,int offset,int length)
184 throws IllegalArgumentException {
185 checkRange(BYTE_BYTES, buffer, offset, length);
186 return decodeByteUnchecked(buffer,offset);
190 * Extract and decode a short out of a byte-array buffer. <br>
191 * This version does not perform any null or range checks!
192 * @param buffer the byte array from which the encoded form should be read
193 * @param offset the position in the array to start reading the encoded form
195 public static short decodeShortUnchecked(byte[] buffer,int offset) {
196 return
197 (short) ((decodeByteUnchecked(buffer,offset) << BYTE_BITS) +
198 (decodeByteUnchecked(buffer,offset+BYTE_BYTES) & BYTE_MASK));
202 * Decode a short out of a byte-array buffer.
203 * @param buffer the byte array from which the encoded form should be read
204 * @param offset the position in the array to start reading the encoded form
205 * @param length the maximum number of bytes that may be read
207 public static short decodeShort(byte[] buffer,int offset,int length)
208 throws IllegalArgumentException {
209 checkRange(SHORT_BYTES, buffer, offset, length);
210 return decodeShortUnchecked(buffer,offset);
214 * Extract and decode an int out of a byte-array buffer. <br>
215 * This version does not perform any null or range checks!
216 * @param buffer the byte array from which the encoded form should be read
217 * @param offset the position in the array to start reading the encoded form
219 public static int decodeIntUnchecked(byte[] buffer,int offset) {
220 return ((decodeShortUnchecked(buffer,offset) << SHORT_BITS) +
221 (decodeShortUnchecked(buffer,offset+SHORT_BYTES) & SHORT_MASK));
225 * Decode an int out of a byte-array buffer.
226 * @param buffer the byte array from which the encoded form should be read
227 * @param offset the position in the array to start reading the encoded form
228 * @param length the maximum number of bytes that may be read
230 public static int decodeInt(byte[] buffer,int offset,int length)
231 throws IllegalArgumentException {
232 checkRange(INT_BYTES, buffer, offset, length);
233 return decodeIntUnchecked(buffer,offset);
237 * Extract and decode a long out of a byte-array buffer. <br>
238 * This version does not perform any null or range checks!
239 * @param buffer the byte array from which the encoded form should be read
240 * @param offset the position in the array to start reading the encoded form
242 public static long decodeLongUnchecked(byte[] buffer,int offset) {
243 return ((((long) decodeIntUnchecked(buffer,offset)) << INT_BITS) +
244 (decodeIntUnchecked(buffer,offset+INT_BYTES) & INT_MASK));
248 * Decode a long out of a byte-array buffer.
249 * @param buffer the byte array from which the encoded form should be read
250 * @param offset the position in the array to start reading the encoded form
251 * @param length the maximum number of bytes that may be read
253 public static long decodeLong(byte[] buffer,int offset,int length)
254 throws IllegalArgumentException {
255 checkRange(LONG_BYTES, buffer, offset, length);
256 return decodeLongUnchecked(buffer,offset);
260 * Verifies that the buffer exists, that the writeable region fits into
261 * the buffer, and that the writeable length is long enough.
262 * @param minLength the length that will be written
263 * @param buffer the destination array
264 * @param offset the first position that should be written
265 * @param length the number of bytes that may be written
266 * @exception IllegalArgumentException if the check fails
268 public static void checkRange(int minLength,
269 byte[] buffer, int offset, int length)
270 throws IllegalArgumentException {
271 if (buffer == null)
272 throw new IllegalArgumentException("Buffer is null.");
273 if ((offset < 0) || (length < 0) || (offset + length > buffer.length))
274 throw new IllegalArgumentException("Writeable region does not fit: "+
275 offset+","+length+","+buffer.length);
276 if (minLength > length)
277 throw new IllegalArgumentException("Writeable region is too small: "+
278 minLength+">"+length);
281 /* ***********************************************************************
282 * WRITING TO STRINGS (IN HEX)
283 * ***********************************************************************/
285 * Output a number in unsigned hexadecimal form, padding with zeroes,
286 * with a fixed result size. Extra opening "f"'s are removed.
287 * @param val the number to convert
288 * @param numBytes the number of bytes to write (each is two hex digits)
289 * @return a String representing the number.
291 private static String toHexString(long num, int numBytes) {
292 final StringBuffer buf = new StringBuffer(2*numBytes);
293 writeHexString(num,numBytes,buf);
294 return buf.toString();
298 * Write a number in unsigned hexadecimal form, padding with zeroes,
299 * with a fixed result size. Extra opening "f"'s are removed.
300 * @param val the number to convert
301 * @param numBytes the number of bytes to write (each is two hex digits)
302 * @param buf the StringBuffer into which to write
304 private static void writeHexString(long num, int numBytes, StringBuffer buf){
305 final int startLen = buf.length();
306 int numNibbles = numBytes << 1;
307 int pos = startLen+numNibbles;
308 buf.setLength(pos);
309 while (numNibbles != 0) {
310 --pos;
311 final byte masked = (byte) (num & 0xf);
312 buf.setCharAt(pos,hexCharMap[masked]);
313 num >>>= 4;
314 --numNibbles;
319 * Write a number in unsigned hexadecimal form, padding with zeroes,
320 * with a fixed result size. Extra opening "f"'s are removed.
321 * @param value the number to convert
322 * @param bytes the byte array into which to write
323 * @param offset the offset into <code>bytes</code> to start
324 * @param numBytes the number of bytes to write (each is two hex digits)
326 private static void writeHexString
327 (long value, byte[] bytes, int offset, int numBytes) {
328 int numNibbles = numBytes << 1;
329 int pos = offset+numNibbles;
330 while (numNibbles != 0) {
331 --pos;
332 final byte masked = (byte) (value & 0xf);
333 bytes[pos] = hexByteMap[masked];
334 value >>>= 4;
335 --numNibbles;
339 /* ***********************************************************************
340 * Convert numbers to hex strings
341 * ***********************************************************************/
343 * Output a byte in unsigned hexadecimal form, padding with zeroes.
344 * @param b the byte
345 * @return a String representing the byte.
347 public static String toHexString(byte b) {
348 return toHexString(b,BYTE_BYTES);
352 * Output a short in unsigned hexadecimal form, padding with zeroes.
353 * @param s the short
354 * @return a String representing the short.
356 public static String toHexString(short s) {
357 return toHexString(s,SHORT_BYTES);
361 * Output an int in unsigned hexadecimal form, padding with zeroes.
362 * @param i the int
363 * @return a String representing the int.
365 public static String toHexString(int i) {
366 return toHexString(i,INT_BYTES);
370 * Output a long in unsigned hexadecimal form, padding with zeroes.
371 * @param l the long
372 * @return a String representing the long.
374 public static String toHexString(long l) {
375 return toHexString(l,LONG_BYTES);
379 * Output a BigInteger in unsigned hexadecimal form, padding with zeroes.
380 * @param bi the BigInteger
381 * @return a String representing the BigInteger.
383 public static String toHexString(BigInteger bi) {
384 if(bi == null) return "";
385 return bi.toString(16); // 16-bit radix
388 /* ***********************************************************************
389 * Write hex strings into string buffers
390 * ***********************************************************************/
392 * Write a byte in unsigned hexadecimal form, padding with zeroes.
393 * @param buf the StringBuffer into which to write
394 * @param b the byte
396 public static void writeHexString(byte b, StringBuffer buf) {
397 writeHexString(b,BYTE_BYTES,buf);
401 * Write a short in unsigned hexadecimal form, padding with zeroes.
402 * @param buf the StringBuffer into which to write
403 * @param s the short
405 public static void writeHexString(short s, StringBuffer buf) {
406 writeHexString(s,SHORT_BYTES,buf);
410 * Write a int in unsigned hexadecimal form, padding with zeroes.
411 * @param buf the StringBuffer into which to write
412 * @param i the int
414 public static void writeHexString(int i, StringBuffer buf) {
415 writeHexString(i,INT_BYTES,buf);
419 * Write a long in unsigned hexadecimal form, padding with zeroes.
420 * @param buf the StringBuffer into which to write
421 * @param l the long
423 public static void writeHexString(long l, StringBuffer buf) {
424 writeHexString(l,LONG_BYTES,buf);
427 /* ***********************************************************************
428 * Write hex strings into byte arrays
429 * (with each byte representing a nibble in ASCII)
430 * ***********************************************************************/
432 * Write a byte in unsigned hexadecimal form, padding with zeroes.
433 * @param b the byte
434 * @param bytes the byte array into which to write
435 * @param offset the index in the byte array to start writing
437 public static void writeHexString(byte b, byte[] bytes, int offset) {
438 writeHexString(b,bytes,offset,BYTE_BYTES);
442 * Write a short in unsigned hexadecimal form, padding with zeroes.
443 * @param value the value to write
444 * @param bytes the byte array into which to write
445 * @param offset the index in the byte array to start writing
447 public static void writeHexString(short value, byte[] bytes, int offset) {
448 writeHexString(value,bytes,offset,SHORT_BYTES);
452 * Write a int in unsigned hexadecimal form, padding with zeroes.
453 * @param value the value to write
454 * @param bytes the byte array into which to write
455 * @param offset the index in the byte array to start writing
457 public static void writeHexString(int value, byte[] bytes, int offset) {
458 writeHexString(value,bytes,offset,INT_BYTES);
462 * Write a long in unsigned hexadecimal form, padding with zeroes.
463 * @param value the value to write
464 * @param bytes the byte array into which to write
465 * @param offset the index in the byte array to start writing
467 public static void writeHexString(long value, byte[] bytes, int offset) {
468 writeHexString(value,bytes,offset,LONG_BYTES);
474 * Return a String encoding the bytes from a portion of a byte array
475 * in hex form.
476 * @param bytes the byte array
477 * @param offset the first byte to output
478 * @param length the number of bytes to output
479 * @return the hex dump of the byte array
481 public static String byteArrayToHexString(byte[] bytes,
482 int offset, int length) {
483 StringBuffer buf = new StringBuffer(2*length);
484 for (int i=offset; i<offset+length; i++) {
485 buf.append(Character.forDigit(((bytes[i]>>>4) & 0x0f), 16));
486 buf.append(Character.forDigit(( bytes[i] & 0x0f), 16));
488 return buf.toString();
491 public static byte[] hexStringToByteArray(String aString)
493 int length = aString.length();
494 if ( (length % 2) != 0 )
496 System.err.println("ERROR: Odd Number, can't convert to byte array");
497 return null;
499 byte [] bytes = new byte[(length/2)];
500 for ( int k = 0 ; k < (length/2) ; k++ )
502 bytes[k] = (byte)0;
504 byte [] str_bytes = aString.getBytes();
505 if ( str_bytes.length != length )
507 System.err.println("ERROR: Mismatching lengths");
508 return null;
510 int count = 0;
511 boolean waitingForSecondNibble = false;
512 for ( int i = 0; i < length ; i++ )
514 switch ( str_bytes[i] ) {
515 case ((byte)'0'):
516 if ( waitingForSecondNibble )
518 bytes[count] |= (byte)( (byte)0x0 << 0 );
519 count++;
520 waitingForSecondNibble = false;
522 else
524 bytes[count] |= (byte)( (byte)0x0 << 4 );
525 waitingForSecondNibble = true;
527 break;
528 case ((byte)'1'):
529 if ( waitingForSecondNibble )
531 bytes[count] |= (byte)( (byte)0x1 << 0 );
532 count++;
533 waitingForSecondNibble = false;
535 else
537 bytes[count] |= (byte)( (byte)0x1 << 4 );
538 waitingForSecondNibble = true;
540 break;
541 case ((byte)'2'):
542 if ( waitingForSecondNibble )
544 bytes[count] |= (byte)( (byte)0x2 << 0 );
545 count++;
546 waitingForSecondNibble = false;
548 else
550 bytes[count] |= (byte)( (byte)0x2 << 4 );
551 waitingForSecondNibble = true;
553 break;
554 case ((byte)'3'):
555 if ( waitingForSecondNibble )
557 bytes[count] |= (byte)( (byte)0x3 << 0 );
558 count++;
559 waitingForSecondNibble = false;
561 else
563 bytes[count] |= (byte)( (byte)0x3 << 4 );
564 waitingForSecondNibble = true;
566 break;
567 case ((byte)'4'):
568 if ( waitingForSecondNibble )
570 bytes[count] |= (byte)( (byte)0x4 << 0 );
571 count++;
572 waitingForSecondNibble = false;
574 else
576 bytes[count] |= (byte)( (byte)0x4 << 4 );
577 waitingForSecondNibble = true;
579 break;
580 case ((byte)'5'):
581 if ( waitingForSecondNibble )
583 bytes[count] |= (byte)( (byte)0x5 << 0 );
584 count++;
585 waitingForSecondNibble = false;
587 else
589 bytes[count] |= (byte)( (byte)0x5 << 4 );
590 waitingForSecondNibble = true;
592 break;
593 case ((byte)'6'):
594 if ( waitingForSecondNibble )
596 bytes[count] |= (byte)( (byte)0x6 << 0 );
597 count++;
598 waitingForSecondNibble = false;
600 else
602 bytes[count] |= (byte)( (byte)0x6 << 4 );
603 waitingForSecondNibble = true;
605 break;
606 case ((byte)'7'):
607 if ( waitingForSecondNibble )
609 bytes[count] |= (byte)( (byte)0x7 << 0 );
610 count++;
611 waitingForSecondNibble = false;
613 else
615 bytes[count] |= (byte)( (byte)0x7 << 4 );
616 waitingForSecondNibble = true;
618 break;
619 case ((byte)'8'):
620 if ( waitingForSecondNibble )
622 bytes[count] |= (byte)( (byte)0x8 << 0 );
623 count++;
624 waitingForSecondNibble = false;
626 else
628 bytes[count] |= (byte)( (byte)0x8 << 4 );
629 waitingForSecondNibble = true;
631 break;
632 case ((byte)'9'):
633 if ( waitingForSecondNibble )
635 bytes[count] |= (byte)( (byte)0x9 << 0 );
636 count++;
637 waitingForSecondNibble = false;
639 else
641 bytes[count] |= (byte)( (byte)0x9 << 4 );
642 waitingForSecondNibble = true;
644 break;
645 case ((byte)'a'):
646 case ((byte)'A'):
647 if ( waitingForSecondNibble )
649 bytes[count] |= (byte)( (byte)0xa << 0 );
650 count++;
651 waitingForSecondNibble = false;
653 else
655 bytes[count] |= (byte)( (byte)0xa << 4 );
656 waitingForSecondNibble = true;
658 break;
659 case ((byte)'b'):
660 case ((byte)'B'):
661 if ( waitingForSecondNibble )
663 bytes[count] |= (byte)( (byte)0xb << 0 );
664 count++;
665 waitingForSecondNibble = false;
667 else
669 bytes[count] |= (byte)( (byte)0xb << 4 );
670 waitingForSecondNibble = true;
672 break;
673 case ((byte)'c'):
674 case ((byte)'C'):
675 if ( waitingForSecondNibble )
677 bytes[count] |= (byte)( (byte)0xc << 0 );
678 count++;
679 waitingForSecondNibble = false;
681 else
683 bytes[count] |= (byte)( (byte)0xc << 4 );
684 waitingForSecondNibble = true;
686 break;
688 case ((byte)'d'):
689 case ((byte)'D'):
690 if ( waitingForSecondNibble )
692 bytes[count] |= (byte)( (byte)0xd << 0 );
693 count++;
694 waitingForSecondNibble = false;
696 else
698 bytes[count] |= (byte)( (byte)0xd << 4 );
699 waitingForSecondNibble = true;
701 break;
703 case ((byte)'e'):
704 case ((byte)'E'):
705 if ( waitingForSecondNibble )
707 bytes[count] |= (byte)( (byte)0xe << 0 );
708 count++;
709 waitingForSecondNibble = false;
711 else
713 bytes[count] |= (byte)( (byte)0xe << 4 );
714 waitingForSecondNibble = true;
716 break;
718 case ((byte)'f'):
719 case ((byte)'F'):
720 if ( waitingForSecondNibble )
722 bytes[count] |= (byte)( (byte)0xf << 0 );
723 count++;
724 waitingForSecondNibble = false;
726 else
728 bytes[count] |= (byte)( (byte)0xf << 4 );
729 waitingForSecondNibble = true;
731 break;
733 default:
734 System.err.println("ERROR: non-hex character");
735 return null;
738 return bytes;
742 * Return a String encoding the bytes in a byte array in hex form. <br>
743 * This is equivalent to
744 * <code>byteArrayToHexString(bytes,0,bytes.length);</code>
745 * @param bytes the byte array
746 * @return the hex dump of the byte array
748 public static String byteArrayToHexString(byte[] bytes) {
749 return byteArrayToHexString(bytes,0,bytes.length);
753 * Turn an unsigned hex string into a long. This whole thing is here
754 * to replace Long.parseLong(str,16) because it fails with large unsigned
755 * hex strings (ones that denote negative values). When they work out
756 * the signed hex vs. unsigned hex issue in the Java API, this can be
757 * retired.
758 * @param str the String to parse
759 * @return the long that was written in <code>str</code>
761 private static long fromHexString(String str,long min) {
762 final int hex = 16;
763 final char firstChar = str.charAt(0);
764 final int digit = Character.digit(firstChar,hex);
765 if (digit < hex/2) {
766 return Long.parseLong(str,hex);
767 } else {
768 /* Subtract <code>hex/2</code> from the first digit and flip the sign. */
769 final String posStr = (Character.forDigit(digit-hex/2, hex) +
770 str.substring(1,str.length()));
771 final long offsetLong = Long.parseLong(posStr,hex);
772 return offsetLong+min;
777 * Output a byte in unsigned hexadecimal form, padding with zeroes.
778 * @param s the String representing the byte.
779 * @return the parsed byte
781 public static byte byteFromHexString(String s) {
782 return (byte)fromHexString(s,Byte.MIN_VALUE);
786 * Output a short in unsigned hexadecimal form, padding with zeroes.
787 * @param s the String representing the short
788 * @return the parsed short
790 public static short shortFromHexString(String s) {
791 return (short)fromHexString(s,Short.MIN_VALUE);
795 * Output an int in unsigned hexadecimal form, padding with zeroes.
796 * @param s the String representing the int.
797 * @return the parsed int
799 public static int intFromHexString(String s) {
800 return (int)fromHexString(s,Integer.MIN_VALUE);
804 * Output a long in unsigned hexadecimal form, padding with zeroes.
805 * @param s the String representing the long.
806 * @return the parsed long
808 public static long longFromHexString(String s) {
809 return fromHexString(s,Long.MIN_VALUE);
813 * Decode a long out of a byte-array buffer. (convienience method)
814 * @param pBytes the byte array from which the encoded form should be read
815 * @return long decoded from bytes
817 public static long decodeLong (byte[] pBytes)
818 throws NumberFormatException
820 if (pBytes == null)
822 throw new NumberFormatException("null byte array passed");
824 if (pBytes.length != NumberCodec.LONG_BYTES)
826 throw new NumberFormatException("expecting byte array length of: " +
827 NumberCodec.LONG_BYTES + " got: " + pBytes.length);
829 return NumberCodec.decodeLong(pBytes, 0, pBytes.length);
833 * Encode a long into a byte-array buffer. (convienience method)
834 * @param pLong the long to be encoded
835 * @return encoded bytes of the long
837 public static byte[] encodeLong (long pLong)
839 byte[] bytes = new byte[NumberCodec.LONG_BYTES];
840 NumberCodec.encodeLong(pLong, bytes, 0, bytes.length);
841 return bytes;
845 * Decode a int out of a byte-array buffer. (convienience method)
846 * @param pBytes the byte array from which the encoded form should be read
847 * @return int decoded from bytes
849 public static int decodeInt (byte[] pBytes)
850 throws NumberFormatException
852 if (pBytes == null)
854 throw new NumberFormatException("null byte array passed");
856 if (pBytes.length != NumberCodec.LONG_BYTES)
858 throw new NumberFormatException("expecting byte array length of: " +
859 NumberCodec.INT_BYTES + " got: " + pBytes.length);
861 return NumberCodec.decodeInt(pBytes, 0, pBytes.length);
865 * Encode a int into a byte-array buffer. (convienience method)
866 * @param pInt the int to be encoded
867 * @return encoded bytes of the int
869 public static byte[] encodeInt (int pInt)
870 throws NumberFormatException
872 byte[] bytes = new byte[NumberCodec.INT_BYTES];
873 NumberCodec.encodeInt(pInt, bytes, 0, bytes.length);
874 return bytes;