pycapnp 2.2.2__cp39-cp39-win_amd64.whl
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.
- capnp/__init__.pxd +0 -0
- capnp/__init__.py +62 -0
- capnp/_gen.py +80 -0
- capnp/c++.capnp +48 -0
- capnp/helpers/__init__.pxd +0 -0
- capnp/helpers/capabilityHelper.h +139 -0
- capnp/helpers/checkCompiler.h +8 -0
- capnp/helpers/deserialize.h +12 -0
- capnp/helpers/fixMaybe.h +11 -0
- capnp/helpers/helpers.pxd +34 -0
- capnp/helpers/non_circular.pxd +8 -0
- capnp/helpers/rpcHelper.h +21 -0
- capnp/helpers/serialize.h +14 -0
- capnp/includes/PyCustomMessageBuilder.h +28 -0
- capnp/includes/__init__.pxd +0 -0
- capnp/includes/capnp_cpp.pxd +497 -0
- capnp/includes/schema_cpp.pxd +826 -0
- capnp/includes/types.pxd +18 -0
- capnp/lib/__init__.pxd +0 -0
- capnp/lib/__init__.py +0 -0
- capnp/lib/capnp.cp39-win_amd64.pyd +0 -0
- capnp/lib/capnp.pxd +170 -0
- capnp/lib/capnp.pyx +4746 -0
- capnp/lib/capnp_api.h +120 -0
- capnp/lib/pickle_helper.py +7 -0
- capnp/persistent.capnp +122 -0
- capnp/rpc-twoparty.capnp +167 -0
- capnp/rpc.capnp +1530 -0
- capnp/schema.capnp +542 -0
- capnp/stream.capnp +50 -0
- capnp/templates/module.pyx +249 -0
- capnp/templates/setup.py.tmpl +38 -0
- capnp/version.py +7 -0
- pycapnp-2.2.2.dist-info/METADATA +654 -0
- pycapnp-2.2.2.dist-info/RECORD +39 -0
- pycapnp-2.2.2.dist-info/WHEEL +5 -0
- pycapnp-2.2.2.dist-info/entry_points.txt +2 -0
- pycapnp-2.2.2.dist-info/licenses/LICENSE.md +24 -0
- pycapnp-2.2.2.dist-info/top_level.txt +1 -0
capnp/__init__.pxd
ADDED
|
File without changes
|
capnp/__init__.py
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"""A python library wrapping the Cap'n Proto C++ library
|
|
2
|
+
|
|
3
|
+
Example Usage::
|
|
4
|
+
|
|
5
|
+
import capnp
|
|
6
|
+
|
|
7
|
+
addressbook = capnp.load('addressbook.capnp')
|
|
8
|
+
|
|
9
|
+
# Building
|
|
10
|
+
addresses = addressbook.AddressBook.newMessage()
|
|
11
|
+
people = addresses.init('people', 1)
|
|
12
|
+
|
|
13
|
+
alice = people[0]
|
|
14
|
+
alice.id = 123
|
|
15
|
+
alice.name = 'Alice'
|
|
16
|
+
alice.email = 'alice@example.com'
|
|
17
|
+
alicePhone = alice.init('phones', 1)[0]
|
|
18
|
+
alicePhone.type = 'mobile'
|
|
19
|
+
|
|
20
|
+
f = open('example.bin', 'w')
|
|
21
|
+
addresses.write(f)
|
|
22
|
+
f.close()
|
|
23
|
+
|
|
24
|
+
# Reading
|
|
25
|
+
f = open('example.bin')
|
|
26
|
+
|
|
27
|
+
addresses = addressbook.AddressBook.read(f)
|
|
28
|
+
|
|
29
|
+
for person in addresses.people:
|
|
30
|
+
print(person.name, ':', person.email)
|
|
31
|
+
for phone in person.phones:
|
|
32
|
+
print(phone.type, ':', phone.number)
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
# flake8: noqa F401 F403 F405
|
|
36
|
+
from .version import version as __version__
|
|
37
|
+
from .lib.capnp import *
|
|
38
|
+
from .lib.capnp import (
|
|
39
|
+
_CapabilityClient,
|
|
40
|
+
_DynamicCapabilityClient,
|
|
41
|
+
_DynamicListBuilder,
|
|
42
|
+
_DynamicListReader,
|
|
43
|
+
_DynamicOrphan,
|
|
44
|
+
_DynamicResizableListBuilder,
|
|
45
|
+
_DynamicStructBuilder,
|
|
46
|
+
_DynamicStructReader,
|
|
47
|
+
_EventLoop,
|
|
48
|
+
_InterfaceModule,
|
|
49
|
+
_ListSchema,
|
|
50
|
+
_MallocMessageBuilder,
|
|
51
|
+
_PyCustomMessageBuilder,
|
|
52
|
+
_PackedFdMessageReader,
|
|
53
|
+
_StreamFdMessageReader,
|
|
54
|
+
_StructModule,
|
|
55
|
+
_write_message_to_fd,
|
|
56
|
+
_write_packed_message_to_fd,
|
|
57
|
+
_AsyncIoStream as AsyncIoStream,
|
|
58
|
+
_init_capnp_api,
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
_init_capnp_api()
|
|
62
|
+
add_import_hook() # enable import hook by default
|
capnp/_gen.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
from jinja2 import Environment, PackageLoader
|
|
5
|
+
|
|
6
|
+
import capnp
|
|
7
|
+
import schema_capnp
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def find_type(code, id):
|
|
11
|
+
for node in code["nodes"]:
|
|
12
|
+
if node["id"] == id:
|
|
13
|
+
return node
|
|
14
|
+
|
|
15
|
+
return None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def main():
|
|
19
|
+
env = Environment(loader=PackageLoader("capnp", "templates"))
|
|
20
|
+
env.filters["format_name"] = lambda name: name[name.find(":") + 1 :]
|
|
21
|
+
|
|
22
|
+
code = schema_capnp.CodeGeneratorRequest.read(sys.stdin)
|
|
23
|
+
code = code.to_dict()
|
|
24
|
+
code["nodes"] = [
|
|
25
|
+
node for node in code["nodes"] if "struct" in node and node["scopeId"] != 0
|
|
26
|
+
]
|
|
27
|
+
for node in code["nodes"]:
|
|
28
|
+
displayName = node["displayName"]
|
|
29
|
+
parent, path = displayName.split(":")
|
|
30
|
+
node["module_path"] = (
|
|
31
|
+
parent.replace(".", "_")
|
|
32
|
+
+ "."
|
|
33
|
+
+ ".".join([x[0].upper() + x[1:] for x in path.split(".")])
|
|
34
|
+
)
|
|
35
|
+
node["module_name"] = path.replace(".", "_")
|
|
36
|
+
node["c_module_path"] = "::".join(
|
|
37
|
+
[x[0].upper() + x[1:] for x in path.split(".")]
|
|
38
|
+
)
|
|
39
|
+
node["schema"] = "_{}_Schema".format(node["module_name"])
|
|
40
|
+
is_union = False
|
|
41
|
+
for field in node["struct"]["fields"]:
|
|
42
|
+
if field["discriminantValue"] != 65535:
|
|
43
|
+
is_union = True
|
|
44
|
+
field["c_name"] = field["name"][0].upper() + field["name"][1:]
|
|
45
|
+
if "slot" in field:
|
|
46
|
+
field["type"] = list(field["slot"]["type"].keys())[0]
|
|
47
|
+
if not isinstance(field["slot"]["type"][field["type"]], dict):
|
|
48
|
+
continue
|
|
49
|
+
sub_type = field["slot"]["type"][field["type"]].get("typeId", None)
|
|
50
|
+
if sub_type:
|
|
51
|
+
field["sub_type"] = find_type(code, sub_type)
|
|
52
|
+
sub_type = field["slot"]["type"][field["type"]].get("elementType", None)
|
|
53
|
+
if sub_type:
|
|
54
|
+
field["sub_type"] = sub_type
|
|
55
|
+
else:
|
|
56
|
+
field["type"] = find_type(code, field["group"]["typeId"])
|
|
57
|
+
node["is_union"] = is_union
|
|
58
|
+
|
|
59
|
+
include_dir = os.path.abspath(os.path.join(os.path.dirname(capnp.__file__), ".."))
|
|
60
|
+
module = env.get_template("module.pyx")
|
|
61
|
+
|
|
62
|
+
for f in code["requestedFiles"]:
|
|
63
|
+
filename = f["filename"].replace(".", "_") + "_cython.pyx"
|
|
64
|
+
|
|
65
|
+
file_code = dict(code)
|
|
66
|
+
file_code["nodes"] = [
|
|
67
|
+
node
|
|
68
|
+
for node in file_code["nodes"]
|
|
69
|
+
if node["displayName"].startswith(f["filename"])
|
|
70
|
+
]
|
|
71
|
+
with open(filename, "w") as out:
|
|
72
|
+
out.write(module.render(code=file_code, file=f, include_dir=include_dir))
|
|
73
|
+
|
|
74
|
+
setup = env.get_template("setup.py.tmpl")
|
|
75
|
+
with open("setup_capnp.py", "w") as out:
|
|
76
|
+
out.write(setup.render(code=code))
|
|
77
|
+
print(
|
|
78
|
+
"You now need to build the cython module by running `python setup_capnp.py build_ext --inplace`."
|
|
79
|
+
)
|
|
80
|
+
print()
|
capnp/c++.capnp
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
|
|
2
|
+
# Licensed under the MIT License:
|
|
3
|
+
#
|
|
4
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
5
|
+
# of this software and associated documentation files (the "Software"), to deal
|
|
6
|
+
# in the Software without restriction, including without limitation the rights
|
|
7
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
# copies of the Software, and to permit persons to whom the Software is
|
|
9
|
+
# furnished to do so, subject to the following conditions:
|
|
10
|
+
#
|
|
11
|
+
# The above copyright notice and this permission notice shall be included in
|
|
12
|
+
# all copies or substantial portions of the Software.
|
|
13
|
+
#
|
|
14
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
20
|
+
# THE SOFTWARE.
|
|
21
|
+
|
|
22
|
+
@0xbdf87d7bb8304e81;
|
|
23
|
+
$namespace("capnp::annotations");
|
|
24
|
+
|
|
25
|
+
annotation namespace(file): Text;
|
|
26
|
+
annotation name(field, enumerant, struct, enum, interface, method, param, group, union): Text;
|
|
27
|
+
|
|
28
|
+
annotation allowCancellation(interface, method, file) :Void;
|
|
29
|
+
# Indicates that the server-side implementation of a method is allowed to be canceled when the
|
|
30
|
+
# client requests cancellation. Without this annotation, once a method call has been delivered to
|
|
31
|
+
# the server-side application code, any requests by the client to cancel it will be ignored, and
|
|
32
|
+
# the method will run to completion anyway. This applies even for local in-process calls.
|
|
33
|
+
#
|
|
34
|
+
# This behavior applies specifically to implementations that inherit from the C++ `Foo::Server`
|
|
35
|
+
# interface. The annotation won't affect DynamicCapability::Server implementations; they must set
|
|
36
|
+
# the cancellation mode at runtime.
|
|
37
|
+
#
|
|
38
|
+
# When applied to an interface rather than an individual method, the annotation applies to all
|
|
39
|
+
# methods in the interface. When applied to a file, it applies to all methods defined in the file.
|
|
40
|
+
#
|
|
41
|
+
# It's generally recommended that this annotation be applied to all methods. However, when doing
|
|
42
|
+
# so, it is important that the server implementation use cancellation-safe code. See:
|
|
43
|
+
#
|
|
44
|
+
# https://github.com/capnproto/capnproto/blob/master/kjdoc/tour.md#cancellation
|
|
45
|
+
#
|
|
46
|
+
# If your code is not cancellation-safe, then allowing cancellation might give a malicious client
|
|
47
|
+
# an easy way to induce use-after-free or other bugs in your server, by requesting cancellation
|
|
48
|
+
# when not expected.
|
|
File without changes
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "capnp/dynamic.h"
|
|
4
|
+
#include <kj/async-io.h>
|
|
5
|
+
#include <capnp/serialize-async.h>
|
|
6
|
+
#include <stdexcept>
|
|
7
|
+
#include "Python.h"
|
|
8
|
+
|
|
9
|
+
class GILAcquire {
|
|
10
|
+
public:
|
|
11
|
+
GILAcquire() : gstate(PyGILState_Ensure()) {}
|
|
12
|
+
~GILAcquire() {
|
|
13
|
+
PyGILState_Release(gstate);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
PyGILState_STATE gstate;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
class GILRelease {
|
|
20
|
+
public:
|
|
21
|
+
GILRelease() {
|
|
22
|
+
Py_UNBLOCK_THREADS
|
|
23
|
+
}
|
|
24
|
+
~GILRelease() {
|
|
25
|
+
Py_BLOCK_THREADS
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
PyThreadState *_save; // The macros above read/write from this variable
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
class PyRefCounter {
|
|
32
|
+
public:
|
|
33
|
+
PyObject * obj;
|
|
34
|
+
|
|
35
|
+
PyRefCounter(PyObject * o) : obj(o) {
|
|
36
|
+
GILAcquire gil;
|
|
37
|
+
Py_INCREF(obj);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
PyRefCounter(const PyRefCounter & ref) : obj(ref.obj) {
|
|
41
|
+
GILAcquire gil;
|
|
42
|
+
Py_INCREF(obj);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
~PyRefCounter() {
|
|
46
|
+
GILAcquire gil;
|
|
47
|
+
Py_DECREF(obj);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
inline kj::Own<PyRefCounter> stealPyRef(PyObject* o) {
|
|
52
|
+
auto ret = kj::heap<PyRefCounter>(o);
|
|
53
|
+
Py_DECREF(o);
|
|
54
|
+
return ret;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
::kj::Promise<kj::Own<PyRefCounter>> convert_to_pypromise(capnp::RemotePromise<capnp::DynamicStruct> promise);
|
|
58
|
+
|
|
59
|
+
inline ::kj::Promise<kj::Own<PyRefCounter>> convert_to_pypromise(kj::Promise<void> promise) {
|
|
60
|
+
return promise.then([]() {
|
|
61
|
+
GILAcquire gil;
|
|
62
|
+
return kj::heap<PyRefCounter>(Py_None);
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
void c_reraise_kj_exception();
|
|
67
|
+
|
|
68
|
+
void check_py_error();
|
|
69
|
+
|
|
70
|
+
::kj::Promise<kj::Own<PyRefCounter>> then(kj::Promise<kj::Own<PyRefCounter>> promise,
|
|
71
|
+
kj::Own<PyRefCounter> func, kj::Own<PyRefCounter> error_func);
|
|
72
|
+
|
|
73
|
+
class PythonInterfaceDynamicImpl final: public capnp::DynamicCapability::Server {
|
|
74
|
+
public:
|
|
75
|
+
kj::Own<PyRefCounter> py_server;
|
|
76
|
+
kj::Own<PyRefCounter> kj_loop;
|
|
77
|
+
|
|
78
|
+
#if (CAPNP_VERSION_MAJOR < 1)
|
|
79
|
+
PythonInterfaceDynamicImpl(capnp::InterfaceSchema & schema,
|
|
80
|
+
kj::Own<PyRefCounter> _py_server,
|
|
81
|
+
kj::Own<PyRefCounter> kj_loop)
|
|
82
|
+
: capnp::DynamicCapability::Server(schema),
|
|
83
|
+
py_server(kj::mv(_py_server)), kj_loop(kj::mv(kj_loop)) { }
|
|
84
|
+
#else
|
|
85
|
+
PythonInterfaceDynamicImpl(capnp::InterfaceSchema & schema,
|
|
86
|
+
kj::Own<PyRefCounter> _py_server,
|
|
87
|
+
kj::Own<PyRefCounter> kj_loop)
|
|
88
|
+
: capnp::DynamicCapability::Server(schema, { true }),
|
|
89
|
+
py_server(kj::mv(_py_server)), kj_loop(kj::mv(kj_loop)) { }
|
|
90
|
+
#endif
|
|
91
|
+
|
|
92
|
+
~PythonInterfaceDynamicImpl() {
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
kj::Promise<void> call(capnp::InterfaceSchema::Method method,
|
|
96
|
+
capnp::CallContext< capnp::DynamicStruct, capnp::DynamicStruct> context);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
inline void allowCancellation(capnp::CallContext<capnp::DynamicStruct, capnp::DynamicStruct> context) {
|
|
100
|
+
#if (CAPNP_VERSION_MAJOR < 1)
|
|
101
|
+
context.allowCancellation();
|
|
102
|
+
#endif
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
class PyAsyncIoStream: public kj::AsyncIoStream {
|
|
106
|
+
public:
|
|
107
|
+
kj::Own<PyRefCounter> protocol;
|
|
108
|
+
|
|
109
|
+
PyAsyncIoStream(kj::Own<PyRefCounter> protocol) : protocol(kj::mv(protocol)) {}
|
|
110
|
+
~PyAsyncIoStream();
|
|
111
|
+
|
|
112
|
+
kj::Promise<size_t> tryRead(void* buffer, size_t minBytes, size_t maxBytes);
|
|
113
|
+
|
|
114
|
+
kj::Promise<void> write(const void* buffer, size_t size);
|
|
115
|
+
|
|
116
|
+
kj::Promise<void> write(kj::ArrayPtr<const kj::ArrayPtr<const kj::byte>> pieces);
|
|
117
|
+
|
|
118
|
+
kj::Promise<void> whenWriteDisconnected();
|
|
119
|
+
|
|
120
|
+
void shutdownWrite();
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
template <typename T>
|
|
124
|
+
inline void rejectDisconnected(kj::PromiseFulfiller<T>& fulfiller, kj::StringPtr message) {
|
|
125
|
+
fulfiller.reject(KJ_EXCEPTION(DISCONNECTED, message));
|
|
126
|
+
}
|
|
127
|
+
inline void rejectVoidDisconnected(kj::PromiseFulfiller<void>& fulfiller, kj::StringPtr message) {
|
|
128
|
+
fulfiller.reject(KJ_EXCEPTION(DISCONNECTED, message));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
inline kj::Exception makeException(kj::StringPtr message) {
|
|
132
|
+
return KJ_EXCEPTION(FAILED, message);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
kj::Promise<void> taskToPromise(kj::Own<PyRefCounter> coroutine, PyObject* callback);
|
|
136
|
+
|
|
137
|
+
::kj::Promise<kj::Own<PyRefCounter>> tryReadMessage(kj::AsyncIoStream& stream, capnp::ReaderOptions opts);
|
|
138
|
+
|
|
139
|
+
void init_capnp_api();
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
#ifdef _MSC_VER
|
|
2
|
+
#pragma comment(lib, "Ws2_32.lib")
|
|
3
|
+
#pragma comment(lib, "advapi32.lib")
|
|
4
|
+
#endif
|
|
5
|
+
|
|
6
|
+
#include "capnp/dynamic.h"
|
|
7
|
+
|
|
8
|
+
static_assert(CAPNP_VERSION >= 8000, "Version of Cap'n Proto C++ Library is too old. Please upgrade to a version >= 0.8 and then re-install this python library");
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "capnp/dynamic.h"
|
|
4
|
+
#include "capnp/schema.capnp.h"
|
|
5
|
+
|
|
6
|
+
/// @brief Convert the dynamic struct to a Node::Reader
|
|
7
|
+
::capnp::schema::Node::Reader toReader(capnp::DynamicStruct::Reader reader)
|
|
8
|
+
{
|
|
9
|
+
// requires an intermediate step to AnyStruct before going directly to Node::Reader,
|
|
10
|
+
// since there exists no direct conversion from DynamicStruct::Reader to Node::Reader.
|
|
11
|
+
return reader.as<capnp::AnyStruct>().as<capnp::schema::Node>();
|
|
12
|
+
}
|
capnp/helpers/fixMaybe.h
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
from capnp.includes.capnp_cpp cimport (
|
|
2
|
+
Maybe, PyPromise, VoidPromise, RemotePromise,
|
|
3
|
+
DynamicCapability, InterfaceSchema, EnumSchema, StructSchema, DynamicValue, Capability,
|
|
4
|
+
RpcSystem, MessageBuilder, Own, PyRefCounter, Node, DynamicStruct, CallContext
|
|
5
|
+
)
|
|
6
|
+
|
|
7
|
+
from capnp.includes.schema_cpp cimport ByteArray
|
|
8
|
+
|
|
9
|
+
from non_circular cimport c_reraise_kj_exception as reraise_kj_exception
|
|
10
|
+
|
|
11
|
+
from cpython.ref cimport PyObject
|
|
12
|
+
|
|
13
|
+
cdef extern from "capnp/helpers/fixMaybe.h":
|
|
14
|
+
EnumSchema.Enumerant fixMaybe(Maybe[EnumSchema.Enumerant]) except +reraise_kj_exception
|
|
15
|
+
StructSchema.Field fixMaybe(Maybe[StructSchema.Field]) except +reraise_kj_exception
|
|
16
|
+
|
|
17
|
+
cdef extern from "capnp/helpers/capabilityHelper.h":
|
|
18
|
+
PyPromise then(PyPromise promise, Own[PyRefCounter] func, Own[PyRefCounter] error_func)
|
|
19
|
+
PyPromise convert_to_pypromise(RemotePromise)
|
|
20
|
+
PyPromise convert_to_pypromise(VoidPromise)
|
|
21
|
+
VoidPromise taskToPromise(Own[PyRefCounter] coroutine, PyObject* callback)
|
|
22
|
+
void allowCancellation(CallContext context) except +reraise_kj_exception nogil
|
|
23
|
+
void init_capnp_api()
|
|
24
|
+
|
|
25
|
+
cdef extern from "capnp/helpers/rpcHelper.h":
|
|
26
|
+
Own[Capability.Client] bootstrapHelper(RpcSystem&) except +reraise_kj_exception
|
|
27
|
+
Own[Capability.Client] bootstrapHelperServer(RpcSystem&) except +reraise_kj_exception
|
|
28
|
+
|
|
29
|
+
cdef extern from "capnp/helpers/serialize.h":
|
|
30
|
+
ByteArray messageToPackedBytes(MessageBuilder &, size_t wordCount) except +reraise_kj_exception
|
|
31
|
+
|
|
32
|
+
cdef extern from "capnp/helpers/deserialize.h":
|
|
33
|
+
Node.Reader toReader(DynamicStruct.Reader reader) except +reraise_kj_exception
|
|
34
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "capnp/dynamic.h"
|
|
4
|
+
#include <capnp/rpc.capnp.h>
|
|
5
|
+
#include "capnp/rpc-twoparty.h"
|
|
6
|
+
#include "Python.h"
|
|
7
|
+
#include "capabilityHelper.h"
|
|
8
|
+
|
|
9
|
+
kj::Own<capnp::Capability::Client> bootstrapHelper(capnp::RpcSystem<capnp::rpc::twoparty::SturdyRefHostId>& client) {
|
|
10
|
+
capnp::MallocMessageBuilder hostIdMessage(8);
|
|
11
|
+
auto hostId = hostIdMessage.initRoot<capnp::rpc::twoparty::SturdyRefHostId>();
|
|
12
|
+
hostId.setSide(capnp::rpc::twoparty::Side::SERVER);
|
|
13
|
+
return kj::heap<capnp::Capability::Client>(client.bootstrap(hostId));
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
kj::Own<capnp::Capability::Client> bootstrapHelperServer(capnp::RpcSystem<capnp::rpc::twoparty::SturdyRefHostId>& client) {
|
|
17
|
+
capnp::MallocMessageBuilder hostIdMessage(8);
|
|
18
|
+
auto hostId = hostIdMessage.initRoot<capnp::rpc::twoparty::SturdyRefHostId>();
|
|
19
|
+
hostId.setSide(capnp::rpc::twoparty::Side::CLIENT);
|
|
20
|
+
return kj::heap<capnp::Capability::Client>(client.bootstrap(hostId));
|
|
21
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "kj/io.h"
|
|
4
|
+
#include "capnp/dynamic.h"
|
|
5
|
+
#include "capnp/serialize-packed.h"
|
|
6
|
+
|
|
7
|
+
kj::Array< ::capnp::byte> messageToPackedBytes(capnp::MessageBuilder & message, size_t wordCount)
|
|
8
|
+
{
|
|
9
|
+
|
|
10
|
+
kj::Array<capnp::byte> result = kj::heapArray<capnp::byte>(wordCount * 8);
|
|
11
|
+
kj::ArrayOutputStream out(result.asPtr());
|
|
12
|
+
capnp::writePackedMessage(out, message);
|
|
13
|
+
return heapArray(out.getArray()); // TODO: make this non-copying somehow
|
|
14
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include "Python.h"
|
|
4
|
+
#include <capnp/message.h>
|
|
5
|
+
#include <capnp/serialize.h>
|
|
6
|
+
#include <vector>
|
|
7
|
+
|
|
8
|
+
namespace capnp {
|
|
9
|
+
|
|
10
|
+
class PyCustomMessageBuilder : public capnp::MessageBuilder {
|
|
11
|
+
public:
|
|
12
|
+
explicit PyCustomMessageBuilder(PyObject* allocateSegmentCallable,
|
|
13
|
+
uint firstSegmentWords = capnp::SUGGESTED_FIRST_SEGMENT_WORDS);
|
|
14
|
+
|
|
15
|
+
~PyCustomMessageBuilder() noexcept(false) override;
|
|
16
|
+
|
|
17
|
+
kj::ArrayPtr<capnp::word> allocateSegment(capnp::uint minimumSize) override;
|
|
18
|
+
|
|
19
|
+
private:
|
|
20
|
+
PyObject* allocateSegmentCallable;
|
|
21
|
+
|
|
22
|
+
uint firstSize;
|
|
23
|
+
uint curSize = 0;
|
|
24
|
+
|
|
25
|
+
std::vector<PyObject*> allocatedBuffers;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
}
|
|
File without changes
|