capn_proto-rpc 0.1.1.alpha.rpc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +10 -0
  3. data/.travis.yml +19 -0
  4. data/Gemfile +2 -0
  5. data/LICENSE +19 -0
  6. data/README.md +249 -0
  7. data/Rakefile +44 -0
  8. data/capn_proto.gemspec +37 -0
  9. data/examples/addressbook.bin +0 -0
  10. data/examples/addressbook.capnp +31 -0
  11. data/examples/create_test_data.py +39 -0
  12. data/examples/example.rb +38 -0
  13. data/ext/capn_proto/.ycm_extra_conf.py +65 -0
  14. data/ext/capn_proto/EzRpc_client.cc +52 -0
  15. data/ext/capn_proto/EzRpc_client.h +21 -0
  16. data/ext/capn_proto/EzRpc_server.cc +79 -0
  17. data/ext/capn_proto/EzRpc_server.h +32 -0
  18. data/ext/capn_proto/call_context.cc +67 -0
  19. data/ext/capn_proto/call_context.h +25 -0
  20. data/ext/capn_proto/capability_client.cc +47 -0
  21. data/ext/capn_proto/capability_client.h +21 -0
  22. data/ext/capn_proto/class_builder.cc +80 -0
  23. data/ext/capn_proto/class_builder.h +72 -0
  24. data/ext/capn_proto/cxx_compiler.rb +126 -0
  25. data/ext/capn_proto/dynamic_capability_client.cc +73 -0
  26. data/ext/capn_proto/dynamic_capability_client.h +22 -0
  27. data/ext/capn_proto/dynamic_list_builder.cc +123 -0
  28. data/ext/capn_proto/dynamic_list_builder.h +27 -0
  29. data/ext/capn_proto/dynamic_list_reader.cc +63 -0
  30. data/ext/capn_proto/dynamic_list_reader.h +25 -0
  31. data/ext/capn_proto/dynamic_object_builder.cc +57 -0
  32. data/ext/capn_proto/dynamic_object_builder.h +22 -0
  33. data/ext/capn_proto/dynamic_object_reader.cc +56 -0
  34. data/ext/capn_proto/dynamic_object_reader.h +22 -0
  35. data/ext/capn_proto/dynamic_struct_builder.cc +180 -0
  36. data/ext/capn_proto/dynamic_struct_builder.h +34 -0
  37. data/ext/capn_proto/dynamic_struct_reader.cc +69 -0
  38. data/ext/capn_proto/dynamic_struct_reader.h +25 -0
  39. data/ext/capn_proto/dynamic_value_builder.cc +53 -0
  40. data/ext/capn_proto/dynamic_value_builder.h +13 -0
  41. data/ext/capn_proto/dynamic_value_reader.cc +55 -0
  42. data/ext/capn_proto/dynamic_value_reader.h +13 -0
  43. data/ext/capn_proto/exception.cc +34 -0
  44. data/ext/capn_proto/exception.h +20 -0
  45. data/ext/capn_proto/extconf.rb +32 -0
  46. data/ext/capn_proto/field_list.cc +51 -0
  47. data/ext/capn_proto/field_list.h +23 -0
  48. data/ext/capn_proto/flat_array_message_reader.cc +61 -0
  49. data/ext/capn_proto/flat_array_message_reader.h +21 -0
  50. data/ext/capn_proto/init.cc +71 -0
  51. data/ext/capn_proto/interface_method.cc +38 -0
  52. data/ext/capn_proto/interface_method.h +21 -0
  53. data/ext/capn_proto/interface_schema.cc +51 -0
  54. data/ext/capn_proto/interface_schema.h +26 -0
  55. data/ext/capn_proto/list_nested_node_reader.cc +53 -0
  56. data/ext/capn_proto/list_nested_node_reader.h +24 -0
  57. data/ext/capn_proto/malloc_message_builder.cc +51 -0
  58. data/ext/capn_proto/malloc_message_builder.h +21 -0
  59. data/ext/capn_proto/message_builder.cc +22 -0
  60. data/ext/capn_proto/message_builder.h +17 -0
  61. data/ext/capn_proto/message_reader.cc +30 -0
  62. data/ext/capn_proto/message_reader.h +17 -0
  63. data/ext/capn_proto/nested_node_reader.cc +42 -0
  64. data/ext/capn_proto/nested_node_reader.h +21 -0
  65. data/ext/capn_proto/parsed_schema.cc +65 -0
  66. data/ext/capn_proto/parsed_schema.h +24 -0
  67. data/ext/capn_proto/rb.cc +0 -0
  68. data/ext/capn_proto/rb.h +0 -0
  69. data/ext/capn_proto/remote_promise.cc +116 -0
  70. data/ext/capn_proto/remote_promise.h +30 -0
  71. data/ext/capn_proto/ruby_capability_server.cc +23 -0
  72. data/ext/capn_proto/ruby_capability_server.h +21 -0
  73. data/ext/capn_proto/ruby_capn_proto.cc +4 -0
  74. data/ext/capn_proto/ruby_capn_proto.h +42 -0
  75. data/ext/capn_proto/schema_node_reader.cc +59 -0
  76. data/ext/capn_proto/schema_node_reader.h +23 -0
  77. data/ext/capn_proto/schema_parser.cc +61 -0
  78. data/ext/capn_proto/schema_parser.h +20 -0
  79. data/ext/capn_proto/stream_fd_message_reader.cc +59 -0
  80. data/ext/capn_proto/stream_fd_message_reader.h +21 -0
  81. data/ext/capn_proto/struct_schema.cc +59 -0
  82. data/ext/capn_proto/struct_schema.h +23 -0
  83. data/ext/capn_proto/util.cc +30 -0
  84. data/ext/capn_proto/util.h +17 -0
  85. data/lib/capn_proto.rb +231 -0
  86. data/lib/capn_proto/version.rb +3 -0
  87. data/media/captain_proto.png +0 -0
  88. data/media/captain_proto_small.png +0 -0
  89. data/spec/addressbook.bin +0 -0
  90. data/spec/addressbook.capnp +31 -0
  91. data/spec/capn_proto_spec.rb +80 -0
  92. data/spec/create_test_data.py +38 -0
  93. data/spec/spec_helper.rb +8 -0
  94. data/tests/hidraCordatus.capnp +16 -0
  95. data/tests/hidraCordatusEmployer.rb +33 -0
  96. data/tests/hidraCordatusMaster.rb +51 -0
  97. metadata +216 -0
