repeated_field.c
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2014 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 #include "protobuf.h"
32 
33 // -----------------------------------------------------------------------------
34 // Repeated field container type.
35 // -----------------------------------------------------------------------------
36 
37 const rb_data_type_t RepeatedField_type = {
38  "Google::Protobuf::RepeatedField",
40 };
41 
43 
45  RepeatedField* self;
46  TypedData_Get_Struct(_self, RepeatedField, &RepeatedField_type, self);
47  return self;
48 }
49 
50 void* RepeatedField_memoryat(RepeatedField* self, int index, int element_size) {
51  return ((uint8_t *)self->elements) + index * element_size;
52 }
53 
54 static int index_position(VALUE _index, RepeatedField* repeated_field) {
55  int index = NUM2INT(_index);
57  index = repeated_field->size + index;
58  }
59  return index;
60 }
61 
62 VALUE RepeatedField_subarray(VALUE _self, long beg, long len) {
63  RepeatedField* self = ruby_to_RepeatedField(_self);
64  int element_size = native_slot_size(self->field_type);
65  upb_fieldtype_t field_type = self->field_type;
66  VALUE field_type_class = self->field_type_class;
67 
68  size_t off = beg * element_size;
69  VALUE ary = rb_ary_new2(len);
70  for (int i = beg; i < beg + len; i++, off += element_size) {
71  void* mem = ((uint8_t *)self->elements) + off;
72  VALUE elem = native_slot_get(field_type, field_type_class, mem);
73  rb_ary_push(ary, elem);
74  }
75  return ary;
76 }
77 
78 /*
79  * call-seq:
80  * RepeatedField.each(&block)
81  *
82  * Invokes the block once for each element of the repeated field. RepeatedField
83  * also includes Enumerable; combined with this method, the repeated field thus
84  * acts like an ordinary Ruby sequence.
85  */
86 VALUE RepeatedField_each(VALUE _self) {
87  RepeatedField* self = ruby_to_RepeatedField(_self);
88  upb_fieldtype_t field_type = self->field_type;
89  VALUE field_type_class = self->field_type_class;
90  int element_size = native_slot_size(field_type);
91 
92  size_t off = 0;
93  for (int i = 0; i < self->size; i++, off += element_size) {
94  void* memory = (void *) (((uint8_t *)self->elements) + off);
96  rb_yield(val);
97  }
98  return _self;
99 }
100 
101 
102 /*
103  * call-seq:
104  * RepeatedField.[](index) => value
105  *
106  * Accesses the element at the given index. Returns nil on out-of-bounds
107  */
108 VALUE RepeatedField_index(int argc, VALUE* argv, VALUE _self) {
109  RepeatedField* self = ruby_to_RepeatedField(_self);
110  int element_size = native_slot_size(self->field_type);
111  upb_fieldtype_t field_type = self->field_type;
112  VALUE field_type_class = self->field_type_class;
113 
114  VALUE arg = argv[0];
115  long beg, len;
116 
117  if (argc == 1){
118  if (FIXNUM_P(arg)) {
119  /* standard case */
120  void* memory;
121  int index = index_position(argv[0], self);
122  if (index < 0 || index >= self->size) {
123  return Qnil;
124  }
125  memory = RepeatedField_memoryat(self, index, element_size);
127  }else{
128  /* check if idx is Range */
129  switch (rb_range_beg_len(arg, &beg, &len, self->size, 0)) {
130  case Qfalse:
131  break;
132  case Qnil:
133  return Qnil;
134  default:
135  return RepeatedField_subarray(_self, beg, len);
136  }
137  }
138  }
139  /* assume 2 arguments */
140  beg = NUM2LONG(argv[0]);
141  len = NUM2LONG(argv[1]);
142  if (beg < 0) {
143  beg += self->size;
144  }
145  if (beg >= self->size) {
146  return Qnil;
147  }
148  return RepeatedField_subarray(_self, beg, len);
149 }
150 
151 /*
152  * call-seq:
153  * RepeatedField.[]=(index, value)
154  *
155  * Sets the element at the given index. On out-of-bounds assignments, extends
156  * the array and fills the hole (if any) with default values.
157  */
158 VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val) {
159  RepeatedField* self = ruby_to_RepeatedField(_self);
160  upb_fieldtype_t field_type = self->field_type;
161  VALUE field_type_class = self->field_type_class;
162  int element_size = native_slot_size(field_type);
163  void* memory;
164 
165  int index = index_position(_index, self);
166  if (index < 0 || index >= (INT_MAX - 1)) {
167  return Qnil;
168  }
169  if (index >= self->size) {
170  upb_fieldtype_t field_type = self->field_type;
171  int element_size = native_slot_size(field_type);
172  RepeatedField_reserve(self, index + 1);
173  for (int i = self->size; i <= index; i++) {
174  void* elem = RepeatedField_memoryat(self, i, element_size);
176  }
177  self->size = index + 1;
178  }
179 
180  memory = RepeatedField_memoryat(self, index, element_size);
182  return Qnil;
183 }
184 
185 static int kInitialSize = 8;
186 
187 void RepeatedField_reserve(RepeatedField* self, int new_size) {
188  void* old_elems = self->elements;
189  int elem_size = native_slot_size(self->field_type);
190  if (new_size <= self->capacity) {
191  return;
192  }
193  if (self->capacity == 0) {
194  self->capacity = kInitialSize;
195  }
196  while (self->capacity < new_size) {
197  self->capacity *= 2;
198  }
199  self->elements = ALLOC_N(uint8_t, elem_size * self->capacity);
200  if (old_elems != NULL) {
201  memcpy(self->elements, old_elems, self->size * elem_size);
202  xfree(old_elems);
203  }
204 }
205 
206 /*
207  * call-seq:
208  * RepeatedField.push(value)
209  *
210  * Adds a new element to the repeated field.
211  */
212 VALUE RepeatedField_push(VALUE _self, VALUE val) {
213  RepeatedField* self = ruby_to_RepeatedField(_self);
214  upb_fieldtype_t field_type = self->field_type;
215  int element_size = native_slot_size(field_type);
216  void* memory;
217 
218  RepeatedField_reserve(self, self->size + 1);
219  memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
220  native_slot_set("", field_type, self->field_type_class, memory, val);
221  // native_slot_set may raise an error; bump size only after set.
222  self->size++;
223  return _self;
224 }
225 
226 VALUE RepeatedField_push_vararg(VALUE _self, VALUE args) {
227  for (int i = 0; i < RARRAY_LEN(args); i++) {
228  RepeatedField_push(_self, rb_ary_entry(args, i));
229  }
230  return _self;
231 }
232 
233 // Used by parsing handlers.
234 void RepeatedField_push_native(VALUE _self, void* data) {
235  RepeatedField* self = ruby_to_RepeatedField(_self);
236  upb_fieldtype_t field_type = self->field_type;
237  int element_size = native_slot_size(field_type);
238  void* memory;
239 
240  RepeatedField_reserve(self, self->size + 1);
241  memory = (void *) (((uint8_t *)self->elements) + self->size * element_size);
242  memcpy(memory, data, element_size);
243  self->size++;
244 }
245 
246 void* RepeatedField_index_native(VALUE _self, int index) {
247  RepeatedField* self = ruby_to_RepeatedField(_self);
248  upb_fieldtype_t field_type = self->field_type;
249  int element_size = native_slot_size(field_type);
250  return RepeatedField_memoryat(self, index, element_size);
251 }
252 
253 int RepeatedField_size(VALUE _self) {
254  RepeatedField* self = ruby_to_RepeatedField(_self);
255  return self->size;
256 }
257 
258 /*
259  * Private ruby method, used by RepeatedField.pop
260  */
261 VALUE RepeatedField_pop_one(VALUE _self) {
262  RepeatedField* self = ruby_to_RepeatedField(_self);
263  upb_fieldtype_t field_type = self->field_type;
264  VALUE field_type_class = self->field_type_class;
265  int element_size = native_slot_size(field_type);
266  int index;
267  void* memory;
268  VALUE ret;
269 
270  if (self->size == 0) {
271  return Qnil;
272  }
273  index = self->size - 1;
274  memory = RepeatedField_memoryat(self, index, element_size);
276  self->size--;
277  return ret;
278 }
279 
280 /*
281  * call-seq:
282  * RepeatedField.replace(list)
283  *
284  * Replaces the contents of the repeated field with the given list of elements.
285  */
286 VALUE RepeatedField_replace(VALUE _self, VALUE list) {
287  RepeatedField* self = ruby_to_RepeatedField(_self);
288  Check_Type(list, T_ARRAY);
289  self->size = 0;
290  for (int i = 0; i < RARRAY_LEN(list); i++) {
291  RepeatedField_push(_self, rb_ary_entry(list, i));
292  }
293  return list;
294 }
295 
296 /*
297  * call-seq:
298  * RepeatedField.clear
299  *
300  * Clears (removes all elements from) this repeated field.
301  */
302 VALUE RepeatedField_clear(VALUE _self) {
303  RepeatedField* self = ruby_to_RepeatedField(_self);
304  self->size = 0;
305  return _self;
306 }
307 
308 /*
309  * call-seq:
310  * RepeatedField.length
311  *
312  * Returns the length of this repeated field.
313  */
314 VALUE RepeatedField_length(VALUE _self) {
315  RepeatedField* self = ruby_to_RepeatedField(_self);
316  return INT2NUM(self->size);
317 }
318 
319 static VALUE RepeatedField_new_this_type(VALUE _self) {
320  RepeatedField* self = ruby_to_RepeatedField(_self);
321  VALUE new_rptfield = Qnil;
322  VALUE element_type = fieldtype_to_ruby(self->field_type);
323  if (self->field_type_class != Qnil) {
324  new_rptfield = rb_funcall(CLASS_OF(_self), rb_intern("new"), 2,
325  element_type, self->field_type_class);
326  } else {
327  new_rptfield = rb_funcall(CLASS_OF(_self), rb_intern("new"), 1,
328  element_type);
329  }
330  return new_rptfield;
331 }
332 
333 /*
334  * call-seq:
335  * RepeatedField.dup => repeated_field
336  *
337  * Duplicates this repeated field with a shallow copy. References to all
338  * non-primitive element objects (e.g., submessages) are shared.
339  */
340 VALUE RepeatedField_dup(VALUE _self) {
341  RepeatedField* self = ruby_to_RepeatedField(_self);
342  VALUE new_rptfield = RepeatedField_new_this_type(_self);
343  RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
344  upb_fieldtype_t field_type = self->field_type;
345  size_t elem_size = native_slot_size(field_type);
346  size_t off = 0;
347  RepeatedField_reserve(new_rptfield_self, self->size);
348  for (int i = 0; i < self->size; i++, off += elem_size) {
349  void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
350  void* from_mem = (uint8_t *)self->elements + off;
351  native_slot_dup(field_type, to_mem, from_mem);
352  new_rptfield_self->size++;
353  }
354 
355  return new_rptfield;
356 }
357 
358 // Internal only: used by Google::Protobuf.deep_copy.
359 VALUE RepeatedField_deep_copy(VALUE _self) {
360  RepeatedField* self = ruby_to_RepeatedField(_self);
361  VALUE new_rptfield = RepeatedField_new_this_type(_self);
362  RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
363  upb_fieldtype_t field_type = self->field_type;
364  size_t elem_size = native_slot_size(field_type);
365  size_t off = 0;
366  RepeatedField_reserve(new_rptfield_self, self->size);
367  for (int i = 0; i < self->size; i++, off += elem_size) {
368  void* to_mem = (uint8_t *)new_rptfield_self->elements + off;
369  void* from_mem = (uint8_t *)self->elements + off;
370  native_slot_deep_copy(field_type, to_mem, from_mem);
371  new_rptfield_self->size++;
372  }
373 
374  return new_rptfield;
375 }
376 
377 /*
378  * call-seq:
379  * RepeatedField.to_ary => array
380  *
381  * Used when converted implicitly into array, e.g. compared to an Array.
382  * Also called as a fallback of Object#to_a
383  */
384 VALUE RepeatedField_to_ary(VALUE _self) {
385  RepeatedField* self = ruby_to_RepeatedField(_self);
386  upb_fieldtype_t field_type = self->field_type;
387 
388  size_t elem_size = native_slot_size(field_type);
389  size_t off = 0;
390  VALUE ary = rb_ary_new2(self->size);
391  for (int i = 0; i < self->size; i++, off += elem_size) {
392  void* mem = ((uint8_t *)self->elements) + off;
393  VALUE elem = native_slot_get(field_type, self->field_type_class, mem);
394  rb_ary_push(ary, elem);
395  }
396  return ary;
397 }
398 
399 /*
400  * call-seq:
401  * RepeatedField.==(other) => boolean
402  *
403  * Compares this repeated field to another. Repeated fields are equal if their
404  * element types are equal, their lengths are equal, and each element is equal.
405  * Elements are compared as per normal Ruby semantics, by calling their :==
406  * methods (or performing a more efficient comparison for primitive types).
407  *
408  * Repeated fields with dissimilar element types are never equal, even if value
409  * comparison (for example, between integers and floats) would have otherwise
410  * indicated that every element has equal value.
411  */
412 VALUE RepeatedField_eq(VALUE _self, VALUE _other) {
413  RepeatedField* self;
414  RepeatedField* other;
415 
416  if (_self == _other) {
417  return Qtrue;
418  }
419 
420  if (TYPE(_other) == T_ARRAY) {
421  VALUE self_ary = RepeatedField_to_ary(_self);
422  return rb_equal(self_ary, _other);
423  }
424 
425  self = ruby_to_RepeatedField(_self);
426  other = ruby_to_RepeatedField(_other);
427  if (self->field_type != other->field_type ||
428  self->field_type_class != other->field_type_class ||
429  self->size != other->size) {
430  return Qfalse;
431  }
432 
433  {
434  upb_fieldtype_t field_type = self->field_type;
435  size_t elem_size = native_slot_size(field_type);
436  size_t off = 0;
437  for (int i = 0; i < self->size; i++, off += elem_size) {
438  void* self_mem = ((uint8_t *)self->elements) + off;
439  void* other_mem = ((uint8_t *)other->elements) + off;
440  if (!native_slot_eq(field_type, self_mem, other_mem)) {
441  return Qfalse;
442  }
443  }
444  return Qtrue;
445  }
446 }
447 
448 /*
449  * call-seq:
450  * RepeatedField.hash => hash_value
451  *
452  * Returns a hash value computed from this repeated field's elements.
453  */
454 VALUE RepeatedField_hash(VALUE _self) {
455  RepeatedField* self = ruby_to_RepeatedField(_self);
456  st_index_t h = rb_hash_start(0);
457  VALUE hash_sym = rb_intern("hash");
458  upb_fieldtype_t field_type = self->field_type;
459  VALUE field_type_class = self->field_type_class;
460  size_t elem_size = native_slot_size(field_type);
461  size_t off = 0;
462  for (int i = 0; i < self->size; i++, off += elem_size) {
463  void* mem = ((uint8_t *)self->elements) + off;
464  VALUE elem = native_slot_get(field_type, field_type_class, mem);
465  h = rb_hash_uint(h, NUM2LONG(rb_funcall(elem, hash_sym, 0)));
466  }
467  h = rb_hash_end(h);
468 
469  return INT2FIX(h);
470 }
471 
472 /*
473  * call-seq:
474  * RepeatedField.+(other) => repeated field
475  *
476  * Returns a new repeated field that contains the concatenated list of this
477  * repeated field's elements and other's elements. The other (second) list may
478  * be either another repeated field or a Ruby array.
479  */
480 VALUE RepeatedField_plus(VALUE _self, VALUE list) {
481  VALUE dupped = RepeatedField_dup(_self);
482 
483  if (TYPE(list) == T_ARRAY) {
484  for (int i = 0; i < RARRAY_LEN(list); i++) {
485  VALUE elem = rb_ary_entry(list, i);
486  RepeatedField_push(dupped, elem);
487  }
488  } else if (RB_TYPE_P(list, T_DATA) && RTYPEDDATA_P(list) &&
489  RTYPEDDATA_TYPE(list) == &RepeatedField_type) {
490  RepeatedField* self = ruby_to_RepeatedField(_self);
491  RepeatedField* list_rptfield = ruby_to_RepeatedField(list);
492  if (self->field_type != list_rptfield->field_type ||
493  self->field_type_class != list_rptfield->field_type_class) {
494  rb_raise(rb_eArgError,
495  "Attempt to append RepeatedField with different element type.");
496  }
497  for (int i = 0; i < list_rptfield->size; i++) {
498  void* mem = RepeatedField_index_native(list, i);
499  RepeatedField_push_native(dupped, mem);
500  }
501  } else {
502  rb_raise(rb_eArgError, "Unknown type appending to RepeatedField");
503  }
504 
505  return dupped;
506 }
507 
508 /*
509  * call-seq:
510  * RepeatedField.concat(other) => self
511  *
512  * concats the passed in array to self. Returns a Ruby array.
513  */
514 VALUE RepeatedField_concat(VALUE _self, VALUE list) {
515  Check_Type(list, T_ARRAY);
516  for (int i = 0; i < RARRAY_LEN(list); i++) {
517  RepeatedField_push(_self, rb_ary_entry(list, i));
518  }
519  return _self;
520 }
521 
522 
524  if (rb_ivar_get(klass, descriptor_instancevar_interned) == Qnil) {
525  rb_raise(rb_eArgError,
526  "Type class has no descriptor. Please pass a "
527  "class or enum as returned by the DescriptorPool.");
528  }
529  if (type == UPB_TYPE_MESSAGE) {
530  VALUE desc = rb_ivar_get(klass, descriptor_instancevar_interned);
531  if (!RB_TYPE_P(desc, T_DATA) || !RTYPEDDATA_P(desc) ||
532  RTYPEDDATA_TYPE(desc) != &_Descriptor_type) {
533  rb_raise(rb_eArgError, "Descriptor has an incorrect type.");
534  }
535  if (rb_get_alloc_func(klass) != &Message_alloc) {
536  rb_raise(rb_eArgError,
537  "Message class was not returned by the DescriptorPool.");
538  }
539  } else if (type == UPB_TYPE_ENUM) {
540  VALUE enumdesc = rb_ivar_get(klass, descriptor_instancevar_interned);
541  if (!RB_TYPE_P(enumdesc, T_DATA) || !RTYPEDDATA_P(enumdesc) ||
542  RTYPEDDATA_TYPE(enumdesc) != &_EnumDescriptor_type) {
543  rb_raise(rb_eArgError, "Descriptor has an incorrect type.");
544  }
545  }
546 }
547 
548 void RepeatedField_init_args(int argc, VALUE* argv,
549  VALUE _self) {
550  RepeatedField* self = ruby_to_RepeatedField(_self);
551  VALUE ary = Qnil;
552  if (argc < 1) {
553  rb_raise(rb_eArgError, "Expected at least 1 argument.");
554  }
555  self->field_type = ruby_to_fieldtype(argv[0]);
556 
557  if (self->field_type == UPB_TYPE_MESSAGE ||
558  self->field_type == UPB_TYPE_ENUM) {
559  if (argc < 2) {
560  rb_raise(rb_eArgError, "Expected at least 2 arguments for message/enum.");
561  }
562  self->field_type_class = argv[1];
563  if (argc > 2) {
564  ary = argv[2];
565  }
566  validate_type_class(self->field_type, self->field_type_class);
567  } else {
568  if (argc > 2) {
569  rb_raise(rb_eArgError, "Too many arguments: expected 1 or 2.");
570  }
571  if (argc > 1) {
572  ary = argv[1];
573  }
574  }
575 
576  if (ary != Qnil) {
577  if (!RB_TYPE_P(ary, T_ARRAY)) {
578  rb_raise(rb_eArgError, "Expected array as initialize argument");
579  }
580  for (int i = 0; i < RARRAY_LEN(ary); i++) {
581  RepeatedField_push(_self, rb_ary_entry(ary, i));
582  }
583  }
584 }
585 
586 // Mark, free, alloc, init and class setup functions.
587 
588 void RepeatedField_mark(void* _self) {
589  RepeatedField* self = (RepeatedField*)_self;
590  upb_fieldtype_t field_type = self->field_type;
591  int element_size = native_slot_size(field_type);
592  rb_gc_mark(self->field_type_class);
593  for (int i = 0; i < self->size; i++) {
594  void* memory = (((uint8_t *)self->elements) + i * element_size);
595  native_slot_mark(self->field_type, memory);
596  }
597 }
598 
599 void RepeatedField_free(void* _self) {
600  RepeatedField* self = (RepeatedField*)_self;
601  xfree(self->elements);
602  xfree(self);
603 }
604 
605 /*
606  * call-seq:
607  * RepeatedField.new(type, type_class = nil, initial_elems = [])
608  *
609  * Creates a new repeated field. The provided type must be a Ruby symbol, and
610  * can take on the same values as those accepted by FieldDescriptor#type=. If
611  * the type is :message or :enum, type_class must be non-nil, and must be the
612  * Ruby class or module returned by Descriptor#msgclass or
613  * EnumDescriptor#enummodule, respectively. An initial list of elements may also
614  * be provided.
615  */
618  self->elements = NULL;
619  self->size = 0;
620  self->capacity = 0;
621  self->field_type = -1;
622  self->field_type_class = Qnil;
623  return TypedData_Wrap_Struct(klass, &RepeatedField_type, self);
624 }
625 
626 VALUE RepeatedField_init(int argc, VALUE* argv, VALUE self) {
627  RepeatedField_init_args(argc, argv, self);
628  return Qnil;
629 }
630 
631 void RepeatedField_register(VALUE module) {
632  VALUE klass = rb_define_class_under(
633  module, "RepeatedField", rb_cObject);
634  rb_define_alloc_func(klass, RepeatedField_alloc);
635  rb_gc_register_address(&cRepeatedField);
637 
638  rb_define_method(klass, "initialize",
639  RepeatedField_init, -1);
640  rb_define_method(klass, "each", RepeatedField_each, 0);
641  rb_define_method(klass, "[]", RepeatedField_index, -1);
642  rb_define_method(klass, "at", RepeatedField_index, -1);
643  rb_define_method(klass, "[]=", RepeatedField_index_set, 2);
644  rb_define_method(klass, "push", RepeatedField_push_vararg, -2);
645  rb_define_method(klass, "<<", RepeatedField_push, 1);
646  rb_define_private_method(klass, "pop_one", RepeatedField_pop_one, 0);
647  rb_define_method(klass, "replace", RepeatedField_replace, 1);
648  rb_define_method(klass, "clear", RepeatedField_clear, 0);
649  rb_define_method(klass, "length", RepeatedField_length, 0);
650  rb_define_method(klass, "size", RepeatedField_length, 0);
651  rb_define_method(klass, "dup", RepeatedField_dup, 0);
652  // Also define #clone so that we don't inherit Object#clone.
653  rb_define_method(klass, "clone", RepeatedField_dup, 0);
654  rb_define_method(klass, "==", RepeatedField_eq, 1);
655  rb_define_method(klass, "to_ary", RepeatedField_to_ary, 0);
656  rb_define_method(klass, "hash", RepeatedField_hash, 0);
657  rb_define_method(klass, "+", RepeatedField_plus, 1);
658  rb_define_method(klass, "concat", RepeatedField_concat, 1);
659  rb_include_module(klass, rb_mEnumerable);
660 }
native_slot_dup
void native_slot_dup(upb_fieldtype_t type, void *to, void *from)
Definition: ruby/ext/google/protobuf_c/storage.c:358
RepeatedField_concat
VALUE RepeatedField_concat(VALUE _self, VALUE list)
Definition: repeated_field.c:514
native_slot_set
bool native_slot_set(upb_fieldtype_t type, const zend_class_entry *klass, void *memory, zval *value TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:87
RepeatedField::elements
void * elements
Definition: ruby/ext/google/protobuf_c/protobuf.h:398
RepeatedField_size
int RepeatedField_size(VALUE _self)
Definition: repeated_field.c:253
NULL
NULL
Definition: test_security_zap.cpp:405
field_type
zend_class_entry * field_type
Definition: php/ext/google/protobuf/message.c:2028
native_slot_init
void native_slot_init(upb_fieldtype_t type, void *memory, CACHED_VALUE *cache)
Definition: php/ext/google/protobuf/storage.c:276
RepeatedField_reserve
void RepeatedField_reserve(RepeatedField *self, int new_size)
Definition: repeated_field.c:187
descriptor_instancevar_interned
ID descriptor_instancevar_interned
Definition: ruby/ext/google/protobuf_c/protobuf.c:78
_EnumDescriptor_type
const rb_data_type_t _EnumDescriptor_type
self
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern self
Definition: php/ext/google/protobuf/map.c:543
RepeatedField_init_args
void RepeatedField_init_args(int argc, VALUE *argv, VALUE _self)
Definition: repeated_field.c:548
RepeatedField_subarray
VALUE RepeatedField_subarray(VALUE _self, long beg, long len)
Definition: repeated_field.c:62
protobuf.h
RepeatedField_new_this_type
static VALUE RepeatedField_new_this_type(VALUE _self)
Definition: repeated_field.c:319
validate_type_class
void validate_type_class(upb_fieldtype_t type, VALUE klass)
Definition: repeated_field.c:523
desc
#define desc
Definition: extension_set.h:342
RepeatedField_replace
VALUE RepeatedField_replace(VALUE _self, VALUE list)
Definition: repeated_field.c:286
RepeatedField_index_set
VALUE RepeatedField_index_set(VALUE _self, VALUE _index, VALUE val)
Definition: repeated_field.c:158
RepeatedField::field_type
upb_fieldtype_t field_type
Definition: ruby/ext/google/protobuf_c/protobuf.h:396
RepeatedField_plus
VALUE RepeatedField_plus(VALUE _self, VALUE list)
Definition: repeated_field.c:480
native_slot_size
size_t native_slot_size(upb_fieldtype_t type)
Definition: php/ext/google/protobuf/storage.c:43
Message_alloc
VALUE Message_alloc(VALUE klass)
Definition: ruby/ext/google/protobuf_c/message.c:60
native_slot_eq
bool native_slot_eq(upb_fieldtype_t type, void *mem1, void *mem2)
Definition: ruby/ext/google/protobuf_c/storage.c:382
RepeatedField::size
int size
Definition: ruby/ext/google/protobuf_c/protobuf.h:399
RepeatedField_init
VALUE RepeatedField_init(int argc, VALUE *argv, VALUE self)
Definition: repeated_field.c:626
RepeatedField_each
VALUE RepeatedField_each(VALUE _self)
Definition: repeated_field.c:86
RepeatedField_index_native
void * RepeatedField_index_native(VALUE _self, int index)
Definition: repeated_field.c:246
ALLOC
#define ALLOC(class_name)
Definition: php/ext/google/protobuf/protobuf.h:1477
RepeatedField_push_vararg
VALUE RepeatedField_push_vararg(VALUE _self, VALUE args)
Definition: repeated_field.c:226
_Descriptor_type
const rb_data_type_t _Descriptor_type
repeated_field
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern repeated_field
Definition: array.c:486
RepeatedField_length
VALUE RepeatedField_length(VALUE _self)
Definition: repeated_field.c:314
ALLOC_N
#define ALLOC_N(class_name, n)
Definition: php/ext/google/protobuf/protobuf.h:1479
native_slot_mark
void native_slot_mark(upb_fieldtype_t type, void *memory)
Definition: ruby/ext/google/protobuf_c/storage.c:346
RepeatedField_type
const rb_data_type_t RepeatedField_type
Definition: repeated_field.c:37
ruby_to_RepeatedField
RepeatedField * ruby_to_RepeatedField(VALUE _self)
Definition: repeated_field.c:44
field_type_class
const zend_class_entry * field_type_class(const upb_fielddef *field PHP_PROTO_TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:552
RepeatedField_push
VALUE RepeatedField_push(VALUE _self, VALUE val)
Definition: repeated_field.c:212
index_position
static int index_position(VALUE _index, RepeatedField *repeated_field)
Definition: repeated_field.c:54
RepeatedField_register
void RepeatedField_register(VALUE module)
Definition: repeated_field.c:631
native_slot_deep_copy
void native_slot_deep_copy(upb_fieldtype_t type, void *to, void *from)
Definition: ruby/ext/google/protobuf_c/storage.c:362
RepeatedField_mark
void RepeatedField_mark(void *_self)
Definition: repeated_field.c:588
native_slot_get
void native_slot_get(upb_fieldtype_t type, const void *memory, CACHED_VALUE *cache TSRMLS_DC)
Definition: php/ext/google/protobuf/storage.c:311
RepeatedField_push_native
void RepeatedField_push_native(VALUE _self, void *data)
Definition: repeated_field.c:234
UPB_TYPE_MESSAGE
@ UPB_TYPE_MESSAGE
Definition: php/ext/google/protobuf/upb.h:421
UPB_TYPE_ENUM
@ UPB_TYPE_ENUM
Definition: php/ext/google/protobuf/upb.h:417
cRepeatedField
VALUE cRepeatedField
Definition: repeated_field.c:42
RepeatedField_dup
VALUE RepeatedField_dup(VALUE _self)
Definition: repeated_field.c:340
i
int i
Definition: gmock-matchers_test.cc:764
RepeatedField_alloc
VALUE RepeatedField_alloc(VALUE klass)
Definition: repeated_field.c:616
RepeatedField::field_type_class
VALUE field_type_class
Definition: ruby/ext/google/protobuf_c/protobuf.h:397
type
GLenum type
Definition: glcorearb.h:2695
len
int len
Definition: php/ext/google/protobuf/map.c:206
RepeatedField_deep_copy
VALUE RepeatedField_deep_copy(VALUE _self)
Definition: repeated_field.c:359
fieldtype_to_ruby
VALUE fieldtype_to_ruby(upb_fieldtype_t type)
Definition: defs.c:752
size
GLsizeiptr size
Definition: glcorearb.h:2943
RepeatedField_clear
VALUE RepeatedField_clear(VALUE _self)
Definition: repeated_field.c:302
RepeatedField_hash
VALUE RepeatedField_hash(VALUE _self)
Definition: repeated_field.c:454
TYPE
#define TYPE(u, l)
Definition: php/ext/google/protobuf/upb.c:8510
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
RepeatedField_index
VALUE RepeatedField_index(int argc, VALUE *argv, VALUE _self)
Definition: repeated_field.c:108
val
GLuint GLfloat * val
Definition: glcorearb.h:3604
RepeatedField_pop_one
VALUE RepeatedField_pop_one(VALUE _self)
Definition: repeated_field.c:261
ruby_to_fieldtype
upb_fieldtype_t ruby_to_fieldtype(VALUE type)
Definition: defs.c:724
RepeatedField_free
void RepeatedField_free(void *_self)
Definition: repeated_field.c:599
index
GLuint index
Definition: glcorearb.h:3055
klass
zend_class_entry * klass
Definition: php/ext/google/protobuf/protobuf.h:801
RepeatedField_memoryat
void * RepeatedField_memoryat(RepeatedField *self, int index, int element_size)
Definition: repeated_field.c:50
kInitialSize
static int kInitialSize
Definition: repeated_field.c:185
upb_fieldtype_t
upb_fieldtype_t
Definition: php/ext/google/protobuf/upb.h:410
h
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:4147
benchmarks.python.py_benchmark.args
args
Definition: py_benchmark.py:24
RepeatedField_eq
VALUE RepeatedField_eq(VALUE _self, VALUE _other)
Definition: repeated_field.c:412
RepeatedField_to_ary
VALUE RepeatedField_to_ary(VALUE _self)
Definition: repeated_field.c:384
RepeatedField
Definition: ruby/ext/google/protobuf_c/protobuf.h:395


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:58