1ffe3c632Sopenharmony_ci#region Copyright notice and license
2ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format
3ffe3c632Sopenharmony_ci// Copyright 2008 Google Inc.  All rights reserved.
4ffe3c632Sopenharmony_ci// https://developers.google.com/protocol-buffers/
5ffe3c632Sopenharmony_ci//
6ffe3c632Sopenharmony_ci// Redistribution and use in source and binary forms, with or without
7ffe3c632Sopenharmony_ci// modification, are permitted provided that the following conditions are
8ffe3c632Sopenharmony_ci// met:
9ffe3c632Sopenharmony_ci//
10ffe3c632Sopenharmony_ci//     * Redistributions of source code must retain the above copyright
11ffe3c632Sopenharmony_ci// notice, this list of conditions and the following disclaimer.
12ffe3c632Sopenharmony_ci//     * Redistributions in binary form must reproduce the above
13ffe3c632Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer
14ffe3c632Sopenharmony_ci// in the documentation and/or other materials provided with the
15ffe3c632Sopenharmony_ci// distribution.
16ffe3c632Sopenharmony_ci//     * Neither the name of Google Inc. nor the names of its
17ffe3c632Sopenharmony_ci// contributors may be used to endorse or promote products derived from
18ffe3c632Sopenharmony_ci// this software without specific prior written permission.
19ffe3c632Sopenharmony_ci//
20ffe3c632Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21ffe3c632Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22ffe3c632Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23ffe3c632Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24ffe3c632Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25ffe3c632Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26ffe3c632Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27ffe3c632Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28ffe3c632Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29ffe3c632Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30ffe3c632Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31ffe3c632Sopenharmony_ci#endregion
32ffe3c632Sopenharmony_ci
33ffe3c632Sopenharmony_ciusing System;
34ffe3c632Sopenharmony_ci
35ffe3c632Sopenharmony_cinamespace Google.Protobuf
36ffe3c632Sopenharmony_ci{
37ffe3c632Sopenharmony_ci    // This part of CodedOutputStream provides all the static entry points that are used
38ffe3c632Sopenharmony_ci    // by generated code and internally to compute the size of messages prior to being
39ffe3c632Sopenharmony_ci    // written to an instance of CodedOutputStream.
40ffe3c632Sopenharmony_ci    public sealed partial class CodedOutputStream
41ffe3c632Sopenharmony_ci    {
42ffe3c632Sopenharmony_ci        private const int LittleEndian64Size = 8;
43ffe3c632Sopenharmony_ci        private const int LittleEndian32Size = 4;
44ffe3c632Sopenharmony_ci
45ffe3c632Sopenharmony_ci        internal const int DoubleSize = LittleEndian64Size;
46ffe3c632Sopenharmony_ci        internal const int FloatSize = LittleEndian32Size;
47ffe3c632Sopenharmony_ci        internal const int BoolSize = 1;
48ffe3c632Sopenharmony_ci
49ffe3c632Sopenharmony_ci        /// <summary>
50ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
51ffe3c632Sopenharmony_ci        /// double field, including the tag.
52ffe3c632Sopenharmony_ci        /// </summary>
53ffe3c632Sopenharmony_ci        public static int ComputeDoubleSize(double value)
54ffe3c632Sopenharmony_ci        {
55ffe3c632Sopenharmony_ci            return DoubleSize;
56ffe3c632Sopenharmony_ci        }
57ffe3c632Sopenharmony_ci
58ffe3c632Sopenharmony_ci        /// <summary>
59ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
60ffe3c632Sopenharmony_ci        /// float field, including the tag.
61ffe3c632Sopenharmony_ci        /// </summary>
62ffe3c632Sopenharmony_ci        public static int ComputeFloatSize(float value)
63ffe3c632Sopenharmony_ci        {
64ffe3c632Sopenharmony_ci            return FloatSize;
65ffe3c632Sopenharmony_ci        }
66ffe3c632Sopenharmony_ci
67ffe3c632Sopenharmony_ci        /// <summary>
68ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
69ffe3c632Sopenharmony_ci        /// uint64 field, including the tag.
70ffe3c632Sopenharmony_ci        /// </summary>
71ffe3c632Sopenharmony_ci        public static int ComputeUInt64Size(ulong value)
72ffe3c632Sopenharmony_ci        {
73ffe3c632Sopenharmony_ci            return ComputeRawVarint64Size(value);
74ffe3c632Sopenharmony_ci        }
75ffe3c632Sopenharmony_ci
76ffe3c632Sopenharmony_ci        /// <summary>
77ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode an
78ffe3c632Sopenharmony_ci        /// int64 field, including the tag.
79ffe3c632Sopenharmony_ci        /// </summary>
80ffe3c632Sopenharmony_ci        public static int ComputeInt64Size(long value)
81ffe3c632Sopenharmony_ci        {
82ffe3c632Sopenharmony_ci            return ComputeRawVarint64Size((ulong) value);
83ffe3c632Sopenharmony_ci        }
84ffe3c632Sopenharmony_ci
85ffe3c632Sopenharmony_ci        /// <summary>
86ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode an
87ffe3c632Sopenharmony_ci        /// int32 field, including the tag.
88ffe3c632Sopenharmony_ci        /// </summary>
89ffe3c632Sopenharmony_ci        public static int ComputeInt32Size(int value)
90ffe3c632Sopenharmony_ci        {
91ffe3c632Sopenharmony_ci            if (value >= 0)
92ffe3c632Sopenharmony_ci            {
93ffe3c632Sopenharmony_ci                return ComputeRawVarint32Size((uint) value);
94ffe3c632Sopenharmony_ci            }
95ffe3c632Sopenharmony_ci            else
96ffe3c632Sopenharmony_ci            {
97ffe3c632Sopenharmony_ci                // Must sign-extend.
98ffe3c632Sopenharmony_ci                return 10;
99ffe3c632Sopenharmony_ci            }
100ffe3c632Sopenharmony_ci        }
101ffe3c632Sopenharmony_ci
102ffe3c632Sopenharmony_ci        /// <summary>
103ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
104ffe3c632Sopenharmony_ci        /// fixed64 field, including the tag.
105ffe3c632Sopenharmony_ci        /// </summary>
106ffe3c632Sopenharmony_ci        public static int ComputeFixed64Size(ulong value)
107ffe3c632Sopenharmony_ci        {
108ffe3c632Sopenharmony_ci            return LittleEndian64Size;
109ffe3c632Sopenharmony_ci        }
110ffe3c632Sopenharmony_ci
111ffe3c632Sopenharmony_ci        /// <summary>
112ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
113ffe3c632Sopenharmony_ci        /// fixed32 field, including the tag.
114ffe3c632Sopenharmony_ci        /// </summary>
115ffe3c632Sopenharmony_ci        public static int ComputeFixed32Size(uint value)
116ffe3c632Sopenharmony_ci        {
117ffe3c632Sopenharmony_ci            return LittleEndian32Size;
118ffe3c632Sopenharmony_ci        }
119ffe3c632Sopenharmony_ci
120ffe3c632Sopenharmony_ci        /// <summary>
121ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
122ffe3c632Sopenharmony_ci        /// bool field, including the tag.
123ffe3c632Sopenharmony_ci        /// </summary>
124ffe3c632Sopenharmony_ci        public static int ComputeBoolSize(bool value)
125ffe3c632Sopenharmony_ci        {
126ffe3c632Sopenharmony_ci            return BoolSize;
127ffe3c632Sopenharmony_ci        }
128ffe3c632Sopenharmony_ci
129ffe3c632Sopenharmony_ci        /// <summary>
130ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
131ffe3c632Sopenharmony_ci        /// string field, including the tag.
132ffe3c632Sopenharmony_ci        /// </summary>
133ffe3c632Sopenharmony_ci        public static int ComputeStringSize(String value)
134ffe3c632Sopenharmony_ci        {
135ffe3c632Sopenharmony_ci            int byteArraySize = WritingPrimitives.Utf8Encoding.GetByteCount(value);
136ffe3c632Sopenharmony_ci            return ComputeLengthSize(byteArraySize) + byteArraySize;
137ffe3c632Sopenharmony_ci        }
138ffe3c632Sopenharmony_ci
139ffe3c632Sopenharmony_ci        /// <summary>
140ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
141ffe3c632Sopenharmony_ci        /// group field, including the tag.
142ffe3c632Sopenharmony_ci        /// </summary>
143ffe3c632Sopenharmony_ci        public static int ComputeGroupSize(IMessage value)
144ffe3c632Sopenharmony_ci        {
145ffe3c632Sopenharmony_ci            return value.CalculateSize();
146ffe3c632Sopenharmony_ci        }
147ffe3c632Sopenharmony_ci
148ffe3c632Sopenharmony_ci        /// <summary>
149ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode an
150ffe3c632Sopenharmony_ci        /// embedded message field, including the tag.
151ffe3c632Sopenharmony_ci        /// </summary>
152ffe3c632Sopenharmony_ci        public static int ComputeMessageSize(IMessage value)
153ffe3c632Sopenharmony_ci        {
154ffe3c632Sopenharmony_ci            int size = value.CalculateSize();
155ffe3c632Sopenharmony_ci            return ComputeLengthSize(size) + size;
156ffe3c632Sopenharmony_ci        }
157ffe3c632Sopenharmony_ci
158ffe3c632Sopenharmony_ci        /// <summary>
159ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
160ffe3c632Sopenharmony_ci        /// bytes field, including the tag.
161ffe3c632Sopenharmony_ci        /// </summary>
162ffe3c632Sopenharmony_ci        public static int ComputeBytesSize(ByteString value)
163ffe3c632Sopenharmony_ci        {
164ffe3c632Sopenharmony_ci            return ComputeLengthSize(value.Length) + value.Length;
165ffe3c632Sopenharmony_ci        }
166ffe3c632Sopenharmony_ci
167ffe3c632Sopenharmony_ci        /// <summary>
168ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
169ffe3c632Sopenharmony_ci        /// uint32 field, including the tag.
170ffe3c632Sopenharmony_ci        /// </summary>
171ffe3c632Sopenharmony_ci        public static int ComputeUInt32Size(uint value)
172ffe3c632Sopenharmony_ci        {
173ffe3c632Sopenharmony_ci            return ComputeRawVarint32Size(value);
174ffe3c632Sopenharmony_ci        }
175ffe3c632Sopenharmony_ci
176ffe3c632Sopenharmony_ci        /// <summary>
177ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a
178ffe3c632Sopenharmony_ci        /// enum field, including the tag. The caller is responsible for
179ffe3c632Sopenharmony_ci        /// converting the enum value to its numeric value.
180ffe3c632Sopenharmony_ci        /// </summary>
181ffe3c632Sopenharmony_ci        public static int ComputeEnumSize(int value)
182ffe3c632Sopenharmony_ci        {
183ffe3c632Sopenharmony_ci            // Currently just a pass-through, but it's nice to separate it logically.
184ffe3c632Sopenharmony_ci            return ComputeInt32Size(value);
185ffe3c632Sopenharmony_ci        }
186ffe3c632Sopenharmony_ci
187ffe3c632Sopenharmony_ci        /// <summary>
188ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode an
189ffe3c632Sopenharmony_ci        /// sfixed32 field, including the tag.
190ffe3c632Sopenharmony_ci        /// </summary>
191ffe3c632Sopenharmony_ci        public static int ComputeSFixed32Size(int value)
192ffe3c632Sopenharmony_ci        {
193ffe3c632Sopenharmony_ci            return LittleEndian32Size;
194ffe3c632Sopenharmony_ci        }
195ffe3c632Sopenharmony_ci
196ffe3c632Sopenharmony_ci        /// <summary>
197ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode an
198ffe3c632Sopenharmony_ci        /// sfixed64 field, including the tag.
199ffe3c632Sopenharmony_ci        /// </summary>
200ffe3c632Sopenharmony_ci        public static int ComputeSFixed64Size(long value)
201ffe3c632Sopenharmony_ci        {
202ffe3c632Sopenharmony_ci            return LittleEndian64Size;
203ffe3c632Sopenharmony_ci        }
204ffe3c632Sopenharmony_ci
205ffe3c632Sopenharmony_ci        /// <summary>
206ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode an
207ffe3c632Sopenharmony_ci        /// sint32 field, including the tag.
208ffe3c632Sopenharmony_ci        /// </summary>
209ffe3c632Sopenharmony_ci        public static int ComputeSInt32Size(int value)
210ffe3c632Sopenharmony_ci        {
211ffe3c632Sopenharmony_ci            return ComputeRawVarint32Size(WritingPrimitives.EncodeZigZag32(value));
212ffe3c632Sopenharmony_ci        }
213ffe3c632Sopenharmony_ci
214ffe3c632Sopenharmony_ci        /// <summary>
215ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode an
216ffe3c632Sopenharmony_ci        /// sint64 field, including the tag.
217ffe3c632Sopenharmony_ci        /// </summary>
218ffe3c632Sopenharmony_ci        public static int ComputeSInt64Size(long value)
219ffe3c632Sopenharmony_ci        {
220ffe3c632Sopenharmony_ci            return ComputeRawVarint64Size(WritingPrimitives.EncodeZigZag64(value));
221ffe3c632Sopenharmony_ci        }
222ffe3c632Sopenharmony_ci
223ffe3c632Sopenharmony_ci        /// <summary>
224ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a length,
225ffe3c632Sopenharmony_ci        /// as written by <see cref="WriteLength"/>.
226ffe3c632Sopenharmony_ci        /// </summary>
227ffe3c632Sopenharmony_ci        public static int ComputeLengthSize(int length)
228ffe3c632Sopenharmony_ci        {
229ffe3c632Sopenharmony_ci            return ComputeRawVarint32Size((uint) length);
230ffe3c632Sopenharmony_ci        }
231ffe3c632Sopenharmony_ci
232ffe3c632Sopenharmony_ci        /// <summary>
233ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a varint.
234ffe3c632Sopenharmony_ci        /// </summary>
235ffe3c632Sopenharmony_ci        public static int ComputeRawVarint32Size(uint value)
236ffe3c632Sopenharmony_ci        {
237ffe3c632Sopenharmony_ci            if ((value & (0xffffffff << 7)) == 0)
238ffe3c632Sopenharmony_ci            {
239ffe3c632Sopenharmony_ci                return 1;
240ffe3c632Sopenharmony_ci            }
241ffe3c632Sopenharmony_ci            if ((value & (0xffffffff << 14)) == 0)
242ffe3c632Sopenharmony_ci            {
243ffe3c632Sopenharmony_ci                return 2;
244ffe3c632Sopenharmony_ci            }
245ffe3c632Sopenharmony_ci            if ((value & (0xffffffff << 21)) == 0)
246ffe3c632Sopenharmony_ci            {
247ffe3c632Sopenharmony_ci                return 3;
248ffe3c632Sopenharmony_ci            }
249ffe3c632Sopenharmony_ci            if ((value & (0xffffffff << 28)) == 0)
250ffe3c632Sopenharmony_ci            {
251ffe3c632Sopenharmony_ci                return 4;
252ffe3c632Sopenharmony_ci            }
253ffe3c632Sopenharmony_ci            return 5;
254ffe3c632Sopenharmony_ci        }
255ffe3c632Sopenharmony_ci
256ffe3c632Sopenharmony_ci        /// <summary>
257ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a varint.
258ffe3c632Sopenharmony_ci        /// </summary>
259ffe3c632Sopenharmony_ci        public static int ComputeRawVarint64Size(ulong value)
260ffe3c632Sopenharmony_ci        {
261ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 7)) == 0)
262ffe3c632Sopenharmony_ci            {
263ffe3c632Sopenharmony_ci                return 1;
264ffe3c632Sopenharmony_ci            }
265ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 14)) == 0)
266ffe3c632Sopenharmony_ci            {
267ffe3c632Sopenharmony_ci                return 2;
268ffe3c632Sopenharmony_ci            }
269ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 21)) == 0)
270ffe3c632Sopenharmony_ci            {
271ffe3c632Sopenharmony_ci                return 3;
272ffe3c632Sopenharmony_ci            }
273ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 28)) == 0)
274ffe3c632Sopenharmony_ci            {
275ffe3c632Sopenharmony_ci                return 4;
276ffe3c632Sopenharmony_ci            }
277ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 35)) == 0)
278ffe3c632Sopenharmony_ci            {
279ffe3c632Sopenharmony_ci                return 5;
280ffe3c632Sopenharmony_ci            }
281ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 42)) == 0)
282ffe3c632Sopenharmony_ci            {
283ffe3c632Sopenharmony_ci                return 6;
284ffe3c632Sopenharmony_ci            }
285ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 49)) == 0)
286ffe3c632Sopenharmony_ci            {
287ffe3c632Sopenharmony_ci                return 7;
288ffe3c632Sopenharmony_ci            }
289ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 56)) == 0)
290ffe3c632Sopenharmony_ci            {
291ffe3c632Sopenharmony_ci                return 8;
292ffe3c632Sopenharmony_ci            }
293ffe3c632Sopenharmony_ci            if ((value & (0xffffffffffffffffL << 63)) == 0)
294ffe3c632Sopenharmony_ci            {
295ffe3c632Sopenharmony_ci                return 9;
296ffe3c632Sopenharmony_ci            }
297ffe3c632Sopenharmony_ci            return 10;
298ffe3c632Sopenharmony_ci        }
299ffe3c632Sopenharmony_ci
300ffe3c632Sopenharmony_ci        /// <summary>
301ffe3c632Sopenharmony_ci        /// Computes the number of bytes that would be needed to encode a tag.
302ffe3c632Sopenharmony_ci        /// </summary>
303ffe3c632Sopenharmony_ci        public static int ComputeTagSize(int fieldNumber)
304ffe3c632Sopenharmony_ci        {
305ffe3c632Sopenharmony_ci            return ComputeRawVarint32Size(WireFormat.MakeTag(fieldNumber, 0));
306ffe3c632Sopenharmony_ci        }
307ffe3c632Sopenharmony_ci    }
308ffe3c632Sopenharmony_ci}