summaryrefslogtreecommitdiff
path: root/src/mongo/platform
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/platform')
-rw-r--r--src/mongo/platform/decimal128.cpp27
-rw-r--r--src/mongo/platform/decimal128.h39
2 files changed, 66 insertions, 0 deletions
diff --git a/src/mongo/platform/decimal128.cpp b/src/mongo/platform/decimal128.cpp
index 0d12479f70a..630d2037b50 100644
--- a/src/mongo/platform/decimal128.cpp
+++ b/src/mongo/platform/decimal128.cpp
@@ -1044,4 +1044,31 @@ std::ostream& operator<<(std::ostream& stream, const Decimal128& value) {
return stream << value.toString();
}
+void DataType::Handler<Decimal128>::unsafeLoad(Decimal128* valueOut,
+ const char* ptr,
+ size_t* advanced) {
+ if (valueOut) {
+ ConstDataView decimalView(ptr);
+ uint64_t low = decimalView.read<LittleEndian<uint64_t>>();
+ uint64_t high = decimalView.read<LittleEndian<uint64_t>>(sizeof(uint64_t));
+ *valueOut = Decimal128(Decimal128::Value{low, high});
+ }
+
+ if (advanced) {
+ *advanced = kSizeOfDecimal;
+ }
+}
+
+void DataType::Handler<Decimal128>::unsafeStore(const Decimal128& valueIn,
+ char* ptr,
+ size_t* advanced) {
+ DataView decimalView(ptr);
+ decimalView.write<LittleEndian<uint64_t>>(valueIn.getValue().low64, 0);
+ decimalView.write<LittleEndian<uint64_t>>(valueIn.getValue().high64, sizeof(uint64_t));
+
+ if (advanced) {
+ *advanced = kSizeOfDecimal;
+ }
+}
+
} // namespace mongo
diff --git a/src/mongo/platform/decimal128.h b/src/mongo/platform/decimal128.h
index 64306df0e0c..f14e6b6d73b 100644
--- a/src/mongo/platform/decimal128.h
+++ b/src/mongo/platform/decimal128.h
@@ -39,6 +39,7 @@
#include "mongo/config.h"
+#include "mongo/base/data_type.h"
#include "mongo/util/assert_util.h"
namespace mongo {
@@ -635,4 +636,42 @@ inline bool operator!=(const Decimal128& lhs, const Decimal128& rhs) {
} // namespace literals
+template <>
+struct DataType::Handler<Decimal128> {
+ static void unsafeLoad(Decimal128* valueOut, const char* ptr, size_t* advanced);
+ static void unsafeStore(const Decimal128& valueIn, char* ptr, size_t* advanced);
+
+ static Status load(Decimal128* valueOut,
+ const char* ptr,
+ size_t length,
+ size_t* advanced,
+ std::ptrdiff_t debug_offset) {
+ if (length < kSizeOfDecimal) {
+ return Status(ErrorCodes::Overflow, "Buffer too small to hold Decimal128 value");
+ }
+
+ unsafeLoad(valueOut, ptr, advanced);
+ return Status::OK();
+ }
+
+ static Status store(const Decimal128& valueIn,
+ char* ptr,
+ size_t length,
+ size_t* advanced,
+ std::ptrdiff_t debug_offset) {
+ if (length < kSizeOfDecimal) {
+ return Status(ErrorCodes::Overflow, "Buffer too small to write Decimal128 value");
+ }
+
+ unsafeStore(valueIn, ptr, advanced);
+ return Status::OK();
+ }
+
+ static Decimal128 defaultConstruct() {
+ return Decimal128();
+ }
+
+ static constexpr size_t kSizeOfDecimal = 2 * sizeof(uint64_t);
+};
+
} // namespace mongo