Search code examples
javaniobytebufferapache-mina

How to assign and retrieve a unsigned Long value to ioBuffer


How to assign a unsigned Long value to ioBuffer( apache mina)

My requirement is : I Would have a unsigned Long value ie a value upto 2^64-1 = 18446744073709551615, which needs to be set into a ioBuffer and then retrieved back.

I can use BigInteger in midline or whatever strategy that suits :

long var1 = -3676984925397286887L; // This is signed number whose unsigned equivalent is "14769759148312264729". Actually this is the signed number is what my expectation is in the final output from the ioBuffer. Since Java do not have signed long equivalent, my number is overflowing and turning to a negative number!!

This signed eqiivalent can be brought back and stored in BigInteger with a trick!!

 long quot = (var1 >>> 1) / 5;
 Long rem = var1 - quot * 10;
 BigInteger bi = BigInteger.valueOf(quot).multiply(new BigInteger("10")).add(new BigInteger(rem.toString()));//.multiply(new BigInteger("10").add(new BigInteger(rem+"")));//new BigInteger(quot).multiply(10).add(rem);
    System.out.println(bi);

Till now everything is fine. Now i want it to be stored in ioBuffer.

IoBuffer ioBuffer1 = IoBuffer.allocate(8);
    ioBuffer1.put(bi.toByteArray());
    System.out.println(new BigInteger(ioBuffer1.array()));

Now, when i allocate 8bytes , i get an exception as :

Exception in thread "main" java.nio.BufferOverflowException
at java.nio.HeapByteBuffer.put(HeapByteBuffer.java:189)
at org.apache.mina.core.buffer.AbstractIoBuffer.put(AbstractIoBuffer.java:654)
at org.apache.mina.core.buffer.AbstractIoBuffer.put(AbstractIoBuffer.java:1355)

but if i change it to ioBuffer.allocate(9). I am able to get the value as:

14769759148312264729

Certainly i cant allocate 9 bytes. As unsigned long is 8 bytes. Where am i going wrong!!

Any idea Guys!!

Thanks in advance Nilotpal


Solution

  • The binary representations of the signed and unsigned values are the same, so the only "trick" you need is the sign and magnitude constructor of BigInteger:

    long var1 = -3676984925397286887L;
    
    IoBuffer ioBuffer1 = IoBuffer.allocate(8);
    ioBuffer1.putLong(var1);
    
    BigInteger bi = new BigInteger(1, ioBuffer1.array());
    
    System.out.println(bi);             // 14769759148312264729
    System.out.println(bi.longValue()); // -3676984925397286887