| Home | Trees | Indices | Help |
|
|---|
|
|
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (c) 2007-2009 The PyAMF Project.
4 # See LICENSE for details.
5
6 """
7 AMF3 implementation.
8
9 C{AMF3} is the default serialization for
10 U{ActionScript<http://en.wikipedia.org/wiki/ActionScript>} 3.0 and provides
11 various advantages over L{AMF0<pyamf.amf0>}, which is used for ActionScript 1.0
12 and 2.0. It adds support for sending C{int} and C{uint} objects as integers and
13 supports data types that are available only in ActionScript 3.0, such as
14 L{ByteArray} and L{ArrayCollection}.
15
16 @see: U{Official AMF3 Specification in English (external)
17 <http://opensource.adobe.com/wiki/download/attachments/1114283/amf3_spec_121207.pdf>}
18 @see: U{Official AMF3 Specification in Japanese (external)
19 <http://opensource.adobe.com/wiki/download/attachments/1114283/JP_amf3_spec_121207.pdf>}
20 @see: U{AMF3 documentation on OSFlash (external)
21 <http://osflash.org/documentation/amf3>}
22
23 @since: 0.1.0
24 """
25
26 import types, datetime, zlib
27
28 import pyamf
29 from pyamf import util
30 from pyamf.flex import ObjectProxy, ArrayCollection
31
32 #: If True encode/decode lists/tuples to ArrayCollections
33 #: and dicts to ObjectProxy
34 use_proxies_default = False
35
36 try:
37 set()
38 except NameError:
39 from sets import Set as set
40
42 """
43 All AMF3 data types used in ActionScript 3.0.
44
45 AMF represents ActionScript objects by a single byte representing type, and
46 then by a type-specific byte array that may be of fixed length, may contain
47 length information, or may come with its own end code.
48
49 @see: U{AMF3 data types on OSFlash (external)
50 <http://osflash.org/documentation/amf3#data_types>}
51 """
52 #: The undefined type is represented by the undefined type marker.
53 #: No further information is encoded for this value.
54 UNDEFINED = 0x00
55 #: The undefined type is represented by the undefined type marker.
56 #: No further information is encoded for this value.
57 NULL = 0x01
58 #: The false type is represented by the false type marker and is
59 #: used to encode a Boolean value of C{false}. No further information
60 #: is encoded for this value.
61 #: @note: In ActionScript 3.0 the concept of a primitive and Object
62 #: form of Boolean does not exist.
63 BOOL_FALSE = 0x02
64 #: The true type is represented by the true type marker and is
65 #: used to encode a Boolean value of C{true}. No further information
66 #: is encoded for this value.
67 #: @note: In ActionScript 3.0 the concept of a primitive and Object
68 #: form of Boolean does not exist.
69 BOOL_TRUE = 0x03
70 #: In AMF 3 integers are serialized using a variable length unsigned
71 #: 29-bit integer.
72 #: @see: U{Parsing Integers on OSFlash (external)
73 #: <http://osflash.org/documentation/amf3/parsing_integers>}
74 INTEGER = 0x04
75 #: This type is used to encode an ActionScript Number
76 #: or an ActionScript C{int} of value greater than or equal to 2^28
77 #: or an ActionScript uint of value greater than or equal to 2^29.
78 #: The encoded value is is always an 8 byte IEEE-754 double precision
79 #: floating point value in network byte order (sign bit in low memory).
80 #: The AMF 3 number type is encoded in the same manner as the
81 #: AMF 0 L{Number<pyamf.amf0.ASTypes.NUMBER>} type.
82 NUMBER = 0x05
83 #: ActionScript String values are represented using a single string
84 #: type in AMF 3 - the concept of string and long string types from
85 #: AMF 0 is not used. Strings can be sent as a reference to a previously
86 #: occurring String by using an index to the implicit string reference
87 #: table.
88 #: Strings are encoding using UTF-8 - however the header may either
89 #: describe a string literal or a string reference.
90 STRING = 0x06
91 #: ActionScript 3.0 introduced a new XML type however the legacy
92 #: C{XMLDocument} type from ActionScript 1.0 and 2.0.is retained
93 #: in the language as C{flash.xml.XMLDocument}. Similar to AMF 0, the
94 #: structure of an C{XMLDocument} needs to be flattened into a string
95 #: representation for serialization. As with other strings in AMF,
96 #: the content is encoded in UTF-8. XMLDocuments can be sent as a reference
97 #: to a previously occurring C{XMLDocument} instance by using an index to
98 #: the implicit object reference table.
99 #: @see: U{OSFlash documentation (external)
100 #: <http://osflash.org/documentation/amf3#x07_-_xml_legacy_flash.xml.xmldocument_class>}
101 XML = 0x07
102 #: In AMF 3 an ActionScript Date is serialized simply as the number of
103 #: milliseconds elapsed since the epoch of midnight, 1st Jan 1970 in the
104 #: UTC time zone. Local time zone information is not sent.
105 DATE = 0x08
106 #: ActionScript Arrays are described based on the nature of their indices,
107 #: i.e. their type and how they are positioned in the Array.
108 ARRAY = 0x09
109 #: A single AMF 3 type handles ActionScript Objects and custom user classes.
110 OBJECT = 0x0a
111 #: ActionScript 3.0 introduces a new top-level XML class that supports
112 #: U{E4X<http://en.wikipedia.org/wiki/E4X>} syntax.
113 #: For serialization purposes the XML type needs to be flattened into a
114 #: string representation. As with other strings in AMF, the content is
115 #: encoded using UTF-8.
116 XMLSTRING = 0x0b
117 #: ActionScript 3.0 introduces the L{ByteArray} type to hold an Array
118 #: of bytes. AMF 3 serializes this type using a variable length encoding
119 #: 29-bit integer for the byte-length prefix followed by the raw bytes
120 #: of the L{ByteArray}.
121 #: @see: U{Parsing ByteArrays on OSFlash (external)
122 #: <http://osflash.org/documentation/amf3/parsing_byte_arrays>}
123 BYTEARRAY = 0x0c
124
125 #: List of available ActionScript types in AMF3.
126 ACTIONSCRIPT_TYPES = []
127
128 for x in ASTypes.__dict__:
129 if not x.startswith('_'):
130 ACTIONSCRIPT_TYPES.append(ASTypes.__dict__[x])
131 del x
132
133 #: Reference bit.
134 REFERENCE_BIT = 0x01
135
137 """
138 AMF object encodings.
139 """
140 #: Property list encoding.
141 #: The remaining integer-data represents the number of class members that
142 #: exist. The property names are read as string-data. The values are then
143 #: read as AMF3-data.
144 STATIC = 0x00
145
146 #: Externalizable object.
147 #: What follows is the value of the "inner" object, including type code.
148 #: This value appears for objects that implement IExternalizable, such as
149 #: L{ArrayCollection} and L{ObjectProxy}.
150 EXTERNAL = 0x01
151
152 #: Name-value encoding.
153 #: The property names and values are encoded as string-data followed by
154 #: AMF3-data until there is an empty string property name. If there is a
155 #: class-def reference there are no property names and the number of values
156 #: is equal to the number of properties in the class-def.
157 DYNAMIC = 0x02
158
159 #: Proxy object.
160 PROXY = 0x03
161
163 """
164 I am a C{StringIO} type object containing byte data from the AMF stream.
165 ActionScript 3.0 introduced the C{flash.utils.ByteArray} class to support
166 the manipulation of raw data in the form of an Array of bytes.
167 I provide a set of methods for writing binary data with ActionScript 3.0.
168
169 This class is the I/O counterpart to the L{DataInput} class, which reads
170 binary data.
171
172 @see: U{IDataOutput on Livedocs (external)
173 <http://livedocs.adobe.com/flex/201/langref/flash/utils/IDataOutput.html>}
174 """
176 """
177 @param encoder: Encoder containing the stream.
178 @type encoder: L{amf3.Encoder<pyamf.amf3.Encoder>}
179 """
180 assert isinstance(encoder, Encoder)
181
182 self.encoder = encoder
183 self.stream = encoder.stream
184
186 """
187 Writes a Boolean value.
188
189 @type value: C{bool}
190 @param value: A C{Boolean} value determining which byte is written.
191 If the parameter is C{True}, C{1} is written; if C{False}, C{0} is
192 written.
193
194 @raise ValueError: Non-boolean value found.
195 """
196 if isinstance(value, bool):
197 if value is True:
198 self.stream.write_uchar(1)
199 else:
200 self.stream.write_uchar(0)
201 else:
202 raise ValueError("Non-boolean value found")
203
211
213 """
214 Writes an IEEE 754 double-precision (64-bit) floating
215 point number.
216
217 @type value: C{number}
218 """
219 self.stream.write_double(value)
220
222 """
223 Writes an IEEE 754 single-precision (32-bit) floating
224 point number.
225
226 @type value: C{float}
227 """
228 self.stream.write_float(value)
229
231 """
232 Writes a 32-bit signed integer.
233
234 @type value: C{int}
235 """
236 self.stream.write_long(value)
237
239 """
240 Writes a multibyte string to the datastream using the
241 specified character set.
242
243 @type value: C{str}
244 @param value: The string value to be written.
245 @type charset: C{str}
246 @param charset: The string denoting the character
247 set to use. Possible character set strings include
248 C{shift-jis}, C{cn-gb}, C{iso-8859-1} and others.
249 @see: U{Supported character sets on Livedocs (external)
250 <http://livedocs.adobe.com/flex/201/langref/charset-codes.html>}
251 """
252 self.stream.write(unicode(value).encode(charset))
253
255 """
256 Writes an object to data stream in AMF serialized format.
257
258 @param value: The object to be serialized.
259 @type use_references: C{bool}
260 @param use_references:
261 """
262 self.encoder.writeElement(value, use_references)
263
265 """
266 Writes a 16-bit integer.
267
268 @type value: C{int}
269 @param value: A byte value as an integer.
270 """
271 self.stream.write_short(value)
272
274 """
275 Writes a 32-bit unsigned integer.
276
277 @type value: C{int}
278 @param value: A byte value as an unsigned integer.
279 """
280 self.stream.write_ulong(value)
281
283 """
284 Writes a UTF-8 string to the data stream.
285
286 The length of the UTF-8 string in bytes is written first,
287 as a 16-bit integer, followed by the bytes representing the
288 characters of the string.
289
290 @type value: C{str}
291 @param value: The string value to be written.
292 """
293 if not isinstance(value, unicode):
294 value = unicode(value, 'utf8')
295
296 buf = util.BufferedByteStream()
297 buf.write_utf8_string(value)
298 bytes = buf.getvalue()
299
300 self.stream.write_ushort(len(bytes))
301 self.stream.write(bytes)
302
304 """
305 Writes a UTF-8 string. Similar to L{writeUTF}, but does
306 not prefix the string with a 16-bit length word.
307
308 @type value: C{str}
309 @param value: The string value to be written.
310 """
311 val = None
312
313 if isinstance(value, unicode):
314 val = value
315 else:
316 val = unicode(value, 'utf8')
317
318 self.stream.write_utf8_string(val)
319
321 """
322 I provide a set of methods for reading binary data with ActionScript 3.0.
323
324 This class is the I/O counterpart to the L{DataOutput} class,
325 which writes binary data.
326
327 @see: U{IDataInput on Livedocs (external)
328 <http://livedocs.adobe.com/flex/201/langref/flash/utils/IDataInput.html>}
329 """
331 """
332 @param decoder: AMF3 decoder containing the stream.
333 @type decoder: L{amf3.Decoder<pyamf.amf3.Decoder>}
334 """
335 assert isinstance(decoder, Decoder)
336
337 self.decoder = decoder
338 self.stream = decoder.stream
339
341 """
342 Read C{Boolean}.
343
344 @raise ValueError: Error reading Boolean.
345 @rtype: C{bool}
346 @return: A Boolean value, C{True} if the byte
347 is nonzero, C{False} otherwise.
348 """
349 byte = self.stream.read(1)
350
351 if byte == '\x00':
352 return False
353 elif byte == '\x01':
354 return True
355 else:
356 raise ValueError("Error reading boolean")
357
359 """
360 Reads a signed byte.
361
362 @rtype: C{int}
363 @return: The returned value is in the range -128 to 127.
364 """
365 return self.stream.read_char()
366
368 """
369 Reads an IEEE 754 double-precision floating point number from the
370 data stream.
371
372 @rtype: C{number}
373 @return: An IEEE 754 double-precision floating point number.
374 """
375 return self.stream.read_double()
376
378 """
379 Reads an IEEE 754 single-precision floating point number from the
380 data stream.
381
382 @rtype: C{number}
383 @return: An IEEE 754 single-precision floating point number.
384 """
385 return self.stream.read_float()
386
388 """
389 Reads a signed 32-bit integer from the data stream.
390
391 @rtype: C{int}
392 @return: The returned value is in the range -2147483648 to 2147483647.
393 """
394 return self.stream.read_long()
395
397 """
398 Reads a multibyte string of specified length from the data stream
399 using the specified character set.
400
401 @type length: C{int}
402 @param length: The number of bytes from the data stream to read.
403 @type charset: C{str}
404 @param charset: The string denoting the character set to use.
405
406 @rtype: C{str}
407 @return: UTF-8 encoded string.
408 """
409 #FIXME nick: how to work out the code point byte size (on the fly)?
410 bytes = self.stream.read(length)
411
412 return unicode(bytes, charset)
413
415 """
416 Reads an object from the data stream.
417
418 @return: The deserialized object.
419 """
420 return self.decoder.readElement()
421
423 """
424 Reads a signed 16-bit integer from the data stream.
425
426 @rtype: C{uint}
427 @return: The returned value is in the range -32768 to 32767.
428 """
429 return self.stream.read_short()
430
432 """
433 Reads an unsigned byte from the data stream.
434
435 @rtype: C{uint}
436 @return: The returned value is in the range 0 to 255.
437 """
438 return self.stream.read_uchar()
439
441 """
442 Reads an unsigned 32-bit integer from the data stream.
443
444 @rtype: C{uint}
445 @return: The returned value is in the range 0 to 4294967295.
446 """
447 return self.stream.read_ulong()
448
450 """
451 Reads an unsigned 16-bit integer from the data stream.
452
453 @rtype: C{uint}
454 @return: The returned value is in the range 0 to 65535.
455 """
456 return self.stream.read_ushort()
457
459 """
460 Reads a UTF-8 string from the data stream.
461
462 The string is assumed to be prefixed with an unsigned
463 short indicating the length in bytes.
464
465 @rtype: C{str}
466 @return: A UTF-8 string produced by the byte
467 representation of characters.
468 """
469 length = self.stream.read_ushort()
470 return self.stream.read_utf8_string(length)
471
473 """
474 Reads a sequence of C{length} UTF-8 bytes from the data
475 stream and returns a string.
476
477 @type length: C{int}
478 @param length: The number of bytes from the data stream to read.
479 @rtype: C{str}
480 @return: A UTF-8 string produced by the byte representation of
481 characters of specified C{length}.
482 """
483 return self.readMultiByte(length, 'utf-8')
484
486 """
487 I am a C{StringIO} type object containing byte data from the AMF stream.
488 ActionScript 3.0 introduced the C{flash.utils.ByteArray} class to support
489 the manipulation of raw data in the form of an Array of bytes.
490
491 Supports C{zlib} compression.
492
493 Possible uses of the C{ByteArray} class:
494 - Creating a custom protocol to connect to a client.
495 - Writing your own AMF/Remoting packet.
496 - Optimizing the size of your data by using custom data types.
497
498 @see: U{ByteArray on Livedocs (external)
499 <http://livedocs.adobe.com/flex/201/langref/flash/utils/ByteArray.html>}
500 """