views:

576

answers:

3

AMF3 specification defines use of so called "reference tables" (see Section 2.2 of this specification).

I implemented this behavior in my AMF3 encoder/decoder I developed in Erlang, but being not very experienced with Flash API, I can hardly find how can I easily force Flash to use these reference tables when serializing objects to AMF3; for example if I use ByteArray, it seems that it just repeats full object encodings

 var ba:ByteArray = new ByteArray();
 ba.writeObject("some string1");
 ba.writeObject("some string1");
 # =>
 # <<6,25,115,111,109,101,32,115,116,114,105,110,103,49,
 #   6,25,115,111,109,101,32,115,116,114,105,110,103,49>>

(which is clearly a repetition).

However, if these two strings are in a one single writeObject call, it does seem to use references:

 ba.writeObject(["some string1", "some string1"]);
 # => <<9,5,1,6,25,115,111,109,101,32,115,116,114,105,110,103,49,6,0>>

Socket seems to behave the same way.

So, can I make use of reference tables in Flash code? (provided I might have a non-standard protocol between Flash application and server )

Thank you!

+2  A: 

I think the difference is that in the first example you're writing two string literals. In the second example you're writing an array (or Complex Object in Adobe's specs) that has a reference to two strings. So if you reference the string from an object or an array it will write it in the reference table.

This isn't necessarily a way to enforce it but it seems logical that the AMF serializer built into flash would serialize objects this way so it is probably a reliable way to get the behavior your want (reference table strings).

I hope that is helpful to you!

scott
I just thought there would be a mechanism for maintaining reference tables per connection... at least that is what I understood from their AMF3 spec... Sigh.
Yurii Rashkovskii
but anyway thanks!
Yurii Rashkovskii
A: 

Look at the last page of the official AMF3 spec and you will see that ByteArray is pretty much worthless. You will have to write your own AMF3 serializer/deserializer.

A: 

Hello Yurri,

As per the final sentence of the AMF3 specification (AMF 3.0 Spec at Adobe.com):

Also note that ByteArray uses a new set of implicit reference tables for objects, object traits and strings for each readObject and writeObject call.

It appears that the intention with ByteArray.writeObject is to create a serialization which could be stored or recovered on a per-object basis.

The NetConnection object's behavior is similar to what you had hoped for.

When updating the string-references table, it is important to not add empty strings to the reference table.

When maintaining the object-references table, you may be able to implement defensive programming as follows: the object-references table is constructed recursively and at some times contains objects for which the traits are not yet completely known. If the table indices are not allocated in advance, the numbering will be inconsistent across applications. An AMF3 decoder should not use the traits from a partially-constructed object -- such input should be flagged as erroneous.

The strings-reference table is implemented at the encoder by 'tagging' in-memory string objects as they are serialized. Encoding two different string objects with the same content (matching strings) do not seem to be encoded with one string referencing the other. Both strings will be output and a string-by-reference will not be used.

There may be a solution to your original question. If you have a number of objects all belonging to the same class, and you would like to store those objects all in one storage, I suggest the following: Create a "parent object" with references to all the objects you intend to store. Then use ByteArray.writeObject to persist that parent object. AMF will encode all of the referenced objects and will represent the traits of repeated object classes in an efficient way.

Heath Hunnicutt