From 25a28580a6f307cb8eb040367f5671e678e9896b Mon Sep 17 00:00:00 2001 From: Jon Skeet Date: Wed, 18 Feb 2009 16:06:22 +0000 Subject: Support packed primitive types --- src/ProtocolBuffers/AbstractMessage.cs | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'src/ProtocolBuffers/AbstractMessage.cs') diff --git a/src/ProtocolBuffers/AbstractMessage.cs b/src/ProtocolBuffers/AbstractMessage.cs index 9787e159..0a69f294 100644 --- a/src/ProtocolBuffers/AbstractMessage.cs +++ b/src/ProtocolBuffers/AbstractMessage.cs @@ -110,8 +110,21 @@ namespace Google.ProtocolBuffers { if (field.IsRepeated) { // We know it's an IList, but not the exact type - so // IEnumerable is the best we can do. (C# generics aren't covariant yet.) - foreach (object element in (IEnumerable)entry.Value) { - output.WriteField(field.FieldType, field.FieldNumber, element); + IEnumerable valueList = (IEnumerable) entry.Value; + if (field.IsPacked) { + output.WriteTag(field.FieldNumber, WireFormat.WireType.LengthDelimited); + int dataSize = 0; + foreach (object element in valueList) { + dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element); + } + output.WriteRawVarint32((uint)dataSize); + foreach (object element in valueList) { + output.WriteFieldNoTag(field.FieldType, element); + } + } else { + foreach (object element in valueList) { + output.WriteField(field.FieldType, field.FieldNumber, element); + } } } else { output.WriteField(field.FieldType, field.FieldNumber, entry.Value); @@ -136,8 +149,19 @@ namespace Google.ProtocolBuffers { foreach (KeyValuePair entry in AllFields) { FieldDescriptor field = entry.Key; if (field.IsRepeated) { - foreach (object element in (IEnumerable) entry.Value) { - size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, element); + IEnumerable valueList = (IEnumerable) entry.Value; + if (field.IsPacked) { + int dataSize = 0; + foreach (object element in valueList) { + dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element); + } + size += dataSize; + size += CodedOutputStream.ComputeTagSize(field.FieldNumber); + size += CodedOutputStream.ComputeRawVarint32Size((uint)dataSize); + } else { + foreach (object element in valueList) { + size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, element); + } } } else { size += CodedOutputStream.ComputeFieldSize(field.FieldType, field.FieldNumber, entry.Value); -- cgit v1.2.3