• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 // Protocol Buffers - Google's data interchange format
3 // Copyright 2008 Google Inc.  All rights reserved.
4 //
5 // Use of this source code is governed by a BSD-style
6 // license that can be found in the LICENSE file or at
7 // https://developers.google.com/open-source/licenses/bsd
8 #endregion
9 
10 using System;
11 using System.Buffers;
12 using System.Runtime.CompilerServices;
13 using System.Security;
14 
15 namespace Google.Protobuf
16 {
17     /// <summary>
18     /// An opaque struct that represents the current serialization state and is passed along
19     /// as the serialization proceeds.
20     /// All the public methods are intended to be invoked only by the generated code,
21     /// users should never invoke them directly.
22     /// </summary>
23     [SecuritySafeCritical]
24     public ref struct WriteContext
25     {
26         internal Span<byte> buffer;
27         internal WriterInternalState state;
28 
29         [MethodImpl(MethodImplOptions.AggressiveInlining)]
InitializeGoogle.Protobuf.WriteContext30         internal static void Initialize(ref Span<byte> buffer, ref WriterInternalState state, out WriteContext ctx)
31         {
32             ctx.buffer = buffer;
33             ctx.state = state;
34         }
35 
36         /// <summary>
37         /// Creates a WriteContext instance from CodedOutputStream.
38         /// WARNING: internally this copies the CodedOutputStream's state, so after done with the WriteContext,
39         /// the CodedOutputStream's state needs to be updated.
40         /// </summary>
41         [MethodImpl(MethodImplOptions.AggressiveInlining)]
InitializeGoogle.Protobuf.WriteContext42         internal static void Initialize(CodedOutputStream output, out WriteContext ctx)
43         {
44             ctx.buffer = new Span<byte>(output.InternalBuffer);
45             // ideally we would use a reference to the original state, but that doesn't seem possible
46             // so we just copy the struct that holds the state. We will need to later store the state back
47             // into CodedOutputStream if we want to keep it usable.
48             ctx.state = output.InternalState;
49         }
50 
51         [MethodImpl(MethodImplOptions.AggressiveInlining)]
InitializeGoogle.Protobuf.WriteContext52         internal static void Initialize(IBufferWriter<byte> output, out WriteContext ctx)
53         {
54             ctx.buffer = default;
55             ctx.state = default;
56             WriteBufferHelper.Initialize(output, out ctx.state.writeBufferHelper, out ctx.buffer);
57             ctx.state.limit = ctx.buffer.Length;
58             ctx.state.position = 0;
59         }
60 
61         [MethodImpl(MethodImplOptions.AggressiveInlining)]
InitializeGoogle.Protobuf.WriteContext62         internal static void Initialize(ref Span<byte> buffer, out WriteContext ctx)
63         {
64             ctx.buffer = buffer;
65             ctx.state = default;
66             ctx.state.limit = ctx.buffer.Length;
67             ctx.state.position = 0;
68             WriteBufferHelper.InitializeNonRefreshable(out ctx.state.writeBufferHelper);
69         }
70 
71         /// <summary>
72         /// Writes a double field value, without a tag.
73         /// </summary>
74         /// <param name="value">The value to write</param>
WriteDoubleGoogle.Protobuf.WriteContext75         public void WriteDouble(double value) => WritingPrimitives.WriteDouble(ref buffer, ref state, value);
76 
77         /// <summary>
78         /// Writes a float field value, without a tag.
79         /// </summary>
80         /// <param name="value">The value to write</param>
WriteFloatGoogle.Protobuf.WriteContext81         public void WriteFloat(float value) => WritingPrimitives.WriteFloat(ref buffer, ref state, value);
82 
83         /// <summary>
84         /// Writes a uint64 field value, without a tag.
85         /// </summary>
86         /// <param name="value">The value to write</param>
WriteUInt64Google.Protobuf.WriteContext87         public void WriteUInt64(ulong value) => WritingPrimitives.WriteUInt64(ref buffer, ref state, value);
88 
89         /// <summary>
90         /// Writes an int64 field value, without a tag.
91         /// </summary>
92         /// <param name="value">The value to write</param>
WriteInt64Google.Protobuf.WriteContext93         public void WriteInt64(long value) => WritingPrimitives.WriteInt64(ref buffer, ref state, value);
94 
95         /// <summary>
96         /// Writes an int32 field value, without a tag.
97         /// </summary>
98         /// <param name="value">The value to write</param>
WriteInt32Google.Protobuf.WriteContext99         public void WriteInt32(int value) => WritingPrimitives.WriteInt32(ref buffer, ref state, value);
100 
101         /// <summary>
102         /// Writes a fixed64 field value, without a tag.
103         /// </summary>
104         /// <param name="value">The value to write</param>
WriteFixed64Google.Protobuf.WriteContext105         public void WriteFixed64(ulong value) => WritingPrimitives.WriteFixed64(ref buffer, ref state, value);
106 
107         /// <summary>
108         /// Writes a fixed32 field value, without a tag.
109         /// </summary>
110         /// <param name="value">The value to write</param>
WriteFixed32Google.Protobuf.WriteContext111         public void WriteFixed32(uint value) => WritingPrimitives.WriteFixed32(ref buffer, ref state, value);
112 
113         /// <summary>
114         /// Writes a bool field value, without a tag.
115         /// </summary>
116         /// <param name="value">The value to write</param>
117         public void WriteBool(bool value) => WritingPrimitives.WriteBool(ref buffer, ref state, value);
118 
119         /// <summary>
120         /// Writes a string field value, without a tag.
121         /// The data is length-prefixed.
122         /// </summary>
123         /// <param name="value">The value to write</param>
WriteStringGoogle.Protobuf.WriteContext124         public void WriteString(string value) => WritingPrimitives.WriteString(ref buffer, ref state, value);
125 
126         /// <summary>
127         /// Writes a message, without a tag.
128         /// The data is length-prefixed.
129         /// </summary>
130         /// <param name="value">The value to write</param>
131         public void WriteMessage(IMessage value) => WritingPrimitivesMessages.WriteMessage(ref this, value);
132 
133         /// <summary>
134         /// Writes a group, without a tag, to the stream.
135         /// </summary>
136         /// <param name="value">The value to write</param>
137         public void WriteGroup(IMessage value) => WritingPrimitivesMessages.WriteGroup(ref this, value);
138 
139         /// <summary>
140         /// Write a byte string, without a tag, to the stream.
141         /// The data is length-prefixed.
142         /// </summary>
143         /// <param name="value">The value to write</param>
144         public void WriteBytes(ByteString value) => WritingPrimitives.WriteBytes(ref buffer, ref state, value);
145 
146         /// <summary>
147         /// Writes a uint32 value, without a tag.
148         /// </summary>
149         /// <param name="value">The value to write</param>
WriteUInt32Google.Protobuf.WriteContext150         public void WriteUInt32(uint value) => WritingPrimitives.WriteUInt32(ref buffer, ref state, value);
151 
152         /// <summary>
153         /// Writes an enum value, without a tag.
154         /// </summary>
155         /// <param name="value">The value to write</param>
WriteEnumGoogle.Protobuf.WriteContext156         public void WriteEnum(int value) => WritingPrimitives.WriteEnum(ref buffer, ref state, value);
157 
158         /// <summary>
159         /// Writes an sfixed32 value, without a tag.
160         /// </summary>
161         /// <param name="value">The value to write.</param>
WriteSFixed32Google.Protobuf.WriteContext162         public void WriteSFixed32(int value) => WritingPrimitives.WriteSFixed32(ref buffer, ref state, value);
163 
164         /// <summary>
165         /// Writes an sfixed64 value, without a tag.
166         /// </summary>
167         /// <param name="value">The value to write</param>
WriteSFixed64Google.Protobuf.WriteContext168         public void WriteSFixed64(long value) => WritingPrimitives.WriteSFixed64(ref buffer, ref state, value);
169 
170         /// <summary>
171         /// Writes an sint32 value, without a tag.
172         /// </summary>
173         /// <param name="value">The value to write</param>
WriteSInt32Google.Protobuf.WriteContext174         public void WriteSInt32(int value) => WritingPrimitives.WriteSInt32(ref buffer, ref state, value);
175 
176         /// <summary>
177         /// Writes an sint64 value, without a tag.
178         /// </summary>
179         /// <param name="value">The value to write</param>
WriteSInt64Google.Protobuf.WriteContext180         public void WriteSInt64(long value) => WritingPrimitives.WriteSInt64(ref buffer, ref state, value);
181 
182         /// <summary>
183         /// Writes a length (in bytes) for length-delimited data.
184         /// </summary>
185         /// <remarks>
186         /// This method simply writes a rawint, but exists for clarity in calling code.
187         /// </remarks>
188         /// <param name="length">Length value, in bytes.</param>
WriteLengthGoogle.Protobuf.WriteContext189         public void WriteLength(int length) => WritingPrimitives.WriteLength(ref buffer, ref state, length);
190 
191         /// <summary>
192         /// Encodes and writes a tag.
193         /// </summary>
194         /// <param name="fieldNumber">The number of the field to write the tag for</param>
195         /// <param name="type">The wire format type of the tag to write</param>
WriteTagGoogle.Protobuf.WriteContext196         public void WriteTag(int fieldNumber, WireFormat.WireType type) => WritingPrimitives.WriteTag(ref buffer, ref state, fieldNumber, type);
197 
198         /// <summary>
199         /// Writes an already-encoded tag.
200         /// </summary>
201         /// <param name="tag">The encoded tag</param>
WriteTagGoogle.Protobuf.WriteContext202         public void WriteTag(uint tag) => WritingPrimitives.WriteTag(ref buffer, ref state, tag);
203 
204         /// <summary>
205         /// Writes the given single-byte tag.
206         /// </summary>
207         /// <param name="b1">The encoded tag</param>
208         public void WriteRawTag(byte b1) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1);
209 
210         /// <summary>
211         /// Writes the given two-byte tag.
212         /// </summary>
213         /// <param name="b1">The first byte of the encoded tag</param>
214         /// <param name="b2">The second byte of the encoded tag</param>
WriteRawTagGoogle.Protobuf.WriteContext215         public void WriteRawTag(byte b1, byte b2) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2);
216 
217         /// <summary>
218         /// Writes the given three-byte tag.
219         /// </summary>
220         /// <param name="b1">The first byte of the encoded tag</param>
221         /// <param name="b2">The second byte of the encoded tag</param>
222         /// <param name="b3">The third byte of the encoded tag</param>
WriteRawTagGoogle.Protobuf.WriteContext223         public void WriteRawTag(byte b1, byte b2, byte b3) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3);
224 
225         /// <summary>
226         /// Writes the given four-byte tag.
227         /// </summary>
228         /// <param name="b1">The first byte of the encoded tag</param>
229         /// <param name="b2">The second byte of the encoded tag</param>
230         /// <param name="b3">The third byte of the encoded tag</param>
231         /// <param name="b4">The fourth byte of the encoded tag</param>
WriteRawTagGoogle.Protobuf.WriteContext232         public void WriteRawTag(byte b1, byte b2, byte b3, byte b4) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4);
233 
234         /// <summary>
235         /// Writes the given five-byte tag.
236         /// </summary>
237         /// <param name="b1">The first byte of the encoded tag</param>
238         /// <param name="b2">The second byte of the encoded tag</param>
239         /// <param name="b3">The third byte of the encoded tag</param>
240         /// <param name="b4">The fourth byte of the encoded tag</param>
241         /// <param name="b5">The fifth byte of the encoded tag</param>
WriteRawTagGoogle.Protobuf.WriteContext242         public void WriteRawTag(byte b1, byte b2, byte b3, byte b4, byte b5) => WritingPrimitives.WriteRawTag(ref buffer, ref state, b1, b2, b3, b4, b5);
243 
FlushGoogle.Protobuf.WriteContext244         internal void Flush() => WriteBufferHelper.Flush(ref buffer, ref state);
245 
CheckNoSpaceLeftGoogle.Protobuf.WriteContext246         internal void CheckNoSpaceLeft() => WriteBufferHelper.CheckNoSpaceLeft(ref state);
247 
CopyStateToGoogle.Protobuf.WriteContext248         internal void CopyStateTo(CodedOutputStream output)
249         {
250             output.InternalState = state;
251         }
252 
LoadStateFromGoogle.Protobuf.WriteContext253         internal void LoadStateFrom(CodedOutputStream output)
254         {
255             state = output.InternalState;
256         }
257     }
258 }