Changeset 1110
- Timestamp:
- 03/06/08 19:04:49 (10 months ago)
- Location:
- pyamf/branches/cpyamf-225/pyamf
- Files:
-
- 2 copied
-
amf0.pyx (copied) (copied from pyamf/branches/cpyamf-225/pyamf/amf0.py) (13 diffs)
-
amf3.pyx (copied) (copied from pyamf/branches/cpyamf-225/pyamf/amf3.py) (20 diffs)
Legend:
- Unmodified
- Added
- Removed
-
pyamf/branches/cpyamf-225/pyamf/amf0.pyx
r1101 r1110 4 4 # See LICENSE for details. 5 5 6 """7 AMF0 implementation.8 9 C{AMF0} supports the basic data types used for the NetConnection, NetStream,10 LocalConnection, SharedObjects and other classes in the Flash Player.11 12 @see: U{AMF documentation on OSFlash (external)13 <http://osflash.org/documentation/amf>}14 15 @author: U{Arnar Birgisson<mailto:arnarbi@gmail.com>}16 @author: U{Thijs Triemstra<mailto:info@collab.nl>}17 @author: U{Nick Joyce<mailto:nick@boxdesign.co.uk>}18 19 @since: 0.1.020 """21 22 6 import datetime, types 23 7 … … 32 16 <http://osflash.org/documentation/amf/astypes>} 33 17 """ 34 #: Represented as 9 bytes: 1 byte for C{0Ã00} and 8 bytes a double35 #: representing the value of the number.36 18 NUMBER = 0x00 37 #: Represented as 2 bytes: 1 byte for C{0Ã01} and a second, C{0Ã00}38 #: for C{False}, C{0Ã01} for C{True}.39 19 BOOL = 0x01 40 #: Represented as 3 bytes + len(String): 1 byte C{0Ã02}, then a UTF8 string,41 #: including the top two bytes representing string length as a C{int}.42 20 STRING = 0x02 43 #: Represented as 1 byte, C{0Ã03}, then pairs of UTF8 string, the key, and44 #: an AMF element, ended by three bytes, C{0Ã00} C{0Ã00} C{0Ã09}.45 21 OBJECT = 0x03 46 #: MovieClip does not seem to be supported by Remoting.47 #: It may be used by other AMF clients such as SharedObjects.48 22 MOVIECLIP = 0x04 49 #: 1 single byte, C{0Ã05} indicates null. 50 NULL = 0x05 51 #: 1 single byte, C{0Ã06} indicates null. 23 _NULL = 0x05 52 24 UNDEFINED = 0x06 53 #: When an ActionScript object refers to itself, such C{this.self = this},54 #: or when objects are repeated within the same scope (for example, as the55 #: two parameters of the same function called), a code of C{0Ã07} and an56 #: C{int}, the reference number, are written.57 25 REFERENCE = 0x07 58 #: A MixedArray is indicated by code C{0Ã08}, then a Long representing the59 #: highest numeric index in the array, or 0 if there are none or they are60 #: all negative. After that follow the elements in key : value pairs.61 26 MIXEDARRAY = 0x08 62 #: @see: L{OBJECT}63 27 OBJECTTERM = 0x09 64 #: An array is indicated by C{0x0A}, then a Long for array length, then the65 #: array elements themselves. Arrays are always sparse; values for66 #: inexistant keys are set to null (C{0Ã06}) to maintain sparsity.67 28 ARRAY = 0x0a 68 #: Date is represented as C{00x0B}, then a double, then an C{int}. The double69 #: represents the number of milliseconds since 01/01/1970. The C{int} represents70 #: the timezone offset in minutes between GMT. Note for the latter than values71 #: greater than 720 (12 hours) are represented as M{2^16} - the value. Thus GMT+172 #: is 60 while GMT-5 is 65236.73 29 DATE = 0x0b 74 #: LongString is reserved for strings larger then M{2^16} characters long. It75 #: is represented as C{00x0C} then a LongUTF.76 30 LONGSTRING = 0x0c 77 #: Trying to send values which donât make sense, such as prototypes, functions,78 #: built-in objects, etc. will be indicated by a single C{00x0D} byte.79 31 UNSUPPORTED = 0x0d 80 #: Remoting Server -> Client only.81 #: @see: L{RecordSet}82 #: @see: U{RecordSet structure on OSFlash (external)83 #: <http://osflash.org/documentation/amf/recordset>}84 32 RECORDSET = 0x0e 85 #: The XML element is indicated by C{00x0F} and followed by a LongUTF containing86 #: the string representation of the XML object. The receiving gateway may which87 #: to wrap this string inside a language-specific standard XML object, or simply88 #: pass as a string.89 33 XML = 0x0f 90 #: A typed object is indicated by C{0Ã10}, then a UTF string indicating class91 #: name, and then the same structure as a normal C{0Ã03} Object. The receiving92 #: gateway may use a mapping scheme, or send back as a vanilla object or93 #: associative array.94 34 TYPEDOBJECT = 0x10 95 #: An AMF message sent from an AVM+ client such as the Flash Player 9 may break96 #: out into L{AMF3<pyamf.amf3>} mode. In this case the next byte will be the97 #: AMF3 type code and the data will be in AMF3 format until the decoded object98 #: reaches itâs logical conclusion (for example, an object has no more keys).99 35 AMF3 = 0x11 100 36 101 #: List of available ActionScript types in AMF0.102 37 ACTIONSCRIPT_TYPES = [] 103 38 … … 177 112 178 113 context_class = Context 179 # XXX nick: Do we need to support ASTypes.MOVIECLIP here?180 114 type_map = { 181 115 ASTypes.NUMBER: 'readNumber', … … 183 117 ASTypes.STRING: 'readString', 184 118 ASTypes.OBJECT: 'readObject', 185 ASTypes. NULL: 'readNull',119 ASTypes._NULL: 'readNull', 186 120 ASTypes.UNDEFINED: 'readUndefined', 187 121 ASTypes.REFERENCE: 'readReference', … … 190 124 ASTypes.DATE: 'readDate', 191 125 ASTypes.LONGSTRING: 'readLongString', 192 # TODO: do we need a special value here?193 126 ASTypes.UNSUPPORTED:'readNull', 194 127 ASTypes.XML: 'readXML', … … 369 302 return 370 303 371 for key in filter(lambda x: x in attrs, obj_attrs.keys()): 304 for key in obj_attrs.keys(): 305 if not key in attrs: 306 continue 307 372 308 obj.__setattr__(key, obj_attrs[key]) 373 309 else: … … 460 396 ((datetime.date, datetime.datetime), "writeDate"), 461 397 ((util.ET.iselement,), "writeXML"), 462 ((lambda x: x is pyamf.Undefined,), "writeUndefined"),398 #((lambda x: x is pyamf.Undefined,), "writeUndefined"), 463 399 ((types.InstanceType,types.ObjectType,), "writeObject"), 464 400 ] … … 540 476 @param n: Is ignored. 541 477 """ 542 self.writeType(ASTypes. NULL)478 self.writeType(ASTypes._NULL) 543 479 544 480 def writeArray(self, a): … … 659 595 # TODO: optimise this 660 596 # work out the highest integer index 597 max_index = 0 661 598 try: 662 599 # list comprehensions to save the day 663 max_index = max([y[0] for y in o.items() 664 if isinstance(y[0], (int, long))]) 600 #max_index = max([y[0] for y in o.items() if isinstance(y[0], (int, long))]) 665 601 666 602 if max_index < 0: … … 790 726 while 1: 791 727 try: 792 yield decoder.readElement()793 except pyamf.EOStream:794 break728 pass#yield decoder.readElement() 729 except pyamf.EOStream: 730 break 795 731 796 732 def encode(element, context=None): … … 870 806 ret = '<%s.%s object' % (self.__module__, self.__class__.__name__) 871 807 872 if self.id is not None:873 ret += ' id=%s' % self.id874 875 if self.service is not None:876 ret += ' service=%s' % self.service877 878 ret += ' at 0x%x>' % id(self)808 #if self.id is not None: 809 # ret += ' id=s' % self.id 810 811 #if self.service is not None: 812 # ret += ' service=%s' % self.service 813 814 #ret += ' at 0x%x>' % id(self) 879 815 880 816 return ret … … 899 835 900 836 # check for some python2.3 problems with floats 837 """ 901 838 try: 902 839 float('nan') … … 916 853 917 854 _check_for_int = check_nan(_check_for_int) 855 """ -
pyamf/branches/cpyamf-225/pyamf/amf3.pyx
r1101 r1110 52 52 #: The undefined type is represented by the undefined type marker. 53 53 #: No further information is encoded for this value. 54 NULL = 0x0154 _NULL = 0x01 55 55 #: The false type is represented by the false type marker and is 56 56 #: used to encode a Boolean value of C{false}. No further information … … 623 623 624 624 if hasattr(obj, '__getstate__'): 625 attrs = set([unicode(k) for k in obj.__getstate__()])625 attrs = obj.__getstate__() 626 626 elif hasattr(obj, 'keys'): 627 attrs = set([unicode(k) for k in obj.keys()])627 attrs = obj.keys() 628 628 elif hasattr(obj, 'iteritems'): 629 attrs = set([unicode(k) for k, v in obj.iteritems()]) 629 attrs = [] 630 for k, v in obj.iteritems(): 631 attrs.append(k) 630 632 elif hasattr(obj, '__dict__'): 631 attrs = set([unicode(k) for k in obj.__dict__.keys()])633 attrs = obj.__dict__.keys() 632 634 633 635 static_attrs = dynamic_attrs = None … … 636 638 if self.alias.attrs: 637 639 static_attrs = self.alias.attrs 638 [attrs.remove(x) for x in static_attrs] 640 for x in static_attrs: 641 attrs.remove(x) 639 642 640 643 if self.alias.attr_func: … … 858 861 type_map = { 859 862 ASTypes.UNDEFINED: 'readUndefined', 860 ASTypes. NULL: 'readNull',863 ASTypes._NULL: 'readNull', 861 864 ASTypes.BOOL_FALSE: 'readBoolFalse', 862 865 ASTypes.BOOL_TRUE: 'readBoolTrue', … … 938 941 939 942 while b & 0x80 != 0 and n < 3: 940 result <<=7941 result |= b & 0x7f943 result = result << 7 944 result = result | (b & 0x7f) 942 945 b = self.stream.read_uchar() 943 n +=1946 n = n + 1 944 947 945 948 if n < 3: 946 result <<=7947 result |=b948 else: 949 result <<=8950 result |=b949 result = result << 7 950 result = result | b 951 else: 952 result = result << 8 953 result = result | b 951 954 952 955 if result & 0x10000000 != 0: 953 result <<=1954 result +=1956 result = result << 1 957 result = result + 1 955 958 956 959 return result 960 961 def _readLength(self): 962 x = self.readInteger() 963 964 return (x >> 1, x & REFERENCE_BIT == 0) 957 965 958 966 def readString(self, use_references=True): … … 963 971 @param use_references: 964 972 """ 965 def readLength(): 966 x = self.readInteger() 967 968 return (x >> 1, x & REFERENCE_BIT == 0) 969 970 length, is_reference = readLength() 973 length, is_reference = self._readLength() 971 974 972 975 if use_references and is_reference: … … 1015 1018 return self.context.getObject(size >> 1) 1016 1019 1017 size >>=11020 size = size >> 1 1018 1021 1019 1022 key = self.readString() … … 1053 1056 class_ref = ref & REFERENCE_BIT == 0 1054 1057 1055 ref >>=11058 ref = ref >> 1 1056 1059 1057 1060 if class_ref: … … 1063 1066 return class_ref, class_def, ref >> 2 1064 1067 1068 def _readStatic(self, is_ref, class_def, obj, num_attrs): 1069 if not is_ref: 1070 for i in range(num_attrs): 1071 key = self.readString() 1072 1073 class_def.static_attrs.append(key) 1074 1075 for attr in class_def.static_attrs: 1076 setattr(obj, attr, self.readElement()) 1077 1078 def _readDynamic(self, is_ref, class_def, obj): 1079 attr = self.readString() 1080 1081 while attr != "": 1082 setattr(obj, attr, self.readElement()) 1083 attr = self.readString() 1084 1065 1085 def readObject(self): 1066 1086 """ 1067 1087 Reads an object from the stream. 1068 1088 """ 1069 def readStatic(is_ref, class_def, obj, num_attrs):1070 if not is_ref:1071 for i in range(num_attrs):1072 key = self.readString()1073 1074 class_def.static_attrs.append(key)1075 1076 for attr in class_def.static_attrs:1077 setattr(obj, attr, self.readElement())1078 1079 def readDynamic(is_ref, class_def, obj):1080 attr = self.readString()1081 1082 while attr != "":1083 setattr(obj, attr, self.readElement())1084 attr = self.readString()1085 1086 1089 ref = self.readInteger() 1087 1090 … … 1089 1092 return self.context.getObject(ref >> 1) 1090 1093 1091 ref >>=11094 ref = ref >> 1 1092 1095 1093 1096 class_ref, class_def, num_attrs = self._getClassDefinition(ref) … … 1108 1111 obj.__readamf__(DataInput(self)) 1109 1112 elif class_def.encoding == ObjectEncoding.DYNAMIC: 1110 readStatic(class_ref, class_def, obj_attrs, num_attrs)1111 readDynamic(class_ref, class_def, obj_attrs)1113 self._readStatic(class_ref, class_def, obj_attrs, num_attrs) 1114 self._readDynamic(class_ref, class_def, obj_attrs) 1112 1115 elif class_def.encoding == ObjectEncoding.STATIC: 1113 readStatic(class_ref, class_def, obj_attrs, num_attrs)1116 self._readStatic(class_ref, class_def, obj_attrs, num_attrs) 1114 1117 else: 1115 1118 raise pyamf.DecodeError, "Unknown object encoding" … … 1210 1213 ((datetime.date, datetime.datetime), "writeDate"), 1211 1214 ((util.ET.iselement,), "writeXML"), 1212 ((lambda x: x is pyamf.Undefined,), "writeUndefined"),1215 #((lambda x: x is pyamf.Undefined,), "writeUndefined"), 1213 1216 ((types.InstanceType, types.ObjectType,), "writeInstance"), 1214 1217 ] … … 1272 1275 @param use_references: 1273 1276 """ 1274 self.writeType(ASTypes. NULL)1277 self.writeType(ASTypes._NULL) 1275 1278 1276 1279 def writeBoolean(self, n, use_references=True): … … 1550 1553 self.writeObject(obj, use_references) 1551 1554 1555 def _writeStatic(self, obj, attrs, class_ref): 1556 if not class_ref: 1557 for attr in attrs: 1558 self._writeString(attr) 1559 1560 for attr in attrs: 1561 self.writeElement(obj[attr]) 1562 1552 1563 def writeObject(self, obj, use_references=True): 1553 1564 """ … … 1560 1571 @raise EncodeError: Unknown object encoding. 1561 1572 """ 1562 def writeStatic(obj, attrs, class_ref):1563 if not class_ref:1564 [self._writeString(attr) for attr in attrs]1565 1566 [self.writeElement(obj[attr]) for attr in attrs]1567 1573 1568 1574 self.writeType(ASTypes.OBJECT) … … 1593 1599 if class_def.encoding != ObjectEncoding.EXTERNAL: 1594 1600 if class_def.alias and class_def.alias.attrs is not None: 1595 ref += len(class_def.alias.attrs) << 41601 ref = ref + (len(class_def.alias.attrs) << 4) 1596 1602 1597 1603 self._writeInteger(ref | class_def.encoding << 2 | REFERENCE_BIT << 1 | REFERENCE_BIT) … … 1616 1622 1617 1623 if static_attrs is not None: 1618 writeStatic(obj_attrs, static_attrs, class_ref)1624 self._writeStatic(obj_attrs, static_attrs, class_ref) 1619 1625 1620 1626 if class_def.encoding == ObjectEncoding.DYNAMIC and dynamic_attrs is not None: … … 1694 1700 while 1: 1695 1701 try: 1696 yield decoder.readElement()1697 except pyamf.EOStream:1698 break1702 pass#yield decoder.readElement() 1703 except pyamf.EOStream: 1704 break 1699 1705 1700 1706 def encode(element, context=None): … … 1725 1731 if n > 0x1fffff: 1726 1732 real_value = n 1727 n >>=11728 bytes += chr(0x80 | ((n >> 21) & 0xff))1733 n = n >> 1 1734 bytes = bytes + (chr(0x80 | ((n >> 21) & 0xff))) 1729 1735 1730 1736 if n > 0x3fff: 1731 bytes += chr(0x80 | ((n >> 14) & 0xff))1737 bytes = bytes + (chr(0x80 | ((n >> 14) & 0xff))) 1732 1738 1733 1739 if n > 0x7f: 1734 bytes += chr(0x80 | ((n >> 7) & 0xff))1740 bytes = bytes + (chr(0x80 | ((n >> 7) & 0xff))) 1735 1741 1736 1742 if real_value is not None: … … 1738 1744 1739 1745 if n > 0x1fffff: 1740 bytes +=chr(n & 0xff)1746 bytes = bytes + chr(n & 0xff) 1741 1747 else: 1742 bytes +=chr(n & 0x7f)1748 bytes = bytes + chr(n & 0x7f) 1743 1749 1744 1750 return bytes
