Reputation: 3090
I am working on a very bare bones ByteBuffer for use with java 1.4. I have a small skeleton that basically just have poor implementations of put/getInt() put/getLong(). My problem is that while putInt and getInt works, the getLong() (I think it is) is not working.
When I read out the fourth byte and shift that into the long it overflows. But all my variables are long so it should not overflow.
Heres the code (please bear in mind that this is just a start):
public class ByteBuffer {
private byte[] buffer;
private int first = 0;
private int last = 0;
private int size;
private int elements;
public ByteBuffer(int size) {
this.size = size;
buffer = new byte[size];
}
public void putInt(int theInt) {
for (int i = 0; i < 4; i++) {
put((byte) (theInt >>> (8 * i)));
}
}
public int getInt() {
int theInt = 0;
for (int i = 0; i < 4; i++) {
theInt |= (0xFF & get()) << (8 * i);
}
return theInt;
}
public void putLong(long theLong) {
for (int i = 0; i < 8; i++) {
put((byte) (theLong >>> (8 * i)));
}
}
public long getLong() {
long theLong = 0L;
for (int i = 0; i < 8; i++) {
theLong |= (long) ((0xFF & get()) << (8 * i));
}
return theLong;
}
public void put(byte theByte) {
buffer[last++] = theByte;
if (last == size) {
last = 0;
}
elements++;
}
public byte get() {
byte theByte = buffer[first++];
if (first == size) {
first = 0;
}
elements--;
return theByte;
}
public byte[] array() {
return (byte[]) buffer.clone();
}
/**
* @param args
*/
public static void main(String[] args) {
ByteBuffer buff = new ByteBuffer(512);
buff.putLong(9223372036854775807L);
buff.putLong(-9223372036854775808L);
System.out.println(9223372036854775807L);
System.out.println(-9223372036854775808L);
long l1 = buff.getLong();
long l2 = buff.getLong();
System.out.println(l1);
System.out.println(l2);
}
}
Upvotes: 1
Views: 1152
Reputation: 109593
theLong |= (long) ((0xFF & get()) << (8 * i));
Shifts an int value, propagated from a byte, and can only shift 32 bit positions.
Solution:
theLong |= ((long) (0xFF & get())) << (8 * i);
Upvotes: 2
Reputation: 34323
In your getLong method, you have to cast (0xFF & get()) to a long, before you can shift it more than 32 bits. You could also use a long literal (0xFFL) instead of the int literal (0xFF).
The reason for this is that the resulting type of an "int && byte" operation (0xFF & get()) is an int. The specification of the bit shift operations is such, that "a << b" will actually shift "b modulo 32" bits if a is an int and "b modulo 64" bits if a is a long.
Upvotes: 6