Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New as3 native types support #63

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions cpyamf/amf3.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ cdef class Decoder(codec.Decoder):
cdef int _readStatic(self, ClassDefinition class_def, dict obj) except -1
cdef int _readDynamic(self, ClassDefinition class_def, dict obj) except -1

cdef object readASDictionary(self)
cdef object readBytes(self)
cdef object readInteger(self, int signed=?)
cdef object readByteArray(self)
cdef object readDoubleVector(self)
cdef object readIntVector(self)
cdef object readObjectVector(self)
cdef object readProxy(self, obj)
cdef object readUintVector(self)
cdef object readVector(self, vector_class)


cdef class Encoder(codec.Encoder):
Expand All @@ -59,3 +65,5 @@ cdef class Encoder(codec.Encoder):

cdef int writeByteArray(self, object obj) except -1
cdef int writeProxy(self, obj) except -1
cdef int writeVector(self, object obj) except -1
cdef int writeASDictionary(self, object obj) except -1
115 changes: 115 additions & 0 deletions cpyamf/amf3.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ cdef char TYPE_ARRAY = '\x09'
cdef char TYPE_OBJECT = '\x0A'
cdef char TYPE_XMLSTRING = '\x0B'
cdef char TYPE_BYTEARRAY = '\x0C'
cdef char TYPE_INT_VECTOR = '\x0D'
cdef char TYPE_UINT_VECTOR = '\x0E'
cdef char TYPE_DOUBLE_VECTOR = '\x0F'
cdef char TYPE_OBJECT_VECTOR = '\x10'
cdef char TYPE_DICTIONARY = '\x11'

cdef unsigned int REFERENCE_BIT = 0x01
cdef char REF_CHAR = '\x01'
Expand All @@ -54,6 +59,12 @@ cdef int OBJECT_ENCODING_DYNAMIC = 0x02
cdef int OBJECT_ENCODING_PROXY = 0x03

cdef object ByteArrayType = amf3.ByteArray
cdef object BaseVectorType = amf3.BaseVector
cdef object IntVectorType = amf3.IntVector
cdef object UintVectorType = amf3.UintVector
cdef object DoubleVectorType = amf3.DoubleVector
cdef object ObjectVectorType = amf3.ObjectVector
cdef object ASDictionaryType = amf3.ASDictionary
cdef object DataInput = amf3.DataInput
cdef object DataOutput = amf3.DataOutput
cdef str empty_string = str('')
Expand Down Expand Up @@ -563,6 +574,62 @@ cdef class Decoder(codec.Decoder):
"""
return self.context.getObjectForProxy(obj)

cdef object readVector(self, vector_class):
"""
Reads a vector of a specific datatype.

@note: This is not supported in ActionScript 1.0, 2.0 or early
versions of 3.0.
"""
cdef int ref = _read_ref(self.stream)
cdef int i

if ref & REFERENCE_BIT == 0:
return self.context.getObject(ref >> 1)

cdef object obj = vector_class()
obj.fixed = self.stream.read_uchar()

if isinstance(obj, ObjectVectorType):
obj.classname = self.readString()

cdef int num_items = ref >> 1
for 0 <= i < num_items:
obj.append(obj.reader(self)())

return obj

cdef object readIntVector(self):
return self.readVector(IntVectorType)

cdef object readUintVector(self):
return self.readVector(UintVectorType)

cdef object readDoubleVector(self):
return self.readVector(DoubleVectorType)

cdef object readObjectVector(self):
return self.readVector(ObjectVectorType)

cdef object readASDictionary(self):
cdef int ref = _read_ref(self.stream)
cdef int i
assert ref & REFERENCE_BIT

ref >>= 1

result = ASDictionaryType()
weak_keys = self.stream.read_uchar()
assert weak_keys in [0x00, 0x01]
result.weak_keys = bool(weak_keys)

for 0 <= i < ref:
key = self.readElement()
value = self.readElement()
result[key] = value

return result

cdef object readConcreteElement(self, char t):
if t == TYPE_STRING:
return self.readString()
Expand Down Expand Up @@ -590,6 +657,16 @@ cdef class Decoder(codec.Decoder):
return self.readXML()
elif t == TYPE_XMLSTRING:
return self.readXML()
elif t == TYPE_INT_VECTOR:
return self.readIntVector()
elif t == TYPE_UINT_VECTOR:
return self.readUintVector()
elif t == TYPE_DOUBLE_VECTOR:
return self.readDoubleVector()
elif t == TYPE_OBJECT_VECTOR:
return self.readObjectVector()
elif t == TYPE_DICTIONARY:
return self.readASDictionary()

raise pyamf.DecodeError("Unsupported ActionScript type")

Expand Down Expand Up @@ -1030,12 +1107,50 @@ cdef class Encoder(codec.Encoder):

return self.writeObject(proxy, 1)

cdef int writeVector(self, object n) except -1:
cdef Py_ssize_t ref = self.context.getObjectReference(n)

self.writeType(ord(n.datatype))

if ref != -1:
_encode_integer(self.stream, ref << 1)
return 0

self.context.addObject(n)
_encode_integer(self.stream, (len(n) << 1) | REFERENCE_BIT)
self.stream.write_uchar(1 if n.fixed else 0)

if isinstance(n, ObjectVectorType):
self.serialiseString(n.classname)

for item in n:
n.writer(self)(item)

cdef int writeASDictionary(self, object n) except -1:
self.writeType(TYPE_DICTIONARY)
_encode_integer(self.stream, (len(n) << 1) | REFERENCE_BIT)
self.stream.write_uchar(1 if n.weak_keys else 0)

for key, value in n.iteritems():
self.writeElement(key)
self.writeElement(value)

cdef int handleBasicTypes(self, object element, object py_type) except -1:
cdef int ret = codec.Encoder.handleBasicTypes(self, element, py_type)

if ret == 1: # not handled
if py_type is ByteArrayType:
return self.writeByteArray(element)
elif py_type is IntVectorType:
return self.writeVector(element)
elif py_type is UintVectorType:
return self.writeVector(element)
elif py_type is DoubleVectorType:
return self.writeVector(element)
elif py_type is ObjectVectorType:
return self.writeVector(element)
elif py_type is ASDictionaryType:
return self.writeASDictionary(element)

return ret

Expand Down
Loading