diff --git a/lib/Basics/VelocyPackHelper.cpp b/lib/Basics/VelocyPackHelper.cpp index d167b09714..07bdafa301 100644 --- a/lib/Basics/VelocyPackHelper.cpp +++ b/lib/Basics/VelocyPackHelper.cpp @@ -443,3 +443,59 @@ VPackBuilder VelocyPackHelper::merge(VPackSlice const& lhs, bool nullMeansRemove, bool mergeObjects) { return VPackCollection::merge(lhs, rhs, mergeObjects, nullMeansRemove); } + +double VelocyPackHelper::toDouble(VPackSlice const& slice, bool& failed) { + TRI_ASSERT(!slice.isNone()); + + failed = false; + switch (slice.type()) { + case VPackValueType::None: + case VPackValueType::Null: + return 0.0; + case VPackValueType::Bool: + return (slice.getBoolean() ? 1.0 : 0.0); + case VPackValueType::Double: + case VPackValueType::Int: + case VPackValueType::UInt: + case VPackValueType::SmallInt: + return slice.getNumericValue(); + case VPackValueType::String: + { + std::string tmp = slice.copyString(); + try { + // try converting string to number + return std::stod(tmp); + } catch (...) { + if (tmp.empty()) { + return 0.0; + } + // conversion failed + } + break; + } + case VPackValueType::Array: + { + VPackValueLength const n = slice.length(); + + if (n == 0) { + return 0.0; + } else if (n == 1) { + return VelocyPackHelper::toDouble(slice.at(0), failed); + } + break; + } + case VPackValueType::Object: + case VPackValueType::UTCDate: + case VPackValueType::External: + case VPackValueType::MinKey: + case VPackValueType::MaxKey: + case VPackValueType::Binary: + case VPackValueType::BCD: + case VPackValueType::Custom: + break; + } + + failed = true; + return 0.0; +} + diff --git a/lib/Basics/VelocyPackHelper.h b/lib/Basics/VelocyPackHelper.h index 4b79b34dfd..1f8be8120a 100644 --- a/lib/Basics/VelocyPackHelper.h +++ b/lib/Basics/VelocyPackHelper.h @@ -165,6 +165,13 @@ class VelocyPackHelper { static arangodb::velocypack::Builder merge(arangodb::velocypack::Slice const&, arangodb::velocypack::Slice const&, bool, bool); + + ////////////////////////////////////////////////////////////////////////////// + /// @brief Transforms any VelocyPack to a double value. The second parameter + /// indicates if the transformation was successful. + ////////////////////////////////////////////////////////////////////////////// + + static double toDouble(VPackSlice const&, bool&); }; } }