Added a load function to the capnp module
It takes .capnp file and will load it through the C++ capnproto library. Only major thing left is initializing lists and structs in MessageBuilder
This commit is contained in:
@@ -208,10 +208,12 @@ from types import ModuleType
|
|||||||
|
|
||||||
{%- for node_name, node_dict in nodes.items() recursive %}
|
{%- for node_name, node_dict in nodes.items() recursive %}
|
||||||
temp = {{ node_dict['full_name'] }} = ModuleType('{{ node_dict['full_name'] }}')
|
temp = {{ node_dict['full_name'] }} = ModuleType('{{ node_dict['full_name'] }}')
|
||||||
{%- if node_dict['body'] != 'enum' %}
|
{%- if node_dict['body'] == 'struct' %}
|
||||||
temp.Reader = {{ node_dict['full_name_cython'] }}Reader
|
temp.Reader = {{ node_dict['full_name_cython'] }}Reader
|
||||||
temp.Builder = {{ node_dict['full_name_cython'] }}Builder
|
temp.Builder = {{ node_dict['full_name_cython'] }}Builder
|
||||||
{%- elif node_dict['body'] == 'union' %}
|
{%- elif node_dict['body'] == 'union' %}
|
||||||
|
temp.Reader = {{ node_dict['full_name_cython'] }}Reader
|
||||||
|
temp.Builder = {{ node_dict['full_name_cython'] }}Builder
|
||||||
temp.Which = {{ node_dict['full_name_cython'] }}_Which
|
temp.Which = {{ node_dict['full_name_cython'] }}_Which
|
||||||
{%- else %}
|
{%- else %}
|
||||||
{{ node_dict['full_name'] }} = {{ node_dict['full_name_cython'] }}
|
{{ node_dict['full_name'] }} = {{ node_dict['full_name_cython'] }}
|
||||||
|
|||||||
143
capnp.pyx
143
capnp.pyx
@@ -7,9 +7,11 @@ cimport cython
|
|||||||
cimport capnp_cpp as capnp
|
cimport capnp_cpp as capnp
|
||||||
cimport schema_cpp
|
cimport schema_cpp
|
||||||
from capnp_cpp cimport SchemaLoader as C_SchemaLoader, Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, DynamicUnion as C_DynamicUnion, fixMaybe
|
from capnp_cpp cimport SchemaLoader as C_SchemaLoader, Schema as C_Schema, StructSchema as C_StructSchema, DynamicStruct as C_DynamicStruct, DynamicValue as C_DynamicValue, Type as C_Type, DynamicList as C_DynamicList, DynamicUnion as C_DynamicUnion, fixMaybe
|
||||||
from schema_cpp cimport CodeGeneratorRequest as C_CodeGeneratorRequest, Node as C_Node
|
|
||||||
|
from schema_cpp cimport CodeGeneratorRequest as C_CodeGeneratorRequest, Node as C_Node, EnumNode as C_EnumNode
|
||||||
from cython.operator cimport dereference as deref
|
from cython.operator cimport dereference as deref
|
||||||
|
|
||||||
|
from schema cimport _NodeReader
|
||||||
from libc.stdint cimport *
|
from libc.stdint cimport *
|
||||||
ctypedef unsigned int uint
|
ctypedef unsigned int uint
|
||||||
ctypedef uint8_t UInt8
|
ctypedef uint8_t UInt8
|
||||||
@@ -32,6 +34,7 @@ ctypedef fused valid_values:
|
|||||||
float
|
float
|
||||||
double
|
double
|
||||||
bint
|
bint
|
||||||
|
cython.p_char
|
||||||
|
|
||||||
def _make_enum(enum_name, *sequential, **named):
|
def _make_enum(enum_name, *sequential, **named):
|
||||||
enums = dict(zip(sequential, range(len(sequential))), **named)
|
enums = dict(zip(sequential, range(len(sequential))), **named)
|
||||||
@@ -242,12 +245,34 @@ cdef class _DynamicStructBuilder:
|
|||||||
def __getattr__(self, field):
|
def __getattr__(self, field):
|
||||||
return toPython(self.thisptr.get(field))
|
return toPython(self.thisptr.get(field))
|
||||||
|
|
||||||
def _setattr(self, field, valid_values value):
|
cdef _setattrInt(self, field, value):
|
||||||
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(value)
|
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<long long>value)
|
||||||
|
self.thisptr.set(field, temp)
|
||||||
|
|
||||||
|
cdef _setattrDouble(self, field, value):
|
||||||
|
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<double>value)
|
||||||
|
self.thisptr.set(field, temp)
|
||||||
|
|
||||||
|
cdef _setattrBool(self, field, value):
|
||||||
|
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<bint>value)
|
||||||
|
self.thisptr.set(field, temp)
|
||||||
|
|
||||||
|
cdef _setattrString(self, field, value):
|
||||||
|
cdef C_DynamicValue.Reader temp = C_DynamicValue.Reader(<char*>value)
|
||||||
self.thisptr.set(field, temp)
|
self.thisptr.set(field, temp)
|
||||||
|
|
||||||
def __setattr__(self, field, value):
|
def __setattr__(self, field, value):
|
||||||
self._setattr(field, value)
|
value_type = type(value)
|
||||||
|
if value_type is int:
|
||||||
|
self._setattrInt(field, value)
|
||||||
|
elif value_type is float:
|
||||||
|
self._setattrDouble(field, value)
|
||||||
|
elif value_type is bool:
|
||||||
|
self._setattrBool(field, value)
|
||||||
|
elif value_type is bytes:
|
||||||
|
self._setattrString(field, value)
|
||||||
|
else:
|
||||||
|
raise ValueError("Non primitive type")
|
||||||
|
|
||||||
def _has(self, field):
|
def _has(self, field):
|
||||||
return self.thisptr.has(field)
|
return self.thisptr.has(field)
|
||||||
@@ -299,21 +324,6 @@ cdef class _CodeGeneratorRequestReader:
|
|||||||
def __get__(self):
|
def __get__(self):
|
||||||
return _List_UInt64_Reader().init(self.thisptr.getRequestedFiles())
|
return _List_UInt64_Reader().init(self.thisptr.getRequestedFiles())
|
||||||
|
|
||||||
cdef class _NodeReader:
|
|
||||||
cdef C_Node.Reader thisptr
|
|
||||||
cdef init(self, C_Node.Reader other):
|
|
||||||
self.thisptr = other
|
|
||||||
return self
|
|
||||||
property displayName:
|
|
||||||
def __get__(self):
|
|
||||||
return self.thisptr.getDisplayName().cStr()
|
|
||||||
property scopeId:
|
|
||||||
def __get__(self):
|
|
||||||
return self.thisptr.getScopeId()
|
|
||||||
property id:
|
|
||||||
def __get__(self):
|
|
||||||
return self.thisptr.getId()
|
|
||||||
|
|
||||||
cdef class Schema:
|
cdef class Schema:
|
||||||
cdef C_Schema thisptr
|
cdef C_Schema thisptr
|
||||||
cdef init(self, C_Schema other):
|
cdef init(self, C_Schema other):
|
||||||
@@ -323,6 +333,12 @@ cdef class Schema:
|
|||||||
cpdef asStruct(self):
|
cpdef asStruct(self):
|
||||||
return StructSchema().init(self.thisptr.asStruct())
|
return StructSchema().init(self.thisptr.asStruct())
|
||||||
|
|
||||||
|
cpdef getDependency(self, id):
|
||||||
|
return Schema().init(self.thisptr.getDependency(id))
|
||||||
|
|
||||||
|
cpdef getProto(self):
|
||||||
|
return _NodeReader().init(self.thisptr.getProto())
|
||||||
|
|
||||||
cdef class StructSchema:
|
cdef class StructSchema:
|
||||||
cdef C_StructSchema thisptr
|
cdef C_StructSchema thisptr
|
||||||
cdef init(self, C_StructSchema other):
|
cdef init(self, C_StructSchema other):
|
||||||
@@ -340,18 +356,21 @@ cdef class SchemaLoader:
|
|||||||
cpdef load(self, _NodeReader node):
|
cpdef load(self, _NodeReader node):
|
||||||
return Schema().init(self.thisptr.load(node.thisptr))
|
return Schema().init(self.thisptr.load(node.thisptr))
|
||||||
|
|
||||||
|
cpdef get(self, id):
|
||||||
|
return Schema().init(self.thisptr.get(id))
|
||||||
|
|
||||||
cdef class MessageBuilder:
|
cdef class MessageBuilder:
|
||||||
cdef schema_cpp.MessageBuilder * thisptr
|
cdef schema_cpp.MessageBuilder * thisptr
|
||||||
def __dealloc__(self):
|
def __dealloc__(self):
|
||||||
del self.thisptr
|
del self.thisptr
|
||||||
|
cpdef initRoot(self, StructSchema schema):
|
||||||
|
return _DynamicStructBuilder().init(self.thisptr.initRootDynamicStruct(schema.thisptr))
|
||||||
|
cpdef getRoot(self, StructSchema schema):
|
||||||
|
return _DynamicStructBuilder().init(self.thisptr.getRootDynamicStruct(schema.thisptr))
|
||||||
|
|
||||||
cdef class MallocMessageBuilder(MessageBuilder):
|
cdef class MallocMessageBuilder(MessageBuilder):
|
||||||
def __cinit__(self):
|
def __cinit__(self):
|
||||||
self.thisptr = new schema_cpp.MallocMessageBuilder()
|
self.thisptr = new schema_cpp.MallocMessageBuilder()
|
||||||
cpdef initRootDynamicStruct(self, StructSchema schema):
|
|
||||||
return _DynamicStructBuilder().init(self.thisptr.initRootDynamicStruct(schema.thisptr))
|
|
||||||
cpdef getRootDynamicStruct(self, StructSchema schema):
|
|
||||||
return _DynamicStructBuilder().init(self.thisptr.getRootDynamicStruct(schema.thisptr))
|
|
||||||
|
|
||||||
cdef class MessageReader:
|
cdef class MessageReader:
|
||||||
cdef schema_cpp.MessageReader * thisptr
|
cdef schema_cpp.MessageReader * thisptr
|
||||||
@@ -363,6 +382,8 @@ cdef class MessageReader:
|
|||||||
return _CodeGeneratorRequestReader().init(self.thisptr.getRootCodeGeneratorRequest())
|
return _CodeGeneratorRequestReader().init(self.thisptr.getRootCodeGeneratorRequest())
|
||||||
cpdef getRootDynamicStruct(self, StructSchema schema):
|
cpdef getRootDynamicStruct(self, StructSchema schema):
|
||||||
return _DynamicStructReader().init(self.thisptr.getRootDynamicStruct(schema.thisptr))
|
return _DynamicStructReader().init(self.thisptr.getRootDynamicStruct(schema.thisptr))
|
||||||
|
cpdef getRoot(self, StructSchema schema):
|
||||||
|
return _DynamicStructReader().init(self.thisptr.getRootDynamicStruct(schema.thisptr))
|
||||||
|
|
||||||
cdef class StreamFdMessageReader(MessageReader):
|
cdef class StreamFdMessageReader(MessageReader):
|
||||||
def __cinit__(self, int fd):
|
def __cinit__(self, int fd):
|
||||||
@@ -375,4 +396,78 @@ cdef class PackedFdMessageReader(MessageReader):
|
|||||||
def writeMessageToFd(int fd, MessageBuilder m):
|
def writeMessageToFd(int fd, MessageBuilder m):
|
||||||
schema_cpp.writeMessageToFd(fd, deref(m.thisptr))
|
schema_cpp.writeMessageToFd(fd, deref(m.thisptr))
|
||||||
def writePackedMessageToFd(int fd, MessageBuilder m):
|
def writePackedMessageToFd(int fd, MessageBuilder m):
|
||||||
schema_cpp.writePackedMessageToFd(fd, deref(m.thisptr))
|
schema_cpp.writePackedMessageToFd(fd, deref(m.thisptr))
|
||||||
|
|
||||||
|
def capitalize(s):
|
||||||
|
if len(s) < 2:
|
||||||
|
return s
|
||||||
|
return s[0].upper() + s[1:]
|
||||||
|
def upper_and_under(s):
|
||||||
|
if len(s) < 2:
|
||||||
|
return s
|
||||||
|
ret = [s[0]]
|
||||||
|
for letter in s[1:]:
|
||||||
|
if letter.isupper():
|
||||||
|
ret.append('_')
|
||||||
|
ret.append(letter)
|
||||||
|
return ''.join(ret).upper()
|
||||||
|
|
||||||
|
def make_enum(enum_name, *sequential, **named):
|
||||||
|
enums = dict(zip(sequential, range(len(sequential))), **named)
|
||||||
|
reverse = dict((value, key) for key, value in enums.iteritems())
|
||||||
|
enums['reverse_mapping'] = reverse
|
||||||
|
return type(enum_name, (), enums)
|
||||||
|
|
||||||
|
from types import ModuleType
|
||||||
|
import re
|
||||||
|
import schema
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def _load(m, n, loader, name = None, isUnion = False):
|
||||||
|
if name is None:
|
||||||
|
name = n.displayName
|
||||||
|
local_m = m
|
||||||
|
for sub_name in re.split('[:.]', name):
|
||||||
|
new_m = local_m.__dict__.get(sub_name, ModuleType(sub_name))
|
||||||
|
local_m.__dict__[sub_name] = new_m
|
||||||
|
local_m = new_m
|
||||||
|
for nestedNode in n.nestedNodes:
|
||||||
|
s = loader.get(nestedNode.id)
|
||||||
|
_load(m, s.getProto(), loader, name + ':' + nestedNode.name)
|
||||||
|
body = n.body
|
||||||
|
which = body.which()
|
||||||
|
if which == schema.Node.Body.Which.enumNode:
|
||||||
|
enum = body.enumNode
|
||||||
|
local_m.Which = make_enum(name+':Which', **{upper_and_under(e.name) : e.codeOrder for e in enum.enumerants})
|
||||||
|
elif which == schema.Node.Body.Which.structNode:
|
||||||
|
struct = body.structNode
|
||||||
|
for member in struct.members:
|
||||||
|
if member.body.which() == schema.StructNode.Member.Body.Which.unionMember:
|
||||||
|
sub_name = capitalize(member.name)
|
||||||
|
new_m = local_m.__dict__.get(sub_name, ModuleType(sub_name))
|
||||||
|
local_m.__dict__[sub_name] = new_m
|
||||||
|
new_m.Which = make_enum(sub_name+':Which', **{upper_and_under(e.name) : e.ordinal for e in struct.members})
|
||||||
|
return local_m
|
||||||
|
|
||||||
|
def load(file_name, cat_path='/bin/cat'):
|
||||||
|
p = subprocess.Popen(['capnpc', '-o'+cat_path, file_name], stdout=subprocess.PIPE)
|
||||||
|
ret = p.wait()
|
||||||
|
if ret != 0:
|
||||||
|
raise RuntimeError("capnpc failed for some reason")
|
||||||
|
r = schema.StreamFdMessageReader(p.stdout.fileno())
|
||||||
|
c = r.getRootCodeGeneratorRequest()
|
||||||
|
m = ModuleType(file_name)
|
||||||
|
l = SchemaLoader()
|
||||||
|
m._loader = l
|
||||||
|
for node in c.nodes:
|
||||||
|
s = l.load(node)
|
||||||
|
for node in c.nodes:
|
||||||
|
s = l.load(node)
|
||||||
|
local_m = _load(m, node, l)
|
||||||
|
try:
|
||||||
|
s = s.asStruct()
|
||||||
|
local_m.Schema = s
|
||||||
|
except: pass
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# distutils: language = c++
|
# distutils: language = c++
|
||||||
# distutils: extra_compile_args = --std=c++11
|
# distutils: extra_compile_args = --std=c++11
|
||||||
# distutils: libraries = capnp
|
# distutils: libraries = capnp
|
||||||
from schema_cpp cimport Node, Data, StructNode
|
from schema_cpp cimport Node, Data, StructNode, EnumNode
|
||||||
|
|
||||||
from libc.stdint cimport *
|
from libc.stdint cimport *
|
||||||
ctypedef unsigned int uint
|
ctypedef unsigned int uint
|
||||||
@@ -14,16 +14,54 @@ cdef extern from "kj/common.h" namespace "::kj":
|
|||||||
cdef extern from "capnp/schema.h" namespace "::capnp":
|
cdef extern from "capnp/schema.h" namespace "::capnp":
|
||||||
cdef cppclass Schema:
|
cdef cppclass Schema:
|
||||||
Node.Reader getProto()
|
Node.Reader getProto()
|
||||||
StructSchema asStruct()
|
StructSchema asStruct() except +
|
||||||
|
EnumSchema asEnum() except +
|
||||||
|
Schema getDependency(uint64_t id) except +
|
||||||
|
#InterfaceSchema asInterface() const;
|
||||||
|
|
||||||
|
cdef cppclass MemberForward"::capnp::StructSchema::Member":
|
||||||
|
pass
|
||||||
|
|
||||||
cdef cppclass StructSchema(Schema):
|
cdef cppclass StructSchema(Schema):
|
||||||
|
cppclass MemberList:
|
||||||
|
uint size()
|
||||||
|
MemberForward operator[](uint index)
|
||||||
|
|
||||||
|
cppclass Union:
|
||||||
|
StructNode.Union.Reader getProto()
|
||||||
|
MemberList getMembers()
|
||||||
|
MemberForward getMemberByName(char * name)
|
||||||
|
|
||||||
cppclass Member:
|
cppclass Member:
|
||||||
StructNode.Member.Reader getProto()
|
StructNode.Member.Reader getProto()
|
||||||
StructNode.Reader getProto()
|
StructSchema getContainingStruct()
|
||||||
|
uint getIndex()
|
||||||
|
MemberList getMembers()
|
||||||
|
Union asUnion() except +
|
||||||
|
|
||||||
|
Node.Reader getProto()
|
||||||
|
MemberList getMembers()
|
||||||
|
Member getMemberByName(char * name)
|
||||||
|
|
||||||
|
cdef cppclass EnumSchema:
|
||||||
|
cppclass Enumerant:
|
||||||
|
EnumNode.Enumerant.Reader getProto()
|
||||||
|
EnumSchema getContainingEnum()
|
||||||
|
uint16_t getOrdinal()
|
||||||
|
|
||||||
|
cppclass EnumerantList:
|
||||||
|
uint size()
|
||||||
|
Enumerant operator[](uint index)
|
||||||
|
|
||||||
|
EnumerantList getEnumerants()
|
||||||
|
Enumerant getEnumerantByName(char * name)
|
||||||
|
Node.Reader getProto()
|
||||||
|
|
||||||
cdef extern from "capnp/schema-loader.h" namespace "::capnp":
|
cdef extern from "capnp/schema-loader.h" namespace "::capnp":
|
||||||
cdef cppclass SchemaLoader:
|
cdef cppclass SchemaLoader:
|
||||||
SchemaLoader()
|
SchemaLoader()
|
||||||
Schema load(Node.Reader &) except +
|
Schema load(Node.Reader &) except +
|
||||||
|
Schema get(uint64_t id) except +
|
||||||
|
|
||||||
cdef extern from "capnp/dynamic.h" namespace "::capnp":
|
cdef extern from "capnp/dynamic.h" namespace "::capnp":
|
||||||
cdef cppclass DynamicValueForward"::capnp::DynamicValue":
|
cdef cppclass DynamicValueForward"::capnp::DynamicValue":
|
||||||
|
|||||||
9
schema.pxd
Normal file
9
schema.pxd
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# schema.capnp.cpp.pyx
|
||||||
|
# distutils: language = c++
|
||||||
|
# distutils: extra_compile_args = --std=c++11
|
||||||
|
# distutils: libraries = capnp
|
||||||
|
from schema_cpp cimport Node as C_Node
|
||||||
|
cdef class _NodeReader:
|
||||||
|
cdef C_Node.Reader thisptr
|
||||||
|
cdef init(self, C_Node.Reader other)
|
||||||
|
|
||||||
@@ -1156,7 +1156,6 @@ cdef class _Node_NestedNodeBuilder:
|
|||||||
def __set__(self, val):
|
def __set__(self, val):
|
||||||
self.thisptr.setId(val)
|
self.thisptr.setId(val)
|
||||||
cdef class _NodeReader:
|
cdef class _NodeReader:
|
||||||
cdef C_Node.Reader thisptr
|
|
||||||
cdef init(self, C_Node.Reader other):
|
cdef init(self, C_Node.Reader other):
|
||||||
self.thisptr = other
|
self.thisptr = other
|
||||||
return self
|
return self
|
||||||
@@ -1733,6 +1732,7 @@ temp.Builder = _ValueBuilder
|
|||||||
temp = Value.Body = ModuleType('Value.Body')
|
temp = Value.Body = ModuleType('Value.Body')
|
||||||
temp.Reader = _Value_BodyReader
|
temp.Reader = _Value_BodyReader
|
||||||
temp.Builder = _Value_BodyBuilder
|
temp.Builder = _Value_BodyBuilder
|
||||||
|
temp.Which = _Value_Body_Which
|
||||||
|
|
||||||
temp = ConstNode = ModuleType('ConstNode')
|
temp = ConstNode = ModuleType('ConstNode')
|
||||||
temp.Reader = _ConstNodeReader
|
temp.Reader = _ConstNodeReader
|
||||||
@@ -1745,6 +1745,7 @@ temp.Builder = _TypeBuilder
|
|||||||
temp = Type.Body = ModuleType('Type.Body')
|
temp = Type.Body = ModuleType('Type.Body')
|
||||||
temp.Reader = _Type_BodyReader
|
temp.Reader = _Type_BodyReader
|
||||||
temp.Builder = _Type_BodyBuilder
|
temp.Builder = _Type_BodyBuilder
|
||||||
|
temp.Which = _Type_Body_Which
|
||||||
|
|
||||||
temp = FileNode = ModuleType('FileNode')
|
temp = FileNode = ModuleType('FileNode')
|
||||||
temp.Reader = _FileNodeReader
|
temp.Reader = _FileNodeReader
|
||||||
@@ -1761,6 +1762,7 @@ temp.Builder = _NodeBuilder
|
|||||||
temp = Node.Body = ModuleType('Node.Body')
|
temp = Node.Body = ModuleType('Node.Body')
|
||||||
temp.Reader = _Node_BodyReader
|
temp.Reader = _Node_BodyReader
|
||||||
temp.Builder = _Node_BodyBuilder
|
temp.Builder = _Node_BodyBuilder
|
||||||
|
temp.Which = _Node_Body_Which
|
||||||
|
|
||||||
temp = Node.NestedNode = ModuleType('Node.NestedNode')
|
temp = Node.NestedNode = ModuleType('Node.NestedNode')
|
||||||
temp.Reader = _Node_NestedNodeReader
|
temp.Reader = _Node_NestedNodeReader
|
||||||
@@ -1793,6 +1795,7 @@ temp.Builder = _StructNode_MemberBuilder
|
|||||||
temp = StructNode.Member.Body = ModuleType('StructNode.Member.Body')
|
temp = StructNode.Member.Body = ModuleType('StructNode.Member.Body')
|
||||||
temp.Reader = _StructNode_Member_BodyReader
|
temp.Reader = _StructNode_Member_BodyReader
|
||||||
temp.Builder = _StructNode_Member_BodyBuilder
|
temp.Builder = _StructNode_Member_BodyBuilder
|
||||||
|
temp.Which = _StructNode_Member_Body_Which
|
||||||
|
|
||||||
temp = StructNode.Field = ModuleType('StructNode.Field')
|
temp = StructNode.Field = ModuleType('StructNode.Field')
|
||||||
temp.Reader = _StructNode_FieldReader
|
temp.Reader = _StructNode_FieldReader
|
||||||
@@ -1802,3 +1805,4 @@ temp = Annotation = ModuleType('Annotation')
|
|||||||
temp.Reader = _AnnotationReader
|
temp.Reader = _AnnotationReader
|
||||||
temp.Builder = _AnnotationBuilder
|
temp.Builder = _AnnotationBuilder
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user