bool ArrayData::hasInternalReference(PointerSet &vars, bool ds /* = false */) const { if (isSharedMap()) return false; for (ArrayIter iter(this); iter; ++iter) { CVarRef var = iter.secondRef(); if (var.isReferenced()) { Variant *pvar = var.getRefData(); if (vars.find(pvar) != vars.end()) { return true; } vars.insert(pvar); } if (var.isObject()) { ObjectData *pobj = var.getObjectData(); if (vars.find(pobj) != vars.end()) { return true; } vars.insert(pobj); if (ds && pobj->o_instanceof("Serializable")) { return true; } if (pobj->hasInternalReference(vars, ds)) { return true; } } else if (var.isArray() && var.getArrayData()->hasInternalReference(vars, ds)) { return true; } } return false; }
bool ArrayData::hasInternalReference(PointerSet &vars) const { if (supportValueRef()) { for (ArrayIter iter(this); iter; ++iter) { CVarRef var = iter.secondRef(); if (var.isReferenced()) { Variant *pvar = var.getVariantData(); if (vars.find(pvar) != vars.end()) { return true; } vars.insert(pvar); } if (var.isObject()) { ObjectData *pobj = var.getObjectData(); if (vars.find(pobj) != vars.end()) { return true; } vars.insert(pobj); if (pobj->o_toArray().get()->hasInternalReference(vars)) { return true; } } else if (var.isArray() && var.getArrayData()->hasInternalReference(vars)) { return true; } } } return false; }
void VariableSerializer::write(CVarRef v, bool isArrayKey /* = false */) { if (!isArrayKey && v.isObject()) { write(v.toObject()); return; } setReferenced(v.isReferenced()); setRefCount(v.getRefCount()); v.serialize(this, isArrayKey); }
void EvalObjectData::o_getArray(Array &props) const { String zero("\0", 1, AttachLiteral); for (ArrayIter it(m_privates); !it.end(); it.next()) { String prefix(zero); prefix += it.first(); prefix += zero; for (ArrayIter it2(it.second()); !it2.end(); it2.next()) { CVarRef v = it2.secondRef(); if (v.isInitialized()) { props.set(prefix + it2.first(), v.isReferenced() ? ref(v) : v); } } } DynamicObjectData::o_getArray(props); }
Array ArrayUtil::Slice(CArrRef input, int offset, int length, bool preserve_keys) { int num_in = input.size(); if (offset > num_in) { offset = num_in; } else if (offset < 0 && (offset = (num_in + offset)) < 0) { offset = 0; } if (length < 0) { length = num_in - offset + length; } else if (((unsigned)offset + (unsigned)length) > (unsigned)num_in) { length = num_in - offset; } Array out_hash = Array::Create(); int pos = 0; ArrayIter iter(input); bool supportRef = input->supportValueRef(); for (; pos < offset && iter; ++pos, ++iter) {} for (; pos < offset + length && iter; ++pos, ++iter) { bool doAppend = !preserve_keys && iter.first().isNumeric(); if (supportRef) { CVarRef v = iter.secondRef(); if (v.isReferenced()) v.setContagious(); if (doAppend) { out_hash.append(v); } else { out_hash.set(iter.first(), v); } } else { if (doAppend) { out_hash.append(iter.second()); } else { out_hash.set(iter.first(), iter.second()); } } } return out_hash; }
void EvalObjectData::o_getArray(Array &props, bool pubOnly /* = false */) const { if (!pubOnly) { String zero("\0", 1, AttachLiteral); for (ArrayIter it(m_privates); !it.end(); it.next()) { String prefix(zero); prefix += it.first(); prefix += zero; for (ArrayIter it2(it.second()); !it2.end(); it2.next()) { CVarRef v = it2.secondRef(); if (v.isInitialized()) { props.set(prefix + it2.first(), v.isReferenced() ? ref(v) : v); } } } } DynamicObjectData::o_getArray(props, pubOnly); if (pubOnly) { const ClassInfo *info = ClassInfo::FindClass(o_getClassName()); info->filterProperties(props, ClassInfo::IsProtected); } }
void VariableSerializer::writeArrayValue(const ArrayData *arr, CVarRef value) { // Do not count referenced values after the first if (m_type == Serialize && !(value.isReferenced() && m_arrayIds.find(value.getVariantData()) != m_arrayIds.end())) m_valueCount++; write(value); switch (m_type) { case PrintR: *m_out << '\n'; break; case VarExport: *m_out << ",\n"; break; default: break; } ArrayInfo &info = m_arrayInfos.back(); info.first_element = false; }
bool ArrayData::hasInternalReference(PointerSet &vars, bool ds /* = false */) const { if (isSharedMap()) return false; for (ArrayIter iter(this); iter; ++iter) { CVarRef var = iter.secondRef(); if (var.isReferenced()) { Variant *pvar = var.getVariantData(); if (vars.find(pvar) != vars.end()) { return true; } vars.insert(pvar); } if (var.isObject()) { ObjectData *pobj = var.getObjectData(); if (vars.find(pobj) != vars.end()) { return true; } vars.insert(pobj); if (pobj->o_instanceof("Serializable")) { if (ds) { // We want to detect Serializable object as well return true; } else { // Serializable object does not have internal reference issue return false; } } if (pobj->o_toArray().get()->hasInternalReference(vars, ds)) { return true; } } else if (var.isArray() && var.getArrayData()->hasInternalReference(vars, ds)) { return true; } } return false; }
void VariableSerializer::writeArrayValue(const ArrayData *arr, CVarRef value) { // Do not count referenced values after the first if ((m_type == Serialize || m_type == APCSerialize || m_type == DebuggerSerialize) && !(value.isReferenced() && m_arrayIds->find(value.getVariantData()) != m_arrayIds->end())) { m_valueCount++; } write(value); switch (m_type) { case PrintR: m_buf->append('\n'); break; case VarExport: m_buf->append(",\n"); break; default: break; } ArrayInfo &info = m_arrayInfos.back(); info.first_element = false; }