Java ReadableByteChannel Read getNextVIntAsLong(ByteBuffer buffer, ReadableByteChannel readChannel)

Here you can find the source of getNextVIntAsLong(ByteBuffer buffer, ReadableByteChannel readChannel)

Description

get Next V Int As Long

License

Open Source License

Declaration

public static final long getNextVIntAsLong(ByteBuffer buffer,
            ReadableByteChannel readChannel) throws IOException 

Method Source Code

//package com.java2s;
/*/*w ww  . j  a  va2 s.co m*/
 *  Copyright (C) 2010 Shashank Tulsyan
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel;

public class Main {
    private static final byte sig[] = { 0x0, //null
            -128, //1000 0000
            0x40, //0100 0000
            0x20, //0010 0000
            0x10, //0001 0000
            0x8, //0000 1000
            0x4, //0000 0100
            0x2, //0000 0010
            0x1, //0000 0001 
    };
    public static final long LONG_EQUIVALENT_OF_VINT_NULL = Long.MIN_VALUE;

    public static final long getNextVIntAsLong(ByteBuffer buffer,
            ReadableByteChannel readChannel) throws IOException {
        if (buffer == null) {
            buffer = ByteBuffer.allocate(1);
            readChannel.read(buffer);
        }
        byte firstByte;
        if (buffer.hasRemaining()) {
            firstByte = buffer.get();
        } else {
            firstByte = readAByte(readChannel);
        }
        if (firstByte == 0)
            return LONG_EQUIVALENT_OF_VINT_NULL;

        int numOfBytes = getNumberOfBytesInVint(firstByte);

        //remove indicator bit from firstByte

        //data types in java are signed
        //a byte might get coverted into negative integer
        //that is why anding to 0xff is needed
        firstByte = (byte) ((firstByte & 0xFF) ^ (sig[numOfBytes] & 0xFF));
        long ret = 0;
        byte next;
        //handling first byte
        ret |= (firstByte & 0xFF) << (8 * (numOfBytes - 1));
        //starting from 2nd byte
        for (int i = 1; i < numOfBytes; i++) {
            if (buffer.hasRemaining()) {
                next = buffer.get();//vint[numOfBytes-1-i];
            } else {
                next = readAByte(readChannel);
            }
            ret |= (next & 0xFF) << (8 * (numOfBytes - 1 - i));
        }

        return ret;
    }

    private static final byte readAByte(ReadableByteChannel readChannel)
            throws IOException {
        byte[] tmp = new byte[1];
        if (readChannel == null) {
            throw new NullPointerException(
                    "Buffer exhausted and read channel is null, cannot continue");
        }
        int read = readChannel.read(ByteBuffer.wrap(tmp));
        if (read < 0) {
            throw new IOException(
                    "Channel abruptly ended while expecting more data.");
        }
        return tmp[0];
    }

    public static final int getNumberOfBytesInVint(byte firstByte) {
        if (firstByte == 0)
            return 1; //null stored

        int numOfDig = 1, t;
        for (int i = 1; i < sig.length; i++) {
            //data types in java are signed
            //a byte might get coverted into negative integer
            //that is why anding to 0xff is needed
            t = (firstByte & 0xFF) & (sig[i] & 0xFF);
            if (t != 0) {
                numOfDig = i;
                break;
            }
        }

        return numOfDig;
    }
}

Related

  1. copyChannels(ReadableByteChannel in, WritableByteChannel out)
  2. copyChannels(ReadableByteChannel input, WritableByteChannel output, int bufferSize)
  3. fill(ReadableByteChannel in, ByteBuffer buffer)
  4. infiniteReadableByteChannelFor(ByteBuffer... buffers)
  5. read(ReadableByteChannel channel, ByteBuffer buffer)
  6. read(ReadableByteChannel channel, ByteBuffer buffer)
  7. read(ReadableByteChannel channel, ByteBuffer[] dsts)