17 Mar 2007

Part of what I'm working on right now might involve serializing data into JSON so I'm looking into how I can efficiently serialize a data structure into JSON in ActionScript. Here's the simplest method I could find: It overrides the toString() method in the prototypes of the Array, Object and String classes (yep, good 'ol prototype-based ActionScript) to basically make a complex data structure write itself out in JSON.

[as]// Simple JSON Serializer
// Copyright © 2007 Aral Balkan
// Released under the open source MIT license.
// http://opensource.org/licenses/mit-license.php

Object.prototype.toString = function()
{
var str:String = "{";

for (var i:String in this)
{
str += '"' + i + '": ' + this[i].toString() + ", ";
}

str = str.substr(0, str.length-2);
str += "}";

return str;
}

Array.prototype.toString = function()
{
var str:String = "[";

var len:Number = this.length;
for (var i = 0; i < len; i++)
{
str += this[i].toString();
if ( i != len-1 ) str += ", ";
}

str += "]";
return str;
}

String.prototype.toString = function() { return '"' + this + '"'; };[/as]

To test it, simply #include the auto_json_serializer.as file and then trace out a complex data structure. (If this is too old-school for you, you can always make it into a Mixin.)

[as]#include "auto_json_serialize.as"

data = [1, 'hello', true, [2, 3.1], {a:[{x:10, y:20}, 4], b:false}];
trace (data);[/as]

The test, above, traces [1, "hello", true, [2, 3.1], {"a": [{"x": 10, "y": 20}, 4], "b": false}]. You can verify the validity of the resulting JSON using a strict parser like simplejson or this useful little online JSON syntax checker by Colin Ramsay.

A JSON serializer in about 20 lines of code -- not bad! :)

Update: Madarco mentioned in the comments that the code above does not escape strings as it should. Adding that functionality in adds as many lines of code as the rest of it. The code I've added below to the overriden toString() method of the String class is from the ActionScript JSON class by Trannie Carter.

[as]String.prototype.toString = function()
{
// From JSON.as by Trannie Carter
// http://json.org/json.as
l = this.length;
s = '"';
for (i = 0; i < l; i += 1)
{
c = this.charAt(i);
if (c >= ' ')
{
if (c == '\\' || c == '"')
{
s += '\\';
}
s += c;
}
else
{
switch (c)
{
case '\b':
s += '\\b';
break;

case '\f':
s += '\\f';
break;

case '\n':
s += '\\n';
break;

case '\r':
s += '\\r';
break;

case '\t':
s += '\\t';
break;

default:
c = c.charCodeAt();
s += '\\u00' + Math.floor(c / 16).toString(16) +
(c % 16).toString(16);
}
}
}

s += '"';

return s;
}
[/as]

Download version 0.2 here (6kb, MD5: 2243b3b2d0a5ae2570511de6f47c7a35).

Add Your Comment

Spam Protection by WP-SpamFree

Simple automatic JSON serializer in ActionScript

  1. Hi,
    I’ve not tried with the syntax checker, but it seems that you don’t escape strings like \b \t or “

    Madarco
  2. Ah, good catch… a few more lines in the String.toString() should handle that :)

    aral
  3. Hey Madarco,

    *Quite* a few lines, I apparently should’ve said! :) I’ve updated the post and the download. Strings should now be correctly escaped.

    Now, if only we had a Character class, the code could have been simplified even further ;)

    aral
  4. Sure, now it works fine, good work :)

    Ps. my nick is mAdarco :P

    Madarco
  5. Coolness. Sorry about the typo on your nick — fixed that too :)

    aral
  6. Personally I’d have done it without overriding built-in methods on the prototypes, or at least adding a different one (and making it non-enumerable). Maybe someone is already using toString for some other kind of serialization? It’s also very unsafe — serialization of anything that implements its own toString will almost surely net you an invalid JSON document.

    Bob Ippolito
  7. Oh, and the string escaping seems to imply that the remote end is going to understand UTF-8 properly (or whatever codec Flash encodes text with by default). It might be worth checking for text with a char code of >= ‘ ‘ && > 10) & 0x3ff)
    s2 = 0xdc00 | (n & 0x3ff)
    return ‘\\ux\\ux’ % (s1, s2)

    Bob Ippolito
  8. Oof! Your comment plugin is sure hostile to code…

    Well, look at encode_basestring_ascii in simplejson/encode.py if you want to see how I implemented the UTF-16 surrogate pair stuff.

    There’s also simplejson/_speedups.c that escapes characters with ascii_escape_char — that’s probably even more directly rape paste translatable to ActionScript.

    Bob Ippolito
  9. Hi Bob,

    Thanks for the feedback. I do share your concerns regarding the implementation but believe me there is a use case for it :) (It’s going to become clearer when I release the little pet project I’ve been working on for the past two weeks.)

    I’ll definitely take a look at the files you mentioned and sorry the comments system messed up your code. Know any good plugins for WordPress that handle that better?

    Thanks again for sharing.

    aral
  10. Unfortunately no, I try to know as little about WordPress as possible.

    I’d definitely like to see what you’re cooking up. We don’t do any JSON with Flash, but it’d be nice if it was the easy and obvious way to do things. XML is annoying, and remoting is proprietary.

    Bob Ippolito
  11. The final version of what I’m using it for isn’t JSON but it’s related — oh, the suspense ;) I hope to announce it next week, before Thursday.

    aral
  12. Hi there
    I’m looking on a way to improve this algo effeciency : http://www.json.org/json.as

    Thanks for the work of Trannie Carter but there’s seems to be a big gap of performance between this algorithm and the one we could find on some other script languages like Lua.

    Is the version you give here faster than the original one ?
    If not, could confirm this algorithm is really slow on a big json string ?

    Khelkun