Browse Source

Optimized access to ByteString from coded io.

csharptest 14 years ago
parent
commit
45a93fad4d

+ 29 - 0
src/ProtocolBuffers/ByteString.cs

@@ -51,6 +51,14 @@ namespace Google.ProtocolBuffers
 
 
         private readonly byte[] bytes;
         private readonly byte[] bytes;
 
 
+        /// <summary>
+        /// Internal use only.  Ensure that the provided array is not mutated and belongs to this instance.
+        /// </summary>
+        internal static ByteString AttachBytes(byte[] bytes)
+        {
+            return new ByteString(bytes);
+        }
+
         /// <summary>
         /// <summary>
         /// Constructs a new ByteString from the given byte array. The array is
         /// Constructs a new ByteString from the given byte array. The array is
         /// *not* copied, and must not be modified after this constructor is called.
         /// *not* copied, and must not be modified after this constructor is called.
@@ -237,5 +245,26 @@ namespace Google.ProtocolBuffers
                 get { return output; }
                 get { return output; }
             }
             }
         }
         }
+
+        internal void WriteTo(CodedOutputStream outputStream)
+        {
+            outputStream.WriteRawBytes(bytes, 0, bytes.Length);
+        }
+
+        /// <summary>
+        /// Copies the entire byte array to the destination array provided at the offset specified.
+        /// </summary>
+        public void CopyTo(Array array, int position)
+        {
+            Array.Copy(bytes, 0, array, position, bytes.Length);
+        }
+
+        /// <summary>
+        /// Writes the entire byte array to the provided stream
+        /// </summary>
+        public void WriteTo(System.IO.Stream outputStream)
+        {
+            outputStream.Write(bytes, 0, bytes.Length);
+        }
     }
     }
 }
 }

+ 2 - 2
src/ProtocolBuffers/CodedInputStream.cs

@@ -58,7 +58,7 @@ namespace Google.ProtocolBuffers
     /// TODO(jonskeet): Consider whether recursion and size limits shouldn't be readonly,
     /// TODO(jonskeet): Consider whether recursion and size limits shouldn't be readonly,
     /// set at construction time.
     /// set at construction time.
     /// </remarks>
     /// </remarks>
-    public sealed class CodedInputStream
+    public sealed partial class CodedInputStream
     {
     {
         private readonly byte[] buffer;
         private readonly byte[] buffer;
         private int bufferSize;
         private int bufferSize;
@@ -353,7 +353,7 @@ namespace Google.ProtocolBuffers
             else
             else
             {
             {
                 // Slow path:  Build a byte array first then copy it.
                 // Slow path:  Build a byte array first then copy it.
-                return ByteString.CopyFrom(ReadRawBytes(size));
+                return ByteString.AttachBytes(ReadRawBytes(size));
             }
             }
         }
         }
 
 

+ 5 - 9
src/ProtocolBuffers/CodedOutputStream.cs

@@ -54,7 +54,7 @@ namespace Google.ProtocolBuffers
     /// methods are taken from the protocol buffer type names, not .NET types.
     /// methods are taken from the protocol buffer type names, not .NET types.
     /// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.)
     /// (Hence WriteFloat instead of WriteSingle, and WriteBool instead of WriteBoolean.)
     /// </remarks>
     /// </remarks>
-    public sealed class CodedOutputStream
+    public sealed partial class CodedOutputStream
     {
     {
         /// <summary>
         /// <summary>
         /// The buffer size used by CreateInstance(Stream).
         /// The buffer size used by CreateInstance(Stream).
@@ -257,11 +257,9 @@ namespace Google.ProtocolBuffers
 
 
         public void WriteBytes(int fieldNumber, ByteString value)
         public void WriteBytes(int fieldNumber, ByteString value)
         {
         {
-            // TODO(jonskeet): Optimise this! (No need to copy the bytes twice.)
             WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
             WriteTag(fieldNumber, WireFormat.WireType.LengthDelimited);
-            byte[] bytes = value.ToByteArray();
-            WriteRawVarint32((uint) bytes.Length);
-            WriteRawBytes(bytes);
+            WriteRawVarint32((uint)value.Length);
+            value.WriteTo(this);
         }
         }
 
 
         [CLSCompliant(false)]
         [CLSCompliant(false)]
@@ -564,10 +562,8 @@ namespace Google.ProtocolBuffers
 
 
         public void WriteBytesNoTag(ByteString value)
         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)]
         [CLSCompliant(false)]