Пример #1
0
void Array::unserialize(VariableUnserializer *uns) {
    int64 size = uns->readInt();
    char sep = uns->readChar();
    if (sep != ':') {
        throw Exception("Expected ':' but got '%c'", sep);
    }
    sep = uns->readChar();
    if (sep != '{') {
        throw Exception("Expected '{' but got '%c'", sep);
    }

    if (size == 0) {
        operator=(Create());
    } else {
        // Pre-allocate an ArrayData of the given size, to avoid escalation in
        // the middle, which breaks references.
        operator=(ArrayInit(size).create());
        bool isAPC = (uns->getType() == VariableUnserializer::APCSerialize);
        for (int64 i = 0; i < size; i++) {
            Variant key(uns->unserializeKey());
            if (!key.isString() && !key.isInteger()) {
                throw Exception("Invalid key");
            }
            Variant &value = isAPC ? addLval(key, true) :
                             lvalAt(key, AccessFlags::Key);
            value.unserialize(uns);
        }
    }

    sep = uns->readChar();
    if (sep != '}') {
        throw Exception("Expected '}' but got '%c'", sep);
    }
}
Пример #2
0
Variant *Array::lvalPtr(CStrRef key, bool forWrite, bool create) {
  if (create) {
    if (!m_px) ArrayBase::operator=(ArrayData::Create());
    return &lvalAt(key, AccessFlags::Key);
  }
  Variant *ret = nullptr;
  if (m_px) {
    ArrayData *escalated = m_px->lvalPtr(key, ret,
                                         forWrite && m_px->getCount() > 1,
                                         false);
    if (escalated != m_px) ArrayBase::operator=(escalated);
  }
  return ret;
}
Пример #3
0
HOT_FUNC_HPHP
Variant *Array::lvalPtr(int64 key, bool forWrite, bool create) {
    if (create) {
        if (!m_px) {
            ArrayBase::operator=(ArrayData::Create());
        }
        return &lvalAt(key, AccessFlags::None);
    }
    Variant *ret = NULL;
    if (m_px) {
        ArrayData *escalated = m_px->lvalPtr(key, ret,
                                             forWrite && m_px->getCount() > 1,
                                             false);
        if (escalated) {
            ArrayBase::operator=(escalated);
        }
    }
    return ret;
}
Пример #4
0
Variant Array::refvalAt(CStrRef key, bool isString /* = false */) {
    return strongBind(lvalAt(key, AccessFlags::IsKey(isString)));
}