Here you can find the source of bytesToSVar64(final byte[] buffer, final int offset)
public static long bytesToSVar64(final byte[] buffer, final int offset)
//package com.java2s; /*// www . java2s . c o m * Copyright 2014 NAVER Corp. * * 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. */ public class Main { public static long bytesToSVar64(final byte[] buffer, final int offset) { return zigzagToLong(bytesToVar64(buffer, offset)); } public static long zigzagToLong(final long n) { return (n >>> 1) ^ -(n & 1); } public static long bytesToVar64(final byte[] buffer, final int offset) { if (buffer == null) { throw new NullPointerException("buffer must not be null"); } checkBound(buffer.length, offset); // borrowing the protocol buffer's concept of variable-length encoding // copy https://github.com/google/protobuf 2.6.1 // CodedInputStream.java -> int readRawVarint32() // Implementation notes: // // Optimized for one-byte values, expected to be common. // The particular code below was selected from various candidates // empirically, by winning VarintBenchmark. // // Sign extension of (signed) Java bytes is usually a nuisance, but // we exploit it here to more easily obtain the sign of bytes read. // Instead of cleaning up the sign extension bits by masking eagerly, // we delay until we find the final (positive) byte, when we clear all // accumulated bits with one xor. We depend on javac to constant fold. fastpath: { int pos = offset; int bufferSize = buffer.length; if (bufferSize == pos) { break fastpath; } long x; int y; if ((y = buffer[pos++]) >= 0) { return y; } else if (bufferSize - pos < 9) { break fastpath; } else if ((x = y ^ (buffer[pos++] << 7)) < 0L) { x ^= (~0L << 7); } else if ((x ^= (buffer[pos++] << 14)) >= 0L) { x ^= (~0L << 7) ^ (~0L << 14); } else if ((x ^= (buffer[pos++] << 21)) < 0L) { x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21); } else if ((x ^= ((long) buffer[pos++] << 28)) >= 0L) { x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28); } else if ((x ^= ((long) buffer[pos++] << 35)) < 0L) { x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35); } else if ((x ^= ((long) buffer[pos++] << 42)) >= 0L) { x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42); } else if ((x ^= ((long) buffer[pos++] << 49)) < 0L) { x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42) ^ (~0L << 49); } else { x ^= ((long) buffer[pos++] << 56); x ^= (~0L << 7) ^ (~0L << 14) ^ (~0L << 21) ^ (~0L << 28) ^ (~0L << 35) ^ (~0L << 42) ^ (~0L << 49) ^ (~0L << 56); if (x < 0L) { if (buffer[pos] < 0L) { break fastpath; // Will throw malformedVarint() } } } return x; } return readVar64SlowPath(buffer, offset); } static void checkBound(final int bufferLength, final int offset) { if (offset < 0) { throw new IndexOutOfBoundsException("negative offset:" + offset); } if (offset >= bufferLength) { throw new IndexOutOfBoundsException("invalid offset:" + offset + " bufferLength:" + bufferLength); } } /** Variant of readRawVarint64 for when uncomfortably close to the limit. */ /* Visible for testing */ static long readVar64SlowPath(final byte[] buffer, int offset) { long result = 0; for (int shift = 0; shift < 64; shift += 7) { final byte b = buffer[offset++]; result |= (long) (b & 0x7F) << shift; if ((b & 0x80) == 0) { return result; } } throw new IllegalArgumentException("invalid varLong. start offset:" + offset + " readOffset:" + offset); } }