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