Dictionary::Ptr ObjectQueryHandler::SerializeObjectAttrs(const Object::Ptr& object, const String& attrPrefix, const Array::Ptr& attrs, bool isJoin, bool allAttrs) { Type::Ptr type = object->GetReflectionType(); std::vector<int> fids; if (isJoin && attrs) { ObjectLock olock(attrs); for (const String& attr : attrs) { if (attr == attrPrefix) { allAttrs = true; break; } } } if (!isJoin && (!attrs || attrs->GetLength() == 0)) allAttrs = true; if (allAttrs) { for (int fid = 0; fid < type->GetFieldCount(); fid++) { fids.push_back(fid); } } else if (attrs) { ObjectLock olock(attrs); for (const String& attr : attrs) { String userAttr; if (isJoin) { String::SizeType dpos = attr.FindFirstOf("."); if (dpos == String::NPos) continue; String userJoinAttr = attr.SubStr(0, dpos); if (userJoinAttr != attrPrefix) continue; userAttr = attr.SubStr(dpos + 1); } else userAttr = attr; int fid = type->GetFieldId(userAttr); if (fid < 0) BOOST_THROW_EXCEPTION(ScriptError("Invalid field specified: " + userAttr)); fids.push_back(fid); } } DictionaryData resultAttrs; resultAttrs.reserve(fids.size()); for (int fid : fids) { Field field = type->GetFieldInfo(fid); Value val = object->GetField(fid); /* hide attributes which shouldn't be user-visible */ if (field.Attributes & FANoUserView) continue; /* hide internal navigation fields */ if (field.Attributes & FANavigation && !(field.Attributes & (FAConfig | FAState))) continue; Value sval = Serialize(val, FAConfig | FAState); resultAttrs.emplace_back(field.Name, sval); } return new Dictionary(std::move(resultAttrs)); }