Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/0.9.1/ProtobufCS/src/ProtocolBuffers/AbstractBuilder.cs @ 7489

Last change on this file since 7489 was 3857, checked in by abeham, 15 years ago

#866

  • Added protobuf-csharp-port project source to ExtLibs
File size: 11.3 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;
37using System.Collections.Generic;
38using System.IO;
39using Google.ProtocolBuffers.Descriptors;
40
41namespace Google.ProtocolBuffers {
42  /// <summary>
43  /// Implementation of the non-generic IMessage interface as far as possible.
44  /// </summary>
45  public abstract class AbstractBuilder<TMessage, TBuilder> : IBuilder<TMessage, TBuilder>
46      where TMessage : AbstractMessage<TMessage, TBuilder>
47      where TBuilder : AbstractBuilder<TMessage, TBuilder> {
48
49    protected abstract TBuilder ThisBuilder { get; }
50   
51    #region Unimplemented members of IBuilder
52    public abstract UnknownFieldSet UnknownFields { get; set; }
53    public abstract TBuilder MergeFrom(TMessage other);
54    public abstract bool IsInitialized { get; }
55    public abstract IDictionary<FieldDescriptor, object> AllFields { get; }
56    public abstract object this[FieldDescriptor field] { get; set; }
57    public abstract MessageDescriptor DescriptorForType { get; }
58    public abstract int GetRepeatedFieldCount(FieldDescriptor field);
59    public abstract object this[FieldDescriptor field, int index] { get; set; }
60    public abstract bool HasField(FieldDescriptor field);
61    public abstract TMessage Build();
62    public abstract TMessage BuildPartial();
63    public abstract TBuilder Clone();
64    public abstract TMessage DefaultInstanceForType { get; }
65    public abstract IBuilder CreateBuilderForField(FieldDescriptor field);
66    public abstract TBuilder ClearField(FieldDescriptor field);
67    public abstract TBuilder AddRepeatedField(FieldDescriptor field, object value);
68    #endregion
69
70    #region Implementation of methods which don't require type parameter information
71    public IMessage WeakBuild() {
72      return Build();
73    }
74
75    public IBuilder WeakAddRepeatedField(FieldDescriptor field, object value) {
76      return AddRepeatedField(field, value);
77    }
78
79    public IBuilder WeakClear() {
80      return Clear();
81    }
82
83    public IBuilder WeakMergeFrom(IMessage message) {
84      return MergeFrom(message);
85    }
86
87    public IBuilder WeakMergeFrom(CodedInputStream input) {
88      return MergeFrom(input);
89    }
90
91    public IBuilder WeakMergeFrom(CodedInputStream input, ExtensionRegistry registry) {
92      return MergeFrom(input, registry);
93    }
94
95    public IBuilder WeakMergeFrom(ByteString data) {
96      return MergeFrom(data);
97    }
98
99    public IBuilder WeakMergeFrom(ByteString data, ExtensionRegistry registry) {
100      return MergeFrom(data, registry);
101    }
102
103    public IMessage WeakBuildPartial() {
104      return BuildPartial();
105    }
106
107    public IBuilder WeakClone() {
108      return Clone();
109    }
110
111    public IMessage WeakDefaultInstanceForType {
112      get { return DefaultInstanceForType; }
113    }
114
115    public IBuilder WeakClearField(FieldDescriptor field) {
116      return ClearField(field);
117    }
118    #endregion
119
120    public TBuilder SetUnknownFields(UnknownFieldSet fields) {
121      UnknownFields = fields;
122      return ThisBuilder;
123    }
124
125    public virtual TBuilder Clear() {
126      foreach(FieldDescriptor field in AllFields.Keys) {
127        ClearField(field);
128      }
129      return ThisBuilder;
130    }
131
132    public virtual TBuilder MergeFrom(IMessage other) {
133      if (other.DescriptorForType != DescriptorForType) {
134        throw new ArgumentException("MergeFrom(IMessage) can only merge messages of the same type.");
135      }
136
137      // Note:  We don't attempt to verify that other's fields have valid
138      //   types.  Doing so would be a losing battle.  We'd have to verify
139      //   all sub-messages as well, and we'd have to make copies of all of
140      //   them to insure that they don't change after verification (since
141      //   the Message interface itself cannot enforce immutability of
142      //   implementations).
143      // TODO(jonskeet):  Provide a function somewhere called MakeDeepCopy()
144      //   which allows people to make secure deep copies of messages.
145      foreach (KeyValuePair<FieldDescriptor, object> entry in other.AllFields) {
146        FieldDescriptor field = entry.Key;
147        if (field.IsRepeated) {
148          // Concatenate repeated fields
149          foreach (object element in (IEnumerable) entry.Value) {
150            AddRepeatedField(field, element);
151          }
152        } else if (field.MappedType == MappedType.Message) {
153          // Merge singular messages
154          IMessage existingValue = (IMessage) this[field];
155          if (existingValue == existingValue.WeakDefaultInstanceForType) {
156            this[field] = entry.Value;
157          } else {
158            this[field] = existingValue.WeakCreateBuilderForType()
159                                       .WeakMergeFrom(existingValue)
160                                       .WeakMergeFrom((IMessage) entry.Value)
161                                       .WeakBuild();
162          }
163        } else {
164          // Overwrite simple values
165          this[field] = entry.Value;
166        }
167      }
168      return ThisBuilder;
169    }
170
171    public virtual TBuilder MergeFrom(CodedInputStream input) {
172      return MergeFrom(input, ExtensionRegistry.Empty);
173    }
174
175    public virtual TBuilder MergeFrom(CodedInputStream input, ExtensionRegistry extensionRegistry) {
176      UnknownFieldSet.Builder unknownFields = UnknownFieldSet.CreateBuilder(UnknownFields);
177      unknownFields.MergeFrom(input, extensionRegistry, this);
178      UnknownFields = unknownFields.Build();
179      return ThisBuilder;
180    }
181
182    public virtual TBuilder MergeUnknownFields(UnknownFieldSet unknownFields) {
183      UnknownFields = UnknownFieldSet.CreateBuilder(UnknownFields)
184          .MergeFrom(unknownFields)
185          .Build();
186      return ThisBuilder;
187    }
188
189    public virtual TBuilder MergeFrom(ByteString data) {
190      CodedInputStream input = data.CreateCodedInput();
191      MergeFrom(input);
192      input.CheckLastTagWas(0);
193      return ThisBuilder;
194    }
195
196    public virtual TBuilder MergeFrom(ByteString data, ExtensionRegistry extensionRegistry) {
197      CodedInputStream input = data.CreateCodedInput();
198      MergeFrom(input, extensionRegistry);
199      input.CheckLastTagWas(0);
200      return ThisBuilder;
201    }
202
203    public virtual TBuilder MergeFrom(byte[] data) {
204      CodedInputStream input = CodedInputStream.CreateInstance(data);
205      MergeFrom(input);
206      input.CheckLastTagWas(0);
207      return ThisBuilder;
208    }
209
210    public virtual TBuilder MergeFrom(byte[] data, ExtensionRegistry extensionRegistry) {
211      CodedInputStream input = CodedInputStream.CreateInstance(data);
212      MergeFrom(input, extensionRegistry);
213      input.CheckLastTagWas(0);
214      return ThisBuilder;
215    }
216
217    public virtual TBuilder MergeFrom(Stream input) {
218      CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
219      MergeFrom(codedInput);
220      codedInput.CheckLastTagWas(0);
221      return ThisBuilder;
222    }
223
224    public virtual TBuilder MergeFrom(Stream input, ExtensionRegistry extensionRegistry) {
225      CodedInputStream codedInput = CodedInputStream.CreateInstance(input);
226      MergeFrom(codedInput, extensionRegistry);
227      codedInput.CheckLastTagWas(0);
228      return ThisBuilder;
229    }
230
231    public TBuilder MergeDelimitedFrom(Stream input, ExtensionRegistry extensionRegistry) {
232      int size = (int) CodedInputStream.ReadRawVarint32(input);
233      Stream limitedStream = new LimitedInputStream(input, size);
234      return MergeFrom(limitedStream, extensionRegistry);
235    }
236
237    public TBuilder MergeDelimitedFrom(Stream input) {
238      return MergeDelimitedFrom(input, ExtensionRegistry.Empty);
239    }
240
241    public virtual IBuilder SetField(FieldDescriptor field, object value) {
242      this[field] = value;
243      return ThisBuilder;
244    }
245
246    public virtual IBuilder SetRepeatedField(FieldDescriptor field, int index, object value) {
247      this[field, index] = value;
248      return ThisBuilder;
249    }
250
251    /// <summary>
252    /// Stream implementation which proxies another stream, only allowing a certain amount
253    /// of data to be read. Note that this is only used to read delimited streams, so it
254    /// doesn't attempt to implement everything.
255    /// </summary>
256    private class LimitedInputStream : Stream {
257
258      private readonly Stream proxied;
259      private int bytesLeft;
260
261      internal LimitedInputStream(Stream proxied, int size) {
262        this.proxied = proxied;
263        bytesLeft = size;
264      }
265
266      public override bool CanRead {
267        get { return true; }
268      }
269
270      public override bool CanSeek {
271        get { return false; }
272      }
273
274      public override bool CanWrite {
275        get { return false; }
276      }
277
278      public override void Flush() {
279      }
280
281      public override long Length {
282        get { throw new NotImplementedException(); }
283      }
284
285      public override long Position {
286        get {
287          throw new NotImplementedException();
288        }
289        set {
290          throw new NotImplementedException();
291        }
292      }
293
294      public override int Read(byte[] buffer, int offset, int count) {
295        if (bytesLeft > 0) {
296          int bytesRead = proxied.Read(buffer, offset, Math.Min(bytesLeft, count));
297          bytesLeft -= bytesRead;
298          return bytesRead;
299        }
300        return 0;
301      }
302
303      public override long Seek(long offset, SeekOrigin origin) {
304        throw new NotImplementedException();
305      }
306
307      public override void SetLength(long value) {
308        throw new NotImplementedException();
309      }
310
311      public override void Write(byte[] buffer, int offset, int count) {
312        throw new NotImplementedException();
313      }
314    }
315  }
316}
Note: See TracBrowser for help on using the repository browser.