bool VJSStructuredClone::_IsSerializable (XBOX::VJSValue inValue) { xbox_assert(inValue.IsObject()); XBOX::VJSObject object = inValue.GetObject(); if (object.HasProperty("constructorName") && object.GetProperty("constructorName").IsString() && object.HasProperty("serialize") && object.GetProperty("serialize").IsFunction()) return true; else return false; }
static void _AddToList (XBOX::VJSContext &inContext, const XBOX::VString &inConstructorName, XBOX::VJSObject &inConstructedObject) { if (inContext.GetGlobalObject().HasProperty(inConstructorName)) { XBOX::VJSObject workerObject = inContext.GetGlobalObject().GetPropertyAsObject(inConstructorName); if (workerObject.IsObject() && workerObject.HasProperty("list")) { XBOX::VJSValue value = workerObject.GetProperty("list"); if (value.IsArray()) { XBOX::VJSArray listArray(value); sLONG i; for (i = 0; i < listArray.GetLength(); i++) { value = listArray.GetValueAt(i); if (value.IsNull()) { listArray.SetValueAt(i, inConstructedObject); break; } } if (i == listArray.GetLength()) listArray.PushValue(inConstructedObject); } else { xbox_assert(false); } } else { xbox_assert(false); } } else { xbox_assert(false); } }
USING_TOOLBOX_NAMESPACE VJSStructuredClone *VJSStructuredClone::RetainClone (XBOX::VJSValue inValue) { std::map<JS4D::ValueRef, SNode *> alreadyCreated; std::list<SEntry> toDoList; SNode *root; if ((root = _ValueToNode(inValue, &alreadyCreated, &toDoList)) == NULL) return NULL; while (!toDoList.empty()) { // Property iterator will also iterate Array object indexes (they are converted into string). XBOX::VJSValue value(inValue.GetContext(), toDoList.front().fValueRef); XBOX::VJSPropertyIterator i(value.GetObject()); SNode *p, *q, *r; p = toDoList.front().fNode; xbox_assert(p->fType == eNODE_OBJECT || p->fType == eNODE_ARRAY); toDoList.pop_front(); // Object or Array with no attributes? if (!i.IsValid()) continue; // Get prototype and dump its attribute names. XBOX::VJSObject prototypeObject = value.GetObject().GetPrototype(inValue.GetContext()); bool hasPrototype = prototypeObject.IsObject(); // Iterate child(s). for ( ; i.IsValid(); ++i) { XBOX::VString name; i.GetPropertyName(name); // Check attribute name: If it is part of prototype, do not clone it. if (hasPrototype && prototypeObject.HasProperty(name)) continue; value = i.GetProperty(); if ((r = _ValueToNode(value, &alreadyCreated, &toDoList)) == NULL) break; else if (p->fValue.fFirstChild != NULL) q->fNextSibling = r; else p->fValue.fFirstChild = r; r->fName = name; q = r; } if (p->fValue.fFirstChild != NULL) q->fNextSibling = NULL; if (i.IsValid()) { _FreeNode(root); root = NULL; break; } } if (root != NULL) { VJSStructuredClone *structuredClone; if ((structuredClone = new VJSStructuredClone()) != NULL) structuredClone->fRoot = root; else _FreeNode(root); return structuredClone; } else return NULL; }