/// <summary> /// Serializes the message and writes it to the given output stream. /// This does not flush or close the stream. /// </summary> /// <remarks> /// Protocol Buffers are not self-delimiting. Therefore, if you write /// any more data to the stream after the message, you must somehow ensure /// that the parser on the receiving end does not interpret this as being /// part of the protocol message. One way of doing this is by writing the size /// of the message before the data, then making sure you limit the input to /// that size when receiving the data. Alternatively, use WriteDelimitedTo(Stream). /// </remarks> public override void WriteTo(CodedOutputStream output) { foreach (KeyValuePair <FieldDescriptor, object> entry in AllFields) { FieldDescriptor field = entry.Key; if (field.IsRepeated) { // We know it's an IList<T>, but not the exact type - so // IEnumerable is the best we can do. (C# generics aren't covariant yet.) 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); } } UnknownFieldSet unknownFields = UnknownFields; if (DescriptorForType.Options.MessageSetWireFormat) { unknownFields.WriteAsMessageSetTo(output); } else { unknownFields.WriteTo(output); } }
/// <summary> /// Writes a single field to a CodedOutputStream. /// </summary> public void WriteField(IFieldDescriptorLite field, Object value, CodedOutputStream output) { if (field.IsExtension && field.MessageSetWireFormat) { output.WriteMessageSetExtension(field.FieldNumber, (IMessageLite)value); } else { if (field.IsRepeated) { IEnumerable valueList = (IEnumerable)value; if (field.IsPacked) { output.WriteTag(field.FieldNumber, WireFormat.WireType.LengthDelimited); // Compute the total data size so the length can be written. int dataSize = 0; foreach (object element in valueList) { dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element); } output.WriteRawVarint32((uint)dataSize); // Write the data itself, without any tags. 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, value); } } }
/// <summary> /// Writes a single field to a CodedOutputStream. /// </summary> public void WriteField(FieldDescriptor field, Object value, CodedOutputStream output) { if (field.IsExtension && field.ContainingType.Options.MessageSetWireFormat) { output.WriteMessageSetExtension(field.FieldNumber, (IMessage) value); } else { if (field.IsRepeated) { IEnumerable valueList = (IEnumerable) value; if (field.IsPacked) { output.WriteTag(field.FieldNumber, WireFormat.WireType.LengthDelimited); // Compute the total data size so the length can be written. int dataSize = 0; foreach (object element in valueList) { dataSize += CodedOutputStream.ComputeFieldSizeNoTag(field.FieldType, element); } output.WriteRawVarint32((uint)dataSize); // Write the data itself, without any tags. 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, value); } } }