serde-generate/runtime/cpp/bincode.hpp (65 lines of code) (raw):

// Copyright (c) Facebook, Inc. and its affiliates // SPDX-License-Identifier: MIT OR Apache-2.0 #pragma once #include <cstdint> #include "binary.hpp" #include "serde.hpp" // Maximum length supported in practice (e.g. Java). constexpr size_t BINCODE_MAX_LENGTH = (1ull << 31) - 1; namespace serde { class BincodeSerializer : public BinarySerializer<BincodeSerializer> { using Parent = BinarySerializer<BincodeSerializer>; public: BincodeSerializer() : Parent(SIZE_MAX) {} void serialize_f32(float value); void serialize_f64(double value); void serialize_len(size_t value); void serialize_variant_index(uint32_t value); static constexpr bool enforce_strict_map_ordering = false; }; class BincodeDeserializer : public BinaryDeserializer<BincodeDeserializer> { using Parent = BinaryDeserializer<BincodeDeserializer>; public: BincodeDeserializer(std::vector<uint8_t> bytes) : Parent(std::move(bytes), SIZE_MAX) {} float deserialize_f32(); double deserialize_f64(); size_t deserialize_len(); uint32_t deserialize_variant_index(); static constexpr bool enforce_strict_map_ordering = false; }; // Native floats and doubles must be IEEE-754 values of the expected size. static_assert(std::numeric_limits<float>::is_iec559); static_assert(std::numeric_limits<double>::is_iec559); static_assert(sizeof(float) == sizeof(uint32_t)); static_assert(sizeof(double) == sizeof(uint64_t)); inline void BincodeSerializer::serialize_f32(float value) { Parent::serialize_u32(*reinterpret_cast<uint32_t *>(&value)); } inline void BincodeSerializer::serialize_f64(double value) { Parent::serialize_u64(*reinterpret_cast<uint64_t *>(&value)); } inline void BincodeSerializer::serialize_len(size_t value) { if (value > BINCODE_MAX_LENGTH) { throw serde::serialization_error("Length is too large"); } Parent::serialize_u64((uint64_t)value); } inline void BincodeSerializer::serialize_variant_index(uint32_t value) { Parent::serialize_u32((uint32_t)value); } inline float BincodeDeserializer::deserialize_f32() { auto value = Parent::deserialize_u32(); return *reinterpret_cast<float *>(&value); } inline double BincodeDeserializer::deserialize_f64() { auto value = Parent::deserialize_u64(); return *reinterpret_cast<double *>(&value); } inline size_t BincodeDeserializer::deserialize_len() { auto value = (size_t)Parent::deserialize_u64(); if (value > BINCODE_MAX_LENGTH) { throw serde::deserialization_error("Length is too large"); } return (size_t)value; } inline uint32_t BincodeDeserializer::deserialize_variant_index() { return Parent::deserialize_u32(); } } // end of namespace serde