Optimized access to ByteString from coded io.

pull/288/head
csharptest 14 years ago committed by rogerk
parent efed509b55
commit 45a93fad4d
  1. 29
      src/ProtocolBuffers/ByteString.cs
  2. 4
      src/ProtocolBuffers/CodedInputStream.cs
  3. 14
      src/ProtocolBuffers/CodedOutputStream.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);
}
} }
} }

@ -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));
} }
} }

@ -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)value.Length);
WriteRawVarint32((uint) bytes.Length); value.WriteTo(this);
WriteRawBytes(bytes);
} }
[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.) WriteRawVarint32((uint)value.Length);
byte[] bytes = value.ToByteArray(); value.WriteTo(this);
WriteRawVarint32((uint) bytes.Length);
WriteRawBytes(bytes);
} }
[CLSCompliant(false)] [CLSCompliant(false)]

Loading…
Cancel
Save