When writing a String based encoder in ActionScript you quickly find yourself needing to build up the encoded String a character or so at a time. Without a StringBuffer type in ActionScript you may be tempted to use String concatenation as a simple method to build up a String. The problem with this approach is a number of temporary Strings are created as a result and will hang around until garbage collection catches up.
for (var i:uint =0; i < source.length(); i++)
result += encodeSomething(source.getCharAt(i));
To avoid large memory spikes, a better approach is to build up an Array of character code points as integers and then using them to construct a String in one step using the String.fromCharCode() function:
var buffer:Array = ;
for (var i:uint =0; i < source.length(); i++)
result = String.fromCharCode.apply(null, buffer);
fromCharCode takes a variable number of arguments, we use
Function.apply to pass the Array of integers in a single call.
Note that the arguments of Function.apply end up on the stack, so to avoid a stack overflow you should limit the size of the array to around 64,000 entries. You can always concatenate successive buffers into a final String.
I’ll be at Adobe MAX 2007 North America this year from Sunday 09/30/2007 to Tuesday 10/02/2007 and will be helping out at the LiveCycle Data Services and Flex booths as well as TA’ing the Flex 3: Integration with Java session on Sunday 9am – 5pm.
Hope to see you there!
Even before the release of the highly successful ColdFusion MX 7 two years ago, the ColdFusion team was already hard at work scheming, experimenting, planning, building, creating … and the result is “Scorpio”, the highly anticipated 8th major ColdFusion edition. Building on top of the powerful platform introduced in ColdFusion MX, and the solid feature set of ColdFusion MX 7, “Scorpio” piles on new features and technologies for developers, administrators, technical decision makers, and more. The official “Scorpio” release is scheduled for mid-2007, but you don’t have to wait until then to see it for yourself. Ben Forta and several other members of the CF team will be demoing lots of Scorpio throughout an extended user group tour in the spring, where attendees will get to see “Scorpio” in action, as well as gain access to the pre-release beta, and get the chance to win Adobe software.
To check if the Scorpio pre-release tour is coming to an Adobe user group near you, please check the comprehensive listing of events at: http://www.adobe.com/products/coldfusion/events/.
Java 5.0 introduced typesafe enums which are a special type of class. enums in other languages are typically just an ordered set of properties, however, Java enums allow custom behaviors and logic to be added through constructors, fields and methods.
FDS is based on JDK 1.4.2 and does not natively support enums. ActionScript 3 does not have the concept of enums either. To FDS, an enum class definition looks like a normal class. As such, only public fields and public bean methods with get/set accessors are seen as properties.
An enum can be written to capture the selected value by making the class look like a normal value Object.
public enum FruitEnum
this.value = value;
public String value;
While this doesn’t provide round trip support for enums, it does allow Java to ActionScript conversions of enums.
A public pre-release version of Adobe LiveCycle Data Services 2.5 is now available!
I started a blog to document solutions to questions that I found myself frequently answering on the Flex forums. So the first topic up for discussion is using custom serialization with value objects in RemoteObject. This solution takes advantage of the ActionScript 3 API flash.utils.IExternalizable which is compatible with Java’s java.io.IExternalizable API. By implementing these interfaces on the client and server your value objects can take control of their serialization and customize what data is sent over the wire.
A common use case for using externalizable classes is to include read-only properties in serialization. While there are other approaches to achieve this for server code, there aren’t many approaches available for client code. The server uses the Java Beans API when serializing classes so one could change their value objects to implement java.beans.BeanInfo to customize introspection, however there isn’t an equivalent for this in ActionScript. This may be fine if data is not editable on the client – but many applications involve data manipulation so read-only information needs to be transmitted to maintain the idenity and/or state of an instance. A simpler, brute-force approach might be to track when a setter has been called and throw an error if it is called again – but the fact that your value object had read-only properties wouldn’t be obvious from your API.
So, for an elegant solution that works for both the client and server we are left with the option of making our classes externalizable for two-way custom serialization. Thankfully this is relatively straight-forward. The client ActionScript class simply implements flash.utils.IExternalizable. This API requires two methods readExternal() and writeExternal() which take flash.utils.IDataInput and flash.utils.IDataOutput streams respectively. The implementations of these methods mirror the server Java class, which implements java.io.Externalizable – also with two methods readExternal() and writeExternal() taking java.io.ObjectInput and java.io.ObjectOutput streams respectively.
While the IDataInput and IDataOutput classes let you design your own protocol and write fundamental data types such as byte, int, and UTF-8 encoded Strings, most implementations will take advantage of the readObject() and writeObject() methods respectively as these use AMF 3 to efficiently deserialize and serialize ActionScript objects. (Remember that AMF 3 allows: (a) objects to be sent by reference to avoid redundant instances from being serialized, to retain object relationships and to handle cyclical references, (b) object traits to be sent so that the description of a type is only sent once rather than them repeated for each instance, and (c) reoccuring strings can be sent by reference to again avoid redundant information from being sent). One may even decide to omit property names altogether in their externalizable classes’ custom serialization code and rely on a fixed order to send just the property values.
To see a code example, check out externalizable.zip. While this example focuses on serializing read-only properties there may be many other usages for custom serialization such as omitting properties, avoiding redundant serialization of information or including properties from custom namespaces.