2013-06-26 23:01:37 -07:00
# capnp.pyx
# distutils: language = c++
2013-07-07 03:10:38 -07:00
# distutils: extra_compile_args = --std=c++11 -fpermissive
2013-08-13 22:21:38 -07:00
# distutils: libraries = capnpc
2013-07-07 03:10:38 -07:00
# cython: c_string_type = str
# cython: c_string_encoding = default
2013-08-18 21:48:49 -07:00
# cython: embedsignature = True
2013-06-26 23:01:37 -07:00
2013-06-28 01:04:01 -07:00
cimport cython
2013-06-26 23:01:37 -07:00
cimport capnp_cpp as capnp
cimport schema_cpp
2013-08-26 15:07:13 -07:00
from capnp_cpp cimport Schema as C_Schema , StructSchema as C_StructSchema , DynamicStruct as C_DynamicStruct , DynamicValue as C_DynamicValue , Type as C_Type , DynamicList as C_DynamicList , fixMaybe , SchemaParser as C_SchemaParser , ParsedSchema as C_ParsedSchema , VOID , ArrayPtr , StringPtr , DynamicOrphan as C_DynamicOrphan
2013-07-06 16:53:00 -07:00
2013-08-22 09:18:29 -07:00
from schema_cpp cimport Node as C_Node , EnumNode as C_EnumNode
2013-06-26 23:01:37 -07:00
from cython.operator cimport dereference as deref
from libc.stdint cimport *
ctypedef unsigned int uint
ctypedef uint8_t UInt8
ctypedef uint16_t UInt16
ctypedef uint32_t UInt32
ctypedef uint64_t UInt64
ctypedef int8_t Int8
ctypedef int16_t Int16
ctypedef int32_t Int32
ctypedef int64_t Int64
ctypedef char * Object
ctypedef bint Bool
ctypedef float Float32
ctypedef double Float64
2013-08-13 23:00:43 -07:00
from libc.stdlib cimport malloc , free
2013-06-26 23:01:37 -07:00
2013-06-28 01:04:01 -07:00
ctypedef fused valid_values :
int
long
float
double
bint
2013-07-06 16:53:00 -07:00
cython . p_char
2013-06-28 01:04:01 -07:00
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 )
_Type = _make_enum ( ' DynamicValue.Type ' ,
UNKNOWN = capnp . TYPE_UNKNOWN ,
VOID = capnp . TYPE_VOID ,
BOOL = capnp . TYPE_BOOL ,
INT = capnp . TYPE_INT ,
UINT = capnp . TYPE_UINT ,
FLOAT = capnp . TYPE_FLOAT ,
TEXT = capnp . TYPE_TEXT ,
DATA = capnp . TYPE_DATA ,
LIST = capnp . TYPE_LIST ,
ENUM = capnp . TYPE_ENUM ,
STRUCT = capnp . TYPE_STRUCT ,
INTERFACE = capnp . TYPE_INTERFACE ,
OBJECT = capnp . TYPE_OBJECT )
2013-08-26 14:45:15 -07:00
# Templated classes are weird in cython. I couldn't put it in a pxd header for some reason
2013-07-06 18:51:04 -07:00
cdef extern from " capnp/list.h " namespace " ::capnp " :
2013-06-26 23:01:37 -07:00
cdef cppclass List [T ]:
cppclass Reader :
T operator [ ] ( uint ) except + ValueError
uint size ( )
cppclass Builder :
T operator [ ] ( uint ) except + ValueError
uint size ( )
2013-08-26 14:45:15 -07:00
cdef extern from " <utility> " namespace " std " :
C_DynamicOrphan moveOrphan " std::move " ( C_DynamicOrphan & )
2013-08-10 13:54:25 -07:00
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 ( )
2013-08-13 22:21:38 -07:00
property nestedNodes :
def __get__ ( self ) :
return _List_NestedNode_Reader ( ) . _init ( self . thisptr . getNestedNodes ( ) )
2013-08-25 17:07:08 -07:00
property isStruct :
def __get__ ( self ) :
return self . thisptr . isStruct ( )
property isConst :
def __get__ ( self ) :
return self . thisptr . isConst ( )
2013-08-13 22:21:38 -07:00
cdef class _NestedNodeReader :
cdef C_Node .NestedNode .Reader thisptr
cdef init ( self , C_Node . NestedNode . Reader other ) :
self . thisptr = other
return self
property name :
def __get__ ( self ) :
return self . thisptr . getName ( ) . cStr ( )
property id :
def __get__ ( self ) :
return self . thisptr . getId ( )
2013-08-10 13:54:25 -07:00
2013-06-28 01:04:01 -07:00
cdef class _DynamicListReader :
cdef C_DynamicList .Reader thisptr
2013-07-07 18:48:55 -07:00
cdef public object _parent
cdef _init ( self , C_DynamicList . Reader other , object parent ) :
2013-06-28 01:04:01 -07:00
self . thisptr = other
2013-07-07 18:48:55 -07:00
self . _parent = parent
2013-06-28 01:04:01 -07:00
return self
2013-08-26 14:57:48 -07:00
def __getitem__ ( self , index ) :
2013-06-28 01:04:01 -07:00
size = self . thisptr . size ( )
if index > = size :
raise IndexError ( ' Out of bounds ' )
index = index % size
2013-08-26 14:57:48 -07:00
return toPythonReader ( self . thisptr [ index ] , self . _parent )
2013-06-28 01:04:01 -07:00
def __len__ ( self ) :
return self . thisptr . size ( )
cdef class _DynamicListBuilder :
cdef C_DynamicList .Builder thisptr
2013-07-07 18:48:55 -07:00
cdef public object _parent
cdef _init ( self , C_DynamicList . Builder other , object parent ) :
2013-06-28 01:04:01 -07:00
self . thisptr = other
2013-07-07 18:48:55 -07:00
self . _parent = parent
2013-06-28 01:04:01 -07:00
return self
2013-08-25 16:41:37 -07:00
cpdef _get ( self , index ) except + ValueError :
return toPython ( self . thisptr [ index ] , self . _parent )
2013-06-28 01:04:01 -07:00
def __getitem__ ( self , index ) :
size = self . thisptr . size ( )
if index > = size :
raise IndexError ( ' Out of bounds ' )
index = index % size
2013-08-25 16:41:37 -07:00
return self . _get ( index )
2013-06-28 01:04:01 -07:00
def _setitem ( self , index , valid_values value ) :
cdef C_DynamicValue .Reader temp = C_DynamicValue . Reader ( value )
self . thisptr . set ( index , temp )
def __setitem__ ( self , index , value ) :
size = self . thisptr . size ( )
if index > = size :
raise IndexError ( ' Out of bounds ' )
index = index % size
self . _setitem ( index , value )
def __len__ ( self ) :
return self . thisptr . size ( )
2013-08-13 22:21:38 -07:00
cdef class _List_NestedNode_Reader :
cdef List [C_Node .NestedNode ].Reader thisptr
cdef _init ( self , List [ C_Node . NestedNode ] . Reader other ) :
self . thisptr = other
return self
2013-08-13 23:04:03 -07:00
2013-08-13 22:21:38 -07:00
def __getitem__ ( self , index ) :
size = self . thisptr . size ( )
if index > = size :
raise IndexError ( ' Out of bounds ' )
index = index % size
return _NestedNodeReader ( ) . init ( < C_Node . NestedNode . Reader > self . thisptr [ index ] )
def __len__ ( self ) :
return self . thisptr . size ( )
2013-08-26 14:57:48 -07:00
cdef toPythonReader ( C_DynamicValue . Reader self , object parent ) :
cdef int type = self . getType ( )
if type == capnp . TYPE_BOOL :
return self . asBool ( )
elif type == capnp . TYPE_INT :
return self . asInt ( )
elif type == capnp . TYPE_UINT :
return self . asUint ( )
elif type == capnp . TYPE_FLOAT :
return self . asDouble ( )
elif type == capnp . TYPE_TEXT :
return self . asText ( ) [ : ]
elif type == capnp . TYPE_DATA :
temp = self . asData ( )
return ( < char * > temp . begin ( ) ) [ : temp . size ( ) ]
elif type == capnp . TYPE_LIST :
return list ( _DynamicListReader ( ) . _init ( self . asList ( ) , parent ) )
elif type == capnp . TYPE_STRUCT :
return _DynamicStructReader ( ) . _init ( self . asStruct ( ) , parent )
elif type == capnp . TYPE_ENUM :
return fixMaybe ( self . asEnum ( ) . getEnumerant ( ) ) . getProto ( ) . getName ( ) . cStr ( )
elif type == capnp . TYPE_VOID :
return None
elif type == capnp . TYPE_UNKOWN :
raise ValueError ( " Cannot convert type to Python. Type is unknown by capnproto library " )
else :
raise ValueError ( " Cannot convert type to Python. Type is unhandled by capnproto library " )
2013-06-28 01:04:01 -07:00
2013-08-25 16:41:37 -07:00
cdef toPython ( C_DynamicValue . Builder self , object parent ) :
2013-07-06 23:10:51 -07:00
cdef int type = self . getType ( )
if type == capnp . TYPE_BOOL :
return self . asBool ( )
elif type == capnp . TYPE_INT :
return self . asInt ( )
elif type == capnp . TYPE_UINT :
return self . asUint ( )
elif type == capnp . TYPE_FLOAT :
return self . asDouble ( )
elif type == capnp . TYPE_TEXT :
return self . asText ( ) [ : ]
elif type == capnp . TYPE_DATA :
temp = self . asData ( )
return ( < char * > temp . begin ( ) ) [ : temp . size ( ) ]
elif type == capnp . TYPE_LIST :
2013-07-07 18:48:55 -07:00
return list ( _DynamicListBuilder ( ) . _init ( self . asList ( ) , parent ) )
2013-07-06 23:10:51 -07:00
elif type == capnp . TYPE_STRUCT :
2013-07-07 18:48:55 -07:00
return _DynamicStructBuilder ( ) . _init ( self . asStruct ( ) , parent )
2013-07-06 23:10:51 -07:00
elif type == capnp . TYPE_ENUM :
return fixMaybe ( self . asEnum ( ) . getEnumerant ( ) ) . getProto ( ) . getName ( ) . cStr ( )
2013-06-28 01:04:01 -07:00
elif type == capnp . TYPE_VOID :
return None
elif type == capnp . TYPE_UNKOWN :
raise ValueError ( " Cannot convert type to Python. Type is unknown by capnproto library " )
else :
raise ValueError ( " Cannot convert type to Python. Type is unhandled by capnproto library " )
2013-06-26 23:01:37 -07:00
cdef class _DynamicStructReader :
cdef C_DynamicStruct .Reader thisptr
2013-07-07 18:48:55 -07:00
cdef public object _parent
cdef _init ( self , C_DynamicStruct . Reader other , object parent ) :
2013-06-26 23:01:37 -07:00
self . thisptr = other
2013-07-07 18:48:55 -07:00
self . _parent = parent
2013-06-26 23:01:37 -07:00
return self
2013-07-07 18:48:55 -07:00
2013-06-28 01:04:01 -07:00
def __getattr__ ( self , field ) :
2013-08-26 14:57:48 -07:00
return toPythonReader ( self . thisptr . get ( field ) , self . _parent )
2013-06-28 01:04:01 -07:00
def _has ( self , field ) :
return self . thisptr . has ( field )
2013-08-15 15:44:54 -07:00
cpdef which ( self ) :
2013-08-22 09:18:29 -07:00
return fixMaybe ( self . thisptr . which ( ) ) . getProto ( ) . getName ( ) . cStr ( )
2013-08-15 15:44:54 -07:00
2013-06-28 01:04:01 -07:00
cdef class _DynamicStructBuilder :
cdef C_DynamicStruct .Builder thisptr
2013-07-07 18:48:55 -07:00
cdef public object _parent
cdef _init ( self , C_DynamicStruct . Builder other , object parent ) :
2013-06-28 01:04:01 -07:00
self . thisptr = other
2013-07-07 18:48:55 -07:00
self . _parent = parent
2013-06-28 01:04:01 -07:00
return self
2013-08-26 16:16:58 -07:00
cdef _get ( self , field ) except + ValueError :
2013-07-07 18:48:55 -07:00
return toPython ( self . thisptr . get ( field ) , self . _parent )
2013-06-28 01:04:01 -07:00
2013-08-25 16:41:37 -07:00
def __getattr__ ( self , field ) :
return self . _get ( field )
2013-07-06 16:53:00 -07:00
cdef _setattrInt ( self , field , 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 )
2013-06-28 01:04:01 -07:00
self . thisptr . set ( field , temp )
2013-07-06 23:10:51 -07:00
cdef _setattrVoid ( self , field ) :
cdef C_DynamicValue .Reader temp = C_DynamicValue . Reader ( VOID )
self . thisptr . set ( field , temp )
2013-06-28 01:04:01 -07:00
def __setattr__ ( self , field , value ) :
2013-07-06 16:53:00 -07:00
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 )
2013-07-07 03:10:38 -07:00
elif value_type is str :
2013-07-06 16:53:00 -07:00
self . _setattrString ( field , value )
2013-07-06 23:10:51 -07:00
elif value is None :
self . _setattrVoid ( field )
2013-07-06 16:53:00 -07:00
else :
raise ValueError ( " Non primitive type " )
2013-06-28 01:04:01 -07:00
def _has ( self , field ) :
2013-06-26 23:01:37 -07:00
return self . thisptr . has ( field )
2013-07-06 23:10:51 -07:00
cpdef init ( self , field , size = None ) except + ValueError :
if size is None :
2013-08-25 16:41:37 -07:00
return toPython ( self . thisptr . init ( field ) , self . _parent )
2013-07-06 23:10:51 -07:00
else :
2013-08-25 16:41:37 -07:00
return toPython ( self . thisptr . init ( field , size ) , self . _parent )
2013-07-06 23:10:51 -07:00
2013-08-26 14:57:48 -07:00
cpdef which ( self ) :
return fixMaybe ( self . thisptr . which ( ) ) . getProto ( ) . getName ( ) . cStr ( )
2013-06-26 23:01:37 -07:00
2013-08-26 14:45:15 -07:00
cdef class _DynamicOrphan :
cdef C_DynamicOrphan thisptr
cdef public object _parent
cdef _init ( self , C_DynamicOrphan other , object parent ) :
self . thisptr = moveOrphan ( other )
self . _parent = parent
return self
2013-08-26 15:07:13 -07:00
cdef class _Schema :
2013-06-26 23:01:37 -07:00
cdef C_Schema thisptr
2013-07-06 23:10:51 -07:00
cdef _init ( self , C_Schema other ) :
2013-06-26 23:01:37 -07:00
self . thisptr = other
return self
2013-08-25 17:07:08 -07:00
cpdef asConstValue ( self ) :
2013-08-26 14:57:48 -07:00
return toPythonReader ( < C_DynamicValue . Reader > self . thisptr . asConst ( ) , self )
2013-08-25 17:07:08 -07:00
2013-06-26 23:01:37 -07:00
cpdef asStruct ( self ) :
2013-08-26 15:07:13 -07:00
return _StructSchema ( ) . _init ( self . thisptr . asStruct ( ) )
2013-06-26 23:01:37 -07:00
2013-07-06 16:53:00 -07:00
cpdef getDependency ( self , id ) :
2013-08-26 15:07:13 -07:00
return _Schema ( ) . _init ( self . thisptr . getDependency ( id ) )
2013-07-06 16:53:00 -07:00
cpdef getProto ( self ) :
return _NodeReader ( ) . init ( self . thisptr . getProto ( ) )
2013-08-26 15:07:13 -07:00
cdef class _StructSchema :
2013-06-26 23:01:37 -07:00
cdef C_StructSchema thisptr
2013-07-06 23:10:51 -07:00
cdef _init ( self , C_StructSchema other ) :
2013-06-26 23:01:37 -07:00
self . thisptr = other
return self
2013-08-26 15:07:13 -07:00
cdef class _ParsedSchema :
2013-08-13 22:21:38 -07:00
cdef C_ParsedSchema thisptr
cdef _init ( self , C_ParsedSchema other ) :
self . thisptr = other
return self
2013-08-25 17:07:08 -07:00
cpdef asConstValue ( self ) :
2013-08-26 14:57:48 -07:00
return toPythonReader ( < C_DynamicValue . Reader > self . thisptr . asConst ( ) , self )
2013-08-25 17:07:08 -07:00
2013-08-13 22:21:38 -07:00
cpdef asStruct ( self ) :
2013-08-26 15:07:13 -07:00
return _StructSchema ( ) . _init ( self . thisptr . asStruct ( ) )
2013-08-13 22:21:38 -07:00
cpdef getDependency ( self , id ) :
2013-08-26 15:07:13 -07:00
return _Schema ( ) . _init ( self . thisptr . getDependency ( id ) )
2013-08-13 22:21:38 -07:00
cpdef getProto ( self ) :
return _NodeReader ( ) . init ( self . thisptr . getProto ( ) )
cpdef getNested ( self , name ) :
2013-08-26 15:07:13 -07:00
return _ParsedSchema ( ) . _init ( self . thisptr . getNested ( name ) )
2013-08-13 22:21:38 -07:00
2013-08-26 15:07:13 -07:00
cdef class _SchemaParser :
2013-08-13 22:21:38 -07:00
cdef C_SchemaParser * thisptr
def __cinit__ ( self ) :
self . thisptr = new C_SchemaParser ( )
def __dealloc__ ( self ) :
del self . thisptr
2013-08-13 23:00:43 -07:00
def parseDiskFile ( self , displayName , diskPath , imports ) :
cdef StringPtr * importArray = < StringPtr * > malloc ( sizeof ( StringPtr ) * len ( imports ) )
for i in range ( len ( imports ) ) :
importArray [ i ] = StringPtr ( imports [ i ] )
cdef ArrayPtr [StringPtr ] importsPtr = ArrayPtr [ StringPtr ] ( importArray , < size_t > len ( imports ) )
2013-08-13 22:21:38 -07:00
2013-08-26 15:07:13 -07:00
ret = _ParsedSchema ( )
2013-08-13 23:00:43 -07:00
ret . _init ( self . thisptr . parseDiskFile ( displayName , diskPath , importsPtr ) )
free ( importArray )
2013-08-13 22:21:38 -07:00
return ret
2013-06-26 23:01:37 -07:00
cdef class MessageBuilder :
2013-08-26 16:16:58 -07:00
""" An abstract base class for building Cap ' n Proto messages
. . warning : : Don ' t ever instantiate this class directly. It is only used for inheritance.
"""
2013-06-26 23:01:37 -07:00
cdef schema_cpp .MessageBuilder * thisptr
def __dealloc__ ( self ) :
del self . thisptr
2013-08-26 16:16:58 -07:00
2013-07-07 18:48:55 -07:00
def __init__ ( self ) :
raise NotImplementedError ( " This is an abstract base class. You should use MallocMessageBuilder instead " )
2013-07-06 23:10:51 -07:00
cpdef initRoot ( self , schema ) :
2013-08-26 16:16:58 -07:00
""" A method for instantiating Cap ' n Proto structs
You will need to pass in a schema to specify which struct to
instantiate . Schemas are available in a loaded Cap ' n Proto module::
addressbook = capnp . load ( ' addressbook.capnp ' )
. . .
person = message . initRoot ( addressbook . Person )
: type schema : Schema
: param schema : A Cap ' n proto schema specifying which struct to instantiate
: rtype : : class : `_DynamicStructBuilder`
: return : An object where you will set all the members
"""
2013-08-26 15:07:13 -07:00
cdef _StructSchema s
2013-07-06 23:10:51 -07:00
if hasattr ( schema , ' Schema ' ) :
s = schema . Schema
else :
s = schema
2013-07-07 18:48:55 -07:00
return _DynamicStructBuilder ( ) . _init ( self . thisptr . initRootDynamicStruct ( s . thisptr ) , self )
2013-08-26 14:57:48 -07:00
2013-07-06 23:10:51 -07:00
cpdef getRoot ( self , schema ) :
2013-08-26 16:16:58 -07:00
""" A method for instantiating Cap ' n Proto structs, from an already pre-written buffers
Don ' t use this method unless you know what you ' re doing . You probably
want to use initRoot instead : :
addressbook = capnp . load ( ' addressbook.capnp ' )
. . .
person = message . initRoot ( addressbook . Person )
. . .
person = message . getRoot ( addressbook . Person )
: type schema : Schema
: param schema : A Cap ' n proto schema specifying which struct to instantiate
: rtype : : class : `_DynamicStructBuilder`
: return : An object where you will set all the members
"""
2013-08-26 15:07:13 -07:00
cdef _StructSchema s
2013-07-06 23:10:51 -07:00
if hasattr ( schema , ' Schema ' ) :
s = schema . Schema
else :
s = schema
2013-07-07 18:48:55 -07:00
return _DynamicStructBuilder ( ) . _init ( self . thisptr . getRootDynamicStruct ( s . thisptr ) , self )
2013-06-26 23:01:37 -07:00
cdef class MallocMessageBuilder ( MessageBuilder ) :
2013-08-26 16:16:58 -07:00
""" The main class for building Cap ' n Proto messages
You will use this class to handle arena allocation of the Cap ' n Proto
messages . You also use this object when you ' re done assigning to Cap ' n
Proto objects , and wish to serialize them : :
addressbook = capnp . load ( ' addressbook.capnp ' )
message = capnp . MallocMessageBuilder ( )
person = message . initRoot ( addressbook . Person )
person . name = ' alice '
. . .
writeMessageToFd ( open ( ' out.txt ' , ' w ' ) . fileno ( ) , message )
"""
2013-06-26 23:01:37 -07:00
def __cinit__ ( self ) :
self . thisptr = new schema_cpp . MallocMessageBuilder ( )
2013-08-26 16:16:58 -07:00
2013-07-07 18:48:55 -07:00
def __init__ ( self ) :
pass
2013-06-26 23:01:37 -07:00
2013-08-26 15:07:13 -07:00
cdef class _MessageReader :
2013-08-26 16:16:58 -07:00
""" An abstract base class for reading Cap ' n Proto messages
. . warning : : Don ' t ever instantiate this class. It is only used for inheritance.
"""
2013-06-26 23:01:37 -07:00
cdef schema_cpp .MessageReader * thisptr
def __dealloc__ ( self ) :
del self . thisptr
2013-07-07 18:48:55 -07:00
def __init__ ( self ) :
raise NotImplementedError ( " This is an abstract base class " )
2013-08-18 21:48:49 -07:00
cpdef _getRootNode ( self ) :
2013-06-26 23:01:37 -07:00
return _NodeReader ( ) . init ( self . thisptr . getRootNode ( ) )
2013-08-26 14:57:48 -07:00
2013-07-06 23:10:51 -07:00
cpdef getRoot ( self , schema ) :
2013-08-26 16:16:58 -07:00
""" A method for instantiating Cap ' n Proto structs
You will need to pass in a schema to specify which struct to
instantiate . Schemas are available in a loaded Cap ' n Proto module::
addressbook = capnp . load ( ' addressbook.capnp ' )
. . .
person = message . getRoot ( addressbook . Person )
: type schema : Schema
: param schema : A Cap ' n proto schema specifying which struct to instantiate
: rtype : : class : `_DynamicStructReader`
: return : An object with all the data of the read Cap ' n Proto message.
Access members with . syntax .
"""
2013-08-26 15:07:13 -07:00
cdef _StructSchema s
2013-07-06 23:10:51 -07:00
if hasattr ( schema , ' Schema ' ) :
s = schema . Schema
else :
s = schema
2013-07-07 18:48:55 -07:00
return _DynamicStructReader ( ) . _init ( self . thisptr . getRootDynamicStruct ( s . thisptr ) , self )
2013-06-26 23:01:37 -07:00
2013-08-26 15:07:13 -07:00
cdef class StreamFdMessageReader ( _MessageReader ) :
2013-08-26 16:16:58 -07:00
""" Read a Cap ' n Proto message from a file descriptor
You use this class to for reading message ( s ) from a file . It ' s analagous to the inverse of writeMessageToFd and :class:`MessageBuilder`, but in one class.::
message = StreamFdMessageReader ( open ( ' out.txt ' ) . fileno ( ) )
person = message . getRoot ( addressbook . Person )
print person . name
: Parameters : - fd ( `int` ) - A file descriptor
"""
2013-07-07 18:48:55 -07:00
def __init__ ( self , int fd ) :
2013-06-26 23:01:37 -07:00
self . thisptr = new schema_cpp . StreamFdMessageReader ( fd )
2013-08-26 15:07:13 -07:00
cdef class PackedFdMessageReader ( _MessageReader ) :
2013-08-26 16:16:58 -07:00
""" Read a Cap ' n Proto message from a file descriptor in a packed manner
You use this class to for reading message ( s ) from a file . It ' s analagous to the inverse of writePackedMessageToFd and :class:`MessageBuilder`, but in one class.::
message = StreamFdMessageReader ( open ( ' out.txt ' ) . fileno ( ) )
person = message . getRoot ( addressbook . Person )
print person . name
: Parameters : - fd ( `int` ) - A file descriptor
"""
2013-07-07 18:48:55 -07:00
def __init__ ( self , int fd ) :
2013-06-26 23:01:37 -07:00
self . thisptr = new schema_cpp . PackedFdMessageReader ( fd )
2013-08-26 16:16:58 -07:00
def writeMessageToFd ( int fd , MessageBuilder message ) :
""" Serialize a Cap ' n Proto message to a file descriptor
You use this method to serialize your message to a file . Please note that
you must pass a file descriptor ( ie . an int ) , not a file object . Make sure
you use the proper reader to match this ( ie . don ' t use PackedFdMessageReader)::
message = capnp . MallocMessageBuilder ( )
. . .
writeMessageToFd ( open ( ' out.txt ' , ' w ' ) . fileno ( ) , message )
. . .
StreamFdMessageReader ( open ( ' out.txt ' ) . fileno ( ) )
: type fd : int
: param fd : A file descriptor
: type message : : class : `MessageBuilder`
: param message : The Cap ' n Proto message to serialize
: rtype : void
"""
schema_cpp . writeMessageToFd ( fd , deref ( message . thisptr ) )
def writePackedMessageToFd ( int fd , MessageBuilder message ) :
""" Serialize a Cap ' n Proto message to a file descriptor in a packed manner
You use this method to serialize your message to a file . Please note that
you must pass a file descriptor ( ie . an int ) , not a file object . Also , note
the difference in names with writeMessageToFd . This method uses a different
serialization specification , and your reader will need to match . : :
message = capnp . MallocMessageBuilder ( )
. . .
writePackedMessageToFd ( open ( ' out.txt ' , ' w ' ) . fileno ( ) , message )
. . .
PackedFdMessageReader ( open ( ' out.txt ' ) . fileno ( ) )
: type fd : int
: param fd : A file descriptor
: type message : : class : `MessageBuilder`
: param message : The Cap ' n Proto message to serialize
2013-08-13 23:04:03 -07:00
2013-08-26 16:16:58 -07:00
: rtype : void
"""
schema_cpp . writePackedMessageToFd ( fd , deref ( message . thisptr ) )
2013-07-06 16:53:00 -07:00
2013-08-26 15:07:13 -07:00
from types import ModuleType as _ModuleType
import os as _os
2013-08-13 22:21:38 -07:00
2013-08-26 10:07:54 -07:00
def load ( file_name , display_name = None , imports = [ ] ) :
2013-08-26 16:16:58 -07:00
""" Load a Cap ' n Proto schema from a file
2013-08-13 22:21:38 -07:00
2013-08-26 10:07:54 -07:00
You will have to load a schema before you can begin doing anything
meaningful with this library . Loading a schema is much like Loading
2013-08-26 14:57:48 -07:00
a Python module ( and load even returns a `ModuleType` ) . Once it ' s been
2013-08-26 10:07:54 -07:00
loaded , you use it much like any other Module : :
2013-08-13 22:21:38 -07:00
2013-08-26 10:07:54 -07:00
addressbook = capnp . load ( ' addressbook.capnp ' )
print addressbook . qux # qux is a top level constant
# 123
message = capnp . MallocMessageBuilder ( )
person = message . initRoot ( addressbook . Person )
2013-08-13 22:21:38 -07:00
2013-08-26 10:07:54 -07:00
: type file_name : str
: param file_name : A relative or absolute path to a Cap ' n Proto schema
: type display_name : str
: param display_name : The name internally used by the Cap ' n Proto library
for the loaded schema . By default , it ' s just os.path.basename(file_name)
: type imports : list
: param imports : A list of str directories to add to the import path.
: rtype : ModuleType
: return : A module corresponding to the loaded schema . You can access
parsed schemas and constants with . syntax
: Raises : : exc : `exceptions.ValueError` if `file_name` doesn ' t exist
"""
def _load ( nodeSchema , module ) :
module . _nodeSchema = nodeSchema
nodeProto = nodeSchema . getProto ( )
module . _nodeProto = nodeProto
for node in nodeProto . nestedNodes :
2013-08-26 15:07:13 -07:00
local_module = _ModuleType ( node . name )
2013-08-26 10:07:54 -07:00
module . __dict__ [ node . name ] = local_module
schema = nodeSchema . getNested ( node . name )
proto = schema . getProto ( )
if proto . isStruct :
local_module . Schema = schema . asStruct ( )
elif proto . isConst :
module . __dict__ [ node . name ] = schema . asConstValue ( )
_load ( schema , local_module )
2013-08-13 22:21:38 -07:00
if display_name is None :
2013-08-26 15:07:13 -07:00
display_name = _os . path . basename ( file_name )
module = _ModuleType ( display_name )
parser = _SchemaParser ( )
2013-08-13 22:21:38 -07:00
module . _parser = parser
2013-08-13 23:00:43 -07:00
fileSchema = parser . parseDiskFile ( display_name , file_name , imports )
2013-08-13 22:21:38 -07:00
_load ( fileSchema , module )
2013-07-06 16:53:00 -07:00
2013-07-06 18:40:05 -07:00
return module