aboutsummaryrefslogtreecommitdiffhomepage
path: root/csharp/src/Google.Protobuf/CodedInputStream.cs
diff options
context:
space:
mode:
authorGravatar Jon Skeet <jonskeet@google.com>2015-08-05 11:23:38 +0100
committerGravatar Jon Skeet <jonskeet@google.com>2015-08-05 11:23:38 +0100
commitff334a60eb2e74722867dd41b78d7c8c90bc8d0c (patch)
tree6aca2c954c9ea56bff5690d6ee7e5423a2ac13d8 /csharp/src/Google.Protobuf/CodedInputStream.cs
parent607940321c8ceeb80ec1099d94add8eef86825e5 (diff)
Change ReadTag and PeekTag to just use 0 as a return value for "end of stream", rather than using an awkward out parameter.
This simplifies quite a lot of code. Generated code in next commit.
Diffstat (limited to 'csharp/src/Google.Protobuf/CodedInputStream.cs')
-rw-r--r--csharp/src/Google.Protobuf/CodedInputStream.cs56
1 files changed, 24 insertions, 32 deletions
diff --git a/csharp/src/Google.Protobuf/CodedInputStream.cs b/csharp/src/Google.Protobuf/CodedInputStream.cs
index 5da03b5c..0e2495f1 100644
--- a/csharp/src/Google.Protobuf/CodedInputStream.cs
+++ b/csharp/src/Google.Protobuf/CodedInputStream.cs
@@ -254,37 +254,35 @@ namespace Google.Protobuf
#region Reading of tags etc
/// <summary>
- /// Attempts to peek at the next field tag.
+ /// Peeks at the next field tag. This is like calling <see cref="ReadTag"/>, but the
+ /// tag is not consumed. (So a subsequent call to <see cref="ReadTag"/> will return the
+ /// same value.)
/// </summary>
- public bool PeekNextTag(out uint fieldTag)
+ public uint PeekTag()
{
if (hasNextTag)
{
- fieldTag = nextTag;
- return true;
+ return nextTag;
}
uint savedLast = lastTag;
- hasNextTag = ReadTag(out nextTag);
- lastTag = savedLast;
- fieldTag = nextTag;
- return hasNextTag;
+ nextTag = ReadTag();
+ hasNextTag = true;
+ lastTag = savedLast; // Undo the side effect of ReadTag
+ return nextTag;
}
/// <summary>
- /// Attempts to read a field tag, returning false if we have reached the end
- /// of the input data.
+ /// Reads a field tag, returning the tag of 0 for "end of stream".
/// </summary>
- /// <param name="fieldTag">The 'tag' of the field (id * 8 + wire-format)</param>
- /// <returns>true if the next fieldTag was read</returns>
- public bool ReadTag(out uint fieldTag)
+ /// <returns>The next field tag, or 0 for end of stream. (0 is never a valid tag.)</returns>
+ public uint ReadTag()
{
if (hasNextTag)
{
- fieldTag = nextTag;
- lastTag = fieldTag;
+ lastTag = nextTag;
hasNextTag = false;
- return true;
+ return lastTag;
}
// Optimize for the incredibly common case of having at least two bytes left in the buffer,
@@ -294,7 +292,7 @@ namespace Google.Protobuf
int tmp = buffer[bufferPos++];
if (tmp < 128)
{
- fieldTag = (uint)tmp;
+ lastTag = (uint)tmp;
}
else
{
@@ -302,13 +300,13 @@ namespace Google.Protobuf
if ((tmp = buffer[bufferPos++]) < 128)
{
result |= tmp << 7;
- fieldTag = (uint) result;
+ lastTag = (uint) result;
}
else
{
// Nope, rewind and go the potentially slow route.
bufferPos -= 2;
- fieldTag = ReadRawVarint32();
+ lastTag = ReadRawVarint32();
}
}
}
@@ -316,20 +314,18 @@ namespace Google.Protobuf
{
if (IsAtEnd)
{
- fieldTag = 0;
- lastTag = fieldTag;
- return false;
+ lastTag = 0;
+ return 0; // This is the only case in which we return 0.
}
- fieldTag = ReadRawVarint32();
+ lastTag = ReadRawVarint32();
}
- lastTag = fieldTag;
if (lastTag == 0)
{
// If we actually read zero, that's not a valid tag.
throw InvalidProtocolBufferException.InvalidTag();
}
- return true;
+ return lastTag;
}
/// <summary>
@@ -580,14 +576,10 @@ namespace Google.Protobuf
/// </summary>
public bool MaybeConsumeTag(uint tag)
{
- uint next;
- if (PeekNextTag(out next))
+ if (PeekTag() == tag)
{
- if (next == tag)
- {
- hasNextTag = false;
- return true;
- }
+ hasNextTag = false;
+ return true;
}
return false;
}