class LEB128 {

	public static long decode(BinaryReader reader, boolean isSigned) throws IOException {
		int nextByte = 0;
		int shift = 0;
		long value = 0;
		boolean overflow = false;
		while (true) {
			nextByte = reader.readNextUnsignedByte();
			if (shift == 70 || (isSigned == false && shift == 63 && nextByte > 1)) {
				// if the value being read is more than 64 bits long mark it as overflow.
				// keep reading the rest of the number so the caller is not left in the
				// middle of the LEB128 number's guts.
				overflow = true;
			}

			// must cast to long before shifting otherwise shift values greater than 32 cause problems
			value |= ((long) (nextByte & 0x7F)) << shift;
			shift += 7;

			if ((nextByte & 0x80) == 0) {
				break;
			}
		}
		if (overflow) {
			throw new IOException(
				"Unsupported LEB128 value, too large to fit in 64bit java long variable");
		}
		if ((isSigned) && (shift < Long.SIZE) && ((nextByte & 0x40) != 0)) {
			value |= -(1 << shift);
		}

		return value;
	}

}