Package: cypyserialize
A pythonic semantic for describing binary data structures and associated
python objects.Installationpip install cypyserializeBasic UsageFor this first example we’re going to define a simple 2D point with the
attributesxandyrepresenting binary doubles.classPoint(cypyserialize.SerializableObject):"Basic point class"x=cypyserialize.double()y=cypyserialize.double()Object instances of thePointclass, which extends theSerializableObject, can be initialized in several different ways.
First, omitting any parameters the instance will be populated with
default values (here we haven’t specified defaults so 0.0 is assumed).
The attributes can be assigned values after initialization.>>>p=Point()# create default instance>>>list(p.items())[('x',None),('y',None)]>>>p.x=5000.0# set x>>>p.y=300.5# set y>>>list(p.items())[('x',5000.0),('y',300.5)]Alternately, the object can be initialized with our values. The
parameter order should match the order specified in the class attribute_field_order.>>>p=Point(5000.0,300.5)>>>list(p.items())[('x',5000.0),('y',300.5)]Or we can use the attribute names if we forgot the order.>>>p=Point(y=300.5,x=5000.0)>>>list(p.items())[('x',5000.0),('y',300.5)]Or mix the two (just remeber that after the first named parameter
subsequent parameters will have to be named as well).>>>p=Point(5000.0,y=300.5)>>>list(p.items())[('x',5000.0),('y',300.5)]To get the binary representation just call the class methodpack>>>p.pack()bytearray(b'\x00\x00\x00\x00\x00\x88\xb3@\x00\x00\x00\x00\x00\xc8r@')Lastly, we can initialize with a binary string.>>>p=Point(b'\x00\x00\x00\x00\x00\x88\xb3@\x00\x00\x00\x00\x00\xc8r@')>>>list(p.items())[('x',5000.0),('y',300.5)]Using SubstructuresWe’re going to reuse thePointclass to describe a rectangular
bounding box with two attributes, the northwest and southeast corners.classBoundingBox(cypyserialize.SerializableObject):northwest=Point()southeast=Point()Seriously, it’s that easy. Let’s initialize one of these.>>>bb=BoundingBox()>>>list(bb.items())[('northwest',<Pointobject>),('southeast',<Pointobject>)]Let’s try that again but with some points>>>bb=BoundingBox(Point(0.0,10.0),Point(15.0,0.0))>>>bb.northwest.y10.0>>>bb.southeast.x15.0OverloadingSubclasses of SerializableObject can be extended and overloaded. This
can be especially handy if you have a standard structure that you don’t
want to redefine.Here we’re going to make a simple datagram structure with a start and
end flag, a timestamp and some arbitrary body that we’ll overload in a
second.classGenericDatagram(cypyserialize.SerializableObject):STX=cypyserialize.uchar(value=0x02)timestamp=cypyserialize.uint()body=cypyserialize.none()ETX=cypyserialize.uchar(value=0x03)Now that we have generic datagram lets make it a wrapper on the
BoundingBox structure we defined earlier as an extension of the
GenericDatagram structure.classBoundingBoxDatagram(GenericDatagram):body=BoundingBox()That’s it. Lets create one of this. We’ll set the timestamp and get the
binary.>>>p=BoundingBoxDatagram()>>>p.timestamp=time.time()>>>p.body=BoundingBox(Point(0,10),Point(10,0))>>>p.items()[('STX',2),('timestamp',1398373100.412985),('body',<__main__.BoundingBoxobjectat0xb713f3c4>),('ETX',3)]>>>p.pack()'\x02...'Arrays of SubstructuresNow we’re going to reuse the point structure to describe a path as a
series of points with a description.classPath(cypyserialize.SerializableObject):# the pointspoints=cypyserialize.SerializableArray(Point(),count=cypyserialize.uint())countwith be the field type that is used to read and write the
number ofPoint()objects in the structure.Byte Order*Currently Unsupported*Byte order is always little endian at present.Custom Computed AttributesclassBetterBoundingBox(BoundingBox):def__init__(self):self.area=(self.southeast.x-self.northwest.x)*\(self.northwest.y-self.southeast.y)Note that we need to acceptargsandkargs, we don’t need to
call the superclassinitthough as it wasn’t defined on BoundingBox.Lets try it out.>>>bb=BetterBoundingBox(Point(0,10),Point(10,0))>>>printbb.area100