google-protobuf 3.0.0.alpha.1.0 → 3.0.0.alpha.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of google-protobuf might be problematic. Click here for more details.

@@ -600,6 +600,9 @@ typedef struct {
600
600
 
601
601
  // Like strdup(), which isn't always available since it's not ANSI C.
602
602
  char *upb_strdup(const char *s);
603
+ // Variant that works with a length-delimited rather than NULL-delimited string,
604
+ // as supported by strtable.
605
+ char *upb_strdup2(const char *s, size_t len);
603
606
 
604
607
  UPB_INLINE void _upb_value_setval(upb_value *v, _upb_value val,
605
608
  upb_ctype_t ctype) {
@@ -654,12 +657,24 @@ FUNCS(fptr, fptr, upb_func*, UPB_CTYPE_FPTR);
654
657
 
655
658
  typedef union {
656
659
  uintptr_t num;
657
- const char *str; // We own, nullz.
660
+ struct {
661
+ // We own this. NULL-terminated but may also contain binary data; see
662
+ // explicit length below.
663
+ // TODO: move the length to the start of the string in order to reduce
664
+ // tabkey's size (to one machine word) in a way that supports static
665
+ // initialization.
666
+ const char *str;
667
+ size_t length;
668
+ } s;
658
669
  } upb_tabkey;
659
670
 
660
671
  #define UPB_TABKEY_NUM(n) {n}
661
672
  #ifdef UPB_C99
662
- #define UPB_TABKEY_STR(s) {.str = s}
673
+ // Given that |s| is a string literal, sizeof(s) gives us a
674
+ // compile-time-constant strlen(). We must ensure that this works for static
675
+ // data initializers.
676
+ #define UPB_TABKEY_STR(strval) { .s = { .str = strval, \
677
+ .length = sizeof(strval) - 1 } }
663
678
  #endif
664
679
  // TODO(haberman): C++
665
680
  #define UPB_TABKEY_NONE {0}
