From 45a93fad4d7123887d14135ee15ee3e9b0d4ca58 Mon Sep 17 00:00:00 2001 From: csharptest Date: Thu, 2 Jun 2011 10:52:37 -0500 Subject: Optimized access to ByteString from coded io. --- src/ProtocolBuffers/ByteString.cs | 29 +++++++++++++++++++++++++++++ src/ProtocolBuffers/CodedInputStream.cs | 4 ++-- src/ProtocolBuffers/CodedOutputStream.cs | 14 +++++--------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/ProtocolBuffers/ByteString.cs b/src/ProtocolBuffers/ByteString.cs index 2cce287a..83d4a2df 100644 --- a/src/ProtocolBuffers/ByteString.cs +++ b/src/ProtocolBuffers/ByteString.cs @@ -51,6 +51,14 @@ namespace Google.ProtocolBuffers private readonly byte[] bytes; + /// + /// Internal use only. Ensure that the provided array is not mutated and belongs to this instance. + /// + internal static ByteString AttachBytes(byte[] bytes) + { + return new ByteString(bytes); + } + /// /// Constructs a new ByteString from the given byte array. The array is /// *not* copied, and must not be modified after this constructor is called. @@ -237,5 +245,26 @@ namespace Google.ProtocolBuffers get { return output; } } } + + internal void WriteTo(CodedOutputStream outputStream) + { + outputStream.WriteRawBytes(bytes, 0, bytes.Length); + } + + /// + /// Copies the entire byte array to the destination array provided at the offset specified. + /// + public void CopyTo(Array array, int position) + { + Array.Copy(bytes, 0, array, position, bytes.Length); + } + + /// + /// Writes the entire byte array to the provided stream + /// + public void WriteTo(System.IO.Stream outputStream) + { + outputStream.Write(bytes, 0, bytes.Length); + } } } \ No newline at end of file diff --git a/src/ProtocolBuffers/CodedInputStream.cs b/src/ProtocolBuffers/CodedInputStream.cs index 225cf4da..a9afbe60 100644 --- a/src/ProtocolBuffers/CodedInputStream.cs +++ b/src/ProtocolBuffers/CodedInputStream.cs @@ -58,7 +58,7 @@ namespace Google.ProtocolBuffers /// TODO(jonskeet): Consider whether recursion and size limits shouldn't be readonly, /// set at construction time. /// - public sealed class CodedInputStream + public sealed partial class CodedInputStream { private readonly byte[] buffer; private int bufferSize; @@ -353,7 +353,7 @@ namespace Google.ProtocolBuffers else { // Slow path: Build a byte array first then copy it. - return ByteString.CopyFrom(ReadRawBytes(size)); + return ByteString.AttachBytes(ReadRawBytes(size)); } } diff --git a/src/ProtocolBuffers/CodedOutputStream.cs b/src/ProtocolBuffers/CodedOutputStream.cs index f905b357..f30c8061 100644 --- a/src/ProtocolBuffers/CodedOutputStream.cs +++ b/src/ProtocolBuffers/CodedOutputStream.cs @@ -54,7 +54,7 @@ namespace Google.ProtocolBuffers /// methods are taken from the protocol buffer type names, not .NET types. /// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.) /// - public sealed class CodedOutputStream + public sealed partial class CodedOutputStream { /// /// The buffer size used by CreateInstance(Stream). @@ -257,11 +257,9 @@ namespace Google.ProtocolBuffers public void WriteBytes(int fieldNumber, ByteString value) { - // TODO(jonskeet): Optimise this! (No need to copy the bytes twice.) WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited); - byte[] bytes = value.ToByteArray(); - WriteRawVarint32((uint) bytes.Length); - WriteRawBytes(bytes); + WriteRawVarint32((uint)value.Length); + value.WriteTo(this); } [CLSCompliant(false)] @@ -564,10 +562,8 @@ namespace Google.ProtocolBuffers public void WriteBytesNoTag(ByteString value) { - // TODO(jonskeet): Optimise this! (No need to copy the bytes twice.) - byte[] bytes = value.ToByteArray(); - WriteRawVarint32((uint) bytes.Length); - WriteRawBytes(bytes); + WriteRawVarint32((uint)value.Length); + value.WriteTo(this); } [CLSCompliant(false)] -- cgit v1.2.3