Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/2.4.1/ProtobufCS/src/ProtocolBuffers/FieldAccess/RepeatedPrimitiveAccessor.cs @ 15682

Last change on this file since 15682 was 8295, checked in by abeham, 12 years ago

#1897:

  • Removed protocol buffers 0.9.1
  • Added protocol buffers 2.4.1
  • Updated proto processing command
File size: 7.0 KB
Line 
1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc.  All rights reserved.
3// http://github.com/jskeet/dotnet-protobufs/
4// Original C++/Java/Python code:
5// http://code.google.com/p/protobuf/
6//
7// Redistribution and use in source and binary forms, with or without
8// modification, are permitted provided that the following conditions are
9// met:
10//
11//     * Redistributions of source code must retain the above copyright
12// notice, this list of conditions and the following disclaimer.
13//     * Redistributions in binary form must reproduce the above
14// copyright notice, this list of conditions and the following disclaimer
15// in the documentation and/or other materials provided with the
16// distribution.
17//     * Neither the name of Google Inc. nor the names of its
18// contributors may be used to endorse or promote products derived from
19// this software without specific prior written permission.
20//
21// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32using System;
33using System.Collections;
34using System.Reflection;
35
36namespace Google.ProtocolBuffers.FieldAccess
37{
38    /// <summary>
39    /// Accessor for a repeated field of type int, ByteString etc.
40    /// </summary>
41    internal class RepeatedPrimitiveAccessor<TMessage, TBuilder> : IFieldAccessor<TMessage, TBuilder>
42        where TMessage : IMessage<TMessage, TBuilder>
43        where TBuilder : IBuilder<TMessage, TBuilder>
44    {
45        private readonly Type clrType;
46        private readonly Func<TMessage, object> getValueDelegate;
47        private readonly Func<TBuilder, IBuilder> clearDelegate;
48        private readonly Action<TBuilder, object> addValueDelegate;
49        private readonly Func<TBuilder, object> getRepeatedWrapperDelegate;
50        private readonly Func<TMessage, int> countDelegate;
51        private readonly MethodInfo getElementMethod;
52        private readonly MethodInfo setElementMethod;
53
54        // Replacement for Type.EmptyTypes which apparently isn't available on the compact framework
55        internal static readonly Type[] EmptyTypes = new Type[0];
56
57        /// <summary>
58        /// The CLR type of the field (int, the enum type, ByteString, the message etc).
59        /// This is taken from the return type of the method used to retrieve a single
60        /// value.
61        /// </summary>
62        protected Type ClrType
63        {
64            get { return clrType; }
65        }
66
67        internal RepeatedPrimitiveAccessor(string name)
68        {
69            PropertyInfo messageProperty = typeof (TMessage).GetProperty(name + "List");
70            PropertyInfo builderProperty = typeof (TBuilder).GetProperty(name + "List");
71            PropertyInfo countProperty = typeof (TMessage).GetProperty(name + "Count");
72            MethodInfo clearMethod = typeof (TBuilder).GetMethod("Clear" + name, EmptyTypes);
73            getElementMethod = typeof (TMessage).GetMethod("Get" + name, new Type[] {typeof (int)});
74            clrType = getElementMethod.ReturnType;
75            MethodInfo addMethod = typeof (TBuilder).GetMethod("Add" + name, new Type[] {ClrType});
76            setElementMethod = typeof (TBuilder).GetMethod("Set" + name, new Type[] {typeof (int), ClrType});
77            if (messageProperty == null
78                || builderProperty == null
79                || countProperty == null
80                || clearMethod == null
81                || addMethod == null
82                || getElementMethod == null
83                || setElementMethod == null)
84            {
85                throw new ArgumentException("Not all required properties/methods available");
86            }
87            clearDelegate =
88                (Func<TBuilder, IBuilder>) Delegate.CreateDelegate(typeof (Func<TBuilder, IBuilder>), null, clearMethod);
89            countDelegate = (Func<TMessage, int>) Delegate.CreateDelegate
90                                                      (typeof (Func<TMessage, int>), null, countProperty.GetGetMethod());
91            getValueDelegate = ReflectionUtil.CreateUpcastDelegate<TMessage>(messageProperty.GetGetMethod());
92            addValueDelegate = ReflectionUtil.CreateDowncastDelegateIgnoringReturn<TBuilder>(addMethod);
93            getRepeatedWrapperDelegate = ReflectionUtil.CreateUpcastDelegate<TBuilder>(builderProperty.GetGetMethod());
94        }
95
96        public bool Has(TMessage message)
97        {
98            throw new InvalidOperationException();
99        }
100
101        public virtual IBuilder CreateBuilder()
102        {
103            throw new InvalidOperationException();
104        }
105
106        public virtual object GetValue(TMessage message)
107        {
108            return getValueDelegate(message);
109        }
110
111        public void SetValue(TBuilder builder, object value)
112        {
113            // Add all the elements individually.  This serves two purposes:
114            // 1) Verifies that each element has the correct type.
115            // 2) Insures that the caller cannot modify the list later on and
116            //    have the modifications be reflected in the message.
117            Clear(builder);
118            foreach (object element in (IEnumerable) value)
119            {
120                AddRepeated(builder, element);
121            }
122        }
123
124        public void Clear(TBuilder builder)
125        {
126            clearDelegate(builder);
127        }
128
129        public int GetRepeatedCount(TMessage message)
130        {
131            return countDelegate(message);
132        }
133
134        public virtual object GetRepeatedValue(TMessage message, int index)
135        {
136            return getElementMethod.Invoke(message, new object[] {index});
137        }
138
139        public virtual void SetRepeated(TBuilder builder, int index, object value)
140        {
141            ThrowHelper.ThrowIfNull(value, "value");
142            setElementMethod.Invoke(builder, new object[] {index, value});
143        }
144
145        public virtual void AddRepeated(TBuilder builder, object value)
146        {
147            ThrowHelper.ThrowIfNull(value, "value");
148            addValueDelegate(builder, value);
149        }
150
151        /// <summary>
152        /// The builder class's accessor already builds a read-only wrapper for
153        /// us, which is exactly what we want.
154        /// </summary>
155        public object GetRepeatedWrapper(TBuilder builder)
156        {
157            return getRepeatedWrapperDelegate(builder);
158        }
159    }
160}
Note: See TracBrowser for help on using the repository browser.