Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/0.9.1/ProtobufCS/src/ProtocolBuffers/UnknownField.cs @ 4095

Last change on this file since 4095 was 3857, checked in by abeham, 14 years ago

#866

  • Added protobuf-csharp-port project source to ExtLibs
File size: 13.6 KB
Line 
1#region Copyright notice and license
2// Protocol Buffers - Google's data interchange format
3// Copyright 2008 Google Inc.  All rights reserved.
4// http://github.com/jskeet/dotnet-protobufs/
5// Original C++/Java/Python code:
6// http://code.google.com/p/protobuf/
7//
8// Redistribution and use in source and binary forms, with or without
9// modification, are permitted provided that the following conditions are
10// met:
11//
12//     * Redistributions of source code must retain the above copyright
13// notice, this list of conditions and the following disclaimer.
14//     * Redistributions in binary form must reproduce the above
15// copyright notice, this list of conditions and the following disclaimer
16// in the documentation and/or other materials provided with the
17// distribution.
18//     * Neither the name of Google Inc. nor the names of its
19// contributors may be used to endorse or promote products derived from
20// this software without specific prior written permission.
21//
22// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33#endregion
34
35using System;
36using System.Collections.Generic;
37using System.Collections.ObjectModel;
38using Google.ProtocolBuffers.Collections;
39
40namespace Google.ProtocolBuffers {
41  /// <summary>
42  /// Represents a single field in an UnknownFieldSet.
43  ///
44  /// An UnknownField consists of five lists of values. The lists correspond
45   /// to the five "wire types" used in the protocol buffer binary format.
46   /// The wire type of each field can be determined from the encoded form alone,
47   /// without knowing the field's declared type. So, we are able to parse
48   /// unknown values at least this far and separate them. Normally, only one
49   /// of the five lists will contain any values, since it is impossible to
50   /// define a valid message type that declares two different types for the
51   /// same field number. However, the code is designed to allow for the case
52   /// where the same unknown field number is encountered using multiple different
53   /// wire types.
54   ///
55   /// UnknownField is an immutable class. To construct one, you must use an
56   /// UnknownField.Builder.
57  /// </summary>
58  public sealed class UnknownField {
59
60    private static readonly UnknownField defaultInstance = CreateBuilder().Build();
61    private readonly ReadOnlyCollection<ulong> varintList;
62    private readonly ReadOnlyCollection<uint> fixed32List;
63    private readonly ReadOnlyCollection<ulong> fixed64List;
64    private readonly ReadOnlyCollection<ByteString> lengthDelimitedList;
65    private readonly ReadOnlyCollection<UnknownFieldSet> groupList;
66
67    private UnknownField(ReadOnlyCollection<ulong> varintList,
68        ReadOnlyCollection<uint> fixed32List,
69        ReadOnlyCollection<ulong> fixed64List,
70        ReadOnlyCollection<ByteString> lengthDelimitedList,
71        ReadOnlyCollection<UnknownFieldSet> groupList) {
72      this.varintList = varintList;
73      this.fixed32List = fixed32List;
74      this.fixed64List = fixed64List;
75      this.lengthDelimitedList = lengthDelimitedList;
76      this.groupList = groupList;
77    }
78
79    public static UnknownField DefaultInstance {
80      get { return defaultInstance; }
81    }
82
83    /// <summary>
84    /// The list of varint values for this field.
85    /// </summary>
86    public IList<ulong> VarintList {
87      get { return varintList; }
88    }
89
90    /// <summary>
91    /// The list of fixed32 values for this field.
92    /// </summary>
93    public IList<uint> Fixed32List {
94      get { return fixed32List; }
95    }
96
97    /// <summary>
98    /// The list of fixed64 values for this field.
99    /// </summary>
100    public IList<ulong> Fixed64List {
101      get { return fixed64List; }
102    }
103
104    /// <summary>
105    /// The list of length-delimited values for this field.
106    /// </summary>
107    public IList<ByteString> LengthDelimitedList {
108      get { return lengthDelimitedList; }
109    }
110
111    /// <summary>
112    /// The list of embedded group values for this field. These
113    /// are represented using UnknownFieldSets rather than Messages
114    /// since the group's type is presumably unknown.
115    /// </summary>
116    public IList<UnknownFieldSet> GroupList {
117      get { return groupList; }
118    }
119
120    public override bool Equals(object other) {
121      if (ReferenceEquals(this, other)) {
122        return true;
123      }
124      UnknownField otherField = other as UnknownField;
125      return otherField != null
126        && Lists.Equals(varintList, otherField.varintList)
127        && Lists.Equals(fixed32List, otherField.fixed32List)
128        && Lists.Equals(fixed64List, otherField.fixed64List)
129        && Lists.Equals(lengthDelimitedList, otherField.lengthDelimitedList)
130        && Lists.Equals(groupList, otherField.groupList);
131    }
132
133    public override int GetHashCode() {
134      int hash = 43;
135      hash = hash * 47 + Lists.GetHashCode(varintList);
136      hash = hash * 47 + Lists.GetHashCode(fixed32List);
137      hash = hash * 47 + Lists.GetHashCode(fixed64List);
138      hash = hash * 47 + Lists.GetHashCode(lengthDelimitedList);
139      hash = hash * 47 + Lists.GetHashCode(groupList);
140      return hash;
141    }
142
143    /// <summary>
144    /// Constructs a new Builder.
145    /// </summary>
146    public static Builder CreateBuilder() {
147      return new Builder();
148    }
149
150    /// <summary>
151    /// Constructs a new Builder and initializes it to a copy of <paramref name="copyFrom"/>.
152    /// </summary>
153    public static Builder CreateBuilder(UnknownField copyFrom) {
154      return new Builder().MergeFrom(copyFrom);
155    }
156   
157    /// <summary>
158    /// Serializes the field, including the field number, and writes it to
159    /// <paramref name="output"/>.
160    /// </summary>
161    public void WriteTo(int fieldNumber, CodedOutputStream output) {
162      foreach (ulong value in varintList) {
163        output.WriteUInt64(fieldNumber, value);
164      }
165      foreach (uint value in fixed32List) {
166        output.WriteFixed32(fieldNumber, value);
167      }
168      foreach (ulong value in fixed64List) {
169        output.WriteFixed64(fieldNumber, value);
170      }
171      foreach (ByteString value in lengthDelimitedList) {
172        output.WriteBytes(fieldNumber, value);
173      }
174      foreach (UnknownFieldSet value in groupList) {
175        output.WriteUnknownGroup(fieldNumber, value);
176      }
177    }
178
179    /// <summary>
180    /// Computes the number of bytes required to encode this field, including field
181    /// number.
182    /// </summary>
183    public int GetSerializedSize(int fieldNumber) {
184      int result = 0;
185      foreach (ulong value in varintList) {
186        result += CodedOutputStream.ComputeUInt64Size(fieldNumber, value);
187      }
188      foreach (uint value in fixed32List) {
189        result += CodedOutputStream.ComputeFixed32Size(fieldNumber, value);
190      }
191      foreach (ulong value in fixed64List) {
192        result += CodedOutputStream.ComputeFixed64Size(fieldNumber, value);
193      }
194      foreach (ByteString value in lengthDelimitedList) {
195        result += CodedOutputStream.ComputeBytesSize(fieldNumber, value);
196      }
197      foreach (UnknownFieldSet value in groupList) {
198        result += CodedOutputStream.ComputeUnknownGroupSize(fieldNumber, value);
199      }
200      return result;
201    }
202
203    /// <summary>
204    /// Serializes the length-delimited values of the field, including field
205    /// number, and writes them to <paramref name="output"/> using the MessageSet wire format.
206    /// </summary>
207    /// <param name="fieldNumber"></param>
208    /// <param name="output"></param>
209    public void WriteAsMessageSetExtensionTo(int fieldNumber, CodedOutputStream output) {
210      foreach (ByteString value in lengthDelimitedList) {
211        output.WriteRawMessageSetExtension(fieldNumber, value);
212      }
213    }
214
215    /// <summary>
216    /// Get the number of bytes required to encode this field, incuding field number,
217    /// using the MessageSet wire format.
218    /// </summary>
219    public int GetSerializedSizeAsMessageSetExtension(int fieldNumber) {
220      int result = 0;
221      foreach (ByteString value in lengthDelimitedList) {
222        result += CodedOutputStream.ComputeRawMessageSetExtensionSize(fieldNumber, value);
223      }
224      return result;
225    }
226
227    /// <summary>
228    /// Used to build instances of UnknownField.
229    /// </summary>
230    public sealed class Builder {
231
232      private List<ulong> varintList;
233      private List<uint> fixed32List;
234      private List<ulong> fixed64List;
235      private List<ByteString> lengthDelimitedList;
236      private List<UnknownFieldSet> groupList;
237
238      /// <summary>
239      /// Builds the field. After building, the builder is reset to an empty
240      /// state. (This is actually easier than making it unusable.)
241      /// </summary>
242      public UnknownField Build() {
243        return new UnknownField(MakeReadOnly(ref varintList),
244            MakeReadOnly(ref fixed32List),
245            MakeReadOnly(ref fixed64List),
246            MakeReadOnly(ref lengthDelimitedList),
247            MakeReadOnly(ref groupList));
248      }
249
250      /// <summary>
251      /// Merge the values in <paramref name="other" /> into this field.  For each list
252      /// of values, <paramref name="other"/>'s values are append to the ones in this
253      /// field.
254      /// </summary>
255      public Builder MergeFrom(UnknownField other) {
256        varintList = AddAll(varintList, other.VarintList);
257        fixed32List = AddAll(fixed32List, other.Fixed32List);
258        fixed64List = AddAll(fixed64List, other.Fixed64List);
259        lengthDelimitedList = AddAll(lengthDelimitedList, other.LengthDelimitedList);
260        groupList = AddAll(groupList, other.GroupList);
261        return this;
262      }
263
264      /// <summary>
265      /// Returns a new list containing all of the given specified values from
266      /// both the <paramref name="current"/> and <paramref name="extras"/> lists.
267      /// If <paramref name="current" /> is null and <paramref name="extras"/> is empty,
268      /// null is returned. Otherwise, either a new list is created (if <paramref name="current" />
269      /// is null) or the elements of <paramref name="extras"/> are added to <paramref name="current" />.
270      /// </summary>
271      private static List<T> AddAll<T>(List<T> current, IList<T> extras)
272      {
273        if (extras.Count == 0) {
274          return current;
275        }
276        if (current == null) {
277          current = new List<T>(extras);
278        } else {
279          current.AddRange(extras);
280        }
281        return current;
282      }
283
284      /// <summary>
285      /// Clears the contents of this builder.
286      /// </summary>
287      public Builder Clear() {
288        varintList = null;
289        fixed32List = null;
290        fixed64List = null;
291        lengthDelimitedList = null;
292        groupList = null;
293        return this;
294      }
295
296      /// <summary>
297      /// Adds a varint value.
298      /// </summary>
299      [CLSCompliant(false)]
300      public Builder AddVarint(ulong value) {
301        varintList = Add(varintList, value);
302        return this;
303      }
304
305      /// <summary>
306      /// Adds a fixed32 value.
307      /// </summary>
308      [CLSCompliant(false)]
309      public Builder AddFixed32(uint value) {
310        fixed32List = Add(fixed32List, value);
311        return this;
312      }
313
314      /// <summary>
315      /// Adds a fixed64 value.
316      /// </summary>
317      [CLSCompliant(false)]
318      public Builder AddFixed64(ulong value) {
319        fixed64List = Add(fixed64List, value);
320        return this;
321      }
322
323      /// <summary>
324      /// Adds a length-delimited value.
325      /// </summary>
326      public Builder AddLengthDelimited(ByteString value) {
327        lengthDelimitedList = Add(lengthDelimitedList, value);
328        return this;
329      }
330
331      /// <summary>
332      /// Adds an embedded group.
333      /// </summary>
334      /// <param name="value"></param>
335      /// <returns></returns>
336      public Builder AddGroup(UnknownFieldSet value) {
337        groupList = Add(groupList, value);
338        return this;
339      }
340
341      /// <summary>
342      /// Adds <paramref name="value"/> to the <paramref name="list"/>, creating
343      /// a new list if <paramref name="list"/> is null. The list is returned - either
344      /// the original reference or the new list.
345      /// </summary>
346      private static List<T> Add<T>(List<T> list, T value) {
347        if (list == null) {
348          list = new List<T>();
349        }
350        list.Add(value);
351        return list;
352      }
353
354      /// <summary>
355      /// Returns a read-only version of the given IList, and clears
356      /// the field used for <paramref name="list"/>. If the value
357      /// is null, an empty list is produced using Lists.Empty.
358      /// </summary>
359      /// <returns></returns>
360      private static ReadOnlyCollection<T> MakeReadOnly<T>(ref List<T> list) {
361        ReadOnlyCollection<T> ret = list == null ? Lists<T>.Empty : new ReadOnlyCollection<T>(list);
362        list = null;
363        return ret;
364      }
365    }
366  }
367}
Note: See TracBrowser for help on using the repository browser.