diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2022-01-20 21:02:35 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2022-01-21 08:51:01 +0100 |
commit | 4871cae48c1c9f522a0c0cc85a852b0568ca31e6 (patch) | |
tree | f4f98dc69c0ad28f9bfda7d85a315c4c62549f2d /comphelper | |
parent | b438a4502d2b388012b0744374e86d1ff0543e8d (diff) |
comphelper: move JsonToPropertyValues() from desktop/
Because filter/ code will need this in a bit, and that can't depend on
desktop/.
Change-Id: I07f0f8ef30942a2d11388c6721c7f277e117bfba
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/128709
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'comphelper')
-rw-r--r-- | comphelper/source/misc/sequenceashashmap.cxx | 137 |
1 files changed, 137 insertions, 0 deletions
diff --git a/comphelper/source/misc/sequenceashashmap.cxx b/comphelper/source/misc/sequenceashashmap.cxx index eb78e60c55d2..c6ac57326935 100644 --- a/comphelper/source/misc/sequenceashashmap.cxx +++ b/comphelper/source/misc/sequenceashashmap.cxx @@ -19,11 +19,82 @@ #include <sal/config.h> +#include <boost/property_tree/json_parser.hpp> + #include <com/sun/star/beans/NamedValue.hpp> #include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/reflection/XIdlField.hpp> +#include <com/sun/star/reflection/theCoreReflection.hpp> #include <comphelper/sequenceashashmap.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/propertysequence.hxx> +#include <sal/log.hxx> + +using namespace com::sun::star; +namespace +{ +uno::Any jsonToUnoAny(const boost::property_tree::ptree& aTree) +{ + uno::Any aAny; + uno::Any aValue; + sal_Int32 nFields; + uno::Reference<reflection::XIdlField> aField; + boost::property_tree::ptree aNodeNull, aNodeValue, aNodeField; + const std::string& rType = aTree.get<std::string>("type", ""); + const std::string& rValue = aTree.get<std::string>("value", ""); + uno::Sequence<uno::Reference<reflection::XIdlField>> aFields; + uno::Reference<reflection::XIdlClass> xIdlClass + = css::reflection::theCoreReflection::get(comphelper::getProcessComponentContext()) + ->forName(OUString::fromUtf8(rType.c_str())); + if (xIdlClass.is()) + { + uno::TypeClass aTypeClass = xIdlClass->getTypeClass(); + xIdlClass->createObject(aAny); + aFields = xIdlClass->getFields(); + nFields = aFields.getLength(); + aNodeValue = aTree.get_child("value", aNodeNull); + if (nFields > 0 && aNodeValue != aNodeNull) + { + for (sal_Int32 itField = 0; itField < nFields; ++itField) + { + aField = aFields[itField]; + aNodeField = aNodeValue.get_child(aField->getName().toUtf8().getStr(), aNodeNull); + if (aNodeField != aNodeNull) + { + aValue = jsonToUnoAny(aNodeField); + aField->set(aAny, aValue); + } + } + } + else if (!rValue.empty()) + { + if (aTypeClass == uno::TypeClass_VOID) + aAny.clear(); + else if (aTypeClass == uno::TypeClass_BYTE) + aAny <<= static_cast<sal_Int8>(OString(rValue.c_str()).toInt32()); + else if (aTypeClass == uno::TypeClass_BOOLEAN) + aAny <<= OString(rValue.c_str()).toBoolean(); + else if (aTypeClass == uno::TypeClass_SHORT) + aAny <<= static_cast<sal_Int16>(OString(rValue.c_str()).toInt32()); + else if (aTypeClass == uno::TypeClass_UNSIGNED_SHORT) + aAny <<= static_cast<sal_uInt16>(OString(rValue.c_str()).toUInt32()); + else if (aTypeClass == uno::TypeClass_LONG) + aAny <<= OString(rValue.c_str()).toInt32(); + else if (aTypeClass == uno::TypeClass_UNSIGNED_LONG) + aAny <<= static_cast<sal_uInt32>(OString(rValue.c_str()).toInt32()); + else if (aTypeClass == uno::TypeClass_FLOAT) + aAny <<= OString(rValue.c_str()).toFloat(); + else if (aTypeClass == uno::TypeClass_DOUBLE) + aAny <<= OString(rValue.c_str()).toDouble(); + else if (aTypeClass == uno::TypeClass_STRING) + aAny <<= OUString::fromUtf8(rValue.c_str()); + } + } + return aAny; +} +} namespace comphelper{ @@ -234,6 +305,72 @@ void SequenceAsHashMap::update(const SequenceAsHashMap& rUpdate) } } +std::vector<css::beans::PropertyValue> JsonToPropertyValues(const OString& rJson) +{ + std::vector<beans::PropertyValue> aArguments; + boost::property_tree::ptree aTree, aNodeNull, aNodeValue; + std::stringstream aStream(rJson.getStr()); + boost::property_tree::read_json(aStream, aTree); + + for (const auto& rPair : aTree) + { + const std::string& rType = rPair.second.get<std::string>("type", ""); + const std::string& rValue = rPair.second.get<std::string>("value", ""); + + beans::PropertyValue aValue; + aValue.Name = OUString::fromUtf8(rPair.first.c_str()); + if (rType == "string") + aValue.Value <<= OUString::fromUtf8(rValue.c_str()); + else if (rType == "boolean") + aValue.Value <<= OString(rValue.c_str()).toBoolean(); + else if (rType == "float") + aValue.Value <<= OString(rValue.c_str()).toFloat(); + else if (rType == "long") + aValue.Value <<= OString(rValue.c_str()).toInt32(); + else if (rType == "short") + aValue.Value <<= sal_Int16(OString(rValue.c_str()).toInt32()); + else if (rType == "unsigned short") + aValue.Value <<= sal_uInt16(OString(rValue.c_str()).toUInt32()); + else if (rType == "int64") + aValue.Value <<= OString(rValue.c_str()).toInt64(); + else if (rType == "int32") + aValue.Value <<= OString(rValue.c_str()).toInt32(); + else if (rType == "int16") + aValue.Value <<= sal_Int16(OString(rValue.c_str()).toInt32()); + else if (rType == "uint64") + aValue.Value <<= OString(rValue.c_str()).toUInt64(); + else if (rType == "uint32") + aValue.Value <<= OString(rValue.c_str()).toUInt32(); + else if (rType == "uint16") + aValue.Value <<= sal_uInt16(OString(rValue.c_str()).toUInt32()); + else if (rType == "[]byte") + { + aNodeValue = rPair.second.get_child("value", aNodeNull); + if (aNodeValue != aNodeNull && aNodeValue.size() == 0) + { + uno::Sequence<sal_Int8> aSeqByte(reinterpret_cast<const sal_Int8*>(rValue.c_str()), + rValue.size()); + aValue.Value <<= aSeqByte; + } + } + else if (rType == "[]any") + { + aNodeValue = rPair.second.get_child("value", aNodeNull); + if (aNodeValue != aNodeNull && !aNodeValue.empty()) + { + uno::Sequence<uno::Any> aSeq(aNodeValue.size()); + std::transform(aNodeValue.begin(), aNodeValue.end(), aSeq.getArray(), + [](const auto& rSeqPair) { return jsonToUnoAny(rSeqPair.second); }); + aValue.Value <<= aSeq; + } + } + else + SAL_WARN("comphelper", "JsonToPropertyValues: unhandled type '" << rType << "'"); + aArguments.push_back(aValue); + } + return aArguments; +} + } // namespace comphelper /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |