Skip to content

Instantly share code, notes, and snippets.

@magcius
Created August 11, 2009 18:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magcius/166043 to your computer and use it in GitHub Desktop.
Save magcius/166043 to your computer and use it in GitHub Desktop.
import struct
from pypy.translator.avm.util import serialize_u32 as u32
# ======================================
# Constants
# ======================================
# String types
TYPE_STRING_Utf8 = 0x01
# Number types
TYPE_NUMBER_Int = 0x03
TYPE_NUMBER_UInt = 0x04
TYPE_NUMBER_DOUBLE = 0x06
# Boolean types
TYPE_BOOLEAN_False = 0x0A
TYPE_BOOLEAN_True = 0x0B
# Object types
TYPE_OBJECT_Undefined = 0x00
TYPE_OBJECT_Null = 0x0C
# Namespace types
TYPE_NAMESPACE_PrivateNamespace = 0x05
TYPE_NAMESPACE_Namespace = 0x08
TYPE_NAMESPACE_PackageNamespace = 0x16
TYPE_NAMESPACE_PackageInternalNs = 0x17
TYPE_NAMESPACE_ProtectedNamespace = 0x18
TYPE_NAMESPACE_ExplicitNamespace = 0x19
TYPE_NAMESPACE_StaticProtectedNs = 0x1A
# Namespace Set types
TYPE_NAMESPACE_SET_NamespaceSet = 0x15
# Multiname types
TYPE_MULTINAME_QName = 0x07
TYPE_MULTINAME_QNameA = 0x0D
TYPE_MULTINAME_Multiname = 0x09
TYPE_MULTINAME_MultinameA = 0x0E
TYPE_MULTINAME_RtqName = 0x0F
TYPE_MULTINAME_RtqNameA = 0x10
TYPE_MULTINAME_RtqNameL = 0x11
TYPE_MULTINAME_RtqNameLA = 0x12
TYPE_MULTINAME_NameL = 0x13
TYPE_MULTINAME_NameLA = 0x14
TYPE_MULTINAME_MultinameL = 0x1B
TYPE_MULTINAME_MultinameLA = 0x1C
# ======================================
# Namespaces
# ======================================
class Namespace(object):
def __init__(self, kind, name):
self.kind = kind
self.name = name
self._name_index = None
def __eq__(self, other):
return self.name == other.name and self.kind == other.kind
def __ne__(self, other):
return self.name != other.name or self.kind != other.kind
def write_to_pool(self, pool):
self._name_index = pool.utf8_index(name)
def serialize(self):
assert self._name_index is not None, "Please call write_to_pool before serializing"
return chr(self.kind) + u32(self._name_index)
class NamespaceSet(object):
def __init__(self, *namespaces):
self.namespaces = namespaces
self._namespace_indices = None
def __len__(self):
return len(self.namespaces)
def __eq__(self, other):
return len(self) == len(other) and all(n1 == n2 for n1, n2 in zip(self.namespaces, other.namespaces))
def __ne__(self, other):
return len(self) != len(other) or any(n1 != n2 for n1, n2 in zip(self.namespaces, other.namespaces))
def write_to_pool(self, pool):
self._namespace_indices = [pool.namespace_index(ns) for ns in self.namespaces]
def serialize(self):
assert self._namespace_indices is not None, "Please call write_to_pool before serializing"
return u32(len(self.namespaces)) + ''.join(u32(index) for index in self_namespace_indices)
NO_NAMESPACE = Namespace(TYPE_NAMESPACE_Namespace, "")
ANY_NAMESPACE = Namespace(TYPE_NAMESPACE_Namespace, "*")
NO_NAMESPACE_SET = NamespaceSet()
# ======================================
# Multinames
# ======================================
class MultinameL(object):
KIND = TYPE_MULTINAME_MultinameL
def __init__(self, ns_set):
self.ns_set = ns_set
self._ns_set_index = None
def write_to_pool(self, pool):
self._ns_set_index = pool.nsset_index(self.ns_set)
def serialize(self):
assert self._ns_set_index is not None, "Please call write_to_pool before serializing"
return chr(self.KIND) + u32(self._ns_set_index)
class MultinameLA(MultinameL):
KIND = TYPE_MULTINAME_MultinameLA
class Multiname(MultinameL):
KIND = TYPE_MULTINAME_Multiname
def __init__(self, name, ns_set):
super(Multiname, self).__init__(ns_set)
self.name = name
self._name_index = None
def write_to_pool(self, pool):
super(Multiname, self).write_to_pool(pool)
self._name_index = pool.utf8_index(self.name)
def serialize(self):
assert self._name_index is not None, "Please call write_to_pool before serializing"
assert self._ns_set_index is not None, "Please call write_to_pool before serializing"
return chr(self.kind) + u32(self._name_index) + u32(self._ns_set_index)
class MultinameA(Multiname):
KIND = TYPE_MULTINAME_MultinameA
class QName(object):
KIND = TYPE_MULTINAME_QName
def __init__(self, name, ns):
self.name = name
self.ns = ns
self._name_index = None
self._ns_index = None
def write_to_pool(self, pool):
self._name_index = pool.utf8_index(self.name)
self._ns_index = pool.namespace_index(self.ns)
def serialize(self):
assert self._name_index is not None, "Please call write_to_pool before serializing"
assert self._ns_index is not None, "Please call write_to_pool before serializing"
return chr(self.kind) + u32(self._ns_index) + u32(self._name_index)
class QNameA(QName):
KIND = TYPE_MULTINAME_QNameA
class RtqNameL(object):
KIND = TYPE_MULTINAME_RtqNameL
def serialize(self):
return chr(self.kind)
class RtqNameLA(RtqNameL):
KIND = TYPE_MULTINAME_RtqNameLA
class RtqName(object)::
KIND = TYPE_MULTINAME_RtqName
def __init__(self, name):
self.name = name
self._name_index = None
def write_to_pool(self, pool):
self._name_index = pool.utf8_index(name)
def serialize(self):
assert self._name_index is not None, "Please call write_to_pool before serializing"
# ======================================
# Constant Pool
# ======================================
def constant_index_base(default, pool_name):
def fn(self, value):
if value == default:
return 0
pool = getattr(self, pool_name)
if value in pool:
return pool.index(value) + 1
else:
pool.append(value)
return len(pool)
return fn
class AbcConstantPool(object):
def __init__(self):
self.int_pool = []
self.uint_pool = []
self.double_pool = []
self.utf8_pool = []
self.namespace_pool = []
self.nsset_pool = []
self.multiname_pool = []
int_index = constant_index_base(0, "int_pool")
uint_index = constant_index_base(0, "uint_pool")
double_index = constant_index_base(float("nan"), "double_pool")
utf8_index = constant_index_base("", "utf8_pool")
namespace_index = constant_index_base(ANY_NAMESPACE, "namespace_pool")
nsset_index = constant_index_base(NO_NAMESPACE_SET, "nsset_pool")
def has_RTNS(self, index):
return self.multiname_pool[index].kind in (TYPE_MULTINAME_RtqName, TYPE_MULTINAME_RtqNameA, TYPE_MULTINAME_RtqNameL, TYPE_MULTINAME_RtqNameLA)
def has_RTName(self, index):
return self.multiname_pool[index].kind in (TYPE_MULTINAME_MultinameL, TYPE_MULTINAME_MultinameLA, TYPE_MULTINAME_RtqNameL, TYPE_MULTINAME_RtqNameLA)
def serialize(self):
def double(double):
return struct.pack("<d", double)
def utf8(string):
return u32(len(string)) + string
def serializable(item):
item.write_to_pool(self)
return item.serialize()
def write_pool(pool, fn):
return u32(len(pool)) + ''.join(fn(i) for i in pool)
buffer = ""
buffer += write_pool(self.int_pool, u32)
buffer += write_pool(self.uint_pool, u32)
buffer += write_pool(self.double_pool, double)
buffer += write_pool(self.utf8_pool, utf8)
buffer += write_pool(self.namespace_pool, serializable)
buffer += write_pool(self.nsset_pool, serializable)
buffer += write_pool(self.multiname_pool, serializable)
return buffer
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment