/// <summary> /// Writes out part of an array of bytes. /// </summary> public static void WriteRawBytes(ref Span <byte> buffer, ref WriterInternalState state, ReadOnlySpan <byte> value) { if (buffer.Length - state.position >= value.Length) { // We have room in the current buffer. value.CopyTo(buffer.Slice(state.position, value.Length)); state.position += value.Length; } else { // When writing to a CodedOutputStream backed by a Stream, we could avoid // copying the data twice (first copying to the current buffer and // and later writing from the current buffer to the underlying Stream) // in some circumstances by writing the data directly to the underlying Stream. // Current this is not being done to avoid specialcasing the code for // CodedOutputStream vs IBufferWriter<byte>. int bytesWritten = 0; while (buffer.Length - state.position < value.Length - bytesWritten) { int length = buffer.Length - state.position; value.Slice(bytesWritten, length).CopyTo(buffer.Slice(state.position, length)); bytesWritten += length; state.position += length; WriteBufferHelper.RefreshBuffer(ref buffer, ref state); } // copy the remaining data int remainderLength = value.Length - bytesWritten; value.Slice(bytesWritten, remainderLength).CopyTo(buffer.Slice(state.position, remainderLength)); state.position += remainderLength; } }
internal static void Initialize(IBufferWriter <byte> output, out WriteContext ctx) { ctx.buffer = default; ctx.state = default; WriteBufferHelper.Initialize(output, out ctx.state.writeBufferHelper, out ctx.buffer); ctx.state.limit = ctx.buffer.Length; ctx.state.position = 0; }
internal static void Initialize(ref Span <byte> buffer, out WriteContext ctx) { ctx.buffer = buffer; ctx.state = default; ctx.state.limit = ctx.buffer.Length; ctx.state.position = 0; WriteBufferHelper.InitializeNonRefreshable(out ctx.state.writeBufferHelper); }
private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen) { this.output = ProtoPreconditions.CheckNotNull(output, nameof(output)); this.buffer = buffer; this.state.position = 0; this.state.limit = buffer.Length; WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper); this.leaveOpen = leaveOpen; }
/// <summary> /// Creates a new CodedOutputStream that writes directly to the given /// byte array slice. If more bytes are written than fit in the array, /// OutOfSpaceException will be thrown. /// </summary> private CodedOutputStream(byte[] buffer, int offset, int length) { this.output = null; this.buffer = ProtoPreconditions.CheckNotNull(buffer, nameof(buffer)); this.state.position = offset; this.state.limit = offset + length; WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper); leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference }
private static void WriteRawByte(ref Span <byte> buffer, ref WriterInternalState state, byte value) { if (state.position == buffer.Length) { WriteBufferHelper.RefreshBuffer(ref buffer, ref state); } buffer[state.position++] = value; }
/// <summary> /// Verifies that SpaceLeft returns zero. It's common to create a byte array /// that is exactly big enough to hold a message, then write to it with /// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that /// the message was actually as big as expected, which can help finding bugs. /// </summary> public void CheckNoSpaceLeft() { WriteBufferHelper.CheckNoSpaceLeft(ref state); }
/// <summary> /// Flushes any buffered data to the underlying stream (if there is one). /// </summary> public void Flush() { var span = new Span <byte>(buffer); WriteBufferHelper.Flush(ref span, ref state); }
internal void CheckNoSpaceLeft() { WriteBufferHelper.CheckNoSpaceLeft(ref state); }
internal void Flush() { WriteBufferHelper.Flush(ref buffer, ref state); }
public static void InitializeNonRefreshable(out WriteBufferHelper instance) { instance.bufferWriter = null; instance.codedOutputStream = null; }
public static void Initialize(IBufferWriter <byte> bufferWriter, out WriteBufferHelper instance, out Span <byte> buffer) { instance.bufferWriter = bufferWriter; instance.codedOutputStream = null; buffer = default; // TODO: initialize the initial buffer so that the first write is not via slowpath. }
public static void Initialize(CodedOutputStream codedOutputStream, out WriteBufferHelper instance) { instance.bufferWriter = null; instance.codedOutputStream = codedOutputStream; }