Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : #ifndef GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__
32 : #define GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__
33 :
34 : #include <google/protobuf/map_field.h>
35 : #include <google/protobuf/reflection.h>
36 : #include <google/protobuf/repeated_field.h>
37 :
38 : namespace google {
39 : namespace protobuf {
40 : namespace internal {
41 : // A base class for RepeatedFieldAccessor implementations that can support
42 : // random-access efficiently. All iterator methods delegates the work to
43 : // corresponding random-access methods.
44 0 : class RandomAccessRepeatedFieldAccessor : public RepeatedFieldAccessor {
45 : public:
46 0 : virtual ~RandomAccessRepeatedFieldAccessor() {}
47 :
48 0 : virtual Iterator* BeginIterator(const Field* data) const {
49 0 : return PositionToIterator(0);
50 : }
51 0 : virtual Iterator* EndIterator(const Field* data) const {
52 0 : return PositionToIterator(this->Size(data));
53 : }
54 0 : virtual Iterator* CopyIterator(const Field* data,
55 : const Iterator* iterator) const {
56 0 : return const_cast<Iterator*>(iterator);
57 : }
58 0 : virtual Iterator* AdvanceIterator(const Field* data,
59 : Iterator* iterator) const {
60 0 : return PositionToIterator(IteratorToPosition(iterator) + 1);
61 : }
62 0 : virtual bool EqualsIterator(const Field* data,
63 : const Iterator* a,
64 : const Iterator* b) const {
65 0 : return a == b;
66 : }
67 0 : virtual void DeleteIterator(const Field* data, Iterator* iterator) const {
68 0 : }
69 0 : virtual const Value* GetIteratorValue(const Field* data,
70 : const Iterator* iterator,
71 : Value* scratch_space) const {
72 : return Get(data, static_cast<int>(IteratorToPosition(iterator)),
73 0 : scratch_space);
74 : }
75 :
76 : private:
77 : static intptr_t IteratorToPosition(const Iterator* iterator) {
78 0 : return reinterpret_cast<intptr_t>(iterator);
79 : }
80 : static Iterator* PositionToIterator(intptr_t position) {
81 0 : return reinterpret_cast<Iterator*>(position);
82 : }
83 : };
84 :
85 : // Base class for RepeatedFieldAccessor implementations that manipulates
86 : // RepeatedField<T>.
87 : template<typename T>
88 : class RepeatedFieldWrapper : public RandomAccessRepeatedFieldAccessor {
89 : public:
90 0 : RepeatedFieldWrapper() {}
91 0 : virtual ~RepeatedFieldWrapper() {}
92 0 : virtual bool IsEmpty(const Field* data) const {
93 0 : return GetRepeatedField(data)->empty();
94 : }
95 0 : virtual int Size(const Field* data) const {
96 0 : return GetRepeatedField(data)->size();
97 : }
98 0 : virtual const Value* Get(const Field* data, int index,
99 : Value* scratch_space) const {
100 0 : return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space);
101 : }
102 0 : virtual void Clear(Field* data) const {
103 0 : MutableRepeatedField(data)->Clear();
104 0 : }
105 0 : virtual void Set(Field* data, int index, const Value* value) const {
106 0 : MutableRepeatedField(data)->Set(index, ConvertToT(value));
107 0 : }
108 0 : virtual void Add(Field* data, const Value* value) const {
109 0 : MutableRepeatedField(data)->Add(ConvertToT(value));
110 0 : }
111 0 : virtual void RemoveLast(Field* data) const {
112 0 : MutableRepeatedField(data)->RemoveLast();
113 0 : }
114 0 : virtual void SwapElements(Field* data, int index1, int index2) const {
115 0 : MutableRepeatedField(data)->SwapElements(index1, index2);
116 0 : }
117 :
118 : protected:
119 : typedef RepeatedField<T> RepeatedFieldType;
120 : static const RepeatedFieldType* GetRepeatedField(const Field* data) {
121 : return reinterpret_cast<const RepeatedFieldType*>(data);
122 : }
123 : static RepeatedFieldType* MutableRepeatedField(Field* data) {
124 : return reinterpret_cast<RepeatedFieldType*>(data);
125 : }
126 :
127 : // Convert an object recevied by this accessor to an object to be stored in
128 : // the underlying RepeatedField.
129 : virtual T ConvertToT(const Value* value) const = 0;
130 :
131 : // Convert an object stored in RepeatedPtrField to an object that will be
132 : // returned by this accessor. If the two objects have the same type (true
133 : // for string fields with ctype=STRING), a pointer to the source object can
134 : // be returned directly. Otherwise, data should be copied from value to
135 : // scratch_space and scratch_space should be returned.
136 : virtual const Value* ConvertFromT(const T& value,
137 : Value* scratch_space) const = 0;
138 : };
139 :
140 : // Base class for RepeatedFieldAccessor implementations that manipulates
141 : // RepeatedPtrField<T>.
142 : template<typename T>
143 : class RepeatedPtrFieldWrapper : public RandomAccessRepeatedFieldAccessor {
144 : public:
145 0 : RepeatedPtrFieldWrapper() {}
146 0 : virtual ~RepeatedPtrFieldWrapper() {}
147 0 : virtual bool IsEmpty(const Field* data) const {
148 0 : return GetRepeatedField(data)->empty();
149 : }
150 0 : virtual int Size(const Field* data) const {
151 0 : return GetRepeatedField(data)->size();
152 : }
153 0 : virtual const Value* Get(const Field* data, int index,
154 : Value* scratch_space) const {
155 0 : return ConvertFromT(GetRepeatedField(data)->Get(index), scratch_space);
156 : }
157 0 : virtual void Clear(Field* data) const {
158 0 : MutableRepeatedField(data)->Clear();
159 0 : }
160 0 : virtual void Set(Field* data, int index, const Value* value) const {
161 0 : ConvertToT(value, MutableRepeatedField(data)->Mutable(index));
162 0 : }
163 0 : virtual void Add(Field* data, const Value* value) const {
164 0 : T* allocated = New(value);
165 0 : ConvertToT(value, allocated);
166 0 : MutableRepeatedField(data)->AddAllocated(allocated);
167 0 : }
168 0 : virtual void RemoveLast(Field* data) const {
169 0 : MutableRepeatedField(data)->RemoveLast();
170 0 : }
171 0 : virtual void SwapElements(Field* data, int index1, int index2) const {
172 0 : MutableRepeatedField(data)->SwapElements(index1, index2);
173 0 : }
174 :
175 : protected:
176 : typedef RepeatedPtrField<T> RepeatedFieldType;
177 : static const RepeatedFieldType* GetRepeatedField(const Field* data) {
178 : return reinterpret_cast<const RepeatedFieldType*>(data);
179 : }
180 : static RepeatedFieldType* MutableRepeatedField(Field* data) {
181 : return reinterpret_cast<RepeatedFieldType*>(data);
182 : }
183 :
184 : // Create a new T instance. For repeated message fields, T can be specified
185 : // as google::protobuf::Message so we can't use "new T()" directly. In that case, value
186 : // should be a message of the same type (it's ensured by the caller) and a
187 : // new message object will be created using it.
188 : virtual T* New(const Value* value) const = 0;
189 :
190 : // Convert an object received by this accessor to an object that will be
191 : // stored in the underlying RepeatedPtrField.
192 : virtual void ConvertToT(const Value* value, T* result) const = 0;
193 :
194 : // Convert an object stored in RepeatedPtrField to an object that will be
195 : // returned by this accessor. If the two objects have the same type (true
196 : // for string fields with ctype=STRING), a pointer to the source object can
197 : // be returned directly. Otherwise, data should be copied from value to
198 : // scratch_space and scratch_space should be returned.
199 : virtual const Value* ConvertFromT(const T& value,
200 : Value* scratch_space) const = 0;
201 : };
202 :
203 : // An implementation of RandomAccessRepeatedFieldAccessor that manipulates
204 : // MapFieldBase.
205 : class MapFieldAccessor : public RandomAccessRepeatedFieldAccessor {
206 : public:
207 0 : MapFieldAccessor() {}
208 0 : virtual ~MapFieldAccessor() {}
209 0 : virtual bool IsEmpty(const Field* data) const {
210 0 : return GetRepeatedField(data)->empty();
211 : }
212 0 : virtual int Size(const Field* data) const {
213 0 : return GetRepeatedField(data)->size();
214 : }
215 0 : virtual const Value* Get(const Field* data, int index,
216 : Value* scratch_space) const {
217 0 : return ConvertFromEntry(GetRepeatedField(data)->Get(index), scratch_space);
218 : }
219 0 : virtual void Clear(Field* data) const {
220 0 : MutableRepeatedField(data)->Clear();
221 0 : }
222 0 : virtual void Set(Field* data, int index, const Value* value) const {
223 0 : ConvertToEntry(value, MutableRepeatedField(data)->Mutable(index));
224 0 : }
225 0 : virtual void Add(Field* data, const Value* value) const {
226 0 : Message* allocated = New(value);
227 0 : ConvertToEntry(value, allocated);
228 0 : MutableRepeatedField(data)->AddAllocated(allocated);
229 0 : }
230 0 : virtual void RemoveLast(Field* data) const {
231 0 : MutableRepeatedField(data)->RemoveLast();
232 0 : }
233 0 : virtual void SwapElements(Field* data, int index1, int index2) const {
234 0 : MutableRepeatedField(data)->SwapElements(index1, index2);
235 0 : }
236 0 : virtual void Swap(
237 : Field* data,
238 : const internal::RepeatedFieldAccessor* other_mutator,
239 : Field* other_data) const {
240 0 : GOOGLE_CHECK(this == other_mutator);
241 0 : MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
242 0 : }
243 :
244 : protected:
245 : typedef RepeatedPtrField<Message> RepeatedFieldType;
246 : static const RepeatedFieldType* GetRepeatedField(const Field* data) {
247 : return reinterpret_cast<const RepeatedFieldType*>(
248 0 : (&reinterpret_cast<const MapFieldBase*>(data)->GetRepeatedField()));
249 : }
250 : static RepeatedFieldType* MutableRepeatedField(Field* data) {
251 : return reinterpret_cast<RepeatedFieldType*>(
252 0 : reinterpret_cast<MapFieldBase*>(data)->MutableRepeatedField());
253 : }
254 0 : virtual Message* New(const Value* value) const {
255 0 : return static_cast<const Message*>(value)->New();
256 : }
257 : // Convert an object received by this accessor to an MapEntry message to be
258 : // stored in the underlying MapFieldBase.
259 0 : virtual void ConvertToEntry(const Value* value, Message* result) const {
260 0 : result->CopyFrom(*static_cast<const Message*>(value));
261 0 : }
262 : // Convert a MapEntry message stored in the underlying MapFieldBase to an
263 : // object that will be returned by this accessor.
264 0 : virtual const Value* ConvertFromEntry(const Message& value,
265 : Value* scratch_space) const {
266 0 : return static_cast<const Value*>(&value);
267 : }
268 : };
269 :
270 : // Default implementations of RepeatedFieldAccessor for primitive types.
271 : template<typename T>
272 : class RepeatedFieldPrimitiveAccessor : public RepeatedFieldWrapper<T> {
273 : typedef void Field;
274 : typedef void Value;
275 : using RepeatedFieldWrapper<T>::MutableRepeatedField;
276 :
277 : public:
278 0 : RepeatedFieldPrimitiveAccessor() {}
279 0 : virtual ~RepeatedFieldPrimitiveAccessor() {}
280 0 : virtual void Swap(
281 : Field* data,
282 : const internal::RepeatedFieldAccessor* other_mutator,
283 : Field* other_data) const {
284 : // Currently RepeatedFieldPrimitiveAccessor is the only implementation of
285 : // RepeatedFieldAccessor for primitive types. As we are using singletons
286 : // for these accessors, here "other_mutator" must be "this".
287 0 : GOOGLE_CHECK(this == other_mutator);
288 0 : MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
289 0 : }
290 :
291 : protected:
292 0 : virtual T ConvertToT(const Value* value) const {
293 0 : return *static_cast<const T*>(value);
294 : }
295 0 : virtual const Value* ConvertFromT(const T& value,
296 : Value* scratch_space) const {
297 0 : return static_cast<const Value*>(&value);
298 : }
299 : };
300 :
301 : // Default implementation of RepeatedFieldAccessor for string fields with
302 : // ctype=STRING.
303 : class RepeatedPtrFieldStringAccessor : public RepeatedPtrFieldWrapper<string> {
304 : typedef void Field;
305 : typedef void Value;
306 : using RepeatedFieldAccessor::Add;
307 :
308 : public:
309 0 : RepeatedPtrFieldStringAccessor() {}
310 0 : virtual ~RepeatedPtrFieldStringAccessor() {}
311 0 : virtual void Swap(
312 : Field* data,
313 : const internal::RepeatedFieldAccessor* other_mutator,
314 : Field* other_data) const {
315 0 : if (this == other_mutator) {
316 0 : MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
317 : } else {
318 : RepeatedPtrField<string> tmp;
319 0 : tmp.Swap(MutableRepeatedField(data));
320 0 : int other_size = other_mutator->Size(other_data);
321 0 : for (int i = 0; i < other_size; ++i) {
322 0 : Add<string>(data, other_mutator->Get<string>(other_data, i));
323 : }
324 0 : int size = Size(data);
325 0 : other_mutator->Clear(other_data);
326 0 : for (int i = 0; i < size; ++i) {
327 0 : other_mutator->Add<string>(other_data, tmp.Get(i));
328 : }
329 : }
330 0 : }
331 :
332 : protected:
333 0 : virtual string* New(const Value*) const {
334 0 : return new string();
335 : }
336 0 : virtual void ConvertToT(const Value* value, string* result) const {
337 : *result = *static_cast<const string*>(value);
338 0 : }
339 0 : virtual const Value* ConvertFromT(const string& value,
340 : Value* scratch_space) const {
341 0 : return static_cast<const Value*>(&value);
342 : }
343 : };
344 :
345 :
346 : class RepeatedPtrFieldMessageAccessor
347 : : public RepeatedPtrFieldWrapper<Message> {
348 : typedef void Field;
349 : typedef void Value;
350 :
351 : public:
352 0 : RepeatedPtrFieldMessageAccessor() {}
353 0 : virtual ~RepeatedPtrFieldMessageAccessor() {}
354 0 : virtual void Swap(
355 : Field* data,
356 : const internal::RepeatedFieldAccessor* other_mutator,
357 : Field* other_data) const {
358 0 : GOOGLE_CHECK(this == other_mutator);
359 0 : MutableRepeatedField(data)->Swap(MutableRepeatedField(other_data));
360 0 : }
361 :
362 : protected:
363 0 : virtual Message* New(const Value* value) const {
364 0 : return static_cast<const Message*>(value)->New();
365 : }
366 0 : virtual void ConvertToT(const Value* value, Message* result) const {
367 0 : result->CopyFrom(*static_cast<const Message*>(value));
368 0 : }
369 0 : virtual const Value* ConvertFromT(const Message& value,
370 : Value* scratch_space) const {
371 0 : return static_cast<const Value*>(&value);
372 : }
373 : };
374 : } // namespace internal
375 : } // namespace protobuf
376 :
377 : } // namespace google
378 : #endif // GOOGLE_PROTOBUF_REFLECTION_INTERNAL_H__
|