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; }
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; 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; // Set first child. value = i.GetProperty(); if ((p->fValue.fFirstChild = _ValueToNode(value, &alreadyCreated, &toDoList)) == NULL) { _FreeNode(root); root = NULL; break; } q = p->fValue.fFirstChild; i.GetPropertyName(q->fName); ++i; // Iterate sibling(s). for ( ; i.IsValid(); ++i) { value = i.GetProperty(); if ((p = _ValueToNode(value, &alreadyCreated, &toDoList)) == NULL) break; else { q = q->fNextSibling = p; i.GetPropertyName(p->fName); } } 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; }