package serialize { import flash.utils.Dictionary; // Base implementation of a serializer. It actually does not store anything // yet; only maintains some administration. // We keep track of a stack of objects currently being serialized, and a // dictionary of all objects serialized so far. public class SerializerBase implements Serializer { private var _stack : Array; // stack of objects being serialized. private var _dict : Dictionary; // types of the serialized objects. private var _memo : Dictionary; // objects that are serialized so far. public function SerializerBase() : void { resetBase(); } // resets the state of the serializer private function resetBase() : void { _stack = new Array(); _dict = new Dictionary(true); _memo = new Dictionary(true); } // Calls 'actualBeginObject'. public function beginObject(obj : Object, objType : String) : void { _stack.push(obj); _dict[obj] = objType; _memo[obj] = actualBeginObject(obj, objType); } // Calls 'actualEndObject'. public function endObject() : void { actualEndObject(); var obj : Object = _stack.pop(); } // Dispatches either 'storeFieldPrim' and 'storeFieldRec' to actually // store the field. public function storeField(name : QName, val : Object) : void { if (val is Serializable) { var v : Serializable = val as Serializable; storeFieldRec(name, v, _memo[v]); } else { storeFieldPrim(name, val); } } // Resets the state of the serializer. public function reset() : void { resetBase(); actualReset(); } // Returns the current nesting depth of serialization. // This method may also be called by the serializer to // base detail based on the serialization depth. public function get currentDepth() : int { return _stack.length; } // Returns the current object being serialized. // This method may also be called by the serializer. It // then returns the parent object if the serializer did // not start a 'beginObject' yet. public function get currentObject() : Object { return _stack[_stack.length-1]; } // Returns the type of the current object being serialized. // This method may also be called by the serializer. public function get currentObjectType() : String { return _dict[this.currentObject]; } // Returns the token associated with the current object being serialized. // This method may also be called by the serializer. public function get currentToken() : Object { return _memo[this.currentObject]; } // // The following methods should be implemented by an actual implementation // that inherits from SerializerBase. // // This functions may associate atoken with the object, which is given // to the storeFieldRec method when the same object is encountered again. protected function actualBeginObject(obj : Object, objType : String) : Object { // override this function return null; } protected function actualEndObject() : void { // override this function } protected function actualReset() : void { // override this function } // Actually stores a primitive value (i.e. a non-Serializable value). protected function storeFieldPrim(name : QName, val : Object) : void { // override this function } // Actually stores a Serializable value. // The function can return an arbitrary object (some token associated with 'val'). // If the object is serialized recursively (i.e. the object graph is cyclic), then // 'prev' contains the token returned by the previous serialization of the object. protected function storeFieldRec(name : QName, val : Serializable, prev : *) : void { // override this function } } }