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

Sign up to get free protection for your applications and to get access to all the features.

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