Added unsigned numbers to java. Added big endian/network byte order utils

This commit is contained in:
nathan 2014-12-18 20:28:56 +01:00
parent ff8c718a6b
commit 97a8207dd7
12 changed files with 2708 additions and 164 deletions

View File

@ -90,3 +90,10 @@
http://www.cs.gmu.edu/~sean/research/mersenne/MersenneTwisterFast.java
Copyright 2003 by Sean Luke
Portions copyright 1993 by Michael Lecuyer
- jOOU, Unsigned Numbers for Java - Apache 2.0 License
https://github.com/jOOQ/jOOU/tree/master/jOOU
Copyright 2011-2013, Lukas Eder, lukas.eder@gmail.com

View File

@ -0,0 +1,493 @@
/*
* Copyright 2014 dorkbox, llc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package dorkbox.util.bytes;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
/**
* This is (mostly) motorola, and is "network byte order".
* This is also the default for Java.
* <p>
* arm is technically bi-endian
*/
public class BigEndian {
// the following are ALL in Bit-Endian (byte[0] is most significant)
// TODO: switch these to big endian. these are a copy of little endian
/** CHAR to and from bytes */
public static class Char_ {
@SuppressWarnings("fallthrough")
public static char from(byte[] bytes, int offset, int bytenum) {
char number = 0;
switch (bytenum) {
case 2: number |= (bytes[offset+0] & 0xFF) << 8;
case 1: number |= (bytes[offset+1] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static char from(byte[] bytes) {
char number = 0;
switch (bytes.length) {
case 2: number |= (bytes[0] & 0xFF) << 8;
case 1: number |= (bytes[1] & 0xFF) << 0;
}
return number;
}
public static char from(byte b0, byte b1) {
return (char) ((b0 & 0xFF) << 8 |
(b1 & 0xFF) << 0);
}
public static byte[] toBytes(char x) {
return new byte[] {(byte) (x >> 8),
(byte) (x >> 0)
};
}
public static char from(ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static char fromStream(InputStream inputStream) throws IOException {
byte[] b = new byte[2];
if (inputStream.read(b) != 2) {
throw new EOFException();
}
return from(b[0], b[1]);
}
}
/** UNSIGNED CHAR to and from bytes */
public static class UChar_ {
@SuppressWarnings("fallthrough")
public static UShort from(byte[] bytes, int offset, int bytenum) {
char number = 0;
switch (bytenum) {
case 2: number |= (bytes[offset+0] & 0xFF) << 8;
case 1: number |= (bytes[offset+1] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static UShort from(byte[] bytes) {
short number = 0;
switch (bytes.length) {
case 2: number |= (bytes[0] & 0xFF) << 8;
case 1: number |= (bytes[1] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
public static UShort from(byte b0, byte b1) {
return UShort.valueOf((short)
((b0 & 0xFF) << 8) |
(b1 & 0xFF) << 0) ;
}
public static byte[] toBytes(UShort x) {
int num = x.intValue();
return new byte[] {(byte) ((num & 0xFF00) >> 8),
(byte) (num & 0x00FF >> 0),
};
}
public static UShort from(ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static UShort fromStream(InputStream inputStream) throws IOException {
byte[] b = new byte[2];
if (inputStream.read(b) != 2) {
throw new EOFException();
}
return from(b[0], b[1]);
}
}
/** SHORT to and from bytes */
public static class Short_ {
@SuppressWarnings("fallthrough")
public static short from(byte[] bytes, int offset, int bytenum) {
short number = 0;
switch (bytenum) {
case 2: number |= (bytes[offset+0] & 0xFF) << 8;
case 1: number |= (bytes[offset+1] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static short from(byte[] bytes) {
short number = 0;
switch (bytes.length) {
case 2: number |= (bytes[0] & 0xFF) << 8;
case 1: number |= (bytes[1] & 0xFF) << 0;
}
return number;
}
public static short from(byte b0, byte b1) {
return (short) ((b0 & 0xFF) << 8 |
(b1 & 0xFF) << 0);
}
public static byte[] toBytes(short x) {
return new byte[] {(byte) (x >> 8),
(byte) (x >> 0)
};
}
public static short from(ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static short fromStream(InputStream inputStream) throws IOException {
byte[] b = new byte[2];
if (inputStream.read(b) != 2) {
throw new EOFException();
}
return from(b[0], b[1]);
}
}
/** UNSIGNED SHORT to and from bytes */
public static class UShort_ {
@SuppressWarnings("fallthrough")
public static UShort from(byte[] bytes, int offset, int bytenum) {
char number = 0;
switch (bytenum) {
case 2: number |= (bytes[offset+0] & 0xFF) << 8;
case 1: number |= (bytes[offset+1] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static UShort from(byte[] bytes) {
short number = 0;
switch (bytes.length) {
case 2: number |= (bytes[0] & 0xFF) << 8;
case 1: number |= (bytes[1] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
public static UShort from(byte b0, byte b1) {
return UShort.valueOf((short)
((b0 & 0xFF) << 8) |
(b1 & 0xFF) << 0) ;
}
public static byte[] toBytes(UShort x) {
int num = x.intValue();
return new byte[] {(byte) ((num & 0xFF00) >> 8),
(byte) (num & 0x00FF >> 0),
};
}
public static UShort from(ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static UShort fromStream(InputStream inputStream) throws IOException {
byte[] b = new byte[2];
if (inputStream.read(b) != 2) {
throw new EOFException();
}
return from(b[0], b[1]);
}
}
/** INT to and from bytes */
public static class Int_ {
@SuppressWarnings("fallthrough")
public static int from(byte[] bytes, int offset, int bytenum) {
int number = 0;
switch (bytenum) {
case 4: number |= (bytes[offset+0] & 0xFF) << 24;
case 3: number |= (bytes[offset+1] & 0xFF) << 16;
case 2: number |= (bytes[offset+2] & 0xFF) << 8;
case 1: number |= (bytes[offset+3] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static int from(byte[] bytes) {
int number = 0;
switch (bytes.length) {
case 4: number |= (bytes[0] & 0xFF) << 24;
case 3: number |= (bytes[1] & 0xFF) << 16;
case 2: number |= (bytes[2] & 0xFF) << 8;
case 1: number |= (bytes[3] & 0xFF) << 0;
}
return number;
}
public static int from(byte b0, byte b1, byte b2, byte b3) {
return (b0 & 0xFF) << 24 |
(b1 & 0xFF) << 16 |
(b2 & 0xFF) << 8 |
(b3 & 0xFF) << 0;
}
public static byte[] toBytes(int x) {
return new byte[] {(byte) (x >> 24),
(byte) (x >> 16),
(byte) (x >> 8),
(byte) (x >> 0)
} ;
}
public static int from(ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get());
}
public static int fromStream(InputStream inputStream) throws IOException {
byte[] b = new byte[4];
if (inputStream.read(b) != 4) {
throw new EOFException();
}
return from(b[0], b[1], b[2], b[3]);
}
}
/** UNSIGNED INT to and from bytes */
public static class UInt_ {
@SuppressWarnings("fallthrough")
public static UInteger from(byte[] bytes, int offset, int bytenum) {
int number = 0;
switch (bytenum) {
case 4: number |= (bytes[offset+0] & 0xFF) << 24;
case 3: number |= (bytes[offset+1] & 0xFF) << 16;
case 2: number |= (bytes[offset+2] & 0xFF) << 8;
case 1: number |= (bytes[offset+3] & 0xFF) << 0;
}
return UInteger.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static UInteger from(byte[] bytes) {
int number = 0;
switch (bytes.length) {
case 4: number |= (bytes[0] & 0xFF) << 24;
case 3: number |= (bytes[1] & 0xFF) << 16;
case 2: number |= (bytes[2] & 0xFF) << 8;
case 1: number |= (bytes[3] & 0xFF) << 0;
}
return UInteger.valueOf(number);
}
public static UInteger from(byte b0, byte b1, byte b2, byte b3) {
int number = (b0 & 0xFF) << 24 |
(b1 & 0xFF) << 16 |
(b2 & 0xFF) << 8 |
(b3 & 0xFF) << 0;
return UInteger.valueOf(number);
}
public static byte[] toBytes(UInteger x) {
long num = x.longValue();
return new byte[] {(byte) ((num & 0xFF000000L) >> 24),
(byte) ((num & 0x00FF0000L) >> 16),
(byte) ((num & 0x0000FF00L) >> 8),
(byte) (num & 0x000000FFL >> 0)
};
}
public static UInteger from(ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get());
}
public static UInteger fromStream(InputStream inputStream) throws IOException {
byte[] b = new byte[4];
if (inputStream.read(b) != 4) {
throw new EOFException();
}
return from(b[0], b[1], b[2], b[3]);
}
}
/** LONG to and from bytes */
public static class Long_ {
@SuppressWarnings("fallthrough")
public static long from(byte[] bytes, int offset, int bytenum) {
long number = 0;
switch (bytenum) {
case 8: number |= (long) (bytes[offset+0] & 0xFF) << 56;
case 7: number |= (long) (bytes[offset+1] & 0xFF) << 48;
case 6: number |= (long) (bytes[offset+2] & 0xFF) << 40;
case 5: number |= (long) (bytes[offset+3] & 0xFF) << 32;
case 4: number |= (long) (bytes[offset+4] & 0xFF) << 24;
case 3: number |= (long) (bytes[offset+5] & 0xFF) << 16;
case 2: number |= (long) (bytes[offset+6] & 0xFF) << 8;
case 1: number |= (long) (bytes[offset+7] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static long from(byte[] bytes) {
long number = 0L;
switch (bytes.length) {
case 8: number |= (long) (bytes[0] & 0xFF) << 56;
case 7: number |= (long) (bytes[1] & 0xFF) << 48;
case 6: number |= (long) (bytes[2] & 0xFF) << 40;
case 5: number |= (long) (bytes[3] & 0xFF) << 32;
case 4: number |= (long) (bytes[4] & 0xFF) << 24;
case 3: number |= (long) (bytes[5] & 0xFF) << 16;
case 2: number |= (long) (bytes[6] & 0xFF) << 8;
case 1: number |= (long) (bytes[7] & 0xFF) << 0;
}
return number;
}
public static long from(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
return (long) (b0 & 0xFF) << 56 |
(long) (b1 & 0xFF) << 48 |
(long) (b2 & 0xFF) << 40 |
(long) (b3 & 0xFF) << 32 |
(long) (b4 & 0xFF) << 24 |
(long) (b5 & 0xFF) << 16 |
(long) (b6 & 0xFF) << 8 |
(long) (b7 & 0xFF) << 0;
}
public static byte[] toBytes (long x) {
return new byte[] {(byte) (x >> 56),
(byte) (x >> 48),
(byte) (x >> 40),
(byte) (x >> 32),
(byte) (x >> 24),
(byte) (x >> 16),
(byte) (x >> 8),
(byte) (x >> 0)
};
}
public static long from(ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
}
public static long fromStream(InputStream inputStream) throws IOException {
byte[] b = new byte[8];
if (inputStream.read(b) != 8) {
throw new EOFException();
}
return from(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
}
}
/** UNSIGNED LONG to and from bytes */
public static class ULong_ {
@SuppressWarnings("fallthrough")
public static ULong from(byte[] bytes, int offset, int bytenum) {
long number = 0;
switch (bytenum) {
case 8: number |= (long) (bytes[offset+0] & 0xFF) << 56;
case 7: number |= (long) (bytes[offset+1] & 0xFF) << 48;
case 6: number |= (long) (bytes[offset+2] & 0xFF) << 40;
case 5: number |= (long) (bytes[offset+3] & 0xFF) << 32;
case 4: number |= (long) (bytes[offset+4] & 0xFF) << 24;
case 3: number |= (long) (bytes[offset+5] & 0xFF) << 16;
case 2: number |= (long) (bytes[offset+6] & 0xFF) << 8;
case 1: number |= (long) (bytes[offset+7] & 0xFF) << 0;
}
return ULong.valueOf(number);
}
public static ULong from(byte[] bytes) {
BigInteger ulong = new BigInteger(1, bytes);
return ULong.valueOf(ulong);
}
public static ULong from(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
byte[] bytes = new byte[] {b0, b1, b2, b3, b4, b5, b6, b7};
BigInteger ulong = new BigInteger(1, bytes);
return ULong.valueOf(ulong);
}
public static byte[] toBytes (ULong x) {
return x.toBigInteger().toByteArray();
}
public static ULong from(ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
}
public static ULong from(InputStream inputStream) throws IOException {
byte[] b = new byte[8];
if (inputStream.read(b) != 8) {
throw new EOFException();
}
return from(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
}
}
}

View File

@ -15,175 +15,273 @@
*/
package dorkbox.util.bytes;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigInteger;
import java.nio.ByteBuffer;
/**
* This is intel/amd/arm arch!
*
* <p>
* arm is technically bi-endian
* <p>
* Network byte order IS big endian, as is Java.
*/
public class LittleEndian {
// the following are ALL in Little-Endian (big is to the right, first byte is least significant, unsigned bytes)
// the following are ALL in Little-Endian (byte[0] is least significant)
/** CHAR to and from bytes */
public static class Char_ {
@SuppressWarnings("fallthrough")
public static final char fromBytes(byte[] bytes) {
public static char from(byte[] bytes, int offset, int bytenum) {
char number = 0;
switch (bytes.length) {
case 2: number += (bytes[1] & 0xFF) << 8;
case 1: number += (bytes[0] & 0xFF) << 0;
switch (bytenum) {
case 2: number |= (bytes[offset+1] & 0xFF) << 8;
case 1: number |= (bytes[offset+0] & 0xFF) << 0;
}
return number;
}
public static final char fromBytes(byte b0, byte b1) {
@SuppressWarnings("fallthrough")
public static char from(byte[] bytes) {
char number = 0;
switch (bytes.length) {
case 2: number |= (bytes[1] & 0xFF) << 8;
case 1: number |= (bytes[0] & 0xFF) << 0;
}
return number;
}
public static char from(byte b0, byte b1) {
return (char) ((b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0);
}
public static final byte[] toBytes(char x) {
public static byte[] toBytes(char x) {
return new byte[] {(byte) (x >> 0),
(byte) (x >> 8)
};
}
public static final int fromBytes(ByteBuffer buff) {
return fromBytes(buff.get(), buff.get());
public static char from(ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static char from(InputStream inputStream) throws IOException {
byte[] b = new byte[2];
if (inputStream.read(b) != 2) {
throw new EOFException();
}
return from(b[0], b[1]);
}
}
/** CHAR to and from bytes */
/** UNSIGNED CHAR to and from bytes */
public static class UChar_ {
@SuppressWarnings("fallthrough")
public static final char fromBytes(byte[] bytes) {
public static UShort from(byte[] bytes, int offset, int bytenum) {
char number = 0;
switch (bytes.length) {
case 2: number += (bytes[1] & 0xFF) << 8;
case 1: number += (bytes[0] & 0xFF) << 0;
switch (bytenum) {
case 2: number |= (bytes[offset+1] & 0xFF) << 8;
case 1: number |= (bytes[offset+0] & 0xFF) << 0;
}
return number;
return UShort.valueOf(number);
}
public static final char fromBytes(byte b0, byte b1) {
return (char) ((b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0);
@SuppressWarnings("fallthrough")
public static UShort from(byte[] bytes) {
short number = 0;
switch (bytes.length) {
case 2: number |= (bytes[1] & 0xFF) << 8;
case 1: number |= (bytes[0] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
public static UShort from(byte b0, byte b1) {
return UShort.valueOf((short)
((b1 & 0xFF) << 8) |
(b0 & 0xFF) << 0) ;
}
public static final byte[] toBytes(char x) {
return new byte[] {(byte) (x >> 8),
(byte) (x >> 0)
public static byte[] toBytes(UShort x) {
int num = x.intValue();
return new byte[] {(byte) (num & 0x00FF >> 0),
(byte) ((num & 0xFF00) >> 8)
};
}
public static final int fromBytes(ByteBuffer buff) {
return fromBytes(buff.get(), buff.get());
public static UShort from(ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static UShort from(InputStream inputStream) throws IOException {
byte[] b = new byte[2];
if (inputStream.read(b) != 2) {
throw new EOFException();
}
return from(b[0], b[1]);
}
}
/** SHORT to and from bytes */
public static class Short_ {
@SuppressWarnings("fallthrough")
public static final short fromBytes(byte[] bytes) {
public static short from(byte[] bytes, int offset, int bytenum) {
short number = 0;
switch (bytes.length) {
case 2: number += (bytes[1] & 0xFF) << 8;
case 1: number += (bytes[0] & 0xFF) << 0;
switch (bytenum) {
case 2: number |= (bytes[offset+1] & 0xFF) << 8;
case 1: number |= (bytes[offset+0] & 0xFF) << 0;
}
return number;
}
public static final short fromBytes(byte b0, byte b1) {
@SuppressWarnings("fallthrough")
public static short from(byte[] bytes) {
short number = 0;
switch (bytes.length) {
case 2: number |= (bytes[1] & 0xFF) << 8;
case 1: number |= (bytes[0] & 0xFF) << 0;
}
return number;
}
public static short from(byte b0, byte b1) {
return (short) ((b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0);
}
public static final byte[] toBytes(short x) {
public static byte[] toBytes(short x) {
return new byte[] {(byte) (x >> 0),
(byte) (x >> 8)
};
}
public static final int fromBytes(ByteBuffer buff) {
return fromBytes(buff.get(), buff.get());
public static short from(ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static short from(InputStream inputStream) throws IOException {
byte[] b = new byte[2];
if (inputStream.read(b) != 2) {
throw new EOFException();
}
return from(b[0], b[1]);
}
}
/** SHORT to and from bytes */
/** UNSIGNED SHORT to and from bytes */
public static class UShort_ {
@SuppressWarnings("fallthrough")
public static final short fromBytes(byte[] bytes) {
short number = 0;
switch (bytes.length) {
case 2: number += (bytes[1] & 0xFF) << 8;
case 1: number += (bytes[0] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static short fromBytes(byte[] bytes, int offset, int bytenum) {
public static UShort from(byte[] bytes, int offset, int bytenum) {
short number = 0;
switch (bytenum) {
case 2: number += (bytes[offset+1] & 0xFF) << 8;
case 1: number += (bytes[offset+0] & 0xFF) << 0;
case 2: number |= (bytes[offset+1] & 0xFF) << 8;
case 1: number |= (bytes[offset+0] & 0xFF) << 0;
}
return number;
return UShort.valueOf(number);
}
public static final short fromBytes(byte b0, byte b1) {
return (short) ((b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0);
@SuppressWarnings("fallthrough")
public static UShort from(byte[] bytes) {
short number = 0;
switch (bytes.length) {
case 2: number |= (bytes[1] & 0xFF) << 8;
case 1: number |= (bytes[0] & 0xFF) << 0;
}
return UShort.valueOf(number);
}
public static UShort from(byte b0, byte b1) {
return UShort.valueOf((short)
((b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0));
}
public static final byte[] toBytes(short x) {
return new byte[] {(byte) (x >> 0),
(byte) (x >> 8)
public static byte[] toBytes(UShort x) {
int num = x.intValue();
return new byte[] {(byte) (num & 0x00FF >> 0),
(byte) ((num & 0xFF00) >> 8)
};
}
public static final int fromBytes(ByteBuffer buff) {
return fromBytes(buff.get(), buff.get());
public static UShort from(ByteBuffer buff) {
return from(buff.get(), buff.get());
}
public static UShort from(InputStream inputStream) throws IOException {
byte[] b = new byte[2];
if (inputStream.read(b) != 2) {
throw new EOFException();
}
return from(b[0], b[1]);
}
}
/** INT to and from bytes */
public static class Int_ {
@SuppressWarnings("fallthrough")
public static final int fromBytes(byte[] bytes) {
public static int from(byte[] bytes, int offset, int bytenum) {
int number = 0;
switch (bytes.length) {
case 4: number += (bytes[3] & 0xFF) << 24;
case 3: number += (bytes[2] & 0xFF) << 16;
case 2: number += (bytes[1] & 0xFF) << 8;
case 1: number += (bytes[0] & 0xFF) << 0;
switch (bytenum) {
case 4: number |= (bytes[offset+3] & 0xFF) << 24;
case 3: number |= (bytes[offset+2] & 0xFF) << 16;
case 2: number |= (bytes[offset+1] & 0xFF) << 8;
case 1: number |= (bytes[offset+0] & 0xFF) << 0;
}
return number;
}
public static final int fromBytes(byte b0, byte b1, byte b2, byte b3) {
@SuppressWarnings("fallthrough")
public static int from(byte[] bytes) {
int number = 0;
switch (bytes.length) {
case 4: number |= (bytes[3] & 0xFF) << 24;
case 3: number |= (bytes[2] & 0xFF) << 16;
case 2: number |= (bytes[1] & 0xFF) << 8;
case 1: number |= (bytes[0] & 0xFF) << 0;
}
return number;
}
public static int from(byte b0, byte b1, byte b2, byte b3) {
return (b3 & 0xFF) << 24 |
(b2 & 0xFF) << 16 |
(b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0;
}
public static final byte[] toBytes(int x) {
public static byte[] toBytes(int x) {
return new byte[] {(byte) (x >> 0),
(byte) (x >> 8),
(byte) (x >> 16),
@ -191,83 +289,122 @@ public class LittleEndian {
} ;
}
public static final int fromBytes(ByteBuffer buff) {
return fromBytes(buff.get(), buff.get(), buff.get(), buff.get());
public static int from(ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get());
}
public static int from(InputStream inputStream) throws IOException {
byte[] b = new byte[4];
if (inputStream.read(b) != 4) {
throw new EOFException();
}
return from(b[0], b[1], b[2], b[3]);
}
}
/** INT to and from bytes */
/** UNSIGNED INT to and from bytes */
public static class UInt_ {
@SuppressWarnings("fallthrough")
public static final int fromBytes(byte[] bytes) {
int number = 0;
switch (bytes.length) {
case 4: number += (bytes[3] & 0xFF) << 24;
case 3: number += (bytes[2] & 0xFF) << 16;
case 2: number += (bytes[1] & 0xFF) << 8;
case 1: number += (bytes[0] & 0xFF) << 0;
}
return number;
}
@SuppressWarnings("fallthrough")
public static int fromBytes(byte[] bytes, int offset, int bytenum) {
public static UInteger from(byte[] bytes, int offset, int bytenum) {
int number = 0;
switch (bytenum) {
case 4: number += (bytes[offset+3] & 0xFF) << 24;
case 3: number += (bytes[offset+2] & 0xFF) << 16;
case 2: number += (bytes[offset+1] & 0xFF) << 8;
case 1: number += (bytes[offset+0] & 0xFF) << 0;
case 4: number |= (bytes[offset+3] & 0xFF) << 24;
case 3: number |= (bytes[offset+2] & 0xFF) << 16;
case 2: number |= (bytes[offset+1] & 0xFF) << 8;
case 1: number |= (bytes[offset+0] & 0xFF) << 0;
}
return number;
return UInteger.valueOf(number);
}
public static final int fromBytes(byte b0, byte b1, byte b2, byte b3) {
return (b3 & 0xFF) << 24 |
(b2 & 0xFF) << 16 |
(b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0;
@SuppressWarnings("fallthrough")
public static UInteger from(byte[] bytes) {
int number = 0;
switch (bytes.length) {
case 4: number |= (bytes[3] & 0xFF) << 24;
case 3: number |= (bytes[2] & 0xFF) << 16;
case 2: number |= (bytes[1] & 0xFF) << 8;
case 1: number |= (bytes[0] & 0xFF) << 0;
}
return UInteger.valueOf(number);
}
public static final byte[] toBytes(int x) {
return new byte[] {(byte) (x >> 0),
(byte) (x >> 8),
(byte) (x >> 16),
(byte) (x >> 24)
} ;
public static UInteger from(byte b0, byte b1, byte b2, byte b3) {
int number = (b3 & 0xFF) << 24 |
(b2 & 0xFF) << 16 |
(b1 & 0xFF) << 8 |
(b0 & 0xFF) << 0;
return UInteger.valueOf(number);
}
public static final int fromBytes(ByteBuffer buff) {
return fromBytes(buff.get(), buff.get(), buff.get(), buff.get());
public static byte[] toBytes(UInteger x) {
long num = x.longValue();
return new byte[] {(byte) (num & 0x000000FFL >> 0),
(byte) ((num & 0x0000FF00L) >> 8),
(byte) ((num & 0x00FF0000L) >> 16),
(byte) ((num & 0xFF000000L) >> 24)
};
}
public static UInteger from(ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get());
}
public static UInteger from(InputStream inputStream) throws IOException {
byte[] b = new byte[4];
if (inputStream.read(b) != 4) {
throw new EOFException();
}
return from(b[0], b[1], b[2], b[3]);
}
}
/** LONG to and from bytes */
public static class Long_ {
@SuppressWarnings("fallthrough")
public static final long fromBytes(byte[] bytes) {
long number = 0L;
public static long from(byte[] bytes, int offset, int bytenum) {
long number = 0;
switch (bytes.length) {
case 8: number += (long) (bytes[7] & 0xFF) << 56;
case 7: number += (long) (bytes[6] & 0xFF) << 48;
case 6: number += (long) (bytes[5] & 0xFF) << 40;
case 5: number += (long) (bytes[4] & 0xFF) << 32;
case 4: number += (long) (bytes[3] & 0xFF) << 24;
case 3: number += (long) (bytes[2] & 0xFF) << 16;
case 2: number += (long) (bytes[1] & 0xFF) << 8;
case 1: number += (long) (bytes[0] & 0xFF) << 0;
switch (bytenum) {
case 8: number |= (long) (bytes[offset+7] & 0xFF) << 56;
case 7: number |= (long) (bytes[offset+6] & 0xFF) << 48;
case 6: number |= (long) (bytes[offset+5] & 0xFF) << 40;
case 5: number |= (long) (bytes[offset+4] & 0xFF) << 32;
case 4: number |= (long) (bytes[offset+3] & 0xFF) << 24;
case 3: number |= (long) (bytes[offset+2] & 0xFF) << 16;
case 2: number |= (long) (bytes[offset+1] & 0xFF) << 8;
case 1: number |= (long) (bytes[offset+0] & 0xFF) << 0;
}
return number;
}
public static final long fromBytes(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
@SuppressWarnings("fallthrough")
public static long from(byte[] bytes) {
long number = 0L;
switch (bytes.length) {
case 8: number |= (long) (bytes[7] & 0xFF) << 56;
case 7: number |= (long) (bytes[6] & 0xFF) << 48;
case 6: number |= (long) (bytes[5] & 0xFF) << 40;
case 5: number |= (long) (bytes[4] & 0xFF) << 32;
case 4: number |= (long) (bytes[3] & 0xFF) << 24;
case 3: number |= (long) (bytes[2] & 0xFF) << 16;
case 2: number |= (long) (bytes[1] & 0xFF) << 8;
case 1: number |= (long) (bytes[0] & 0xFF) << 0;
}
return number;
}
public static long from(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
return (long) (b7 & 0xFF) << 56 |
(long) (b6 & 0xFF) << 48 |
(long) (b5 & 0xFF) << 40 |
@ -278,7 +415,7 @@ public class LittleEndian {
(long) (b0 & 0xFF) << 0;
}
public static final byte[] toBytes (long x) {
public static byte[] toBytes (long x) {
return new byte[] {(byte) (x >> 0),
(byte) (x >> 8),
(byte) (x >> 16),
@ -290,74 +427,83 @@ public class LittleEndian {
};
}
public static final long fromBytes(ByteBuffer buff) {
return fromBytes(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
public static long from(ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
}
public static long from(InputStream inputStream) throws IOException {
byte[] b = new byte[8];
if (inputStream.read(b) != 8) {
throw new EOFException();
}
return from(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
}
}
/** LONG to and from bytes */
/** UNSIGNED LONG to and from bytes */
public static class ULong_ {
@SuppressWarnings("fallthrough")
public static int fromBytes(byte[] bytes, int offset, int bytenum) {
int number = 0;
public static ULong from(byte[] bytes, int offset, int bytenum) {
long number = 0;
switch (bytenum) {
case 8: number += (long) (bytes[offset+7] & 0xFF) << 56;
case 7: number += (long) (bytes[offset+6] & 0xFF) << 48;
case 6: number += (long) (bytes[offset+5] & 0xFF) << 40;
case 5: number += (long) (bytes[offset+4] & 0xFF) << 32;
case 4: number += (long) (bytes[offset+3] & 0xFF) << 24;
case 3: number += (long) (bytes[offset+2] & 0xFF) << 16;
case 2: number += (long) (bytes[offset+1] & 0xFF) << 8;
case 1: number += (long) (bytes[offset+0] & 0xFF) << 0;
case 8: number |= (long) (bytes[offset+7] & 0xFF) << 56;
case 7: number |= (long) (bytes[offset+6] & 0xFF) << 48;
case 6: number |= (long) (bytes[offset+5] & 0xFF) << 40;
case 5: number |= (long) (bytes[offset+4] & 0xFF) << 32;
case 4: number |= (long) (bytes[offset+3] & 0xFF) << 24;
case 3: number |= (long) (bytes[offset+2] & 0xFF) << 16;
case 2: number |= (long) (bytes[offset+1] & 0xFF) << 8;
case 1: number |= (long) (bytes[offset+0] & 0xFF) << 0;
}
return number;
return ULong.valueOf(number);
}
@SuppressWarnings("fallthrough")
public static final long fromBytes(byte[] bytes) {
long number = 0L;
public static ULong from(byte[] bytes) {
BigInteger ulong = new BigInteger(1, bytes);
return ULong.valueOf(ulong);
}
switch (bytes.length) {
case 8: number += (long) (bytes[7] & 0xFF) << 56;
case 7: number += (long) (bytes[6] & 0xFF) << 48;
case 6: number += (long) (bytes[5] & 0xFF) << 40;
case 5: number += (long) (bytes[4] & 0xFF) << 32;
case 4: number += (long) (bytes[3] & 0xFF) << 24;
case 3: number += (long) (bytes[2] & 0xFF) << 16;
case 2: number += (long) (bytes[1] & 0xFF) << 8;
case 1: number += (long) (bytes[0] & 0xFF) << 0;
public static ULong from(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
byte[] bytes = new byte[] {b7, b6, b5, b4, b3, b2, b1, b0};
BigInteger ulong = new BigInteger(1, bytes);
return ULong.valueOf(ulong);
}
public static byte[] toBytes (ULong x) {
byte[] bytes = new byte[8];
int offset = 0;
byte temp_byte[] = x.toBigInteger().toByteArray();
int array_count = temp_byte.length-1;
for (int i=7;i>=0;i--) {
if (array_count >= 0) {
bytes[offset] = temp_byte[array_count];
} else {
bytes[offset] = (byte)00;
}
offset++;
array_count--;
}
return number;
return bytes;
}
public static final long fromBytes(byte b0, byte b1, byte b2, byte b3, byte b4, byte b5, byte b6, byte b7) {
return (long) (b7 & 0xFF) << 56 |
(long) (b6 & 0xFF) << 48 |
(long) (b5 & 0xFF) << 40 |
(long) (b4 & 0xFF) << 32 |
(long) (b3 & 0xFF) << 24 |
(long) (b2 & 0xFF) << 16 |
(long) (b1 & 0xFF) << 8 |
(long) (b0 & 0xFF) << 0;
public static ULong from(ByteBuffer buff) {
return from(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
}
public static final byte[] toBytes (long x) {
return new byte[] {(byte) (x >> 0),
(byte) (x >> 8),
(byte) (x >> 16),
(byte) (x >> 24),
(byte) (x >> 32),
(byte) (x >> 40),
(byte) (x >> 48),
(byte) (x >> 56),
};
}
public static ULong from(InputStream inputStream) throws IOException {
byte[] b = new byte[8];
if (inputStream.read(b) != 8) {
throw new EOFException();
}
public static final long fromBytes(ByteBuffer buff) {
return fromBytes(buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get(), buff.get());
return from(b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
}
}
}

View File

@ -0,0 +1,304 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util.bytes;
import java.io.ObjectStreamException;
import java.math.BigInteger;
/**
* The <code>unsigned byte</code> type
*
* @author Lukas Eder
* @author Ed Schaller
*/
public final class UByte extends UNumber implements Comparable<UByte> {
/**
* Generated UID
*/
private static final long serialVersionUID = -6821055240959745390L;
/**
* Cached values
*/
private static final UByte[] VALUES = mkValues();
/**
* A constant holding the minimum value an <code>unsigned byte</code> can
* have, 0.
*/
public static final short MIN_VALUE = 0x00;
/**
* A constant holding the maximum value an <code>unsigned byte</code> can
* have, 2<sup>8</sup>-1.
*/
public static final short MAX_VALUE = 0xff;
/**
* The value modelling the content of this <code>unsigned byte</code>
*/
private final short value;
/**
* Generate a cached value for each byte value.
*
* @return Array of cached values for UByte.
*/
private static final UByte[] mkValues() {
UByte[] ret = new UByte[256];
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
ret[i & MAX_VALUE] = new UByte((byte) i);
}
return ret;
}
/**
* Get an instance of an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned byte</code>.
*/
public static UByte valueOf(String value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(Short.parseShort(value)));
}
/**
* Get an instance of an <code>unsigned byte</code> by masking it with
* <code>0xFF</code> i.e. <code>(byte) -1</code> becomes
* <code>(ubyte) 255</code>
*/
public static UByte valueOf(byte value) {
return valueOfUnchecked((short) (value & MAX_VALUE));
}
/**
* Get the value of a short without checking the value.
*/
private static UByte valueOfUnchecked(short value) throws NumberFormatException {
return VALUES[value & MAX_VALUE];
}
/**
* Get an instance of an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
public static UByte valueOf(short value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(value));
}
/**
* Get an instance of an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
public static UByte valueOf(int value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(value));
}
/**
* Get an instance of an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
public static UByte valueOf(long value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(value));
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
private UByte(long value) throws NumberFormatException {
this.value = rangeCheck(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
private UByte(int value) throws NumberFormatException {
this.value = rangeCheck(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
private UByte(short value) throws NumberFormatException {
this.value = rangeCheck(value);
}
/**
* Create an <code>unsigned byte</code> by masking it with <code>0xFF</code>
* i.e. <code>(byte) -1</code> becomes <code>(ubyte) 255</code>
*/
private UByte(byte value) {
this.value = (short) (value & MAX_VALUE);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned byte</code>.
*/
private UByte(String value) throws NumberFormatException {
this.value = rangeCheck(Short.parseShort(value));
}
/**
* Throw exception if value out of range (short version)
*
* @param value Value to check
* @return value if it is in range
* @throws NumberFormatException if value is out of range
*/
private static short rangeCheck(short value) throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE) {
throw new NumberFormatException("Value is out of range : " + value);
}
return value;
}
/**
* Throw exception if value out of range (int version)
*
* @param value Value to check
* @return value if it is in range
* @throws NumberFormatException if value is out of range
*/
private static short rangeCheck(int value) throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE) {
throw new NumberFormatException("Value is out of range : " + value);
}
return (short) value;
}
/**
* Throw exception if value out of range (long version)
*
* @param value Value to check
* @return value if it is in range
* @throws NumberFormatException if value is out of range
*/
private static short rangeCheck(long value) throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE) {
throw new NumberFormatException("Value is out of range : " + value);
}
return (short) value;
}
/**
* Replace version read through deserialization with cached version. Note
* that this does not use the {@link #valueOfUnchecked(short)} as we have no
* guarantee that the value from the stream is valid.
*
* @return cached instance of this object's value
* @throws ObjectStreamException
*/
private Object readResolve() throws ObjectStreamException {
return valueOf(this.value);
}
@Override
public int intValue() {
return this.value;
}
@Override
public long longValue() {
return this.value;
}
@Override
public float floatValue() {
return this.value;
}
@Override
public double doubleValue() {
return this.value;
}
@Override
public int hashCode() {
return Short.valueOf(this.value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof UByte) {
return this.value == ((UByte) obj).value;
}
return false;
}
@Override
public String toString() {
return Short.valueOf(this.value).toString();
}
@Override
public String toHexString() {
return Integer.toHexString(this.value);
}
@Override
public int compareTo(UByte o) {
return this.value < o.value ? -1 : this.value == o.value ? 0 : 1;
}
@Override
public BigInteger toBigInteger() {
return BigInteger.valueOf(this.value);
}
}

View File

@ -0,0 +1,333 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util.bytes;
import java.io.ObjectStreamException;
/**
* The <code>unsigned int</code> type
*
* @author Lukas Eder
* @author Ed Schaller
*/
public final class UInteger extends UNumber implements Comparable<UInteger> {
private static final Class<UInteger> CLASS = UInteger.class;
private static final String CLASS_NAME = CLASS.getName();
/**
* System property name for the property to set the size of the pre-cache.
*/
private static final String PRECACHE_PROPERTY = CLASS_NAME + ".precacheSize";
/**
* Default size for the value cache.
*/
private static final int DEFAULT_PRECACHE_SIZE = 256;
/**
* Generated UID
*/
private static final long serialVersionUID = -6821055240959745390L;
/**
* Cached values
*/
private static final UInteger[] VALUES = mkValues();
/**
* A constant holding the minimum value an <code>unsigned int</code> can
* have, 0.
*/
public static final long MIN_VALUE = 0x00000000;
/**
* A constant holding the maximum value an <code>unsigned int</code> can
* have, 2<sup>32</sup>-1.
*/
public static final long MAX_VALUE = 0xffffffffL;
/**
* The value modelling the content of this <code>unsigned int</code>
*/
private final long value;
/**
* Figure out the size of the precache.
*
* @return The parsed value of the system property
* {@link #PRECACHE_PROPERTY} or {@link #DEFAULT_PRECACHE_SIZE} if
* the property is not set, not a number or retrieving results in a
* {@link SecurityException}. If the parsed value is zero or
* negative no cache will be created. If the value is larger than
* {@link Integer#MAX_VALUE} then Integer#MAX_VALUE will be used.
*/
private static final int getPrecacheSize() {
String prop = null;
long propParsed;
try {
prop = System.getProperty(PRECACHE_PROPERTY);
}
catch (SecurityException e) {
// security manager stopped us so use default
// FIXME: should we log this somewhere?
return DEFAULT_PRECACHE_SIZE;
}
if (prop == null) {
return DEFAULT_PRECACHE_SIZE;
}
if (prop.length() <= 0) {
// empty value
// FIXME: should we log this somewhere?
return DEFAULT_PRECACHE_SIZE;
}
try {
propParsed = Long.parseLong(prop);
}
catch (NumberFormatException e) {
// not a valid number
// FIXME: should we log this somewhere?
return DEFAULT_PRECACHE_SIZE;
}
// treat negative value as no cache...
if (propParsed < 0) {
return 0;
}
if (propParsed > Integer.MAX_VALUE) {
// FIXME: should we log this somewhere
return Integer.MAX_VALUE;
}
return (int) propParsed;
}
/**
* Generate a cached value for initial unsigned integer values.
*
* @return Array of cached values for UInteger
*/
private static final UInteger[] mkValues() {
int precacheSize = getPrecacheSize();
UInteger[] ret;
if (precacheSize <= 0) {
return null;
}
ret = new UInteger[precacheSize];
for (int i = 0; i < precacheSize; i++) {
ret[i] = new UInteger(i);
}
return ret;
}
/**
* Unchecked internal constructor. This serves two purposes: first it allows
* {@link #UInteger(long)} to stay deprecated without warnings and second
* constructor without unnecessary value checks.
*
* @param value The value to wrap
* @param unused Unused paramater to distinguish between this and the
* deprecated public constructor.
*/
private UInteger(long value, boolean unused) {
this.value = value;
}
/**
* Retrieve a cached value.
*
* @param value Cached value to retrieve
* @return Cached value if one exists. Null otherwise.
*/
private static UInteger getCached(long value) {
if (VALUES != null && value < VALUES.length) {
return VALUES[(int) value];
}
return null;
}
/**
* Get the value of a long without checking the value.
*/
private static UInteger valueOfUnchecked(long value) {
UInteger cached;
if ((cached = getCached(value)) != null) {
return cached;
}
return new UInteger(value, true);
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned int</code>.
*/
public static UInteger valueOf(String value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(Long.parseLong(value)));
}
/**
* Create an <code>unsigned int</code> by masking it with
* <code>0xFFFFFFFF</code> i.e. <code>(int) -1</code> becomes
* <code>(uint) 4294967295</code>
*/
public static UInteger valueOf(int value) {
return valueOfUnchecked(value & MAX_VALUE);
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
*/
public static UInteger valueOf(long value) throws NumberFormatException {
return valueOfUnchecked(rangeCheck(value));
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned int</code>
*/
private UInteger(long value) throws NumberFormatException {
this.value = rangeCheck(value);
}
/**
* Create an <code>unsigned int</code> by masking it with
* <code>0xFFFFFFFF</code> i.e. <code>(int) -1</code> becomes
* <code>(uint) 4294967295</code>
*/
private UInteger(int value) {
this.value = value & MAX_VALUE;
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned int</code>.
*/
private UInteger(String value) throws NumberFormatException {
this.value = rangeCheck(Long.parseLong(value));
}
/**
* Throw exception if value out of range (long version)
*
* @param value Value to check
* @return value if it is in range
* @throws NumberFormatException if value is out of range
*/
private static long rangeCheck(long value) throws NumberFormatException {
if (value < MIN_VALUE || value > MAX_VALUE) {
throw new NumberFormatException("Value is out of range : " + value);
}
return value;
}
/**
* Replace version read through deserialization with cached version.
*
* @return cached instance of this object's value if one exists, otherwise
* this object
* @throws ObjectStreamException
*/
private Object readResolve() throws ObjectStreamException {
UInteger cached;
// the value read could be invalid so check it
rangeCheck(this.value);
if ((cached = getCached(this.value)) != null) {
return cached;
}
return this;
}
@Override
public int intValue() {
return (int) this.value;
}
@Override
public long longValue() {
return this.value;
}
@Override
public float floatValue() {
return this.value;
}
@Override
public double doubleValue() {
return this.value;
}
@Override
public int hashCode() {
return Long.valueOf(this.value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj instanceof UInteger) {
return this.value == ((UInteger) obj).value;
}
return false;
}
@Override
public String toString() {
return Long.valueOf(this.value).toString();
}
public String toHexString() {
return Long.toHexString(this.value);
}
@Override
public int compareTo(UInteger o) {
return this.value < o.value ? -1 : this.value == o.value ? 0 : 1;
}
}

View File

@ -0,0 +1,203 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util.bytes;
import java.math.BigInteger;
/**
* The <code>unsigned long</code> type
*
* @author Lukas Eder
*/
public final class ULong extends UNumber implements Comparable<ULong> {
/**
* Generated UID
*/
private static final long serialVersionUID = -6821055240959745390L;
/**
* A constant holding the minimum value an <code>unsigned long</code> can
* have, 0.
*/
public static final BigInteger MIN_VALUE = BigInteger.ZERO;
/**
* A constant holding the maximum value an <code>unsigned long</code> can
* have, 2<sup>64</sup>-1.
*/
public static final BigInteger MAX_VALUE = new BigInteger("18446744073709551615");
/**
* A constant holding the maximum value + 1 an <code>signed long</code> can
* have, 2<sup>63</sup>.
*/
public static final BigInteger MAX_VALUE_LONG = new BigInteger("9223372036854775808");
/**
* The value modelling the content of this <code>unsigned long</code>
*/
private final BigInteger value;
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned long</code>.
*/
public static ULong valueOf(String value) throws NumberFormatException {
return new ULong(value);
}
/**
* Create an <code>unsigned long</code> by masking it with
* <code>0xFFFFFFFFFFFFFFFF</code> i.e. <code>(long) -1</code> becomes
* <code>(uint) 18446744073709551615</code>
*/
public static ULong valueOf(long value) {
return new ULong(value);
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned long</code>
*/
public static ULong valueOf(BigInteger value) throws NumberFormatException {
return new ULong(value);
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned long</code>
*/
private ULong(BigInteger value) throws NumberFormatException {
this.value = value;
rangeCheck();
}
/**
* Create an <code>unsigned long</code> by masking it with
* <code>0xFFFFFFFFFFFFFFFF</code> i.e. <code>(long) -1</code> becomes
* <code>(uint) 18446744073709551615</code>
*/
private ULong(long value) {
if (value >= 0) {
this.value = BigInteger.valueOf(value);
}
else {
this.value = BigInteger.valueOf(value & Long.MAX_VALUE).add(MAX_VALUE_LONG);
}
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned long</code>.
*/
private ULong(String value) throws NumberFormatException {
this.value = new BigInteger(value);
rangeCheck();
}
private void rangeCheck() throws NumberFormatException {
if (this.value.compareTo(MIN_VALUE) < 0 || this.value.compareTo(MAX_VALUE) > 0) {
throw new NumberFormatException("Value is out of range : " + this.value);
}
}
@Override
public int intValue() {
return this.value.intValue();
}
@Override
public long longValue() {
return this.value.longValue();
}
@Override
public float floatValue() {
return this.value.floatValue();
}
@Override
public double doubleValue() {
return this.value.doubleValue();
}
@Override
public int hashCode() {
return this.value.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ULong) {
return this.value.equals(((ULong) obj).value);
}
return false;
}
/**
* Get this number as a {@link BigInteger}. This is a convenience method for
* calling <code>new BigInteger(toString())</code>
*/
@Override
public BigInteger toBigInteger() {
return this.value;
}
@Override
public String toString() {
return this.value.toString();
}
@Override
public String toHexString() {
return this.value.toString(16);
}
@Override
public int compareTo(ULong o) {
return this.value.compareTo(o.value);
}
}

View File

@ -0,0 +1,64 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util.bytes;
import java.math.BigInteger;
/**
* A base type for unsigned numbers.
*
* @author Lukas Eder
*/
public abstract class UNumber extends Number {
/**
* Generated UID
*/
private static final long serialVersionUID = -7666221938815339843L;
/**
* Converts this number to a hex string representation
*/
public abstract String toHexString();
/**
* Get this number as a {@link BigInteger}. This is a convenience method for
* calling <code>new BigInteger(toString())</code>
*/
public BigInteger toBigInteger() {
return new BigInteger(toString());
}
}

View File

@ -0,0 +1,181 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util.bytes;
/**
* The <code>unsigned short</code> type
*
* @author Lukas Eder
*/
public final class UShort extends UNumber implements Comparable<UShort> {
/**
* Generated UID
*/
private static final long serialVersionUID = -6821055240959745390L;
/**
* A constant holding the minimum value an <code>unsigned short</code> can
* have, 0.
*/
public static final int MIN_VALUE = 0x0000;
/**
* A constant holding the maximum value an <code>unsigned short</code> can
* have, 2<sup>16</sup>-1.
*/
public static final int MAX_VALUE = 0xffff;
/**
* The value modelling the content of this <code>unsigned short</code>
*/
private final int value;
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned short</code>.
*/
public static UShort valueOf(String value) throws NumberFormatException {
return new UShort(value);
}
/**
* Create an <code>unsigned short</code> by masking it with
* <code>0xFFFF</code> i.e. <code>(short) -1</code> becomes
* <code>(ushort) 65535</code>
*/
public static UShort valueOf(short value) {
return new UShort(value);
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned short</code>
*/
public static UShort valueOf(int value) throws NumberFormatException {
return new UShort(value);
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned short</code>
*/
private UShort(int value) throws NumberFormatException {
this.value = value;
rangeCheck();
}
/**
* Create an <code>unsigned short</code> by masking it with
* <code>0xFFFF</code> i.e. <code>(short) -1</code> becomes
* <code>(ushort) 65535</code>
*/
private UShort(short value) {
this.value = value & MAX_VALUE;
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned short</code>.
*/
private UShort(String value) throws NumberFormatException {
this.value = Integer.parseInt(value);
rangeCheck();
}
private void rangeCheck() throws NumberFormatException {
if (this.value < MIN_VALUE || this.value > MAX_VALUE) {
throw new NumberFormatException("Value is out of range : " + this.value);
}
}
@Override
public int intValue() {
return this.value;
}
@Override
public long longValue() {
return this.value;
}
@Override
public float floatValue() {
return this.value;
}
@Override
public double doubleValue() {
return this.value;
}
@Override
public int hashCode() {
return Integer.valueOf(this.value).hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof UShort) {
return this.value == ((UShort) obj).value;
}
return false;
}
@Override
public String toString() {
return Integer.valueOf(this.value).toString();
}
@Override
public String toHexString() {
return Integer.toHexString(this.value);
}
@Override
public int compareTo(UShort o) {
return this.value < o.value ? -1 : this.value == o.value ? 0 : 1;
}
}

View File

@ -0,0 +1,208 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util.bytes;
import java.math.BigInteger;
/**
* A utility class for static access to unsigned number functionality.
* <p>
* It essentially contains factory methods for unsigned number wrappers. In
* future versions, it will also contain some arithmetic methods, handling
* regular arithmetic and bitwise operations
*
* @author Lukas Eder
*/
public final class Unsigned {
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned byte</code>.
* @see UByte#valueOf(String)
*/
public static UByte ubyte(String value) throws NumberFormatException {
return value == null ? null : UByte.valueOf(value);
}
/**
* Create an <code>unsigned byte</code> by masking it with <code>0xFF</code>
* i.e. <code>(byte) -1</code> becomes <code>(ubyte) 255</code>
*
* @see UByte#valueOf(byte)
*/
public static UByte ubyte(byte value) {
return UByte.valueOf(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
* @see UByte#valueOf(short)
*/
public static UByte ubyte(short value) throws NumberFormatException {
return UByte.valueOf(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
* @see UByte#valueOf(short)
*/
public static UByte ubyte(int value) throws NumberFormatException {
return UByte.valueOf(value);
}
/**
* Create an <code>unsigned byte</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned byte</code>
* @see UByte#valueOf(short)
*/
public static UByte ubyte(long value) throws NumberFormatException {
return UByte.valueOf(value);
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned short</code>.
* @see UShort#valueOf(String)
*/
public static UShort ushort(String value) throws NumberFormatException {
return value == null ? null : UShort.valueOf(value);
}
/**
* Create an <code>unsigned short</code> by masking it with
* <code>0xFFFF</code> i.e. <code>(short) -1</code> becomes
* <code>(ushort) 65535</code>
*
* @see UShort#valueOf(short)
*/
public static UShort ushort(short value) {
return UShort.valueOf(value);
}
/**
* Create an <code>unsigned short</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned short</code>
* @see UShort#valueOf(int)
*/
public static UShort ushort(int value) throws NumberFormatException {
return UShort.valueOf(value);
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned int</code>.
* @see UInteger#valueOf(String)
*/
public static UInteger uint(String value) throws NumberFormatException {
return value == null ? null : UInteger.valueOf(value);
}
/**
* Create an <code>unsigned int</code> by masking it with
* <code>0xFFFFFFFF</code> i.e. <code>(int) -1</code> becomes
* <code>(uint) 4294967295</code>
*
* @see UInteger#valueOf(int)
*/
public static UInteger uint(int value) {
return UInteger.valueOf(value);
}
/**
* Create an <code>unsigned int</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned int</code>
* @see UInteger#valueOf(long)
*/
public static UInteger uint(long value) throws NumberFormatException {
return UInteger.valueOf(value);
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> does not contain a
* parsable <code>unsigned long</code>.
* @see ULong#valueOf(String)
*/
public static ULong ulong(String value) throws NumberFormatException {
return value == null ? null : ULong.valueOf(value);
}
/**
* Create an <code>unsigned long</code> by masking it with
* <code>0xFFFFFFFFFFFFFFFF</code> i.e. <code>(long) -1</code> becomes
* <code>(uint) 18446744073709551615</code>
*
* @see ULong#valueOf(long)
*/
public static ULong ulong(long value) {
return ULong.valueOf(value);
}
/**
* Create an <code>unsigned long</code>
*
* @throws NumberFormatException If <code>value</code> is not in the range
* of an <code>unsigned long</code>
* @see ULong#valueOf(BigInteger)
*/
public static ULong ulong(BigInteger value) throws NumberFormatException {
return ULong.valueOf(value);
}
/**
* No instances
*/
private Unsigned() {}
}

View File

@ -0,0 +1,166 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util;
import static dorkbox.util.bytes.Unsigned.ubyte;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.junit.Test;
import dorkbox.util.bytes.UByte;
public class UByteTest {
@SuppressWarnings("deprecation")
@Test
public void testValueOfByte() {
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
assertEquals(i & 0xFF, ubyte((byte) i).intValue());
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfByteCaching() {
for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE; i++) {
UByte a = ubyte((byte) i);
UByte b = ubyte((byte) i);
assertTrue(a == b);
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfShort() {
for (int i = UByte.MIN_VALUE; i <= UByte.MAX_VALUE; i++) {
assertEquals(i & 0xFF, ubyte((short) i).intValue());
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfShortInvalid() {
try {
ubyte((short) (UByte.MIN_VALUE - 1));
fail();
}
catch (NumberFormatException e) {}
try {
ubyte((short) (UByte.MAX_VALUE + 1));
fail();
}
catch (NumberFormatException e) {}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfInt() {
for (int i = UByte.MIN_VALUE; i <= UByte.MAX_VALUE; i++) {
assertEquals(i & 0xFF, ubyte(i).intValue());
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfIntInvalid() {
try {
ubyte(UByte.MIN_VALUE - 1);
fail();
}
catch (NumberFormatException e) {}
try {
ubyte(UByte.MAX_VALUE + 1);
fail();
}
catch (NumberFormatException e) {}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfLong() {
for (int i = UByte.MIN_VALUE; i <= UByte.MAX_VALUE; i++) {
assertEquals(i & 0xFF, ubyte((long) i).intValue());
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongInvalid() {
try {
ubyte((long) UByte.MIN_VALUE - 1);
fail();
}
catch (NumberFormatException e) {}
try {
ubyte((long) UByte.MAX_VALUE + 1);
fail();
}
catch (NumberFormatException e) {}
}
@SuppressWarnings("deprecation")
@Test
public void testSerializeDeserialize() throws ClassNotFoundException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
ByteArrayInputStream bais;
ObjectInputStream ois;
UByte expected = ubyte(42);
UByte input = ubyte(42);
UByte actual;
Object o;
oos.writeObject(input);
oos.close();
bais = new ByteArrayInputStream(baos.toByteArray());
ois = new ObjectInputStream(bais);
o = ois.readObject();
if (!(o instanceof UByte)) {
fail();
}
actual = (UByte) o;
assertEquals(expected, actual); // same value
assertTrue(expected == actual); // identical objects
}
}

View File

@ -0,0 +1,149 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util;
import static dorkbox.util.bytes.Unsigned.uint;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import org.junit.Test;
import dorkbox.util.bytes.UInteger;
public class UIntegerTest {
private static final int CACHE_SIZE=256;
private static final int NEAR_MISS_OFFSET=4;
@SuppressWarnings("deprecation")
@Test
public void testValueOfLong() {
for(long l=01; l<=UInteger.MAX_VALUE; l<<=1) {
assertEquals(l , uint(l).longValue());
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongCachingShift() {
for(long l=01; l<CACHE_SIZE; l<<=1)
{
UInteger a = uint(l);
UInteger b = uint(l);
assertTrue(a == b);
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongCachingNear() {
for(long l=CACHE_SIZE-NEAR_MISS_OFFSET; l<CACHE_SIZE; l++)
{
UInteger a = uint(l);
UInteger b = uint(l);
assertTrue(a == b);
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongNoCachingShift() {
for(long l=CACHE_SIZE; l<=CACHE_SIZE; l<<=1)
{
UInteger a = uint(l);
UInteger b = uint(l);
assertFalse(a == b);
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongNoCachingNear() {
for(long l=CACHE_SIZE; l<=CACHE_SIZE+NEAR_MISS_OFFSET; l++)
{
UInteger a = uint(l);
UInteger b = uint(l);
assertFalse(a == b);
}
}
@SuppressWarnings("deprecation")
@Test
public void testValueOfLongInvalid() {
try {
uint(UInteger.MIN_VALUE - 1);
fail();
}
catch (NumberFormatException e) {}
try {
uint(UInteger.MAX_VALUE + 1);
fail();
}
catch (NumberFormatException e) {}
}
@SuppressWarnings("deprecation")
@Test
public void testSerializeDeserialize() throws ClassNotFoundException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
ByteArrayInputStream bais;
ObjectInputStream ois;
UInteger expected = uint(42);
UInteger input = uint(42);
UInteger actual;
Object o;
oos.writeObject(input);
oos.close();
bais = new ByteArrayInputStream(baos.toByteArray());
ois = new ObjectInputStream(bais);
o = ois.readObject();
if (!(o instanceof UInteger)) {
fail();
}
actual = (UInteger) o;
assertEquals(expected, actual); // same value
assertTrue(expected == actual); // identical objects
}
}

View File

@ -0,0 +1,290 @@
/**
* Copyright (c) 2011-2013, Lukas Eder, lukas.eder@gmail.com
* All rights reserved.
*
* This software is licensed to you under the Apache License, Version 2.0
* (the "License"); You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* . Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* . Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* . Neither the name "jOOU" nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package dorkbox.util;
import static dorkbox.util.bytes.ULong.MAX_VALUE_LONG;
import static dorkbox.util.bytes.Unsigned.ubyte;
import static dorkbox.util.bytes.Unsigned.uint;
import static dorkbox.util.bytes.Unsigned.ulong;
import static dorkbox.util.bytes.Unsigned.ushort;
import static java.math.BigInteger.ONE;
import static java.util.Arrays.asList;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.Test;
import dorkbox.util.bytes.UByte;
import dorkbox.util.bytes.UInteger;
import dorkbox.util.bytes.ULong;
import dorkbox.util.bytes.UNumber;
import dorkbox.util.bytes.UShort;
/**
* @author Lukas Eder
*/
public class UNumberTest {
@Test
public void testRange0() {
testCastable((short) 0, ubyte("0"));
testCastable((short) 0, ubyte((byte) 0));
testCastable((short) 0, ubyte((short) 0));
testCastable(0, ushort("0"));
testCastable(0, ushort((short) 0));
testCastable(0, ushort(0));
testCastable(0L, uint("0"));
testCastable(0L, uint(0));
testCastable(0L, uint(0L));
testCastable(BigInteger.ZERO, ulong("0"));
testCastable(BigInteger.ZERO, ulong(0L));
testCastable(BigInteger.ZERO, ulong(BigInteger.ZERO));
}
@Test
public void testRange1() {
testCastable((short) 1, ubyte("1"));
testCastable((short) 1, ubyte((byte) 1));
testCastable((short) 1, ubyte((short) 1));
testCastable(1, ushort("1"));
testCastable(1, ushort((short) 1));
testCastable(1, ushort(1));
testCastable(1L, uint("1"));
testCastable(1L, uint(1));
testCastable(1L, uint(1L));
testCastable(BigInteger.ONE, ulong("1"));
testCastable(BigInteger.ONE, ulong(1L));
testCastable(BigInteger.ONE, ulong(BigInteger.ONE));
}
@Test
public void testRangeSignedMaxValue() {
testCastable(Byte.MAX_VALUE, ubyte(Byte.toString(Byte.MAX_VALUE)));
testCastable(Byte.MAX_VALUE, ubyte(Byte.MAX_VALUE));
testCastable(Byte.MAX_VALUE, ubyte((short) Byte.MAX_VALUE));
testCastable(Short.MAX_VALUE, ushort(Short.toString(Short.MAX_VALUE)));
testCastable(Short.MAX_VALUE, ushort(Short.MAX_VALUE));
testCastable(Short.MAX_VALUE, ushort((int) Short.MAX_VALUE));
testCastable(Integer.MAX_VALUE, uint(Integer.toString(Integer.MAX_VALUE)));
testCastable(Integer.MAX_VALUE, uint(Integer.MAX_VALUE));
testCastable(Integer.MAX_VALUE, uint((long) Integer.MAX_VALUE));
testCastable(BigInteger.valueOf(Long.MAX_VALUE), ulong(Long.toString(Long.MAX_VALUE)));
testCastable(BigInteger.valueOf(Long.MAX_VALUE), ulong(Long.MAX_VALUE));
testCastable(BigInteger.valueOf(Long.MAX_VALUE), ulong(BigInteger.valueOf(Long.MAX_VALUE)));
}
@Test
public void testRangeSignedMaxValuePlusOne() {
testCastable((short) 0x80, ubyte(Short.toString((short) 0x80)));
testCastable((short) 0x80, ubyte((byte) -0x80));
testCastable((short) 0x80, ubyte((short) 0x80));
testCastable(0x8000, ushort(Integer.toString(0x8000)));
testCastable(0x8000, ushort((short) -0x8000));
testCastable(0x8000, ushort(0x8000));
testCastable(0x80000000L, uint(Long.toString(0x80000000L)));
testCastable(0x80000000L, uint((int) -0x80000000L));
testCastable(0x80000000L, uint(0x80000000L));
testCastable(MAX_VALUE_LONG, ulong(MAX_VALUE_LONG.toString()));
testCastable(MAX_VALUE_LONG, ulong(0x8000000000000000L));
testCastable(MAX_VALUE_LONG, ulong(MAX_VALUE_LONG));
}
@Test
public void testRangeSignedMaxValuePlusTwo() {
testCastable((short) 0x81, ubyte(Short.toString((short) 0x81)));
testCastable((short) 0x81, ubyte((byte) -0x7F));
testCastable((short) 0x81, ubyte((short) 0x81));
testCastable(0x8001, ushort(Integer.toString(0x8001)));
testCastable(0x8001, ushort((short) -0x7FFF));
testCastable(0x8001, ushort(0x8001));
testCastable(0x80000001L, uint(Long.toString(0x80000001L)));
testCastable(0x80000001L, uint((int) -0x7FFFFFFFL));
testCastable(0x80000001L, uint(0x80000001L));
testCastable(MAX_VALUE_LONG.add(ONE), ulong(MAX_VALUE_LONG.add(ONE).toString()));
testCastable(MAX_VALUE_LONG.add(ONE), ulong(0x8000000000000001L));
testCastable(MAX_VALUE_LONG.add(ONE), ulong(MAX_VALUE_LONG.add(ONE)));
}
@Test
public void testRangeUnsignedMaxValue() {
testCastable(UByte.MAX_VALUE, ubyte(Short.toString(UByte.MAX_VALUE)));
testCastable(UByte.MAX_VALUE, ubyte((byte) -1));
testCastable(UByte.MAX_VALUE, ubyte(UByte.MAX_VALUE));
testCastable(UShort.MAX_VALUE, ushort(Integer.toString(UShort.MAX_VALUE)));
testCastable(UShort.MAX_VALUE, ushort((short) -1));
testCastable(UShort.MAX_VALUE, ushort(UShort.MAX_VALUE));
testCastable(UInteger.MAX_VALUE, uint(Long.toString(UInteger.MAX_VALUE)));
testCastable(UInteger.MAX_VALUE, uint(-1));
testCastable(UInteger.MAX_VALUE, uint(UInteger.MAX_VALUE));
testCastable(ULong.MAX_VALUE, ulong(ULong.MAX_VALUE.toString()));
testCastable(ULong.MAX_VALUE, ulong(-1L));
testCastable(ULong.MAX_VALUE, ulong(ULong.MAX_VALUE));
}
@SuppressWarnings("deprecation")
@Test
public void testObjectMethods() {
assertEquals(ubyte((byte) 0), ubyte((byte) 0));
assertEquals(ubyte((byte) 1), ubyte((byte) 1));
assertFalse(ubyte((byte) 0).equals(ubyte((byte) 1)));
assertEquals("0", ubyte((byte) 0).toString());
assertEquals("1", ubyte((byte) 1).toString());
assertEquals(Short.toString(UByte.MAX_VALUE), ubyte((byte) -1).toString());
assertEquals(ushort((short) 0), ushort((short) 0));
assertEquals(ushort((short) 1), ushort((short) 1));
assertFalse(ushort((short) 0).equals(ushort((short) 1)));
assertEquals("0", ushort((short) 0).toString());
assertEquals("1", ushort((short) 1).toString());
assertEquals(Integer.toString(UShort.MAX_VALUE), ushort((short) -1).toString());
assertEquals(uint(0), uint(0));
assertEquals(uint(1), uint(1));
assertFalse(uint(0).equals(uint(1)));
assertEquals("0", uint(0).toString());
assertEquals("1", uint(1).toString());
assertEquals(Long.toString(UInteger.MAX_VALUE), uint(-1).toString());
assertEquals(ulong(0), ulong(0));
assertEquals(ulong(1), ulong(1));
assertFalse(ulong(0).equals(ulong(1)));
assertEquals("0", ulong(0).toString());
assertEquals("1", ulong(1).toString());
assertEquals(ULong.MAX_VALUE.toString(), ulong(-1).toString());
}
@Test
public void testComparable() {
testComparable(asList("1", "2", "3"), ubyte((byte) 1), ubyte((byte) 2), ubyte((byte) 3));
testComparable(asList("1", "2", "3"), ubyte((byte) 3), ubyte((byte) 2), ubyte((byte) 1));
testComparable(asList("1", "2", "3"), ubyte((byte) 3), ubyte((byte) 1), ubyte((byte) 2));
testComparable(asList("1", "1", "2", "3"), ubyte((byte) 3), ubyte((byte) 1), ubyte((byte) 2), ubyte((byte) 1));
testComparable(asList("1", "2", "3"), ushort(1), ushort(2), ushort(3));
testComparable(asList("1", "2", "3"), ushort(3), ushort(2), ushort(1));
testComparable(asList("1", "2", "3"), ushort(3), ushort(1), ushort(2));
testComparable(asList("1", "1", "2", "3"), ushort(3), ushort(1), ushort(2), ushort(1));
testComparable(asList("1", "2", "3"), uint(1), uint(2), uint(3));
testComparable(asList("1", "2", "3"), uint(3), uint(2), uint(1));
testComparable(asList("1", "2", "3"), uint(3), uint(1), uint(2));
testComparable(asList("1", "1", "2", "3"), uint(3), uint(1), uint(2), uint(1));
testComparable(asList("1", "2", "3"), ulong(1), ulong(2), ulong(3));
testComparable(asList("1", "2", "3"), ulong(3), ulong(2), ulong(1));
testComparable(asList("1", "2", "3"), ulong(3), ulong(1), ulong(2));
testComparable(asList("1", "1", "2", "3"), ulong(3), ulong(1), ulong(2), ulong(1));
}
// Test utility methods
@SuppressWarnings({ "rawtypes", "unchecked", "deprecation" })
private void testComparable(List<String> strings, UNumber... numbers) {
List<UNumber> list = new ArrayList<UNumber>(asList(numbers));
Collections.sort((List) list);
for (int i = 0; i < numbers.length; i++) {
assertEquals(strings.get(i), list.get(i).toString());
}
}
@SuppressWarnings("deprecation")
private void testCastable(short value, UByte u) {
assertEquals((byte) value, u.byteValue());
assertEquals(value, u.shortValue());
assertEquals(value, u.intValue());
assertEquals(value, u.longValue());
assertEquals((double) value, u.doubleValue());
assertEquals((float) value, u.floatValue());
assertEquals(new BigInteger("" + value), u.toBigInteger());
}
@SuppressWarnings("deprecation")
private void testCastable(int value, UShort u) {
assertEquals((byte) value, u.byteValue());
assertEquals((short) value, u.shortValue());
assertEquals(value, u.intValue());
assertEquals(value, u.longValue());
assertEquals((double) value, u.doubleValue());
assertEquals((float) value, u.floatValue());
assertEquals(new BigInteger("" + value), u.toBigInteger());
}
@SuppressWarnings("deprecation")
private void testCastable(long value, UInteger u) {
assertEquals((byte) value, u.byteValue());
assertEquals((short) value, u.shortValue());
assertEquals((int) value, u.intValue());
assertEquals(value, u.longValue());
assertEquals((double) value, u.doubleValue());
assertEquals((float) value, u.floatValue());
assertEquals(new BigInteger("" + value), u.toBigInteger());
}
@SuppressWarnings("deprecation")
private void testCastable(BigInteger value, ULong u) {
assertEquals(value.byteValue(), u.byteValue());
assertEquals(value.shortValue(), u.shortValue());
assertEquals(value.intValue(), u.intValue());
assertEquals(value.longValue(), u.longValue());
assertEquals(value.doubleValue(), u.doubleValue());
assertEquals(value.floatValue(), u.floatValue());
assertEquals(new BigInteger("" + value), u.toBigInteger());
}
}