@@ -0,0 +1,27 @@
1
+ #ifndef DYNAMIC_LIST_BUILDER_H
2
+ #define DYNAMIC_LIST_BUILDER_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class DynamicListBuilder {
8
+ public:
9
+ using WrappedType = capnp::DynamicList::Builder;
10
+ static void Init();
11
+ static VALUE alloc(VALUE klass);
12
+ static VALUE create(WrappedType reader, VALUE parent);
13
+ static void free(WrappedType* p);
14
+ static WrappedType* unwrap(VALUE self);
15
+ static VALUE which(VALUE self);
16
+ static VALUE get(VALUE self, VALUE index);
17
+ static VALUE set(VALUE self, VALUE index, VALUE rb_obj);
18
+ static VALUE size(VALUE self);
19
+
20
+ static VALUE Class;
21
+ private:
22
+ static VALUE _get(VALUE self, VALUE index);
23
+ static VALUE _set(VALUE self, VALUE index, VALUE rb_obj);
24
+ };
25
+ }
26
+
27
+ #endif /* DYNAMIC_LIST_BUILDER_H */
@@ -0,0 +1,63 @@
1
+ #include "ruby_capn_proto.h"
2
+ #include "dynamic_list_reader.h"
3
+ #include "dynamic_value_reader.h"
4
+ #include "exception.h"
5
+ #include "class_builder.h"
6
+
7
+ namespace ruby_capn_proto {
8
+ using WrappedType = capnp::DynamicList::Reader;
9
+ VALUE DynamicListReader::Class;
10
+
11
+ void DynamicListReader::Init() {
12
+ ClassBuilder("DynamicListReader", rb_cObject).
13
+ defineAlloc(&alloc).
14
+ defineMethod("[]", &get).
15
+ defineMethod("size", &size).
16
+ store(&Class);
17
+ }
18
+
19
+ VALUE DynamicListReader::alloc(VALUE klass) {
20
+ return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
21
+ }
22
+
23
+ void DynamicListReader::free(WrappedType* p) {
24
+ p->~Reader();
25
+ ruby_xfree(p);
26
+ }
27
+
28
+ WrappedType* DynamicListReader::unwrap(VALUE self) {
29
+ WrappedType* p;
30
+ Data_Get_Struct(self, WrappedType, p);
31
+ return p;
32
+ }
33
+
34
+ VALUE DynamicListReader::create(WrappedType reader, VALUE parent) {
35
+ auto rb_obj = alloc(Class);
36
+ WrappedType* wrapped = unwrap(rb_obj);
37
+ *wrapped = kj::mv(reader);
38
+
39
+ rb_iv_set(rb_obj, "parent", parent);
40
+
41
+ return rb_obj;
42
+ }
43
+
44
+ VALUE DynamicListReader::size(VALUE self) {
45
+ return INT2FIX(unwrap(self)->size());
46
+ }
47
+
48
+ VALUE DynamicListReader::get(VALUE self, VALUE rb_index) {
49
+ try {
50
+ return _get(self, rb_index);
51
+ } catch (kj::Exception ex) {
52
+ return Exception::raise(ex);
53
+ }
54
+ }
55
+
56
+ VALUE DynamicListReader::_get(VALUE self, VALUE rb_index) {
57
+ auto reader = *unwrap(self);
58
+ auto index = FIX2INT(rb_index);
59
+ auto size = reader.size();
60
+
61
+ return DynamicValueReader::to_ruby(reader[index], self);
62
+ }
63
+ }
@@ -0,0 +1,25 @@
1
+ #ifndef DYNAMIC_LIST_READER_H
2
+ #define DYNAMIC_LIST_READER_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class DynamicListReader {
8
+ public:
9
+ using WrappedType = capnp::DynamicList::Reader;
10
+ static void Init();
11
+ static VALUE alloc(VALUE klass);
12
+ static VALUE create(WrappedType reader, VALUE parent);
13
+ static void free(WrappedType* p);
14
+ static WrappedType* unwrap(VALUE self);
15
+ static VALUE which(VALUE self);
16
+ static VALUE get(VALUE self, VALUE index);
17
+ static VALUE size(VALUE self);
18
+
19
+ static VALUE Class;
20
+ private:
21
+ static VALUE _get(VALUE self, VALUE index);
22
+ };
23
+ }
24
+
25
+ #endif /* DYNAMIC_LIST_READER_H */
@@ -0,0 +1,57 @@
1
+ #include "ruby_capn_proto.h"
2
+ #include "dynamic_object_builder.h"
3
+ #include "dynamic_struct_builder.h"
4
+ #include "struct_schema.h"
5
+ #include "class_builder.h"
6
+ #include "util.h"
7
+
8
+ namespace ruby_capn_proto {
9
+ using WrappedType = capnp::AnyPointer::Builder;
10
+ VALUE DynamicObjectBuilder::Class;
11
+
12
+ void DynamicObjectBuilder::Init() {
13
+ ClassBuilder("DynamicObjectBuilder", rb_cObject).
14
+ defineAlloc(&alloc).
15
+ defineMethod("as_struct", &as_struct).
16
+ store(&Class);
17
+ }
18
+
19
+ void DynamicObjectBuilder::free(WrappedType* p) {
20
+ p->~Builder();
21
+ ruby_xfree(p);
22
+ }
23
+
24
+ VALUE DynamicObjectBuilder::alloc(VALUE klass) {
25
+ return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
26
+ }
27
+
28
+ WrappedType* DynamicObjectBuilder::unwrap(VALUE self) {
29
+ WrappedType* p;
30
+ Data_Get_Struct(self, WrappedType, p);
31
+ return p;
32
+ }
33
+
34
+ VALUE DynamicObjectBuilder::create(WrappedType reader, VALUE parent) {
35
+ VALUE rb_obj = alloc(Class);
36
+ WrappedType* wrapped = unwrap(rb_obj);
37
+ *wrapped = kj::mv(reader);
38
+
39
+ rb_iv_set(rb_obj, "parent", parent);
40
+
41
+ return rb_obj;
42
+ }
43
+
44
+ VALUE DynamicObjectBuilder::as_struct(VALUE self, VALUE rb_schema) {
45
+ if (rb_respond_to(rb_schema, rb_intern("schema"))) {
46
+ rb_schema = rb_funcall(rb_schema, rb_intern("schema"), 0);
47
+ }
48
+
49
+ auto reader = *unwrap(self);
50
+ auto schema = *StructSchema::unwrap(rb_schema);
51
+
52
+ return DynamicStructBuilder::create(
53
+ reader.getAs<capnp::DynamicStruct>(schema),
54
+ self,
55
+ false);
56
+ }
57
+ }
@@ -0,0 +1,22 @@
1
+ #ifndef DYNAMIC_OBJECT_BUILDER_H
2
+ #define DYNAMIC_OBJECT_BUILDER_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class DynamicObjectBuilder {
8
+ public:
9
+ using WrappedType = capnp::AnyPointer::Builder;
10
+ static void Init();
11
+ static VALUE alloc(VALUE klass);
12
+ static VALUE create(WrappedType reader, VALUE parent);
13
+ static void free(WrappedType* p);
14
+ static WrappedType* unwrap(VALUE self);
15
+ static VALUE as_struct(VALUE self, VALUE name);
16
+
17
+ static VALUE Class;
18
+ };
19
+ }
20
+
21
+
22
+ #endif
@@ -0,0 +1,56 @@
1
+ #include "ruby_capn_proto.h"
2
+ #include "dynamic_object_reader.h"
3
+ #include "dynamic_struct_reader.h"
4
+ #include "struct_schema.h"
5
+ #include "class_builder.h"
6
+ #include "util.h"
7
+
8
+ namespace ruby_capn_proto {
9
+ using WrappedType = capnp::AnyPointer::Reader;
10
+ VALUE DynamicObjectReader::Class;
11
+
12
+ void DynamicObjectReader::Init() {
13
+ ClassBuilder("DynamicObjectReader", rb_cObject).
14
+ defineAlloc(&alloc).
15
+ defineMethod("as_struct", &as_struct).
16
+ store(&Class);
17
+ }
18
+
19
+ void DynamicObjectReader::free(WrappedType* p) {
20
+ p->~Reader();
21
+ ruby_xfree(p);
22
+ }
23
+
24
+ VALUE DynamicObjectReader::alloc(VALUE klass) {
25
+ return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
26
+ }
27
+
28
+ WrappedType* DynamicObjectReader::unwrap(VALUE self) {
29
+ WrappedType* p;
30
+ Data_Get_Struct(self, WrappedType, p);
31
+ return p;
32
+ }
33
+
34
+ VALUE DynamicObjectReader::create(WrappedType reader, VALUE parent) {
35
+ VALUE rb_obj = alloc(Class);
36
+ WrappedType* wrapped = unwrap(rb_obj);
37
+ *wrapped = kj::mv(reader);
38
+
39
+ rb_iv_set(rb_obj, "parent", parent);
40
+
41
+ return rb_obj;
42
+ }
43
+
44
+ VALUE DynamicObjectReader::as_struct(VALUE self, VALUE rb_schema) {
45
+ if (rb_respond_to(rb_schema, rb_intern("schema"))) {
46
+ rb_schema = rb_funcall(rb_schema, rb_intern("schema"), 0);
47
+ }
48
+
49
+ auto reader = *unwrap(self);
50
+ auto schema = *StructSchema::unwrap(rb_schema);
51
+
52
+ return DynamicStructReader::create(
53
+ reader.getAs<capnp::DynamicStruct>(schema),
54
+ self);
55
+ }
56
+ }
@@ -0,0 +1,22 @@
1
+ #ifndef DYNAMIC_OBJECT_READER_H
2
+ #define DYNAMIC_OBJECT_READER_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class DynamicObjectReader {
8
+ public:
9
+ using WrappedType = capnp::AnyPointer::Reader;
10
+ static void Init();
11
+ static VALUE alloc(VALUE klass);
12
+ static VALUE create(WrappedType reader, VALUE parent);
13
+ static void free(WrappedType* p);
14
+ static WrappedType* unwrap(VALUE self);
15
+ static VALUE as_struct(VALUE self, VALUE name);
16
+
17
+ static VALUE Class;
18
+ };
19
+ }
20
+
21
+
22
+ #endif
@@ -0,0 +1,180 @@
1
+ #include "ruby_capn_proto.h"
2
+ #include "dynamic_struct_builder.h"
3
+ #include "dynamic_struct_reader.h"
4
+ #include "dynamic_value_reader.h"
5
+ #include "dynamic_value_builder.h"
6
+ #include "message_builder.h"
7
+ #include "malloc_message_builder.h"
8
+ #include "interface_schema.h"
9
+ #include "ruby_capability_server.h"
10
+ #include "dynamic_capability_client.h"
11
+ #include "class_builder.h"
12
+ #include "exception.h"
13
+ #include "util.h"
14
+
15
+ namespace ruby_capn_proto {
16
+ using WrappedType = capnp::DynamicStruct::Builder;
17
+ VALUE DynamicStructBuilder::Class;
18
+
19
+ void DynamicStructBuilder::Init() {
20
+ ClassBuilder("DynamicStructBuilder", rb_cObject).
21
+ defineAlloc(&alloc).
22
+ defineMethod("which", &which).
23
+ defineMethod("write", &write).
24
+ defineMethod("to_bytes", &to_bytes).
25
+ defineMethod("[]", &get).
26
+ defineMethod("[]=", &set).
27
+ defineMethod("init", (VALUE (*)(int, VALUE*, VALUE))&init).
28
+ store(&Class);
29
+ }
30
+
31
+ void DynamicStructBuilder::free(WrappedType* p) {
32
+ p->~Builder();
33
+ ruby_xfree(p);
34
+ }
35
+
36
+ VALUE DynamicStructBuilder::alloc(VALUE klass) {
37
+ return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
38
+ }
39
+
40
+ WrappedType* DynamicStructBuilder::unwrap(VALUE self) {
41
+ WrappedType* p;
42
+ Data_Get_Struct(self, WrappedType, p);
43
+ return p;
44
+ }
45
+
46
+ VALUE DynamicStructBuilder::create(WrappedType reader, VALUE parent, bool is_root) {
47
+ VALUE rb_obj = alloc(Class);
48
+ WrappedType* wrapped = unwrap(rb_obj);
49
+ *wrapped = kj::mv(reader);
50
+
51
+ rb_iv_set(rb_obj, "parent", parent);
52
+ rb_iv_set(rb_obj, "is_root", is_root ? Qtrue : Qfalse);
53
+
54
+ return rb_obj;
55
+ }
56
+
57
+ VALUE DynamicStructBuilder::init(int argc, VALUE* argv, VALUE self) {
58
+ VALUE name;
59
+ VALUE count;
60
+
61
+ rb_scan_args(argc, argv, "11", &name, &count);
62
+
63
+ try {
64
+ return _init(self, name, count, argc);
65
+ } catch (kj::Exception ex) {
66
+ return Exception::raise(ex);
67
+ }
68
+ }
69
+
70
+ VALUE DynamicStructBuilder::_init(VALUE self, VALUE rb_name, VALUE rb_count, int argc) {
71
+ auto name = Util::toString(rb_name);
72
+
73
+ if (argc == 1) {
74
+ return DynamicValueBuilder::to_ruby(unwrap(self)->init(name), self);
75
+ } else {
76
+ auto count = NUM2ULONG(rb_count);
77
+ return DynamicValueBuilder::to_ruby(unwrap(self)->init(name, count), self);
78
+ }
79
+ }
80
+
81
+ VALUE DynamicStructBuilder::get(VALUE self, VALUE rb_name) {
82
+ try {
83
+ return _get(self, rb_name);
84
+ } catch (kj::Exception ex) {
85
+ return Exception::raise(ex);
86
+ }
87
+ }
88
+
89
+ VALUE DynamicStructBuilder::_get(VALUE self, VALUE rb_name) {
90
+ auto builder = *unwrap(self);
91
+ auto name = Util::toString(rb_name);
92
+ return DynamicValueBuilder::to_ruby(builder.get(name), self);
93
+ }
94
+
95
+ VALUE DynamicStructBuilder::set(VALUE self, VALUE rb_name, VALUE rb_obj) {
96
+ try {
97
+ return _set(self, rb_name, rb_obj);
98
+ } catch (kj::Exception ex) {
99
+ return Exception::raise(ex);
100
+ }
101
+ }
102
+
103
+ VALUE DynamicStructBuilder::_set(VALUE self, VALUE rb_field, VALUE rb_obj) {
104
+ VALUE klass = rb_funcall(rb_obj, rb_intern("class"), 0);
105
+ auto field = Util::toString(rb_field);
106
+
107
+ // TODO: handle assigning lists (see _setDynamicField)
108
+ if FIXNUM_P(rb_obj) {
109
+ if (Util::isNegative(rb_obj)) {
110
+ unwrap(self)->set(field, NUM2LONG(rb_obj));
111
+ } else {
112
+ unwrap(self)->set(field, NUM2ULONG(rb_obj));
113
+ }
114
+ } else if (RB_TYPE_P(rb_obj, T_FLOAT)) {
115
+ unwrap(self)->set(field, RFLOAT_VALUE(rb_obj));
116
+ } else if (rb_obj == Qtrue || rb_obj == Qfalse) {
117
+ unwrap(self)->set(field, (rb_obj == Qtrue) ? true : false);
118
+ } else if (RB_TYPE_P(rb_obj, T_STRING)) {
119
+ // TODO: need to ensure that the UTF8 char buffer is null terminated.
120
+ // consider something similar to rb_string_value_cstr,
121
+ // which grows the the buffer if necessary.
122
+ capnp::DynamicValue::Reader tmp =
123
+ capnp::Text::Reader(RSTRING_PTR(rb_obj), RSTRING_LEN(rb_obj));
124
+ unwrap(self)->set(field, tmp);
125
+ } else if (NIL_P(rb_obj)) {
126
+ unwrap(self)->set(field, capnp::VOID);
127
+ } else if (rb_equal(klass, DynamicStructReader::Class)) {
128
+ unwrap(self)->set(field, *DynamicStructReader::unwrap(rb_obj));
129
+ } else if (rb_equal(klass, DynamicStructBuilder::Class)) {
130
+ unwrap(self)->set(field, (*DynamicStructBuilder::unwrap(rb_obj)).asReader());
131
+ }else if (Qnil != rb_iv_get(rb_obj,"@schema")){
132
+ VALUE interschema = rb_iv_get(rb_obj,"@schema");
133
+ auto c_schema = InterfaceSchema::unwrap(interschema);
134
+ unwrap(self)->set(field, kj::heap<capnp::RubyCapabilityServer>(*c_schema, rb_obj));
135
+ }else if (rb_equal(klass, DynamicCapabilityClient::Class)){
136
+ unwrap(self)->set(field, *DynamicCapabilityClient::unwrap(rb_obj));
137
+ } else {
138
+ // TODO: raise "Non primitive type"
139
+ }
140
+
141
+ return rb_obj;
142
+ }
143
+
144
+ VALUE DynamicStructBuilder::write(VALUE self, VALUE file) {
145
+ VALUE rb_fileno = rb_funcall(file, rb_intern("fileno"), 0);
146
+ int fileno = FIX2INT(rb_fileno);
147
+ if (!RTEST(rb_iv_get(self, "is_root"))) {
148
+ rb_raise(Exception::Class, "You can only call write() on the message's root struct.");
149
+ }
150
+
151
+ capnp::MessageBuilder* message_builder = MallocMessageBuilder::unwrap(rb_iv_get(self, "parent"));
152
+ try {
153
+ capnp::writeMessageToFd(fileno, message_builder->getSegmentsForOutput());
154
+ return Qnil;
155
+ } catch (kj::Exception ex) {
156
+ return Exception::raise(ex);
157
+ }
158
+ }
159
+
160
+ VALUE DynamicStructBuilder::to_bytes(VALUE self) {
161
+ if (!RTEST(rb_iv_get(self, "is_root"))) {
162
+ rb_raise(Exception::Class, "You can only call to_bytes() on the message's root struct.");
163
+ }
164
+
165
+ capnp::MessageBuilder* message_builder = MallocMessageBuilder::unwrap(rb_iv_get(self, "parent"));
166
+ auto array = capnp::messageToFlatArray(*message_builder);
167
+ return rb_str_new((char*)array.begin(), sizeof(capnp::word) * array.size());
168
+ }
169
+
170
+ VALUE DynamicStructBuilder::which(VALUE self) {
171
+ auto schema_maybe = unwrap(self)->which();
172
+ KJ_IF_MAYBE(schema, schema_maybe) {
173
+ auto name = schema->getProto().getName();
174
+ return rb_str_new(name.begin(), name.size());
175
+ } else {
176
+ // throw std::invalid_argument("member was null");
177
+ return Qnil;
178
+ }
179
+ }
180
+ }