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.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +19 -0
- data/Gemfile +2 -0
- data/LICENSE +19 -0
- data/README.md +249 -0
- data/Rakefile +44 -0
- data/capn_proto.gemspec +37 -0
- data/examples/addressbook.bin +0 -0
- data/examples/addressbook.capnp +31 -0
- data/examples/create_test_data.py +39 -0
- data/examples/example.rb +38 -0
- data/ext/capn_proto/.ycm_extra_conf.py +65 -0
- data/ext/capn_proto/EzRpc_client.cc +52 -0
- data/ext/capn_proto/EzRpc_client.h +21 -0
- data/ext/capn_proto/EzRpc_server.cc +79 -0
- data/ext/capn_proto/EzRpc_server.h +32 -0
- data/ext/capn_proto/call_context.cc +67 -0
- data/ext/capn_proto/call_context.h +25 -0
- data/ext/capn_proto/capability_client.cc +47 -0
- data/ext/capn_proto/capability_client.h +21 -0
- data/ext/capn_proto/class_builder.cc +80 -0
- data/ext/capn_proto/class_builder.h +72 -0
- data/ext/capn_proto/cxx_compiler.rb +126 -0
- data/ext/capn_proto/dynamic_capability_client.cc +73 -0
- data/ext/capn_proto/dynamic_capability_client.h +22 -0
- data/ext/capn_proto/dynamic_list_builder.cc +123 -0
- data/ext/capn_proto/dynamic_list_builder.h +27 -0
- data/ext/capn_proto/dynamic_list_reader.cc +63 -0
- data/ext/capn_proto/dynamic_list_reader.h +25 -0
- data/ext/capn_proto/dynamic_object_builder.cc +57 -0
- data/ext/capn_proto/dynamic_object_builder.h +22 -0
- data/ext/capn_proto/dynamic_object_reader.cc +56 -0
- data/ext/capn_proto/dynamic_object_reader.h +22 -0
- data/ext/capn_proto/dynamic_struct_builder.cc +180 -0
- data/ext/capn_proto/dynamic_struct_builder.h +34 -0
- data/ext/capn_proto/dynamic_struct_reader.cc +69 -0
- data/ext/capn_proto/dynamic_struct_reader.h +25 -0
- data/ext/capn_proto/dynamic_value_builder.cc +53 -0
- data/ext/capn_proto/dynamic_value_builder.h +13 -0
- data/ext/capn_proto/dynamic_value_reader.cc +55 -0
- data/ext/capn_proto/dynamic_value_reader.h +13 -0
- data/ext/capn_proto/exception.cc +34 -0
- data/ext/capn_proto/exception.h +20 -0
- data/ext/capn_proto/extconf.rb +32 -0
- data/ext/capn_proto/field_list.cc +51 -0
- data/ext/capn_proto/field_list.h +23 -0
- data/ext/capn_proto/flat_array_message_reader.cc +61 -0
- data/ext/capn_proto/flat_array_message_reader.h +21 -0
- data/ext/capn_proto/init.cc +71 -0
- data/ext/capn_proto/interface_method.cc +38 -0
- data/ext/capn_proto/interface_method.h +21 -0
- data/ext/capn_proto/interface_schema.cc +51 -0
- data/ext/capn_proto/interface_schema.h +26 -0
- data/ext/capn_proto/list_nested_node_reader.cc +53 -0
- data/ext/capn_proto/list_nested_node_reader.h +24 -0
- data/ext/capn_proto/malloc_message_builder.cc +51 -0
- data/ext/capn_proto/malloc_message_builder.h +21 -0
- data/ext/capn_proto/message_builder.cc +22 -0
- data/ext/capn_proto/message_builder.h +17 -0
- data/ext/capn_proto/message_reader.cc +30 -0
- data/ext/capn_proto/message_reader.h +17 -0
- data/ext/capn_proto/nested_node_reader.cc +42 -0
- data/ext/capn_proto/nested_node_reader.h +21 -0
- data/ext/capn_proto/parsed_schema.cc +65 -0
- data/ext/capn_proto/parsed_schema.h +24 -0
- data/ext/capn_proto/rb.cc +0 -0
- data/ext/capn_proto/rb.h +0 -0
- data/ext/capn_proto/remote_promise.cc +116 -0
- data/ext/capn_proto/remote_promise.h +30 -0
- data/ext/capn_proto/ruby_capability_server.cc +23 -0
- data/ext/capn_proto/ruby_capability_server.h +21 -0
- data/ext/capn_proto/ruby_capn_proto.cc +4 -0
- data/ext/capn_proto/ruby_capn_proto.h +42 -0
- data/ext/capn_proto/schema_node_reader.cc +59 -0
- data/ext/capn_proto/schema_node_reader.h +23 -0
- data/ext/capn_proto/schema_parser.cc +61 -0
- data/ext/capn_proto/schema_parser.h +20 -0
- data/ext/capn_proto/stream_fd_message_reader.cc +59 -0
- data/ext/capn_proto/stream_fd_message_reader.h +21 -0
- data/ext/capn_proto/struct_schema.cc +59 -0
- data/ext/capn_proto/struct_schema.h +23 -0
- data/ext/capn_proto/util.cc +30 -0
- data/ext/capn_proto/util.h +17 -0
- data/lib/capn_proto.rb +231 -0
- data/lib/capn_proto/version.rb +3 -0
- data/media/captain_proto.png +0 -0
- data/media/captain_proto_small.png +0 -0
- data/spec/addressbook.bin +0 -0
- data/spec/addressbook.capnp +31 -0
- data/spec/capn_proto_spec.rb +80 -0
- data/spec/create_test_data.py +38 -0
- data/spec/spec_helper.rb +8 -0
- data/tests/hidraCordatus.capnp +16 -0
- data/tests/hidraCordatusEmployer.rb +33 -0
- data/tests/hidraCordatusMaster.rb +51 -0
- metadata +216 -0
@@ -0,0 +1,80 @@
|
|
1
|
+
#include "ruby_capn_proto.h"
|
2
|
+
#include "class_builder.h"
|
3
|
+
|
4
|
+
namespace ruby_capn_proto {
|
5
|
+
|
6
|
+
VALUE defineClass(const char *name, VALUE superclass = rb_cObject) {
|
7
|
+
VALUE CapnProto = rb_define_module("CapnProto");
|
8
|
+
VALUE klass = rb_define_class_under(CapnProto, name, superclass);
|
9
|
+
// rb_funcall(klass, rb_intern("private_class_method"), 1, rb_str_new2("new"));
|
10
|
+
return klass;
|
11
|
+
}
|
12
|
+
|
13
|
+
ClassBuilder::ClassBuilder(const char* name, VALUE superclass) {
|
14
|
+
this->value = defineClass(name, superclass);
|
15
|
+
}
|
16
|
+
ClassBuilder::ClassBuilder(const char* name, const char* supername) {
|
17
|
+
VALUE superclass = defineClass(supername);
|
18
|
+
this->value = defineClass(name, superclass);
|
19
|
+
}
|
20
|
+
|
21
|
+
ClassBuilder& ClassBuilder::defineAlloc(VALUE (*impl)(VALUE)) {
|
22
|
+
rb_define_alloc_func(this->value, (VALUE (*)(VALUE))impl);
|
23
|
+
return *this;
|
24
|
+
}
|
25
|
+
|
26
|
+
ClassBuilder& ClassBuilder::defineConst(const char* name, VALUE value) {
|
27
|
+
rb_define_const(this->value, name, value);
|
28
|
+
return *this;
|
29
|
+
}
|
30
|
+
|
31
|
+
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE)) {
|
32
|
+
rb_define_method(this->value, name, (VALUE (*)(...))impl, -1);
|
33
|
+
return *this;
|
34
|
+
}
|
35
|
+
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(VALUE)) {
|
36
|
+
rb_define_method(this->value, name, (VALUE (*)(...))impl, 0);
|
37
|
+
return *this;
|
38
|
+
}
|
39
|
+
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE)) {
|
40
|
+
rb_define_method(this->value, name, (VALUE (*)(...))impl, 1);
|
41
|
+
return *this;
|
42
|
+
}
|
43
|
+
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE)) {
|
44
|
+
rb_define_method(this->value, name, (VALUE (*)(...))impl, 2);
|
45
|
+
return *this;
|
46
|
+
}
|
47
|
+
ClassBuilder& ClassBuilder::defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE, VALUE)) {
|
48
|
+
rb_define_method(this->value, name, (VALUE (*)(...))impl, 3);
|
49
|
+
return *this;
|
50
|
+
}
|
51
|
+
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE)) {
|
52
|
+
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, -1);
|
53
|
+
return *this;
|
54
|
+
}
|
55
|
+
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(VALUE)) {
|
56
|
+
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, 0);
|
57
|
+
return *this;
|
58
|
+
}
|
59
|
+
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE)) {
|
60
|
+
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, 1);
|
61
|
+
return *this;
|
62
|
+
}
|
63
|
+
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE)) {
|
64
|
+
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, 2);
|
65
|
+
return *this;
|
66
|
+
}
|
67
|
+
ClassBuilder& ClassBuilder::defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE, VALUE)) {
|
68
|
+
rb_define_singleton_method(this->value, name, (VALUE (*)(...))impl, 3);
|
69
|
+
return *this;
|
70
|
+
}
|
71
|
+
ClassBuilder& ClassBuilder::defineEnumConst(const char* name, int value) {
|
72
|
+
rb_define_const(this->value, name, INT2FIX(value));
|
73
|
+
return *this;
|
74
|
+
}
|
75
|
+
ClassBuilder& ClassBuilder::store(VALUE* storage) {
|
76
|
+
rb_gc_register_address(storage);
|
77
|
+
*storage = this->value;
|
78
|
+
return *this;
|
79
|
+
}
|
80
|
+
}
|
@@ -0,0 +1,72 @@
|
|
1
|
+
#ifndef CLASS_BUILDER_H
|
2
|
+
#define CLASS_BUILDER_H
|
3
|
+
|
4
|
+
#include "ruby_capn_proto.h"
|
5
|
+
|
6
|
+
namespace ruby_capn_proto {
|
7
|
+
class ClassBuilder {
|
8
|
+
public:
|
9
|
+
ClassBuilder() {};
|
10
|
+
ClassBuilder(const char* name, VALUE superclass = rb_cObject);
|
11
|
+
ClassBuilder(const char* name, const char* supername);
|
12
|
+
ClassBuilder& defineAlloc(VALUE (*impl)(VALUE));
|
13
|
+
ClassBuilder& defineConst(const char* name, VALUE value);
|
14
|
+
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE));
|
15
|
+
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE));
|
16
|
+
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE));
|
17
|
+
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE));
|
18
|
+
ClassBuilder& defineMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE, VALUE));
|
19
|
+
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(int, VALUE*, VALUE));
|
20
|
+
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE));
|
21
|
+
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE));
|
22
|
+
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE));
|
23
|
+
ClassBuilder& defineSingletonMethod(const char* name, VALUE (*impl)(VALUE, VALUE, VALUE, VALUE));
|
24
|
+
ClassBuilder& defineEnumConst(const char* name, int value);
|
25
|
+
ClassBuilder& store(VALUE* storage);
|
26
|
+
inline operator VALUE() {return this->value;}
|
27
|
+
protected:
|
28
|
+
VALUE value;
|
29
|
+
};
|
30
|
+
|
31
|
+
template <VALUE(* f)(int, VALUE*, VALUE)>
|
32
|
+
VALUE handleExceptions(int argc, VALUE* argv, VALUE self)
|
33
|
+
{
|
34
|
+
try {
|
35
|
+
return f(argc, argv, self);
|
36
|
+
} catch (...) {
|
37
|
+
rb_raise(rb_eRuntimeError, "caught unkown error");
|
38
|
+
}
|
39
|
+
}
|
40
|
+
|
41
|
+
template <VALUE(* f)(VALUE)>
|
42
|
+
VALUE handleExceptions(VALUE self)
|
43
|
+
{
|
44
|
+
return f(self);
|
45
|
+
}
|
46
|
+
|
47
|
+
template <VALUE(* f)(VALUE, VALUE)>
|
48
|
+
VALUE handleExceptions(VALUE self, VALUE arg1)
|
49
|
+
{
|
50
|
+
return f(self, arg1);
|
51
|
+
}
|
52
|
+
|
53
|
+
template <VALUE(* f)(VALUE, VALUE, VALUE)>
|
54
|
+
VALUE handleExceptions(VALUE self, VALUE arg1, VALUE arg2)
|
55
|
+
{
|
56
|
+
return f(self, arg1, arg2);
|
57
|
+
}
|
58
|
+
|
59
|
+
template <VALUE(* f)(VALUE, VALUE, VALUE, VALUE)>
|
60
|
+
VALUE handleExceptions(VALUE self, VALUE arg2, VALUE arg1, VALUE arg3)
|
61
|
+
{
|
62
|
+
return f(self, arg1, arg2, arg3);
|
63
|
+
}
|
64
|
+
|
65
|
+
template <VALUE(* f)(VALUE, VALUE, VALUE, VALUE, VALUE)>
|
66
|
+
VALUE handleExceptions(VALUE self, VALUE arg2, VALUE arg1, VALUE arg3, VALUE arg4)
|
67
|
+
{
|
68
|
+
return f(self, arg1, arg2, arg3, arg4);
|
69
|
+
}
|
70
|
+
}
|
71
|
+
|
72
|
+
#endif /* CLASS_BUILDER_H */
|
@@ -0,0 +1,126 @@
|
|
1
|
+
require 'shellwords'
|
2
|
+
require 'tmpdir'
|
3
|
+
|
4
|
+
# Discovers support for C++11 features,
|
5
|
+
# and any required CXXFLAGS for such features.
|
6
|
+
class CXXCompiler
|
7
|
+
CXX_COMPILER_FEATURES = <<-CODE
|
8
|
+
template <typename T>
|
9
|
+
struct check
|
10
|
+
{
|
11
|
+
static_assert(sizeof(int) <= sizeof(T), "not big enough");
|
12
|
+
};
|
13
|
+
|
14
|
+
typedef check<check<bool>> right_angle_brackets;
|
15
|
+
|
16
|
+
int a;
|
17
|
+
decltype(a) b;
|
18
|
+
|
19
|
+
typedef check<int> check_type;
|
20
|
+
check_type c;
|
21
|
+
check_type&& cr = static_cast<check_type&&>(c);
|
22
|
+
|
23
|
+
#ifdef __has_include
|
24
|
+
#if __has_include(<type_traits>)
|
25
|
+
#include <type_traits>
|
26
|
+
#endif
|
27
|
+
#endif
|
28
|
+
CODE
|
29
|
+
|
30
|
+
CXX_LIBRARY_FEATURES = <<-CODE
|
31
|
+
#include <initializer_list>
|
32
|
+
#include <unordered_map>
|
33
|
+
#include <atomic>
|
34
|
+
#include <thread>
|
35
|
+
CODE
|
36
|
+
|
37
|
+
# env: The environment variables (e.g. CXX, CXXFLAGS).
|
38
|
+
def initialize(env)
|
39
|
+
@env = env.dup
|
40
|
+
@exist = system("command -v #{@env['CXX'].shellescape} >/dev/null 2>&1")
|
41
|
+
end
|
42
|
+
|
43
|
+
# True if the compiler is accessible on the $PATH.
|
44
|
+
def exist?
|
45
|
+
@exist
|
46
|
+
end
|
47
|
+
|
48
|
+
# True if support for C++11 was detected, false otherwise.
|
49
|
+
def has_cxx11_compiler_support?
|
50
|
+
!!std_flag
|
51
|
+
end
|
52
|
+
|
53
|
+
# True if support for C++11 libraries was detected, false otherwise.
|
54
|
+
def has_cxx11_library_support?
|
55
|
+
!!stdlib_flag
|
56
|
+
end
|
57
|
+
|
58
|
+
# The required std flag (e.g. '-std=c++11'),
|
59
|
+
# empty string if unecessary given the current environment and/or compiler,
|
60
|
+
# or nil in the case where the compiler has no support.
|
61
|
+
def std_flag
|
62
|
+
test_compiler_flags(@env)
|
63
|
+
@std_flag
|
64
|
+
end
|
65
|
+
|
66
|
+
# The required stdlib flag (e.g. '-stdlib=libc++'),
|
67
|
+
# empty string if unecessary given the current environment and/or compiler,
|
68
|
+
# or nil in the case where the compiler has no support.
|
69
|
+
def stdlib_flag
|
70
|
+
test_compiler_flags(@env)
|
71
|
+
@stdlib_flag
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# Detect any required flags.
|
77
|
+
def test_compiler_flags(env)
|
78
|
+
return if @tested || !exist?
|
79
|
+
@tested = true
|
80
|
+
|
81
|
+
cxxflags = (env['CXXFLAGS'] || '')
|
82
|
+
env = env.dup
|
83
|
+
|
84
|
+
flags = ['', '-std=gnu++11', '-std=gnu++0x', '-std=c++11', '-std=c++0x']
|
85
|
+
@std_flag = flags.detect do |flag|
|
86
|
+
env['CXXFLAGS'] = [cxxflags, flag].join(' ')
|
87
|
+
compile(CXX_COMPILER_FEATURES, env)
|
88
|
+
end
|
89
|
+
|
90
|
+
return unless @std_flag
|
91
|
+
|
92
|
+
env = env.dup
|
93
|
+
flags = ['', '-stdlib=libc++']
|
94
|
+
@stdlib_flag = flags.detect do |flag|
|
95
|
+
env['CXXFLAGS'] = [cxxflags, std_flag, flag].join(' ')
|
96
|
+
compile(CXX_LIBRARY_FEATURES, env)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Compile a snippet of C++, returning true or false to indicate
|
101
|
+
# success.
|
102
|
+
def compile(code, env)
|
103
|
+
Dir.mktmpdir do |dir|
|
104
|
+
Dir.chdir(dir) do
|
105
|
+
File.open("test.cc", "w") {|f| f.write(code)}
|
106
|
+
system("#{env['CXX'].shellescape} #{env['CXXFLAGS']} -c test.cc >/dev/null 2>&1")
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
if $0 == __FILE__
|
113
|
+
compiler = CXXCompiler.new(ENV.to_hash)
|
114
|
+
cxx = ENV['CXX']
|
115
|
+
cxxflags = ENV['CXXFLAGS']
|
116
|
+
extra_cxxflags = [compiler.std_flag, compiler.stdlib_flag].join(' ')
|
117
|
+
compiler_support = compiler.has_cxx11_compiler_support? ? 'YES' : 'NO'
|
118
|
+
lib_support = compiler.has_cxx11_library_support? ? 'YES' : 'NO'
|
119
|
+
|
120
|
+
puts " given CXX = #{cxx}"
|
121
|
+
puts " given CXXFLAGS = #{cxxflags}"
|
122
|
+
puts "additional CXXFLAGS = #{extra_cxxflags}"
|
123
|
+
puts ""
|
124
|
+
puts "Has C++11 compiler support? #{compiler_support}"
|
125
|
+
puts "Has C++11 library support? #{lib_support}"
|
126
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
#include "ruby_capn_proto.h"
|
2
|
+
#include "capability_client.h"
|
3
|
+
#include "dynamic_capability_client.h"
|
4
|
+
#include "interface_schema.h"
|
5
|
+
#include "interface_method.h"
|
6
|
+
#include "remote_promise.h"
|
7
|
+
#include "exception.h"
|
8
|
+
#include "class_builder.h"
|
9
|
+
#include "util.h"
|
10
|
+
|
11
|
+
namespace ruby_capn_proto {
|
12
|
+
using WrappedType = capnp::DynamicCapability::Client;
|
13
|
+
VALUE DynamicCapabilityClient::Class;
|
14
|
+
|
15
|
+
void DynamicCapabilityClient::Init() {
|
16
|
+
ClassBuilder("DynamicCapabilityClient", rb_cObject).
|
17
|
+
defineAlloc(&alloc).
|
18
|
+
defineMethod("request_and_send" , &request_and_send).
|
19
|
+
store(&Class);
|
20
|
+
}
|
21
|
+
|
22
|
+
void DynamicCapabilityClient::free(WrappedType* p) {
|
23
|
+
p->~Client();
|
24
|
+
ruby_xfree(p);
|
25
|
+
}
|
26
|
+
|
27
|
+
VALUE DynamicCapabilityClient::alloc(VALUE klass) {
|
28
|
+
return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
|
29
|
+
}
|
30
|
+
|
31
|
+
WrappedType* DynamicCapabilityClient::unwrap(VALUE self) {
|
32
|
+
WrappedType* p;
|
33
|
+
Data_Get_Struct(self, WrappedType, p);
|
34
|
+
return p;
|
35
|
+
}
|
36
|
+
|
37
|
+
VALUE DynamicCapabilityClient::create(VALUE client, VALUE interschema) {
|
38
|
+
|
39
|
+
VALUE self = alloc(Class);
|
40
|
+
WrappedType* rb_self = unwrap(self);
|
41
|
+
auto dyncap = CapabilityClient::unwrap(client)->castAs<capnp::DynamicCapability>(*InterfaceSchema::unwrap(interschema));
|
42
|
+
new (rb_self) capnp::DynamicCapability::Client(dyncap);
|
43
|
+
|
44
|
+
return self;
|
45
|
+
}
|
46
|
+
|
47
|
+
VALUE DynamicCapabilityClient::create(WrappedType native_client){
|
48
|
+
VALUE self = alloc(Class);
|
49
|
+
WrappedType* rb_self = unwrap(self);
|
50
|
+
new (rb_self) capnp::DynamicCapability::Client(native_client);
|
51
|
+
|
52
|
+
return self;
|
53
|
+
}
|
54
|
+
|
55
|
+
VALUE DynamicCapabilityClient::request_and_send(VALUE self , VALUE rb_method , VALUE arrays){
|
56
|
+
// have, a method and a list of lists each list containing a value to set
|
57
|
+
// return, a remote promise.
|
58
|
+
// Data must be a array of arrays
|
59
|
+
// arrays must be like ['expression','literal','3']
|
60
|
+
// this will set in the expression param literal = 3
|
61
|
+
try{
|
62
|
+
auto* method = InterfaceMethod::unwrap(rb_method);
|
63
|
+
auto request = unwrap(self)->newRequest(*method);
|
64
|
+
|
65
|
+
RemotePromise::setParam(&request,arrays);
|
66
|
+
|
67
|
+
capnp::RemotePromise<capnp::DynamicStruct> r = request.send();
|
68
|
+
return RemotePromise::create(r);
|
69
|
+
}catch(kj::Exception e){
|
70
|
+
Exception::raise(e);
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
#ifndef DYNAMIC_CAPABILITY_CLIENT_H
|
2
|
+
#define DYNAMIC_CAPABILITY_CLIENT_H
|
3
|
+
|
4
|
+
#include "ruby_capn_proto.h"
|
5
|
+
|
6
|
+
namespace ruby_capn_proto {
|
7
|
+
class DynamicCapabilityClient {
|
8
|
+
public:
|
9
|
+
using WrappedType = capnp::DynamicCapability::Client;
|
10
|
+
static void Init();
|
11
|
+
static VALUE alloc(VALUE klass);
|
12
|
+
static VALUE create(VALUE capclient, VALUE schema);
|
13
|
+
static VALUE create(WrappedType native_dynclient);
|
14
|
+
static void free(WrappedType* p);
|
15
|
+
static WrappedType* unwrap(VALUE self);
|
16
|
+
static VALUE request_and_send(VALUE self, VALUE method, VALUE data);
|
17
|
+
static VALUE Class;
|
18
|
+
};
|
19
|
+
}
|
20
|
+
|
21
|
+
|
22
|
+
#endif /* DYNAMIC_CAPABILITY_CLIENT_H */
|
@@ -0,0 +1,123 @@
|
|
1
|
+
#include "ruby_capn_proto.h"
|
2
|
+
#include "dynamic_list_builder.h"
|
3
|
+
#include "dynamic_value_builder.h"
|
4
|
+
#include "dynamic_struct_reader.h"
|
5
|
+
#include "dynamic_struct_builder.h"
|
6
|
+
#include "exception.h"
|
7
|
+
#include "util.h"
|
8
|
+
#include "class_builder.h"
|
9
|
+
|
10
|
+
namespace ruby_capn_proto {
|
11
|
+
using WrappedType = capnp::DynamicList::Builder;
|
12
|
+
VALUE DynamicListBuilder::Class;
|
13
|
+
|
14
|
+
void DynamicListBuilder::Init() {
|
15
|
+
ClassBuilder("DynamicListBuilder", rb_cObject).
|
16
|
+
defineAlloc(&alloc).
|
17
|
+
defineMethod("[]", &get).
|
18
|
+
defineMethod("[]=", &set).
|
19
|
+
defineMethod("size", &size).
|
20
|
+
store(&Class);
|
21
|
+
}
|
22
|
+
|
23
|
+
VALUE DynamicListBuilder::alloc(VALUE klass) {
|
24
|
+
return Data_Wrap_Struct(klass, NULL, free, ruby_xmalloc(sizeof(WrappedType)));
|
25
|
+
}
|
26
|
+
|
27
|
+
void DynamicListBuilder::free(WrappedType* p) {
|
28
|
+
p->~Builder();
|
29
|
+
ruby_xfree(p);
|
30
|
+
}
|
31
|
+
|
32
|
+
WrappedType* DynamicListBuilder::unwrap(VALUE self) {
|
33
|
+
WrappedType* p;
|
34
|
+
Data_Get_Struct(self, WrappedType, p);
|
35
|
+
return p;
|
36
|
+
}
|
37
|
+
|
38
|
+
VALUE DynamicListBuilder::create(WrappedType builder, VALUE parent) {
|
39
|
+
auto rb_obj = alloc(Class);
|
40
|
+
WrappedType* wrapped = unwrap(rb_obj);
|
41
|
+
*wrapped = kj::mv(builder);
|
42
|
+
|
43
|
+
rb_iv_set(rb_obj, "parent", parent);
|
44
|
+
|
45
|
+
return rb_obj;
|
46
|
+
}
|
47
|
+
|
48
|
+
VALUE DynamicListBuilder::size(VALUE self) {
|
49
|
+
return INT2FIX(unwrap(self)->size());
|
50
|
+
}
|
51
|
+
|
52
|
+
VALUE DynamicListBuilder::get(VALUE self, VALUE rb_index) {
|
53
|
+
try {
|
54
|
+
return _get(self, rb_index);
|
55
|
+
} catch (kj::Exception ex) {
|
56
|
+
return Exception::raise(ex);
|
57
|
+
}
|
58
|
+
}
|
59
|
+
|
60
|
+
VALUE DynamicListBuilder::_get(VALUE self, VALUE rb_index) {
|
61
|
+
auto builder = *unwrap(self);
|
62
|
+
auto size = builder.size();
|
63
|
+
|
64
|
+
unsigned long index;
|
65
|
+
if (Util::isNegative(rb_index)) {
|
66
|
+
index = NUM2LONG(rb_index) % builder.size();
|
67
|
+
} else {
|
68
|
+
index = NUM2ULONG(rb_index);
|
69
|
+
}
|
70
|
+
|
71
|
+
// return DynamicValueBuilder::to_ruby(builder.get(field), self);
|
72
|
+
return DynamicValueBuilder::to_ruby(builder[index], self);
|
73
|
+
}
|
74
|
+
|
75
|
+
VALUE DynamicListBuilder::set(VALUE self, VALUE rb_index, VALUE rb_obj) {
|
76
|
+
try {
|
77
|
+
return _set(self, rb_index, rb_obj);
|
78
|
+
} catch (kj::Exception ex) {
|
79
|
+
return Exception::raise(ex);
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
VALUE DynamicListBuilder::_set(VALUE self, VALUE rb_index, VALUE rb_obj) {
|
84
|
+
VALUE klass = rb_funcall(rb_obj, rb_intern("class"), 0);
|
85
|
+
|
86
|
+
unsigned long field;
|
87
|
+
if (Util::isNegative(rb_index)) {
|
88
|
+
field = NUM2LONG(rb_index) % unwrap(self)->size();
|
89
|
+
} else {
|
90
|
+
field = NUM2ULONG(rb_index);
|
91
|
+
}
|
92
|
+
|
93
|
+
// TODO: handle assigning lists (see _setDynamicField)
|
94
|
+
if FIXNUM_P(rb_obj) {
|
95
|
+
if (Util::isNegative(rb_obj)) {
|
96
|
+
unwrap(self)->set(field, NUM2LONG(rb_obj));
|
97
|
+
} else {
|
98
|
+
unwrap(self)->set(field, NUM2ULONG(rb_obj));
|
99
|
+
}
|
100
|
+
} else if (RB_TYPE_P(rb_obj, T_FLOAT)) {
|
101
|
+
unwrap(self)->set(field, RFLOAT_VALUE(rb_obj));
|
102
|
+
} else if (rb_obj == Qtrue || rb_obj == Qfalse) {
|
103
|
+
unwrap(self)->set(field, (rb_obj == Qtrue) ? true : false);
|
104
|
+
} else if (RB_TYPE_P(rb_obj, T_STRING)) {
|
105
|
+
// TODO: need to ensure that the UTF8 char buffer is null terminated.
|
106
|
+
// consider something similar to rb_string_value_cstr,
|
107
|
+
// which grows the the buffer if necessary.
|
108
|
+
capnp::DynamicValue::Reader tmp =
|
109
|
+
capnp::Text::Reader(RSTRING_PTR(rb_obj), RSTRING_LEN(rb_obj));
|
110
|
+
unwrap(self)->set(field, tmp);
|
111
|
+
} else if (NIL_P(rb_obj)) {
|
112
|
+
unwrap(self)->set(field, capnp::VOID);
|
113
|
+
} else if (rb_equal(klass, DynamicStructReader::Class)) {
|
114
|
+
unwrap(self)->set(field, *DynamicStructReader::unwrap(rb_obj));
|
115
|
+
} else if (rb_equal(klass, DynamicStructBuilder::Class)) {
|
116
|
+
unwrap(self)->set(field, (*DynamicStructBuilder::unwrap(rb_obj)).asReader());
|
117
|
+
} else {
|
118
|
+
// TODO: raise "Non primitive type"
|
119
|
+
}
|
120
|
+
|
121
|
+
return rb_obj;
|
122
|
+
}
|
123
|
+
}
|