1*1b3f573fSAndroid Build Coastguard Worker #region Copyright notice and license 2*1b3f573fSAndroid Build Coastguard Worker // Protocol Buffers - Google's data interchange format 3*1b3f573fSAndroid Build Coastguard Worker // Copyright 2008 Google Inc. All rights reserved. 4*1b3f573fSAndroid Build Coastguard Worker // https://developers.google.com/protocol-buffers/ 5*1b3f573fSAndroid Build Coastguard Worker // 6*1b3f573fSAndroid Build Coastguard Worker // Redistribution and use in source and binary forms, with or without 7*1b3f573fSAndroid Build Coastguard Worker // modification, are permitted provided that the following conditions are 8*1b3f573fSAndroid Build Coastguard Worker // met: 9*1b3f573fSAndroid Build Coastguard Worker // 10*1b3f573fSAndroid Build Coastguard Worker // * Redistributions of source code must retain the above copyright 11*1b3f573fSAndroid Build Coastguard Worker // notice, this list of conditions and the following disclaimer. 12*1b3f573fSAndroid Build Coastguard Worker // * Redistributions in binary form must reproduce the above 13*1b3f573fSAndroid Build Coastguard Worker // copyright notice, this list of conditions and the following disclaimer 14*1b3f573fSAndroid Build Coastguard Worker // in the documentation and/or other materials provided with the 15*1b3f573fSAndroid Build Coastguard Worker // distribution. 16*1b3f573fSAndroid Build Coastguard Worker // * Neither the name of Google Inc. nor the names of its 17*1b3f573fSAndroid Build Coastguard Worker // contributors may be used to endorse or promote products derived from 18*1b3f573fSAndroid Build Coastguard Worker // this software without specific prior written permission. 19*1b3f573fSAndroid Build Coastguard Worker // 20*1b3f573fSAndroid Build Coastguard Worker // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21*1b3f573fSAndroid Build Coastguard Worker // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23*1b3f573fSAndroid Build Coastguard Worker // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24*1b3f573fSAndroid Build Coastguard Worker // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25*1b3f573fSAndroid Build Coastguard Worker // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26*1b3f573fSAndroid Build Coastguard Worker // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27*1b3f573fSAndroid Build Coastguard Worker // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28*1b3f573fSAndroid Build Coastguard Worker // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29*1b3f573fSAndroid Build Coastguard Worker // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30*1b3f573fSAndroid Build Coastguard Worker // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31*1b3f573fSAndroid Build Coastguard Worker #endregion 32*1b3f573fSAndroid Build Coastguard Worker 33*1b3f573fSAndroid Build Coastguard Worker using Google.Protobuf.Collections; 34*1b3f573fSAndroid Build Coastguard Worker using System; 35*1b3f573fSAndroid Build Coastguard Worker using System.IO; 36*1b3f573fSAndroid Build Coastguard Worker using System.Security; 37*1b3f573fSAndroid Build Coastguard Worker using System.Text; 38*1b3f573fSAndroid Build Coastguard Worker 39*1b3f573fSAndroid Build Coastguard Worker namespace Google.Protobuf 40*1b3f573fSAndroid Build Coastguard Worker { 41*1b3f573fSAndroid Build Coastguard Worker /// <summary> 42*1b3f573fSAndroid Build Coastguard Worker /// Encodes and writes protocol message fields. 43*1b3f573fSAndroid Build Coastguard Worker /// </summary> 44*1b3f573fSAndroid Build Coastguard Worker /// <remarks> 45*1b3f573fSAndroid Build Coastguard Worker /// <para> 46*1b3f573fSAndroid Build Coastguard Worker /// This class is generally used by generated code to write appropriate 47*1b3f573fSAndroid Build Coastguard Worker /// primitives to the stream. It effectively encapsulates the lowest 48*1b3f573fSAndroid Build Coastguard Worker /// levels of protocol buffer format. Unlike some other implementations, 49*1b3f573fSAndroid Build Coastguard Worker /// this does not include combined "write tag and value" methods. Generated 50*1b3f573fSAndroid Build Coastguard Worker /// code knows the exact byte representations of the tags they're going to write, 51*1b3f573fSAndroid Build Coastguard Worker /// so there's no need to re-encode them each time. Manually-written code calling 52*1b3f573fSAndroid Build Coastguard Worker /// this class should just call one of the <c>WriteTag</c> overloads before each value. 53*1b3f573fSAndroid Build Coastguard Worker /// </para> 54*1b3f573fSAndroid Build Coastguard Worker /// <para> 55*1b3f573fSAndroid Build Coastguard Worker /// Repeated fields and map fields are not handled by this class; use <c>RepeatedField<T></c> 56*1b3f573fSAndroid Build Coastguard Worker /// and <c>MapField<TKey, TValue></c> to serialize such fields. 57*1b3f573fSAndroid Build Coastguard Worker /// </para> 58*1b3f573fSAndroid Build Coastguard Worker /// </remarks> 59*1b3f573fSAndroid Build Coastguard Worker [SecuritySafeCritical] 60*1b3f573fSAndroid Build Coastguard Worker public sealed partial class CodedOutputStream : IDisposable 61*1b3f573fSAndroid Build Coastguard Worker { 62*1b3f573fSAndroid Build Coastguard Worker /// <summary> 63*1b3f573fSAndroid Build Coastguard Worker /// The buffer size used by CreateInstance(Stream). 64*1b3f573fSAndroid Build Coastguard Worker /// </summary> 65*1b3f573fSAndroid Build Coastguard Worker public static readonly int DefaultBufferSize = 4096; 66*1b3f573fSAndroid Build Coastguard Worker 67*1b3f573fSAndroid Build Coastguard Worker private readonly bool leaveOpen; 68*1b3f573fSAndroid Build Coastguard Worker private readonly byte[] buffer; 69*1b3f573fSAndroid Build Coastguard Worker private WriterInternalState state; 70*1b3f573fSAndroid Build Coastguard Worker 71*1b3f573fSAndroid Build Coastguard Worker private readonly Stream output; 72*1b3f573fSAndroid Build Coastguard Worker 73*1b3f573fSAndroid Build Coastguard Worker #region Construction 74*1b3f573fSAndroid Build Coastguard Worker /// <summary> 75*1b3f573fSAndroid Build Coastguard Worker /// Creates a new CodedOutputStream that writes directly to the given 76*1b3f573fSAndroid Build Coastguard Worker /// byte array. If more bytes are written than fit in the array, 77*1b3f573fSAndroid Build Coastguard Worker /// OutOfSpaceException will be thrown. 78*1b3f573fSAndroid Build Coastguard Worker /// </summary> CodedOutputStream(byte[] flatArray)79*1b3f573fSAndroid Build Coastguard Worker public CodedOutputStream(byte[] flatArray) : this(flatArray, 0, flatArray.Length) 80*1b3f573fSAndroid Build Coastguard Worker { 81*1b3f573fSAndroid Build Coastguard Worker } 82*1b3f573fSAndroid Build Coastguard Worker 83*1b3f573fSAndroid Build Coastguard Worker /// <summary> 84*1b3f573fSAndroid Build Coastguard Worker /// Creates a new CodedOutputStream that writes directly to the given 85*1b3f573fSAndroid Build Coastguard Worker /// byte array slice. If more bytes are written than fit in the array, 86*1b3f573fSAndroid Build Coastguard Worker /// OutOfSpaceException will be thrown. 87*1b3f573fSAndroid Build Coastguard Worker /// </summary> CodedOutputStream(byte[] buffer, int offset, int length)88*1b3f573fSAndroid Build Coastguard Worker private CodedOutputStream(byte[] buffer, int offset, int length) 89*1b3f573fSAndroid Build Coastguard Worker { 90*1b3f573fSAndroid Build Coastguard Worker this.output = null; 91*1b3f573fSAndroid Build Coastguard Worker this.buffer = ProtoPreconditions.CheckNotNull(buffer, nameof(buffer)); 92*1b3f573fSAndroid Build Coastguard Worker this.state.position = offset; 93*1b3f573fSAndroid Build Coastguard Worker this.state.limit = offset + length; 94*1b3f573fSAndroid Build Coastguard Worker WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper); 95*1b3f573fSAndroid Build Coastguard Worker leaveOpen = true; // Simple way of avoiding trying to dispose of a null reference 96*1b3f573fSAndroid Build Coastguard Worker } 97*1b3f573fSAndroid Build Coastguard Worker CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen)98*1b3f573fSAndroid Build Coastguard Worker private CodedOutputStream(Stream output, byte[] buffer, bool leaveOpen) 99*1b3f573fSAndroid Build Coastguard Worker { 100*1b3f573fSAndroid Build Coastguard Worker this.output = ProtoPreconditions.CheckNotNull(output, nameof(output)); 101*1b3f573fSAndroid Build Coastguard Worker this.buffer = buffer; 102*1b3f573fSAndroid Build Coastguard Worker this.state.position = 0; 103*1b3f573fSAndroid Build Coastguard Worker this.state.limit = buffer.Length; 104*1b3f573fSAndroid Build Coastguard Worker WriteBufferHelper.Initialize(this, out this.state.writeBufferHelper); 105*1b3f573fSAndroid Build Coastguard Worker this.leaveOpen = leaveOpen; 106*1b3f573fSAndroid Build Coastguard Worker } 107*1b3f573fSAndroid Build Coastguard Worker 108*1b3f573fSAndroid Build Coastguard Worker /// <summary> 109*1b3f573fSAndroid Build Coastguard Worker /// Creates a new <see cref="CodedOutputStream" /> which write to the given stream, and disposes of that 110*1b3f573fSAndroid Build Coastguard Worker /// stream when the returned <c>CodedOutputStream</c> is disposed. 111*1b3f573fSAndroid Build Coastguard Worker /// </summary> 112*1b3f573fSAndroid Build Coastguard Worker /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param> CodedOutputStream(Stream output)113*1b3f573fSAndroid Build Coastguard Worker public CodedOutputStream(Stream output) : this(output, DefaultBufferSize, false) 114*1b3f573fSAndroid Build Coastguard Worker { 115*1b3f573fSAndroid Build Coastguard Worker } 116*1b3f573fSAndroid Build Coastguard Worker 117*1b3f573fSAndroid Build Coastguard Worker /// <summary> 118*1b3f573fSAndroid Build Coastguard Worker /// Creates a new CodedOutputStream which write to the given stream and uses 119*1b3f573fSAndroid Build Coastguard Worker /// the specified buffer size. 120*1b3f573fSAndroid Build Coastguard Worker /// </summary> 121*1b3f573fSAndroid Build Coastguard Worker /// <param name="output">The stream to write to. It will be disposed when the returned <c>CodedOutputStream is disposed.</c></param> 122*1b3f573fSAndroid Build Coastguard Worker /// <param name="bufferSize">The size of buffer to use internally.</param> CodedOutputStream(Stream output, int bufferSize)123*1b3f573fSAndroid Build Coastguard Worker public CodedOutputStream(Stream output, int bufferSize) : this(output, new byte[bufferSize], false) 124*1b3f573fSAndroid Build Coastguard Worker { 125*1b3f573fSAndroid Build Coastguard Worker } 126*1b3f573fSAndroid Build Coastguard Worker 127*1b3f573fSAndroid Build Coastguard Worker /// <summary> 128*1b3f573fSAndroid Build Coastguard Worker /// Creates a new CodedOutputStream which write to the given stream. 129*1b3f573fSAndroid Build Coastguard Worker /// </summary> 130*1b3f573fSAndroid Build Coastguard Worker /// <param name="output">The stream to write to.</param> 131*1b3f573fSAndroid Build Coastguard Worker /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed; 132*1b3f573fSAndroid Build Coastguard Worker /// if <c>false</c>, the provided stream is disposed as well.</param> CodedOutputStream(Stream output, bool leaveOpen)133*1b3f573fSAndroid Build Coastguard Worker public CodedOutputStream(Stream output, bool leaveOpen) : this(output, DefaultBufferSize, leaveOpen) 134*1b3f573fSAndroid Build Coastguard Worker { 135*1b3f573fSAndroid Build Coastguard Worker } 136*1b3f573fSAndroid Build Coastguard Worker 137*1b3f573fSAndroid Build Coastguard Worker /// <summary> 138*1b3f573fSAndroid Build Coastguard Worker /// Creates a new CodedOutputStream which write to the given stream and uses 139*1b3f573fSAndroid Build Coastguard Worker /// the specified buffer size. 140*1b3f573fSAndroid Build Coastguard Worker /// </summary> 141*1b3f573fSAndroid Build Coastguard Worker /// <param name="output">The stream to write to.</param> 142*1b3f573fSAndroid Build Coastguard Worker /// <param name="bufferSize">The size of buffer to use internally.</param> 143*1b3f573fSAndroid Build Coastguard Worker /// <param name="leaveOpen">If <c>true</c>, <paramref name="output"/> is left open when the returned <c>CodedOutputStream</c> is disposed; 144*1b3f573fSAndroid Build Coastguard Worker /// if <c>false</c>, the provided stream is disposed as well.</param> CodedOutputStream(Stream output, int bufferSize, bool leaveOpen)145*1b3f573fSAndroid Build Coastguard Worker public CodedOutputStream(Stream output, int bufferSize, bool leaveOpen) : this(output, new byte[bufferSize], leaveOpen) 146*1b3f573fSAndroid Build Coastguard Worker { 147*1b3f573fSAndroid Build Coastguard Worker } 148*1b3f573fSAndroid Build Coastguard Worker #endregion 149*1b3f573fSAndroid Build Coastguard Worker 150*1b3f573fSAndroid Build Coastguard Worker /// <summary> 151*1b3f573fSAndroid Build Coastguard Worker /// Returns the current position in the stream, or the position in the output buffer 152*1b3f573fSAndroid Build Coastguard Worker /// </summary> 153*1b3f573fSAndroid Build Coastguard Worker public long Position 154*1b3f573fSAndroid Build Coastguard Worker { 155*1b3f573fSAndroid Build Coastguard Worker get 156*1b3f573fSAndroid Build Coastguard Worker { 157*1b3f573fSAndroid Build Coastguard Worker if (output != null) 158*1b3f573fSAndroid Build Coastguard Worker { 159*1b3f573fSAndroid Build Coastguard Worker return output.Position + state.position; 160*1b3f573fSAndroid Build Coastguard Worker } 161*1b3f573fSAndroid Build Coastguard Worker return state.position; 162*1b3f573fSAndroid Build Coastguard Worker } 163*1b3f573fSAndroid Build Coastguard Worker } 164*1b3f573fSAndroid Build Coastguard Worker 165*1b3f573fSAndroid Build Coastguard Worker #region Writing of values (not including tags) 166*1b3f573fSAndroid Build Coastguard Worker 167*1b3f573fSAndroid Build Coastguard Worker /// <summary> 168*1b3f573fSAndroid Build Coastguard Worker /// Writes a double field value, without a tag, to the stream. 169*1b3f573fSAndroid Build Coastguard Worker /// </summary> 170*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteDouble(double value)171*1b3f573fSAndroid Build Coastguard Worker public void WriteDouble(double value) 172*1b3f573fSAndroid Build Coastguard Worker { 173*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 174*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteDouble(ref span, ref state, value); 175*1b3f573fSAndroid Build Coastguard Worker } 176*1b3f573fSAndroid Build Coastguard Worker 177*1b3f573fSAndroid Build Coastguard Worker /// <summary> 178*1b3f573fSAndroid Build Coastguard Worker /// Writes a float field value, without a tag, to the stream. 179*1b3f573fSAndroid Build Coastguard Worker /// </summary> 180*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteFloat(float value)181*1b3f573fSAndroid Build Coastguard Worker public void WriteFloat(float value) 182*1b3f573fSAndroid Build Coastguard Worker { 183*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 184*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteFloat(ref span, ref state, value); 185*1b3f573fSAndroid Build Coastguard Worker } 186*1b3f573fSAndroid Build Coastguard Worker 187*1b3f573fSAndroid Build Coastguard Worker /// <summary> 188*1b3f573fSAndroid Build Coastguard Worker /// Writes a uint64 field value, without a tag, to the stream. 189*1b3f573fSAndroid Build Coastguard Worker /// </summary> 190*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteUInt64(ulong value)191*1b3f573fSAndroid Build Coastguard Worker public void WriteUInt64(ulong value) 192*1b3f573fSAndroid Build Coastguard Worker { 193*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 194*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteUInt64(ref span, ref state, value); 195*1b3f573fSAndroid Build Coastguard Worker } 196*1b3f573fSAndroid Build Coastguard Worker 197*1b3f573fSAndroid Build Coastguard Worker /// <summary> 198*1b3f573fSAndroid Build Coastguard Worker /// Writes an int64 field value, without a tag, to the stream. 199*1b3f573fSAndroid Build Coastguard Worker /// </summary> 200*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteInt64(long value)201*1b3f573fSAndroid Build Coastguard Worker public void WriteInt64(long value) 202*1b3f573fSAndroid Build Coastguard Worker { 203*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 204*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteInt64(ref span, ref state, value); 205*1b3f573fSAndroid Build Coastguard Worker } 206*1b3f573fSAndroid Build Coastguard Worker 207*1b3f573fSAndroid Build Coastguard Worker /// <summary> 208*1b3f573fSAndroid Build Coastguard Worker /// Writes an int32 field value, without a tag, to the stream. 209*1b3f573fSAndroid Build Coastguard Worker /// </summary> 210*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteInt32(int value)211*1b3f573fSAndroid Build Coastguard Worker public void WriteInt32(int value) 212*1b3f573fSAndroid Build Coastguard Worker { 213*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 214*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteInt32(ref span, ref state, value); 215*1b3f573fSAndroid Build Coastguard Worker } 216*1b3f573fSAndroid Build Coastguard Worker 217*1b3f573fSAndroid Build Coastguard Worker /// <summary> 218*1b3f573fSAndroid Build Coastguard Worker /// Writes a fixed64 field value, without a tag, to the stream. 219*1b3f573fSAndroid Build Coastguard Worker /// </summary> 220*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteFixed64(ulong value)221*1b3f573fSAndroid Build Coastguard Worker public void WriteFixed64(ulong value) 222*1b3f573fSAndroid Build Coastguard Worker { 223*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 224*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteFixed64(ref span, ref state, value); 225*1b3f573fSAndroid Build Coastguard Worker } 226*1b3f573fSAndroid Build Coastguard Worker 227*1b3f573fSAndroid Build Coastguard Worker /// <summary> 228*1b3f573fSAndroid Build Coastguard Worker /// Writes a fixed32 field value, without a tag, to the stream. 229*1b3f573fSAndroid Build Coastguard Worker /// </summary> 230*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteFixed32(uint value)231*1b3f573fSAndroid Build Coastguard Worker public void WriteFixed32(uint value) 232*1b3f573fSAndroid Build Coastguard Worker { 233*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 234*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteFixed32(ref span, ref state, value); 235*1b3f573fSAndroid Build Coastguard Worker } 236*1b3f573fSAndroid Build Coastguard Worker 237*1b3f573fSAndroid Build Coastguard Worker /// <summary> 238*1b3f573fSAndroid Build Coastguard Worker /// Writes a bool field value, without a tag, to the stream. 239*1b3f573fSAndroid Build Coastguard Worker /// </summary> 240*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteBool(bool value)241*1b3f573fSAndroid Build Coastguard Worker public void WriteBool(bool value) 242*1b3f573fSAndroid Build Coastguard Worker { 243*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 244*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteBool(ref span, ref state, value); 245*1b3f573fSAndroid Build Coastguard Worker } 246*1b3f573fSAndroid Build Coastguard Worker 247*1b3f573fSAndroid Build Coastguard Worker /// <summary> 248*1b3f573fSAndroid Build Coastguard Worker /// Writes a string field value, without a tag, to the stream. 249*1b3f573fSAndroid Build Coastguard Worker /// The data is length-prefixed. 250*1b3f573fSAndroid Build Coastguard Worker /// </summary> 251*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteString(string value)252*1b3f573fSAndroid Build Coastguard Worker public void WriteString(string value) 253*1b3f573fSAndroid Build Coastguard Worker { 254*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 255*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteString(ref span, ref state, value); 256*1b3f573fSAndroid Build Coastguard Worker } 257*1b3f573fSAndroid Build Coastguard Worker 258*1b3f573fSAndroid Build Coastguard Worker /// <summary> 259*1b3f573fSAndroid Build Coastguard Worker /// Writes a message, without a tag, to the stream. 260*1b3f573fSAndroid Build Coastguard Worker /// The data is length-prefixed. 261*1b3f573fSAndroid Build Coastguard Worker /// </summary> 262*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteMessage(IMessage value)263*1b3f573fSAndroid Build Coastguard Worker public void WriteMessage(IMessage value) 264*1b3f573fSAndroid Build Coastguard Worker { 265*1b3f573fSAndroid Build Coastguard Worker // TODO(jtattermusch): if the message doesn't implement IBufferMessage (and thus does not provide the InternalWriteTo method), 266*1b3f573fSAndroid Build Coastguard Worker // what we're doing here works fine, but could be more efficient. 267*1b3f573fSAndroid Build Coastguard Worker // For now, this inefficiency is fine, considering this is only a backward-compatibility scenario (and regenerating the code fixes it). 268*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 269*1b3f573fSAndroid Build Coastguard Worker WriteContext.Initialize(ref span, ref state, out WriteContext ctx); 270*1b3f573fSAndroid Build Coastguard Worker try 271*1b3f573fSAndroid Build Coastguard Worker { 272*1b3f573fSAndroid Build Coastguard Worker WritingPrimitivesMessages.WriteMessage(ref ctx, value); 273*1b3f573fSAndroid Build Coastguard Worker } 274*1b3f573fSAndroid Build Coastguard Worker finally 275*1b3f573fSAndroid Build Coastguard Worker { 276*1b3f573fSAndroid Build Coastguard Worker ctx.CopyStateTo(this); 277*1b3f573fSAndroid Build Coastguard Worker } 278*1b3f573fSAndroid Build Coastguard Worker } 279*1b3f573fSAndroid Build Coastguard Worker 280*1b3f573fSAndroid Build Coastguard Worker /// <summary> 281*1b3f573fSAndroid Build Coastguard Worker /// Writes a message, without a tag, to the stream. 282*1b3f573fSAndroid Build Coastguard Worker /// Only the message data is written, without a length-delimiter. 283*1b3f573fSAndroid Build Coastguard Worker /// </summary> 284*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteRawMessage(IMessage value)285*1b3f573fSAndroid Build Coastguard Worker public void WriteRawMessage(IMessage value) 286*1b3f573fSAndroid Build Coastguard Worker { 287*1b3f573fSAndroid Build Coastguard Worker // TODO(jtattermusch): if the message doesn't implement IBufferMessage (and thus does not provide the InternalWriteTo method), 288*1b3f573fSAndroid Build Coastguard Worker // what we're doing here works fine, but could be more efficient. 289*1b3f573fSAndroid Build Coastguard Worker // For now, this inefficiency is fine, considering this is only a backward-compatibility scenario (and regenerating the code fixes it). 290*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 291*1b3f573fSAndroid Build Coastguard Worker WriteContext.Initialize(ref span, ref state, out WriteContext ctx); 292*1b3f573fSAndroid Build Coastguard Worker try 293*1b3f573fSAndroid Build Coastguard Worker { 294*1b3f573fSAndroid Build Coastguard Worker WritingPrimitivesMessages.WriteRawMessage(ref ctx, value); 295*1b3f573fSAndroid Build Coastguard Worker } 296*1b3f573fSAndroid Build Coastguard Worker finally 297*1b3f573fSAndroid Build Coastguard Worker { 298*1b3f573fSAndroid Build Coastguard Worker ctx.CopyStateTo(this); 299*1b3f573fSAndroid Build Coastguard Worker } 300*1b3f573fSAndroid Build Coastguard Worker } 301*1b3f573fSAndroid Build Coastguard Worker 302*1b3f573fSAndroid Build Coastguard Worker /// <summary> 303*1b3f573fSAndroid Build Coastguard Worker /// Writes a group, without a tag, to the stream. 304*1b3f573fSAndroid Build Coastguard Worker /// </summary> 305*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteGroup(IMessage value)306*1b3f573fSAndroid Build Coastguard Worker public void WriteGroup(IMessage value) 307*1b3f573fSAndroid Build Coastguard Worker { 308*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 309*1b3f573fSAndroid Build Coastguard Worker WriteContext.Initialize(ref span, ref state, out WriteContext ctx); 310*1b3f573fSAndroid Build Coastguard Worker try 311*1b3f573fSAndroid Build Coastguard Worker { 312*1b3f573fSAndroid Build Coastguard Worker WritingPrimitivesMessages.WriteGroup(ref ctx, value); 313*1b3f573fSAndroid Build Coastguard Worker } 314*1b3f573fSAndroid Build Coastguard Worker finally 315*1b3f573fSAndroid Build Coastguard Worker { 316*1b3f573fSAndroid Build Coastguard Worker ctx.CopyStateTo(this); 317*1b3f573fSAndroid Build Coastguard Worker } 318*1b3f573fSAndroid Build Coastguard Worker } 319*1b3f573fSAndroid Build Coastguard Worker 320*1b3f573fSAndroid Build Coastguard Worker /// <summary> 321*1b3f573fSAndroid Build Coastguard Worker /// Write a byte string, without a tag, to the stream. 322*1b3f573fSAndroid Build Coastguard Worker /// The data is length-prefixed. 323*1b3f573fSAndroid Build Coastguard Worker /// </summary> 324*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteBytes(ByteString value)325*1b3f573fSAndroid Build Coastguard Worker public void WriteBytes(ByteString value) 326*1b3f573fSAndroid Build Coastguard Worker { 327*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 328*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteBytes(ref span, ref state, value); 329*1b3f573fSAndroid Build Coastguard Worker } 330*1b3f573fSAndroid Build Coastguard Worker 331*1b3f573fSAndroid Build Coastguard Worker /// <summary> 332*1b3f573fSAndroid Build Coastguard Worker /// Writes a uint32 value, without a tag, to the stream. 333*1b3f573fSAndroid Build Coastguard Worker /// </summary> 334*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteUInt32(uint value)335*1b3f573fSAndroid Build Coastguard Worker public void WriteUInt32(uint value) 336*1b3f573fSAndroid Build Coastguard Worker { 337*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 338*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteUInt32(ref span, ref state, value); 339*1b3f573fSAndroid Build Coastguard Worker } 340*1b3f573fSAndroid Build Coastguard Worker 341*1b3f573fSAndroid Build Coastguard Worker /// <summary> 342*1b3f573fSAndroid Build Coastguard Worker /// Writes an enum value, without a tag, to the stream. 343*1b3f573fSAndroid Build Coastguard Worker /// </summary> 344*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteEnum(int value)345*1b3f573fSAndroid Build Coastguard Worker public void WriteEnum(int value) 346*1b3f573fSAndroid Build Coastguard Worker { 347*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 348*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteEnum(ref span, ref state, value); 349*1b3f573fSAndroid Build Coastguard Worker } 350*1b3f573fSAndroid Build Coastguard Worker 351*1b3f573fSAndroid Build Coastguard Worker /// <summary> 352*1b3f573fSAndroid Build Coastguard Worker /// Writes an sfixed32 value, without a tag, to the stream. 353*1b3f573fSAndroid Build Coastguard Worker /// </summary> 354*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write.</param> WriteSFixed32(int value)355*1b3f573fSAndroid Build Coastguard Worker public void WriteSFixed32(int value) 356*1b3f573fSAndroid Build Coastguard Worker { 357*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 358*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteSFixed32(ref span, ref state, value); 359*1b3f573fSAndroid Build Coastguard Worker } 360*1b3f573fSAndroid Build Coastguard Worker 361*1b3f573fSAndroid Build Coastguard Worker /// <summary> 362*1b3f573fSAndroid Build Coastguard Worker /// Writes an sfixed64 value, without a tag, to the stream. 363*1b3f573fSAndroid Build Coastguard Worker /// </summary> 364*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteSFixed64(long value)365*1b3f573fSAndroid Build Coastguard Worker public void WriteSFixed64(long value) 366*1b3f573fSAndroid Build Coastguard Worker { 367*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 368*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteSFixed64(ref span, ref state, value); 369*1b3f573fSAndroid Build Coastguard Worker } 370*1b3f573fSAndroid Build Coastguard Worker 371*1b3f573fSAndroid Build Coastguard Worker /// <summary> 372*1b3f573fSAndroid Build Coastguard Worker /// Writes an sint32 value, without a tag, to the stream. 373*1b3f573fSAndroid Build Coastguard Worker /// </summary> 374*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteSInt32(int value)375*1b3f573fSAndroid Build Coastguard Worker public void WriteSInt32(int value) 376*1b3f573fSAndroid Build Coastguard Worker { 377*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 378*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteSInt32(ref span, ref state, value); 379*1b3f573fSAndroid Build Coastguard Worker } 380*1b3f573fSAndroid Build Coastguard Worker 381*1b3f573fSAndroid Build Coastguard Worker /// <summary> 382*1b3f573fSAndroid Build Coastguard Worker /// Writes an sint64 value, without a tag, to the stream. 383*1b3f573fSAndroid Build Coastguard Worker /// </summary> 384*1b3f573fSAndroid Build Coastguard Worker /// <param name="value">The value to write</param> WriteSInt64(long value)385*1b3f573fSAndroid Build Coastguard Worker public void WriteSInt64(long value) 386*1b3f573fSAndroid Build Coastguard Worker { 387*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 388*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteSInt64(ref span, ref state, value); 389*1b3f573fSAndroid Build Coastguard Worker } 390*1b3f573fSAndroid Build Coastguard Worker 391*1b3f573fSAndroid Build Coastguard Worker /// <summary> 392*1b3f573fSAndroid Build Coastguard Worker /// Writes a length (in bytes) for length-delimited data. 393*1b3f573fSAndroid Build Coastguard Worker /// </summary> 394*1b3f573fSAndroid Build Coastguard Worker /// <remarks> 395*1b3f573fSAndroid Build Coastguard Worker /// This method simply writes a rawint, but exists for clarity in calling code. 396*1b3f573fSAndroid Build Coastguard Worker /// </remarks> 397*1b3f573fSAndroid Build Coastguard Worker /// <param name="length">Length value, in bytes.</param> WriteLength(int length)398*1b3f573fSAndroid Build Coastguard Worker public void WriteLength(int length) 399*1b3f573fSAndroid Build Coastguard Worker { 400*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 401*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteLength(ref span, ref state, length); 402*1b3f573fSAndroid Build Coastguard Worker } 403*1b3f573fSAndroid Build Coastguard Worker 404*1b3f573fSAndroid Build Coastguard Worker #endregion 405*1b3f573fSAndroid Build Coastguard Worker 406*1b3f573fSAndroid Build Coastguard Worker #region Raw tag writing 407*1b3f573fSAndroid Build Coastguard Worker /// <summary> 408*1b3f573fSAndroid Build Coastguard Worker /// Encodes and writes a tag. 409*1b3f573fSAndroid Build Coastguard Worker /// </summary> 410*1b3f573fSAndroid Build Coastguard Worker /// <param name="fieldNumber">The number of the field to write the tag for</param> 411*1b3f573fSAndroid Build Coastguard Worker /// <param name="type">The wire format type of the tag to write</param> WriteTag(int fieldNumber, WireFormat.WireType type)412*1b3f573fSAndroid Build Coastguard Worker public void WriteTag(int fieldNumber, WireFormat.WireType type) 413*1b3f573fSAndroid Build Coastguard Worker { 414*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 415*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteTag(ref span, ref state, fieldNumber, type); 416*1b3f573fSAndroid Build Coastguard Worker } 417*1b3f573fSAndroid Build Coastguard Worker 418*1b3f573fSAndroid Build Coastguard Worker /// <summary> 419*1b3f573fSAndroid Build Coastguard Worker /// Writes an already-encoded tag. 420*1b3f573fSAndroid Build Coastguard Worker /// </summary> 421*1b3f573fSAndroid Build Coastguard Worker /// <param name="tag">The encoded tag</param> WriteTag(uint tag)422*1b3f573fSAndroid Build Coastguard Worker public void WriteTag(uint tag) 423*1b3f573fSAndroid Build Coastguard Worker { 424*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 425*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteTag(ref span, ref state, tag); 426*1b3f573fSAndroid Build Coastguard Worker } 427*1b3f573fSAndroid Build Coastguard Worker 428*1b3f573fSAndroid Build Coastguard Worker /// <summary> 429*1b3f573fSAndroid Build Coastguard Worker /// Writes the given single-byte tag directly to the stream. 430*1b3f573fSAndroid Build Coastguard Worker /// </summary> 431*1b3f573fSAndroid Build Coastguard Worker /// <param name="b1">The encoded tag</param> WriteRawTag(byte b1)432*1b3f573fSAndroid Build Coastguard Worker public void WriteRawTag(byte b1) 433*1b3f573fSAndroid Build Coastguard Worker { 434*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 435*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawTag(ref span, ref state, b1); 436*1b3f573fSAndroid Build Coastguard Worker } 437*1b3f573fSAndroid Build Coastguard Worker 438*1b3f573fSAndroid Build Coastguard Worker /// <summary> 439*1b3f573fSAndroid Build Coastguard Worker /// Writes the given two-byte tag directly to the stream. 440*1b3f573fSAndroid Build Coastguard Worker /// </summary> 441*1b3f573fSAndroid Build Coastguard Worker /// <param name="b1">The first byte of the encoded tag</param> 442*1b3f573fSAndroid Build Coastguard Worker /// <param name="b2">The second byte of the encoded tag</param> WriteRawTag(byte b1, byte b2)443*1b3f573fSAndroid Build Coastguard Worker public void WriteRawTag(byte b1, byte b2) 444*1b3f573fSAndroid Build Coastguard Worker { 445*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 446*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2); 447*1b3f573fSAndroid Build Coastguard Worker } 448*1b3f573fSAndroid Build Coastguard Worker 449*1b3f573fSAndroid Build Coastguard Worker /// <summary> 450*1b3f573fSAndroid Build Coastguard Worker /// Writes the given three-byte tag directly to the stream. 451*1b3f573fSAndroid Build Coastguard Worker /// </summary> 452*1b3f573fSAndroid Build Coastguard Worker /// <param name="b1">The first byte of the encoded tag</param> 453*1b3f573fSAndroid Build Coastguard Worker /// <param name="b2">The second byte of the encoded tag</param> 454*1b3f573fSAndroid Build Coastguard Worker /// <param name="b3">The third byte of the encoded tag</param> WriteRawTag(byte b1, byte b2, byte b3)455*1b3f573fSAndroid Build Coastguard Worker public void WriteRawTag(byte b1, byte b2, byte b3) 456*1b3f573fSAndroid Build Coastguard Worker { 457*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 458*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3); 459*1b3f573fSAndroid Build Coastguard Worker } 460*1b3f573fSAndroid Build Coastguard Worker 461*1b3f573fSAndroid Build Coastguard Worker /// <summary> 462*1b3f573fSAndroid Build Coastguard Worker /// Writes the given four-byte tag directly to the stream. 463*1b3f573fSAndroid Build Coastguard Worker /// </summary> 464*1b3f573fSAndroid Build Coastguard Worker /// <param name="b1">The first byte of the encoded tag</param> 465*1b3f573fSAndroid Build Coastguard Worker /// <param name="b2">The second byte of the encoded tag</param> 466*1b3f573fSAndroid Build Coastguard Worker /// <param name="b3">The third byte of the encoded tag</param> 467*1b3f573fSAndroid Build Coastguard Worker /// <param name="b4">The fourth byte of the encoded tag</param> WriteRawTag(byte b1, byte b2, byte b3, byte b4)468*1b3f573fSAndroid Build Coastguard Worker public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) 469*1b3f573fSAndroid Build Coastguard Worker { 470*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 471*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4); 472*1b3f573fSAndroid Build Coastguard Worker } 473*1b3f573fSAndroid Build Coastguard Worker 474*1b3f573fSAndroid Build Coastguard Worker /// <summary> 475*1b3f573fSAndroid Build Coastguard Worker /// Writes the given five-byte tag directly to the stream. 476*1b3f573fSAndroid Build Coastguard Worker /// </summary> 477*1b3f573fSAndroid Build Coastguard Worker /// <param name="b1">The first byte of the encoded tag</param> 478*1b3f573fSAndroid Build Coastguard Worker /// <param name="b2">The second byte of the encoded tag</param> 479*1b3f573fSAndroid Build Coastguard Worker /// <param name="b3">The third byte of the encoded tag</param> 480*1b3f573fSAndroid Build Coastguard Worker /// <param name="b4">The fourth byte of the encoded tag</param> 481*1b3f573fSAndroid Build Coastguard Worker /// <param name="b5">The fifth byte of the encoded tag</param> WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5)482*1b3f573fSAndroid Build Coastguard Worker public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) 483*1b3f573fSAndroid Build Coastguard Worker { 484*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 485*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawTag(ref span, ref state, b1, b2, b3, b4, b5); 486*1b3f573fSAndroid Build Coastguard Worker } 487*1b3f573fSAndroid Build Coastguard Worker #endregion 488*1b3f573fSAndroid Build Coastguard Worker 489*1b3f573fSAndroid Build Coastguard Worker #region Underlying writing primitives 490*1b3f573fSAndroid Build Coastguard Worker 491*1b3f573fSAndroid Build Coastguard Worker /// <summary> 492*1b3f573fSAndroid Build Coastguard Worker /// Writes a 32 bit value as a varint. The fast route is taken when 493*1b3f573fSAndroid Build Coastguard Worker /// there's enough buffer space left to whizz through without checking 494*1b3f573fSAndroid Build Coastguard Worker /// for each byte; otherwise, we resort to calling WriteRawByte each time. 495*1b3f573fSAndroid Build Coastguard Worker /// </summary> WriteRawVarint32(uint value)496*1b3f573fSAndroid Build Coastguard Worker internal void WriteRawVarint32(uint value) 497*1b3f573fSAndroid Build Coastguard Worker { 498*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 499*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawVarint32(ref span, ref state, value); 500*1b3f573fSAndroid Build Coastguard Worker } 501*1b3f573fSAndroid Build Coastguard Worker WriteRawVarint64(ulong value)502*1b3f573fSAndroid Build Coastguard Worker internal void WriteRawVarint64(ulong value) 503*1b3f573fSAndroid Build Coastguard Worker { 504*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 505*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawVarint64(ref span, ref state, value); 506*1b3f573fSAndroid Build Coastguard Worker } 507*1b3f573fSAndroid Build Coastguard Worker WriteRawLittleEndian32(uint value)508*1b3f573fSAndroid Build Coastguard Worker internal void WriteRawLittleEndian32(uint value) 509*1b3f573fSAndroid Build Coastguard Worker { 510*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 511*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawLittleEndian32(ref span, ref state, value); 512*1b3f573fSAndroid Build Coastguard Worker } 513*1b3f573fSAndroid Build Coastguard Worker WriteRawLittleEndian64(ulong value)514*1b3f573fSAndroid Build Coastguard Worker internal void WriteRawLittleEndian64(ulong value) 515*1b3f573fSAndroid Build Coastguard Worker { 516*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 517*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawLittleEndian64(ref span, ref state, value); 518*1b3f573fSAndroid Build Coastguard Worker } 519*1b3f573fSAndroid Build Coastguard Worker 520*1b3f573fSAndroid Build Coastguard Worker /// <summary> 521*1b3f573fSAndroid Build Coastguard Worker /// Writes out an array of bytes. 522*1b3f573fSAndroid Build Coastguard Worker /// </summary> WriteRawBytes(byte[] value)523*1b3f573fSAndroid Build Coastguard Worker internal void WriteRawBytes(byte[] value) 524*1b3f573fSAndroid Build Coastguard Worker { 525*1b3f573fSAndroid Build Coastguard Worker WriteRawBytes(value, 0, value.Length); 526*1b3f573fSAndroid Build Coastguard Worker } 527*1b3f573fSAndroid Build Coastguard Worker 528*1b3f573fSAndroid Build Coastguard Worker /// <summary> 529*1b3f573fSAndroid Build Coastguard Worker /// Writes out part of an array of bytes. 530*1b3f573fSAndroid Build Coastguard Worker /// </summary> WriteRawBytes(byte[] value, int offset, int length)531*1b3f573fSAndroid Build Coastguard Worker internal void WriteRawBytes(byte[] value, int offset, int length) 532*1b3f573fSAndroid Build Coastguard Worker { 533*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 534*1b3f573fSAndroid Build Coastguard Worker WritingPrimitives.WriteRawBytes(ref span, ref state, value, offset, length); 535*1b3f573fSAndroid Build Coastguard Worker } 536*1b3f573fSAndroid Build Coastguard Worker 537*1b3f573fSAndroid Build Coastguard Worker #endregion 538*1b3f573fSAndroid Build Coastguard Worker 539*1b3f573fSAndroid Build Coastguard Worker /// <summary> 540*1b3f573fSAndroid Build Coastguard Worker /// Indicates that a CodedOutputStream wrapping a flat byte array 541*1b3f573fSAndroid Build Coastguard Worker /// ran out of space. 542*1b3f573fSAndroid Build Coastguard Worker /// </summary> 543*1b3f573fSAndroid Build Coastguard Worker public sealed class OutOfSpaceException : IOException 544*1b3f573fSAndroid Build Coastguard Worker { OutOfSpaceException()545*1b3f573fSAndroid Build Coastguard Worker internal OutOfSpaceException() 546*1b3f573fSAndroid Build Coastguard Worker : base("CodedOutputStream was writing to a flat byte array and ran out of space.") 547*1b3f573fSAndroid Build Coastguard Worker { 548*1b3f573fSAndroid Build Coastguard Worker } 549*1b3f573fSAndroid Build Coastguard Worker } 550*1b3f573fSAndroid Build Coastguard Worker 551*1b3f573fSAndroid Build Coastguard Worker /// <summary> 552*1b3f573fSAndroid Build Coastguard Worker /// Flushes any buffered data and optionally closes the underlying stream, if any. 553*1b3f573fSAndroid Build Coastguard Worker /// </summary> 554*1b3f573fSAndroid Build Coastguard Worker /// <remarks> 555*1b3f573fSAndroid Build Coastguard Worker /// <para> 556*1b3f573fSAndroid Build Coastguard Worker /// By default, any underlying stream is closed by this method. To configure this behaviour, 557*1b3f573fSAndroid Build Coastguard Worker /// use a constructor overload with a <c>leaveOpen</c> parameter. If this instance does not 558*1b3f573fSAndroid Build Coastguard Worker /// have an underlying stream, this method does nothing. 559*1b3f573fSAndroid Build Coastguard Worker /// </para> 560*1b3f573fSAndroid Build Coastguard Worker /// <para> 561*1b3f573fSAndroid Build Coastguard Worker /// For the sake of efficiency, calling this method does not prevent future write calls - but 562*1b3f573fSAndroid Build Coastguard Worker /// if a later write ends up writing to a stream which has been disposed, that is likely to 563*1b3f573fSAndroid Build Coastguard Worker /// fail. It is recommend that you not call any other methods after this. 564*1b3f573fSAndroid Build Coastguard Worker /// </para> 565*1b3f573fSAndroid Build Coastguard Worker /// </remarks> Dispose()566*1b3f573fSAndroid Build Coastguard Worker public void Dispose() 567*1b3f573fSAndroid Build Coastguard Worker { 568*1b3f573fSAndroid Build Coastguard Worker Flush(); 569*1b3f573fSAndroid Build Coastguard Worker if (!leaveOpen) 570*1b3f573fSAndroid Build Coastguard Worker { 571*1b3f573fSAndroid Build Coastguard Worker output.Dispose(); 572*1b3f573fSAndroid Build Coastguard Worker } 573*1b3f573fSAndroid Build Coastguard Worker } 574*1b3f573fSAndroid Build Coastguard Worker 575*1b3f573fSAndroid Build Coastguard Worker /// <summary> 576*1b3f573fSAndroid Build Coastguard Worker /// Flushes any buffered data to the underlying stream (if there is one). 577*1b3f573fSAndroid Build Coastguard Worker /// </summary> Flush()578*1b3f573fSAndroid Build Coastguard Worker public void Flush() 579*1b3f573fSAndroid Build Coastguard Worker { 580*1b3f573fSAndroid Build Coastguard Worker var span = new Span<byte>(buffer); 581*1b3f573fSAndroid Build Coastguard Worker WriteBufferHelper.Flush(ref span, ref state); 582*1b3f573fSAndroid Build Coastguard Worker } 583*1b3f573fSAndroid Build Coastguard Worker 584*1b3f573fSAndroid Build Coastguard Worker /// <summary> 585*1b3f573fSAndroid Build Coastguard Worker /// Verifies that SpaceLeft returns zero. It's common to create a byte array 586*1b3f573fSAndroid Build Coastguard Worker /// that is exactly big enough to hold a message, then write to it with 587*1b3f573fSAndroid Build Coastguard Worker /// a CodedOutputStream. Calling CheckNoSpaceLeft after writing verifies that 588*1b3f573fSAndroid Build Coastguard Worker /// the message was actually as big as expected, which can help finding bugs. 589*1b3f573fSAndroid Build Coastguard Worker /// </summary> CheckNoSpaceLeft()590*1b3f573fSAndroid Build Coastguard Worker public void CheckNoSpaceLeft() 591*1b3f573fSAndroid Build Coastguard Worker { 592*1b3f573fSAndroid Build Coastguard Worker WriteBufferHelper.CheckNoSpaceLeft(ref state); 593*1b3f573fSAndroid Build Coastguard Worker } 594*1b3f573fSAndroid Build Coastguard Worker 595*1b3f573fSAndroid Build Coastguard Worker /// <summary> 596*1b3f573fSAndroid Build Coastguard Worker /// If writing to a flat array, returns the space left in the array. Otherwise, 597*1b3f573fSAndroid Build Coastguard Worker /// throws an InvalidOperationException. 598*1b3f573fSAndroid Build Coastguard Worker /// </summary> 599*1b3f573fSAndroid Build Coastguard Worker public int SpaceLeft => WriteBufferHelper.GetSpaceLeft(ref state); 600*1b3f573fSAndroid Build Coastguard Worker 601*1b3f573fSAndroid Build Coastguard Worker internal byte[] InternalBuffer => buffer; 602*1b3f573fSAndroid Build Coastguard Worker 603*1b3f573fSAndroid Build Coastguard Worker internal Stream InternalOutputStream => output; 604*1b3f573fSAndroid Build Coastguard Worker 605*1b3f573fSAndroid Build Coastguard Worker internal ref WriterInternalState InternalState => ref state; 606*1b3f573fSAndroid Build Coastguard Worker } 607*1b3f573fSAndroid Build Coastguard Worker } 608