void tvCastToArrayInPlace(TypedValue* tv) { assert(tvIsPlausible(*tv)); tvUnboxIfNeeded(tv); ArrayData* a; do { switch (tv->m_type) { case KindOfUninit: case KindOfNull: a = ArrayData::Create(); continue; case KindOfBoolean: case KindOfInt64: case KindOfDouble: case KindOfPersistentString: a = ArrayData::Create(tvAsVariant(tv)); continue; case KindOfString: a = ArrayData::Create(tvAsVariant(tv)); tvDecRefStr(tv); continue; case KindOfPersistentArray: case KindOfArray: { ArrayData* adIn = tv->m_data.parr; if (adIn->isVecArray()) { tv->m_data.parr = PackedArray::MakeFromVec(adIn, adIn->cowCheck()); tv->m_type = KindOfArray; } else if (adIn->isDict()) { tv->m_data.parr = MixedArray::MakeFromDict(adIn, adIn->cowCheck()); tv->m_type = KindOfArray; } return; } case KindOfObject: // For objects, we fall back on the Variant machinery tvAsVariant(tv) = tv->m_data.pobj->toArray(); return; case KindOfResource: a = ArrayData::Create(tvAsVariant(tv)); tvDecRefRes(tv); continue; case KindOfRef: case KindOfClass: break; } not_reached(); } while (0); assert(!a->isRefCounted() || a->hasExactlyOneRef()); tv->m_data.parr = a; tv->m_type = KindOfArray; }
String HHVM_FUNCTION(serialize, const Variant& value) { switch (value.getType()) { case KindOfUninit: case KindOfNull: return s_Null; case KindOfBoolean: return value.getBoolean() ? s_True : s_False; case KindOfInt64: { StringBuffer sb; sb.append("i:"); sb.append(value.getInt64()); sb.append(';'); return sb.detach(); } case KindOfPersistentString: case KindOfString: { StringData *str = value.getStringData(); StringBuffer sb; sb.append("s:"); sb.append(str->size()); sb.append(":\""); sb.append(str->data(), str->size()); sb.append("\";"); return sb.detach(); } case KindOfResource: return s_Res; case KindOfPersistentArray: case KindOfArray: { ArrayData *arr = value.getArrayData(); if (arr->empty()) { if (arr->isVecArray()) return s_EmptyVecArray; if (arr->isDict()) return s_EmptyDictArray; return s_EmptyArray; } // fall-through } case KindOfDouble: case KindOfObject: { VariableSerializer vs(VariableSerializer::Type::Serialize); return vs.serialize(value, true); } case KindOfRef: case KindOfClass: break; } not_reached(); }