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,23 @@
1
+ #ifndef SCHEMA_NODE_READER_H
2
+ #define SCHEMA_NODE_READER_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class SchemaNodeReader {
8
+ public:
9
+ static void Init();
10
+ static VALUE alloc(VALUE klass);
11
+ static VALUE create(capnp::schema::Node::Reader reader, VALUE parent);
12
+ static void free(capnp::schema::Node::Reader* p);
13
+ static capnp::schema::Node::Reader* unwrap(VALUE self);
14
+ static VALUE get_nested_nodes(VALUE self);
15
+ static VALUE is_struct(VALUE self);
16
+ static VALUE is_enum(VALUE self);
17
+ static VALUE is_interface(VALUE self);
18
+
19
+ static VALUE Class;
20
+ };
21
+ }
22
+
23
+ #endif /* SCHEMA_NODE_READER_H */
@@ -0,0 +1,61 @@
1
+ #include "ruby_capn_proto.h"
2
+ #include "schema_parser.h"
3
+ #include "parsed_schema.h"
4
+ #include "exception.h"
5
+ #include "class_builder.h"
6
+ #include "util.h"
7
+
8
+ namespace ruby_capn_proto {
9
+ VALUE SchemaParser::Class;
10
+ using WrappedType = capnp::SchemaParser;
11
+
12
+ void SchemaParser::Init() {
13
+ ClassBuilder("SchemaParser", rb_cObject).
14
+ defineAlloc(&alloc).
15
+ defineMethod("initialize", &initialize).
16
+ defineMethod("parse_disk_file", &parse_disk_file).
17
+ store(&Class);
18
+ }
19
+
20
+ void SchemaParser::free(SchemaParser* p) {
21
+ p->~SchemaParser();
22
+ ruby_xfree(p);
23
+ }
24
+
25
+ VALUE SchemaParser::alloc(VALUE klass) {
26
+ return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
27
+ }
28
+
29
+ WrappedType* SchemaParser::unwrap(VALUE self) {
30
+ WrappedType* p;
31
+ Data_Get_Struct(self, WrappedType, p);
32
+ return p;
33
+ }
34
+
35
+ VALUE SchemaParser::initialize(VALUE self) {
36
+ WrappedType* p = unwrap(self);
37
+ new (p) WrappedType();
38
+
39
+ return Qnil;
40
+ }
41
+
42
+ VALUE SchemaParser::parse_disk_file(VALUE self, VALUE rb_display_name, VALUE rb_disk_path, VALUE rb_import_path) {
43
+ try {
44
+
45
+ auto imports = Util::toStringArray(rb_import_path);
46
+ auto importsPtrs = KJ_MAP(s, imports) -> kj::StringPtr { return s; };
47
+
48
+ auto display_name = Util::toString(rb_display_name);
49
+ auto schema = unwrap(self)->parseDiskFile(
50
+ display_name,
51
+ StringValueCStr(rb_disk_path),
52
+ importsPtrs
53
+ );
54
+ return ParsedSchema::create(schema, self);
55
+
56
+ }catch ( kj::Exception t ){
57
+ Exception::raise(t);
58
+ return Qnil;
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,20 @@
1
+ #ifndef SCHEMA_PARSER_H
2
+ #define SCHEMA_PARSER_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class SchemaParser {
8
+ public:
9
+ static void Init();
10
+ static VALUE parse_disk_file(VALUE self, VALUE display_name, VALUE disk_path, VALUE import_path);
11
+ static VALUE initialize(VALUE klass);
12
+ static VALUE alloc(VALUE klass);
13
+ static void free(SchemaParser* p);
14
+ static capnp::SchemaParser* unwrap(VALUE self);
15
+
16
+ static VALUE Class;
17
+ };
18
+ }
19
+
20
+ #endif /* SCHEMA_PARSER_H */
@@ -0,0 +1,59 @@
1
+ #include "ruby_capn_proto.h"
2
+ #include "message_reader.h"
3
+ #include "stream_fd_message_reader.h"
4
+ #include "struct_schema.h"
5
+ #include "dynamic_struct_reader.h"
6
+ #include "class_builder.h"
7
+ #include "exception.h"
8
+
9
+ namespace ruby_capn_proto {
10
+ using WrappedType = capnp::StreamFdMessageReader;
11
+ VALUE StreamFdMessageReader::Class;
12
+
13
+ void StreamFdMessageReader::Init() {
14
+ ClassBuilder("StreamFdMessageReader", MessageReader::Class).
15
+ defineAlloc(&alloc).
16
+ defineMethod("initialize", &initialize).
17
+ defineMethod("get_root", &get_root).
18
+ store(&Class);
19
+ }
20
+
21
+ VALUE StreamFdMessageReader::alloc(VALUE klass) {
22
+ return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
23
+ }
24
+
25
+ VALUE StreamFdMessageReader::initialize(VALUE self, VALUE rb_io) {
26
+ VALUE rb_fileno = rb_funcall(rb_io, rb_intern("fileno"), 0);
27
+ auto fileno = FIX2INT(rb_fileno);
28
+ WrappedType* p = unwrap(self);
29
+
30
+ try {
31
+ new (p) WrappedType(fileno);
32
+ } catch (kj::Exception ex) {
33
+ return Exception::raise(ex);
34
+ }
35
+
36
+ return Qnil;
37
+ }
38
+
39
+ void StreamFdMessageReader::free(WrappedType* p) {
40
+ p->~StreamFdMessageReader();
41
+ ruby_xfree(p);
42
+ }
43
+
44
+ WrappedType* StreamFdMessageReader::unwrap(VALUE self) {
45
+ WrappedType* p;
46
+ Data_Get_Struct(self, WrappedType, p);
47
+ return p;
48
+ }
49
+
50
+ VALUE StreamFdMessageReader::get_root(VALUE self, VALUE rb_schema) {
51
+ if (rb_respond_to(rb_schema, rb_intern("schema"))) {
52
+ rb_schema = rb_funcall(rb_schema, rb_intern("schema"), 0);
53
+ }
54
+
55
+ auto schema = *StructSchema::unwrap(rb_schema);
56
+ auto reader = unwrap(self)->getRoot<capnp::DynamicStruct>(schema);
57
+ return DynamicStructReader::create(reader, self);
58
+ }
59
+ }
@@ -0,0 +1,21 @@
1
+ #ifndef STREAM_FD_MESSAGE_READER_H
2
+ #define STREAM_FD_MESSAGE_READER_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class StreamFdMessageReader {
8
+ public:
9
+ using WrappedType = capnp::StreamFdMessageReader;
10
+ static void Init();
11
+ static VALUE alloc(VALUE klass);
12
+ static VALUE initialize(VALUE klass, VALUE io);
13
+ static void free(WrappedType* p);
14
+ static WrappedType* unwrap(VALUE self);
15
+ static VALUE get_root(VALUE self, VALUE schema);
16
+
17
+ static VALUE Class;
18
+ };
19
+ }
20
+
21
+ #endif /* STREAM_FD_MESSAGE_READER_H */
@@ -0,0 +1,59 @@
1
+ #include "ruby_capn_proto.h"
2
+ #include "struct_schema.h"
3
+ #include "field_list.h"
4
+ #include "class_builder.h"
5
+ #include "util.h"
6
+
7
+ namespace ruby_capn_proto {
8
+ using WrappedType = capnp::StructSchema;
9
+ VALUE StructSchema::Class;
10
+
11
+ void StructSchema::Init() {
12
+ ClassBuilder("StructSchema", rb_cObject).
13
+ defineAlloc(&alloc).
14
+ defineMethod("field_names", &field_names).
15
+ defineMethod("fields", &fields).
16
+ store(&Class);
17
+ }
18
+
19
+ void StructSchema::free(WrappedType* p) {
20
+ p->~StructSchema();
21
+ ruby_xfree(p);
22
+ }
23
+
24
+ VALUE StructSchema::alloc(VALUE klass) {
25
+ return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
26
+ }
27
+
28
+ WrappedType* StructSchema::unwrap(VALUE self) {
29
+ WrappedType* p;
30
+ Data_Get_Struct(self, WrappedType, p);
31
+ return p;
32
+ }
33
+
34
+ VALUE StructSchema::create(WrappedType schema, VALUE parent) {
35
+ VALUE rb_obj = alloc(Class);
36
+ WrappedType* wrapped_schema = unwrap(rb_obj);
37
+ *wrapped_schema = kj::mv(schema);
38
+
39
+ rb_iv_set(rb_obj, "parent", parent);
40
+
41
+ return rb_obj;
42
+ }
43
+
44
+ VALUE StructSchema::field_names(VALUE self) {
45
+ auto field_list = unwrap(self)->getFields();
46
+ auto size = field_list.size();
47
+ auto rb_array = rb_ary_new2(size);
48
+ for (int i=0; i<size; i++) {
49
+ auto name = field_list[i].getProto().getName();
50
+ rb_ary_push(rb_array, rb_str_new(name.begin(), name.size()));
51
+ }
52
+
53
+ return rb_array;
54
+ }
55
+
56
+ VALUE StructSchema::fields(VALUE self) {
57
+ return FieldList::create(unwrap(self)->getFields());
58
+ }
59
+ }
@@ -0,0 +1,23 @@
1
+ #ifndef STRUCT_SCHEMA_H
2
+ #define STRUCT_SCHEMA_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class StructSchema {
8
+ public:
9
+ using WrappedType = capnp::StructSchema;
10
+ static void Init();
11
+ static VALUE alloc(VALUE klass);
12
+ static VALUE create(WrappedType schema, VALUE parent);
13
+ static void free(WrappedType* p);
14
+ static WrappedType* unwrap(VALUE self);
15
+ static VALUE field_names(VALUE self);
16
+ static VALUE fields(VALUE self);
17
+
18
+ static VALUE Class;
19
+ };
20
+ }
21
+
22
+
23
+ #endif /* STRUCT_SCHEMA_H */
@@ -0,0 +1,30 @@
1
+ #include "util.h"
2
+
3
+ namespace ruby_capn_proto {
4
+ kj::Array<kj::String> Util::toStringArray(VALUE rb_array) {
5
+ auto len = RARRAY_LEN(rb_array);
6
+ auto array = kj::heapArray<kj::String>(len);
7
+ for (int i=0; i < len; i++) {
8
+ auto rb_str = rb_ary_entry(rb_array, i);
9
+ array[i] = toString(rb_str);
10
+ }
11
+
12
+ return array;
13
+ }
14
+
15
+ kj::String Util::toString(VALUE rb_string) {
16
+ auto rb_val = StringValue(rb_string);
17
+ auto str = RSTRING_PTR(rb_val);
18
+ auto len = RSTRING_LEN(rb_val);
19
+ return kj::heapString(str, len);
20
+ }
21
+
22
+ VALUE Util::toRubyString(kj::StringPtr string) {
23
+ return rb_str_new(string.begin(), string.size());
24
+ }
25
+
26
+ bool Util::isNegative(VALUE rb_obj) {
27
+ if (FIXNUM_P(rb_obj)) return FIX2LONG(rb_obj) < 0;
28
+ return RTEST(rb_funcall(rb_obj, '<', 1, INT2FIX(0)));
29
+ }
30
+ }
@@ -0,0 +1,17 @@
1
+ #ifndef UTIL_H
2
+ #define UTIL_H
3
+
4
+ #include "ruby_capn_proto.h"
5
+
6
+ namespace ruby_capn_proto {
7
+ class Util {
8
+ public:
9
+ static kj::Array<kj::String> toStringArray(VALUE array_of_strings);
10
+ static kj::String toString(VALUE string);
11
+ static bool isNegative(VALUE rb_obj);
12
+
13
+ static VALUE toRubyString(kj::StringPtr string);
14
+ };
15
+ }
16
+
17
+ #endif /* UTIL_H */
@@ -0,0 +1,231 @@
1
+ require 'capn_proto/capn_proto'
2
+ require 'capn_proto/version'
3
+
4
+ module CapnProto
5
+ ListNestedNodeReader.class_eval do
6
+ include Enumerable
7
+ def each
8
+ return to_enum(:each) unless block_given?
9
+ (0...size).each do |n|
10
+ yield self[n]
11
+ end
12
+ end
13
+ end
14
+
15
+ DynamicListReader.class_eval do
16
+ include Enumerable
17
+ def each
18
+ return to_enum(:each) unless block_given?
19
+ (0...size).each do |n|
20
+ yield self[n]
21
+ end
22
+ end
23
+ end
24
+
25
+ DynamicListBuilder.class_eval do
26
+ include Enumerable
27
+ def each
28
+ return to_enum(:each) unless block_given?
29
+ (0...size).each do |n|
30
+ yield self[n]
31
+ end
32
+ end
33
+ end
34
+
35
+ DynamicStructReader.class_eval do
36
+ def method_missing(name, *args, &block)
37
+ name = name.to_s
38
+
39
+ if name.end_with?("?")
40
+ which == name[0..-2]
41
+ else
42
+ self[name]
43
+ end
44
+ end
45
+ end
46
+
47
+ DynamicStructBuilder.class_eval do
48
+ def method_missing(name, *args, &block)
49
+ name = name.to_s
50
+
51
+ if name.start_with?("init") && name.size > 4
52
+ name = name[4..-1]
53
+ name[0] = name[0].downcase
54
+ init(name, *args)
55
+ elsif name.end_with?("=")
56
+ name = name[0..-2]
57
+ self[name] = args[0]
58
+ elsif name.end_with?("?")
59
+ which == name[0..-2]
60
+ else
61
+ self[name]
62
+ end
63
+ end
64
+ end
65
+
66
+ module SchemaLoader
67
+ def schema_parser
68
+ @schema_parser
69
+ end
70
+
71
+ def load_schema(file_name, imports=[])
72
+ display_name = self.name
73
+
74
+ @schema_parser ||= CapnProto::SchemaParser.new
75
+
76
+ load_schema_rec = Proc.new do |schema, mod|
77
+ node = schema.get_proto
78
+ nested_nodes = node.nested_nodes
79
+
80
+ if node.struct?
81
+ struct_schema = schema.as_struct
82
+ mod.instance_variable_set(:@schema, struct_schema)
83
+ mod.extend(Struct)
84
+ end
85
+
86
+ if node.interface?
87
+ interface_schema = schema.as_interface
88
+ mod.instance_variable_set(:@schema, interface_schema)
89
+ mod.extend(Interface)
90
+ end
91
+
92
+ nested_nodes.each do |nested_node|
93
+ const_name = nested_node.name
94
+ const_name[0] = const_name[0].upcase
95
+ nested_mod = mod.const_set(const_name, Module.new)
96
+ nested_schema = schema.get_nested(nested_node.name)
97
+ load_schema_rec.call(nested_schema, nested_mod)
98
+ end
99
+ end
100
+
101
+ schema = @schema_parser.parse_disk_file(
102
+ display_name,
103
+ file_name,
104
+ imports);
105
+
106
+ load_schema_rec.call(schema, self)
107
+ end
108
+
109
+ module Struct
110
+ def schema
111
+ @schema
112
+ end
113
+
114
+ def read_from(io)
115
+ reader = StreamFdMessageReader.new(io)
116
+ reader.get_root(self)
117
+ end
118
+
119
+ def make_from_bytes(bytes)
120
+ # TODO: support FFI pointers
121
+ reader = FlatArrayMessageReader.new(bytes)
122
+ reader.get_root(self)
123
+ end
124
+
125
+ def new_message
126
+ builder = MallocMessageBuilder.new
127
+ builder.init_root(self)
128
+ end
129
+
130
+ def read_packed_from(io)
131
+ raise 'not implemented'
132
+ end
133
+ end
134
+
135
+ module Interface
136
+ attr_reader :schema
137
+
138
+ def method?(name)
139
+ @schema.find_method_by_name name
140
+ end
141
+
142
+ def method!(name) #short and ruby friendlier alias for find_method_by_name
143
+ temp = @schema.find_method_by_name name
144
+ if temp
145
+ return temp
146
+ else
147
+ raise "Method #{name} not found in this interface"
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ class RequestBuilder
154
+ attr_reader :data
155
+
156
+ def initialize
157
+ @data = []
158
+ @currentArray = []
159
+ end
160
+
161
+ def method_missing(*args)
162
+ if args.length == 1
163
+ @currentArray << args.pop.to_s
164
+ return self # to chain methods like .expression.literal(3)
165
+ elsif args.length == 2
166
+ @currentArray << args.shift.to_s
167
+ @currentArray << args.shift
168
+ @data << @currentArray
169
+ @currentArray = []
170
+ else
171
+ super
172
+ end
173
+ end
174
+
175
+ def wait(waitscope)
176
+ @to_request.wait(waitscope)
177
+ end
178
+ end
179
+
180
+ class Request < RequestBuilder
181
+
182
+ def initialize( client, method )
183
+ @to_request = client
184
+ @method = method
185
+ super()
186
+ end
187
+
188
+ def send
189
+ PipelinedRequest.new(@to_request.request_and_send(@method,@data))
190
+ end
191
+
192
+ end
193
+
194
+ class PipelinedRequest < RequestBuilder
195
+ attr_accessor :method
196
+
197
+ def initialize( remotePromise )
198
+ @to_request = remotePromise
199
+ super()
200
+ end
201
+
202
+ def get(value)
203
+ @value = value
204
+ return self # to chain calls like get('value').readRequest
205
+ end
206
+
207
+ def send
208
+ if !@value || !@method
209
+ raise "call both get and set method before calling send"
210
+ end
211
+ @to_request.request_and_send(@value,@method,@data)
212
+ end
213
+ end
214
+
215
+ DynamicCapabilityClient.class_eval do
216
+
217
+ def request(method)
218
+ Request.new(self,method)
219
+ end
220
+
221
+ end
222
+
223
+ class CapabilityServer
224
+
225
+ def initialize(interface)
226
+ @schema = interface
227
+ end
228
+
229
+ end
230
+
231
+ end