public uint ReadTag()
{
if (hasNextTag)
{
lastTag = nextTag;
hasNextTag = false;
return lastTag;
}
// Optimize for the incredibly common case of having at least two bytes left in the buffer,
// and those two bytes being enough to get the tag. This will be true for fields up to 4095.
if (bufferPos + 2 <= bufferSize)
{
int tmp = buffer[bufferPos++];
if (tmp < 128)
{
lastTag = (uint)tmp;
}
else
{
int result = tmp & 0x7f;
if ((tmp = buffer[bufferPos++]) < 128)
{
result |= tmp << 7;
lastTag = (uint) result;
}
else
{
// Nope, rewind and go the potentially slow route.
bufferPos -= 2;
lastTag = ReadRawVarint32();
}
}
}
else
{
if (IsAtEnd)
{
lastTag = 0;
return 0; // This is the only case in which we return 0.
}
lastTag = ReadRawVarint32();
}
if (lastTag == 0)
{
// If we actually read zero, that's not a valid tag.
throw InvalidProtocolBufferException.InvalidTag();
}
return lastTag;
}