xref: /aosp_15_r20/external/protobuf/csharp/src/Google.Protobuf/CodedOutputStream.cs (revision 1b3f573f81763fcece89efc2b6a5209149e44ab8)
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&lt;T&gt;</c>
56*1b3f573fSAndroid Build Coastguard Worker     /// and <c>MapField&lt;TKey, TValue&gt;</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