bool has_members(std::set<std::string> members_, const rapidjson::GenericValue<Encoding, Allocator>& v_) { if (v_.IsObject()) { for (auto i = v_.MemberBegin(), e = v_.MemberEnd(); i != e; ++i) { const auto& name = i->name; if (name.IsString()) { const auto m = members_.find( std::string(name.GetString(), name.GetStringLength())); if (m != members_.end()) { members_.erase(m); if (members_.empty()) { return true; } } } } return members_.empty(); } return false; }
bool member_compare(const std::set<std::string>& members_, const rapidjson::GenericValue<Encoding, Allocator>& v_) { if (v_.IsObject()) { decltype(members_.size()) n = 0; for (auto i = v_.MemberBegin(), e = v_.MemberEnd(); i != e; ++i) { const auto& name = i->name; if (!name.IsString() || members_.find( std::string(name.GetString(), name.GetStringLength())) == members_.end()) { return false; } if (ExpectFullMatch) { ++n; } } return !ExpectFullMatch || n == members_.size(); } else { return false; } }
size_t Page::insert(const rapidjson::GenericValue<rapidjson::UTF8<>>& value) { tasking::RWLockGuard<> lock(m_rwLock, tasking::WRITE); //here we know this page has one chunk big enough to fitt the whole object //including its overhead! so start inserting it. //get the object name std::string name = value.MemberBegin()->name.GetString(); //returns the pos of the first element needed for the headerdata auto firstElementPos = insertObject(value.MemberBegin()->value, nullptr).first; auto l_first = dist(m_body, firstElementPos); //insert the header HeaderMetaData* meta = insertHeader(m_objCount++, 0, common::FNVHash()(name), l_first); if (meta == nullptr) LOG_DEBUG << "wm"; //push the obj to obj index index::ObjectIndex::getInstance().add(meta->getOID(), index::ObjectIndexValue(this->m_id, dist(m_header, meta))); //done! return meta->getOID(); }
void JSObject::FillRecursive(const rapidjson::GenericValue<rapidjson::UTF8<wchar_t>> &val) { using namespace rapidjson; /**/ switch(val.GetType()) { case kNullType: //!< null value = JSValue(); break; case kFalseType: //!< false value = JSValue(false); break; case kTrueType: //!< true value = JSValue(true); break; case kObjectType: //!< object value.type = JSTypeObject; for(GenericValue<UTF8<wchar_t>>::ConstMemberIterator itr2 = val.MemberBegin(); itr2 != val.MemberEnd(); ++itr2) { children.push_back(std::make_pair(itr2->name.GetString(), JSObject())); children.back().second.FillRecursive(itr2->value); } break; case kArrayType: //!< array value.type = JSTypeObject; children.resize(val.Size()); for(SizeType i = 0; i < val.Size(); i++) { children[i].second.FillRecursive(val[i]); } break; case kStringType: //!< string value.str = val.GetString(); value.type = JSTypeString; break; case kNumberType: //!< number value = val.GetDouble(); break; } }
std::pair<void*, void*> Page::insertObject(const rapidjson::GenericValue<rapidjson::UTF8<>>& value, BaseType<size_t>* const last) { //return ptr to the first element void* l_ret = nullptr; //prev element ptr BaseType<size_t>* l_prev = last; //position pointer void* l_pos = nullptr; //get the members for (auto it = value.MemberBegin(); it != value.MemberEnd(); ++it) { switch (it->value.GetType()) { case rapidjson::kNullType: LOG_WARN << "null type: " << it->name.GetString(); continue; case rapidjson::kFalseType: case rapidjson::kTrueType: { l_pos = find(sizeof(BoolTyp)); void* l_new = new (l_pos) BoolTyp(it->value.GetBool()); if (l_prev != nullptr) l_prev->setNext(dist(l_prev, l_new)); //set the ret pointer if (l_ret == nullptr) l_ret = l_pos; } break; case rapidjson::kObjectType: { //pos for the obj id //and insert the ID of the obj l_pos = find(sizeof(ObjHashTyp)); std::string name = it->name.GetString(); auto hash = common::FNVHash()(name); void* l_new = new (l_pos) ObjHashTyp(hash); if (l_prev != nullptr) l_prev->setNext(dist(l_prev, l_new)); // pass the objid Object to the insertobj! // now recursive insert the obj // the second contains the last element inserted // l_pos current contains the last inserted element and get set to the // last element of the obj we insert l_pos = insertObject(it->value, RC(SizeTType*, l_new)).second; //set the ret pointer if (l_ret == nullptr) l_ret = l_new; } break; case rapidjson::kArrayType: { //now insert values l_pos = find(sizeof(ArrayType)); //insert the number of elements which follows size_t l_size = it->value.Size(); void* l_new = new(l_pos) ArrayType(l_size); //update prev if (l_prev != nullptr) l_prev->setNext(dist(l_prev, l_new)); //insert elements l_pos = insertArray(it->value, SC(SizeTType*, l_new)); //set the ret pointer if (l_ret == nullptr) l_ret = l_new; } break; case rapidjson::kStringType: { // find pos where the string fits // somehow we get here sometimes and it does not fit! // which cant be since we lock the whole page l_pos = find(sizeof(StringType) + it->value.GetStringLength()); //add the String Type at the pos of the FreeType auto* l_new = new (l_pos) StringType(it->value.GetString()); if (l_prev != nullptr) l_prev->setNext(dist(l_prev, l_new)); //set the ret pointer if (l_ret == nullptr) l_ret = l_pos; } break; case rapidjson::kNumberType: { //doesnt matter since long long and double are equal on // x64 //find pos where the string fits l_pos = find(sizeof(IntTyp)); void* l_new; if (it->value.IsInt() || it->value.IsInt64()) { //insert INT l_new = new (l_pos) IntTyp(it->value.GetInt64()); } else { //INSERT DOUBLE l_new = new (l_pos) DoubleTyp(it->value.GetDouble()); } if (l_prev != nullptr) l_prev->setNext(dist(l_prev, l_new)); //set the ret pointer if (l_ret == nullptr) l_ret = l_pos; } break; default: LOG_WARN << "Unknown member Type: " << it->name.GetString() << ":" << it->value.GetType(); continue; } //prev is the l_pos now so cast it to this; l_prev = RC(SizeTType*, l_pos); } //if we get here its in! return{ l_ret, l_pos }; }