bool Type::isFundamental() const { return isArithmetic() || isVoid(); }
bool Type::isScalar() const { return isArithmetic() || isEnum() || isPointer() || isMemberPointer(); }
std::vector<uint8_t> BsonSerializer::writeDocument(Bundle& value) const { std::vector<uint8_t> res; BufferWriter wrt(res); // Document length wrt.writeInt32(0); for (auto& elem : value) { auto info = elem.second.type_info(); if (info.isArithmetic()) { if (info.isFloatingPoint()) { wrt.writeUInt8(0x01); // double wrt.writeCString(elem.first); wrt.writeDouble(elem.second.as<double>()); } else { wrt.writeUInt8(0x12); // int64 wrt.writeCString(elem.first); wrt.writeInt64(elem.second.as<int64_t>()); } } else if (elem.second.isSerializable()) { wrt.writeUInt8(0x03); wrt.writeCString(elem.first); Bundle v = elem.second.serialize().as<Bundle>(); auto val = this->writeDocument(v); wrt.writeBytes(val.data(), val.size()); } else if (elem.second.isType<std::vector<AnyValue>>()) { wrt.writeUInt8(0x04); wrt.writeCString(elem.first); std::vector<AnyValue> v = elem.second.as<std::vector<AnyValue>>(); Bundle b; for (size_t i = 0; i < v.size(); i++) b.set(std::to_string(i), v[i]); auto val = this->writeDocument(b); wrt.writeBytes(val.data(), val.size()); } else if (elem.second.isType<std::vector<uint8_t>>()) { wrt.writeUInt8(0x05); wrt.writeCString(elem.first); std::vector<uint8_t> v = elem.second.as<std::vector<uint8_t>>(); if (v.size() > INT32_MAX) throw std::runtime_error("Data too large"); wrt.writeInt32((int32_t)v.size()); // Binary size wrt.writeUInt8(0x00); // Subtype wrt.writeBytes(v.data(), v.size()); // Data } else if (elem.second.isType<bool>()) { wrt.writeUInt8(0x08); wrt.writeCString(elem.first); bool v = elem.second.as<bool>(); wrt.writeUInt8(v ? 0x01 : 0x00); } else if (elem.second.isType<std::nullptr_t>()) { wrt.writeUInt8(0x0A); wrt.writeCString(elem.first); } else if (elem.second.isConvertibleTo<std::string>()) { wrt.writeUInt8(0x02); wrt.writeCString(elem.first); std::string v = elem.second.as<std::string>(); if (v.size() > INT32_MAX - 1) throw std::runtime_error("String too large"); wrt.writeInt32((int32_t)v.size() + 1); wrt.writeCString(v); } } wrt.writeUInt8(0x00); wrt.setPosition(0); wrt.setOverwrite(true); // Update Size value if (wrt.getSize() > INT32_MAX) throw std::runtime_error("Document to large"); wrt.writeInt32((int32_t)wrt.getSize()); return res; }