private static long ReadInteger(
Stream stream,
int headByte,
bool check32bit)
{
int kind = headByte & 0x1f;
if (kind == 0x18) {
int b = stream.ReadByte();
if (b < 0) {
throw new IOException("Premature end of stream");
}
return (headByte != 0x38) ? b : -1 - b;
}
if (kind == 0x19) {
var bytes = new byte[2];
if (stream.Read(bytes, 0, bytes.Length) != bytes.Length) {
throw new IOException("Premature end of stream");
}
int b = ((int)bytes[0]) & 0xff;
b <<= 8;
b |= ((int)bytes[1]) & 0xff;
return (headByte != 0x39) ? b : -1 - b;
}
if (kind == 0x1a || kind == 0x3a) {
var bytes = new byte[4];
if (stream.Read(bytes, 0, bytes.Length) != bytes.Length) {
throw new IOException("Premature end of stream");
}
long b = ((long)bytes[0]) & 0xff;
b <<= 8;
b |= ((long)bytes[1]) & 0xff;
b <<= 8;
b |= ((long)bytes[2]) & 0xff;
b <<= 8;
b |= ((long)bytes[3]) & 0xff;
if (check32bit && (b >> 31) != 0) {
throw new IOException("Not a 32-bit integer");
}
return (headByte != 0x3a) ? b : -1 - b;
}
if (headByte == 0x1b || headByte == 0x3b) {
var bytes = new byte[8];
if (stream.Read(bytes, 0, bytes.Length) != bytes.Length) {
throw new IOException("Premature end of stream");
}
long b;
if (check32bit && (bytes[0] != 0 || bytes[1] != 0 || bytes[2] != 0 ||
bytes[3] != 0)) {
throw new IOException("Not a 32-bit integer");
}
if (!check32bit) {
b = ((long)bytes[0]) & 0xff;
b <<= 8;
b |= ((long)bytes[1]) & 0xff;
b <<= 8;
b |= ((long)bytes[2]) & 0xff;
b <<= 8;
b |= ((long)bytes[3]) & 0xff;
b <<= 8;
}
b = ((long)bytes[4]) & 0xff;
b <<= 8;
b |= ((long)bytes[5]) & 0xff;
b <<= 8;
b |= ((long)bytes[6]) & 0xff;
b <<= 8;
b |= ((long)bytes[7]) & 0xff;
if (check32bit && (b >> 31) != 0) {
throw new IOException("Not a 32-bit integer");
}
return (headByte != 0x3b) ? b : -1 - b;
}
throw new IOException("Not a 32-bit integer");
}