@@ -765,7 +780,14 @@ UPB_INLINE size_t upb_strtable_count(const upb_strtable *t) {
765
780
  // If a table resize was required but memory allocation failed, false is
766
781
  // returned and the table is unchanged.
767
782
  bool upb_inttable_insert(upb_inttable *t, uintptr_t key, upb_value val);
768
- bool upb_strtable_insert(upb_strtable *t, const char *key, upb_value val);
783
+ bool upb_strtable_insert2(upb_strtable *t, const char *key, size_t len,
784
+ upb_value val);
785
+
786
+ // For NULL-terminated strings.
787
+ UPB_INLINE bool upb_strtable_insert(upb_strtable *t, const char *key,
788
+ upb_value val) {
789
+ return upb_strtable_insert2(t, key, strlen(key), val);
790
+ }
769
791
 
770
792
  // Looks up key in this table, returning "true" if the key was found.
771
793
  // If v is non-NULL, copies the value for this key into *v.
@@ -782,7 +804,14 @@ UPB_INLINE bool upb_strtable_lookup(const upb_strtable *t, const char *key,
782
804
  // Removes an item from the table. Returns true if the remove was successful,
783
805
  // and stores the removed item in *val if non-NULL.
784
806
  bool upb_inttable_remove(upb_inttable *t, uintptr_t key, upb_value *val);
785
- bool upb_strtable_remove(upb_strtable *t, const char *key, upb_value *val);
807
+ bool upb_strtable_remove2(upb_strtable *t, const char *key, size_t len,
808
+ upb_value *val);
809
+
810
+ // For NULL-terminated strings.
811
+ UPB_INLINE bool upb_strtable_remove(upb_strtable *t, const char *key,
812
+ upb_value *v) {
813
+ return upb_strtable_remove2(t, key, strlen(key), v);
814
+ }
786
815
 
787
816
  // Updates an existing entry in an inttable. If the entry does not exist,
788
817
  // returns false and does nothing. Unlike insert/remove, this does not
@@ -876,6 +905,7 @@ void upb_strtable_begin(upb_strtable_iter *i, const upb_strtable *t);
876
905
  void upb_strtable_next(upb_strtable_iter *i);
877
906
  bool upb_strtable_done(const upb_strtable_iter *i);
878
907
  const char *upb_strtable_iter_key(upb_strtable_iter *i);
908
+ size_t upb_strtable_iter_keylength(upb_strtable_iter *i);
879
909
  upb_value upb_strtable_iter_value(const upb_strtable_iter *i);
880
910
  void upb_strtable_iter_setdone(upb_strtable_iter *i);
881
911
  bool upb_strtable_iter_isequal(const upb_strtable_iter *i1,
@@ -1777,6 +1807,10 @@ UPB_DEFINE_DEF(upb::MessageDef, msgdef, MSG, UPB_QUOTE(
1777
1807
  // just be moved into symtab.c?
1778
1808
  MessageDef* Dup(const void* owner) const;
1779
1809
 
1810
+ // Is this message a map entry?
1811
+ void setmapentry(bool map_entry);
1812
+ bool mapentry() const;
1813
+
1780
1814
  // Iteration over fields. The order is undefined.
1781
1815
  class iterator : public std::iterator<std::forward_iterator_tag, FieldDef*> {
1782
1816
  public:
@@ -1823,6 +1857,11 @@ UPB_DEFINE_STRUCT(upb_msgdef, upb_def,
1823
1857
  upb_inttable itof; // int to field
1824
1858
  upb_strtable ntof; // name to field
1825
1859
 
1860
+ // Is this a map-entry message?
1861
+ // TODO: set this flag properly for static descriptors; regenerate
1862
+ // descriptor.upb.c.
1863
+ bool map_entry;
1864
+
1826
1865
  // TODO(haberman): proper extension ranges (there can be multiple).
1827
1866
  ));
1828
1867
 
@@ -1830,7 +1869,7 @@ UPB_DEFINE_STRUCT(upb_msgdef, upb_def,
1830
1869
  refs, ref2s) \
1831
1870
  { \
1832
1871
  UPB_DEF_INIT(name, UPB_DEF_MSG, refs, ref2s), selector_count, \
1833
- submsg_field_count, itof, ntof \
1872
+ submsg_field_count, itof, ntof, false \
1834
1873
  }
1835
1874
 
1836
1875
  UPB_BEGIN_EXTERN_C // {
@@ -1878,6 +1917,9 @@ UPB_INLINE upb_fielddef *upb_msgdef_ntof_mutable(upb_msgdef *m,
1878
1917
  return (upb_fielddef *)upb_msgdef_ntof(m, name, len);
1879
1918
  }
1880
1919
 
1920
+ void upb_msgdef_setmapentry(upb_msgdef *m, bool map_entry);
1921
+ bool upb_msgdef_mapentry(const upb_msgdef *m);
1922
+
1881
1923
  // upb_msg_iter i;
1882
1924
  // for(upb_msg_begin(&i, m); !upb_msg_done(&i); upb_msg_next(&i)) {
1883
1925
  // upb_fielddef *f = upb_msg_iter_field(&i);
@@ -2331,6 +2373,12 @@ inline const FieldDef *MessageDef::FindFieldByName(const char *name,
2331
2373
  inline MessageDef* MessageDef::Dup(const void *owner) const {
2332
2374
  return upb_msgdef_dup(this, owner);
2333
2375
  }
2376
+ inline void MessageDef::setmapentry(bool map_entry) {
2377
+ upb_msgdef_setmapentry(this, map_entry);
2378
+ }
2379
+ inline bool MessageDef::mapentry() const {
2380
+ return upb_msgdef_mapentry(this);
2381
+ }
2334
2382
  inline MessageDef::iterator MessageDef::begin() { return iterator(this); }
2335
2383
  inline MessageDef::iterator MessageDef::end() { return iterator::end(this); }
2336
2384
  inline MessageDef::const_iterator MessageDef::begin() const {
@@ -6614,7 +6662,9 @@ typedef enum {
6614
6662
  // | unused (24) | opc |
6615
6663
  // | upb_inttable* (32 or 64) |
6616
6664
 
6617
- OP_HALT = 36, // No arg.
6665
+ OP_DISPATCH = 36, // No arg.
6666
+
6667
+ OP_HALT = 37, // No arg.
6618
6668
  } opcode;
6619
6669
 
6620
6670
  #define OP_MAX OP_HALT
@@ -7291,15 +7341,24 @@ UPB_DEFINE_STRUCT0(upb_json_parser,
7291
7341
  int parser_stack[UPB_JSON_MAX_DEPTH];
7292
7342
  int parser_top;
7293
7343
 
7294
- // A pointer to the beginning of whatever text we are currently parsing.
7295
- const char *text_begin;
7344
+ // The handle for the current buffer.
7345
+ const upb_bufhandle *handle;
7296
7346
 
7297
- // We have to accumulate text for member names, integers, unicode escapes, and
7298
- // base64 partial results.
7347
+ // Accumulate buffer. See details in parser.rl.
7299
7348
  const char *accumulated;
7300
7349
  size_t accumulated_len;
7301
- // TODO: add members and code for allocating a buffer when necessary (when the
7302
- // member spans input buffers or contains escapes).
7350
+ char *accumulate_buf;
7351
+ size_t accumulate_buf_size;
7352
+
7353
+ // Multi-part text data. See details in parser.rl.
7354
+ int multipart_state;
7355
+ upb_selector_t string_selector;
7356
+
7357
+ // Input capture. See details in parser.rl.
7358
+ const char *capture;
7359
+
7360
+ // Intermediate result of parsing a unicode escape sequence.
7361
+ uint32_t digit;
7303
7362
  ));
7304
7363
 
7305
7364
  UPB_BEGIN_EXTERN_C
@@ -36,23 +36,43 @@ module BasicTest
36
36
  add_message "TestMessage2" do
37
37
  optional :foo, :int32, 1
38
38
  end
39
+
39
40
  add_message "Recursive1" do
40
41
  optional :foo, :message, 1, "Recursive2"
41
42
  end
42
43
  add_message "Recursive2" do
43
44
  optional :foo, :message, 1, "Recursive1"
44
45
  end
46
+
45
47
  add_enum "TestEnum" do
46
48
  value :Default, 0
47
49
  value :A, 1
48
50
  value :B, 2
49
51
  value :C, 3
50
52
  end
53
+
51
54
  add_message "BadFieldNames" do
52
55
  optional :dup, :int32, 1
53
56
  optional :class, :int32, 2
54
57
  optional :"a.b", :int32, 3
55
58
  end
59
+
60
+ add_message "MapMessage" do
61
+ map :map_string_int32, :string, :int32, 1
62
+ map :map_string_msg, :string, :message, 2, "TestMessage2"
63
+ end
64
+ add_message "MapMessageWireEquiv" do
65
+ repeated :map_string_int32, :message, 1, "MapMessageWireEquiv_entry1"
66
+ repeated :map_string_msg, :message, 2, "MapMessageWireEquiv_entry2"
67
+ end
68
+ add_message "MapMessageWireEquiv_entry1" do
69
+ optional :key, :string, 1
70
+ optional :value, :int32, 2
71
+ end
72
+ add_message "MapMessageWireEquiv_entry2" do
73
+ optional :key, :string, 1
74
+ optional :value, :message, 2, "TestMessage2"
75
+ end
56
76
  end
57
77
 
58
78
  TestMessage = pool.lookup("TestMessage").msgclass
@@ -61,6 +81,12 @@ module BasicTest
61
81
  Recursive2 = pool.lookup("Recursive2").msgclass
62
82
  TestEnum = pool.lookup("TestEnum").enummodule
63
83
  BadFieldNames = pool.lookup("BadFieldNames").msgclass
84
+ MapMessage = pool.lookup("MapMessage").msgclass
85
+ MapMessageWireEquiv = pool.lookup("MapMessageWireEquiv").msgclass
86
+ MapMessageWireEquiv_entry1 =
87
+ pool.lookup("MapMessageWireEquiv_entry1").msgclass
88
+ MapMessageWireEquiv_entry2 =
89
+ pool.lookup("MapMessageWireEquiv_entry2").msgclass
64
90
 
65
91
  # ------------ test cases ---------------
66
92
 
@@ -300,7 +326,7 @@ module BasicTest
300
326
  l.push :B
301
327
  l.push :C
302
328
  assert l.count == 3
303
- assert_raise NameError do
329
+ assert_raise RangeError do
304
330
  l.push :D
305
331
  end
306
332
  assert l[0] == :A
@@ -324,12 +350,244 @@ module BasicTest
324
350
  end
325
351
  end
326
352
 
353
+ def test_map_basic
354
+ # allowed key types:
355
+ # :int32, :int64, :uint32, :uint64, :bool, :string, :bytes.
356
+
357
+ m = Google::Protobuf::Map.new(:string, :int32)
358
+ m["asdf"] = 1
359
+ assert m["asdf"] == 1
360
+ m["jkl;"] = 42
361
+ assert m == { "jkl;" => 42, "asdf" => 1 }
362
+ assert m.has_key?("asdf")
363
+ assert !m.has_key?("qwerty")
364
+ assert m.length == 2
365
+
366
+ m2 = m.dup
367
+ assert m == m2
368
+ assert m.hash != 0
369
+ assert m.hash == m2.hash
370
+
371
+ collected = {}
372
+ m.each { |k,v| collected[v] = k }
373
+ assert collected == { 42 => "jkl;", 1 => "asdf" }
374
+
375
+ assert m.delete("asdf") == 1
376
+ assert !m.has_key?("asdf")
377
+ assert m["asdf"] == nil
378
+ assert !m.has_key?("asdf")
379
+
380
+ # We only assert on inspect value when there is one map entry because the
381
+ # order in which elements appear is unspecified (depends on the internal
382
+ # hash function). We don't want a brittle test.
383
+ assert m.inspect == "{\"jkl;\" => 42}"
384
+
385
+ assert m.keys == ["jkl;"]
386
+ assert m.values == [42]
387
+
388
+ m.clear
389
+ assert m.length == 0
390
+ assert m == {}
391
+
392
+ assert_raise TypeError do
393
+ m[1] = 1
394
+ end
395
+ assert_raise RangeError do
396
+ m["asdf"] = 0x1_0000_0000
397
+ end
398
+ end
399
+
400
+ def test_map_ctor
401
+ m = Google::Protobuf::Map.new(:string, :int32,
402
+ {"a" => 1, "b" => 2, "c" => 3})
403
+ assert m == {"a" => 1, "c" => 3, "b" => 2}
404
+ end
405
+
406
+ def test_map_keytypes
407
+ m = Google::Protobuf::Map.new(:int32, :int32)
408
+ m[1] = 42
409
+ m[-1] = 42
410
+ assert_raise RangeError do
411
+ m[0x8000_0000] = 1
412
+ end
413
+ assert_raise TypeError do
414
+ m["asdf"] = 1
415
+ end
416
+
417
+ m = Google::Protobuf::Map.new(:int64, :int32)
418
+ m[0x1000_0000_0000_0000] = 1
419
+ assert_raise RangeError do
420
+ m[0x1_0000_0000_0000_0000] = 1
421
+ end
422
+ assert_raise TypeError do
423
+ m["asdf"] = 1
424
+ end
425
+
426
+ m = Google::Protobuf::Map.new(:uint32, :int32)
427
+ m[0x8000_0000] = 1
428
+ assert_raise RangeError do
429
+ m[0x1_0000_0000] = 1
430
+ end
431
+ assert_raise RangeError do
432
+ m[-1] = 1
433
+ end
434
+
435
+ m = Google::Protobuf::Map.new(:uint64, :int32)
436
+ m[0x8000_0000_0000_0000] = 1
437
+ assert_raise RangeError do
438
+ m[0x1_0000_0000_0000_0000] = 1
439
+ end
440
+ assert_raise RangeError do
441
+ m[-1] = 1
442
+ end
443
+
444
+ m = Google::Protobuf::Map.new(:bool, :int32)
445
+ m[true] = 1
446
+ m[false] = 2
447
+ assert_raise TypeError do
448
+ m[1] = 1
449
+ end
450
+ assert_raise TypeError do
451
+ m["asdf"] = 1
452
+ end
453
+
454
+ m = Google::Protobuf::Map.new(:string, :int32)
455
+ m["asdf"] = 1
456
+ assert_raise TypeError do
457
+ m[1] = 1
458
+ end
459
+ assert_raise TypeError do
460
+ bytestring = ["FFFF"].pack("H*")
461
+ m[bytestring] = 1
462
+ end
463
+
464
+ m = Google::Protobuf::Map.new(:bytes, :int32)
465
+ bytestring = ["FFFF"].pack("H*")
466
+ m[bytestring] = 1
467
+ assert_raise TypeError do
468
+ m["asdf"] = 1
469
+ end
470
+ assert_raise TypeError do
471
+ m[1] = 1
472
+ end
473
+ end
474
+
475
+ def test_map_msg_enum_valuetypes
476
+ m = Google::Protobuf::Map.new(:string, :message, TestMessage)
477
+ m["asdf"] = TestMessage.new
478
+ assert_raise TypeError do
479
+ m["jkl;"] = TestMessage2.new
480
+ end
481
+
482
+ m = Google::Protobuf::Map.new(
483
+ :string, :message, TestMessage,
484
+ { "a" => TestMessage.new(:optional_int32 => 42),
485
+ "b" => TestMessage.new(:optional_int32 => 84) })
486
+ assert m.length == 2
487
+ assert m.values.map{|msg| msg.optional_int32}.sort == [42, 84]
488
+
489
+ m = Google::Protobuf::Map.new(:string, :enum, TestEnum,
490
+ { "x" => :A, "y" => :B, "z" => :C })
491
+ assert m.length == 3
492
+ assert m["z"] == :C
493
+ m["z"] = 2
494
+ assert m["z"] == :B
495
+ m["z"] = 4
496
+ assert m["z"] == 4
497
+ assert_raise RangeError do
498
+ m["z"] = :Z
499
+ end
500
+ assert_raise TypeError do
501
+ m["z"] = "z"
502
+ end
503
+ end
504
+
505
+ def test_map_dup_deep_copy
506
+ m = Google::Protobuf::Map.new(
507
+ :string, :message, TestMessage,
508
+ { "a" => TestMessage.new(:optional_int32 => 42),
509
+ "b" => TestMessage.new(:optional_int32 => 84) })
510
+
511
+ m2 = m.dup
512
+ assert m == m2
513
+ assert m.object_id != m2.object_id
514
+ assert m["a"].object_id == m2["a"].object_id
515
+ assert m["b"].object_id == m2["b"].object_id
516
+
517
+ m2 = Google::Protobuf.deep_copy(m)
518
+ assert m == m2
519
+ assert m.object_id != m2.object_id
520
+ assert m["a"].object_id != m2["a"].object_id
521
+ assert m["b"].object_id != m2["b"].object_id
522
+ end
523
+
524
+ def test_map_field
525
+ m = MapMessage.new
526
+ assert m.map_string_int32 == {}
527
+ assert m.map_string_msg == {}
528
+
529
+ m = MapMessage.new(
530
+ :map_string_int32 => {"a" => 1, "b" => 2},
531
+ :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
532
+ "b" => TestMessage2.new(:foo => 2)})
533
+ assert m.map_string_int32.keys.sort == ["a", "b"]
534
+ assert m.map_string_int32["a"] == 1
535
+ assert m.map_string_msg["b"].foo == 2
536
+
537
+ m.map_string_int32["c"] = 3
538
+ assert m.map_string_int32["c"] == 3
539
+ m.map_string_msg["c"] = TestMessage2.new(:foo => 3)
540
+ assert m.map_string_msg["c"] == TestMessage2.new(:foo => 3)
541
+ m.map_string_msg.delete("b")
542
+ m.map_string_msg.delete("c")
543
+ assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
544
+
545
+ assert_raise TypeError do
546
+ m.map_string_msg["e"] = TestMessage.new # wrong value type
547
+ end
548
+ # ensure nothing was added by the above
549
+ assert m.map_string_msg == { "a" => TestMessage2.new(:foo => 1) }
550
+
551
+ m.map_string_int32 = Google::Protobuf::Map.new(:string, :int32)
552
+ assert_raise TypeError do
553
+ m.map_string_int32 = Google::Protobuf::Map.new(:string, :int64)
554
+ end
555
+ assert_raise TypeError do
556
+ m.map_string_int32 = {}
557
+ end
558
+
559
+ assert_raise TypeError do
560
+ m = MapMessage.new(:map_string_int32 => { 1 => "I am not a number" })
561
+ end
562
+ end
563
+
564
+ def test_map_encode_decode
565
+ m = MapMessage.new(
566
+ :map_string_int32 => {"a" => 1, "b" => 2},
567
+ :map_string_msg => {"a" => TestMessage2.new(:foo => 1),
568
+ "b" => TestMessage2.new(:foo => 2)})
569
+ m2 = MapMessage.decode(MapMessage.encode(m))
570
+ assert m == m2
571
+
572
+ m3 = MapMessageWireEquiv.decode(MapMessage.encode(m))
573
+ assert m3.map_string_int32.length == 2
574
+
575
+ kv = {}
576
+ m3.map_string_int32.map { |msg| kv[msg.key] = msg.value }
577
+ assert kv == {"a" => 1, "b" => 2}
578
+
579
+ kv = {}
580
+ m3.map_string_msg.map { |msg| kv[msg.key] = msg.value }
581
+ assert kv == {"a" => TestMessage2.new(:foo => 1),
582
+ "b" => TestMessage2.new(:foo => 2)}
583
+ end
584
+
327
585
  def test_enum_field
328
586
  m = TestMessage.new
329
587
  assert m.optional_enum == :Default
330
588
  m.optional_enum = :A
331
589
  assert m.optional_enum == :A
332
- assert_raise NameError do
590
+ assert_raise RangeError do
333
591
  m.optional_enum = :ASDF
334
592
  end
335
593
  m.optional_enum = 1
@@ -384,7 +642,8 @@ module BasicTest
384
642
  :repeated_string => ["a", "b", "c"],
385
643
  :repeated_int32 => [42, 43, 44],
386
644
  :repeated_enum => [:A, :B, :C, 100],
387
- :repeated_msg => [TestMessage2.new(:foo => 1), TestMessage2.new(:foo => 2)])
645
+ :repeated_msg => [TestMessage2.new(:foo => 1),
646
+ TestMessage2.new(:foo => 2)])
388
647
  data = TestMessage.encode m
389
648
  m2 = TestMessage.decode data
390
649
  assert m == m2