/* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "stdafx.h" #include "scene/sn_utils.h" #include // sanity checks static_assert(std::numeric_limits::is_iec559, "IEEE754 required"); static_assert(sizeof(float) == 4, "Float must be 4 bytes"); static_assert(sizeof(double) == 8, "Double must be 8 bytes"); static_assert(-1 == ~0, "Two's complement required"); // deserialize little endian uint16 uint16_t sn_utils::ld_uint16(std::istream &s) { std::array buf{}; s.read(reinterpret_cast(buf.data()), buf.size()); auto v = static_cast(buf[1] << 8 | buf[0]); return v; } // deserialize little endian uint32 uint32_t sn_utils::ld_uint32(std::istream &s) { std::array buf{}; s.read(reinterpret_cast(buf.data()), buf.size()); uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; return v; } // deserialize little endian int32 int32_t sn_utils::ld_int32(std::istream &s) { std::array buf{}; s.read(reinterpret_cast(buf.data()), buf.size()); uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; return static_cast(v); } // deserialize little endian uint64 uint64_t sn_utils::ld_uint64(std::istream &s) { std::array buf{}; s.read(reinterpret_cast(buf.data()), buf.size()); uint64_t v = (uint64_t)buf[7] << 56 | (uint64_t)buf[6] << 48 | (uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 | (uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 | (uint64_t)buf[1] << 8 | (uint64_t)buf[0]; return v; } // deserialize little endian int64 int64_t sn_utils::ld_int64(std::istream &s) { std::array buf{}; s.read(reinterpret_cast(buf.data()), buf.size()); uint64_t v = (uint64_t)buf[7] << 56 | (uint64_t)buf[6] << 48 | (uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 | (uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 | (uint64_t)buf[1] << 8 | (uint64_t)buf[0]; return static_cast(v); } // deserialize little endian ieee754 float32 float sn_utils::ld_float32(std::istream &s) { std::array buf{}; s.read(reinterpret_cast(buf.data()), buf.size()); uint32_t v = buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; return std::bit_cast(v); } // deserialize little endian ieee754 float64 double sn_utils::ld_float64(std::istream &s) { std::array buf{}; s.read(reinterpret_cast(buf.data()), buf.size()); uint64_t v = (uint64_t)buf[7] << 56 | (uint64_t)buf[6] << 48 | (uint64_t)buf[5] << 40 | (uint64_t)buf[4] << 32 | (uint64_t)buf[3] << 24 | (uint64_t)buf[2] << 16 | (uint64_t)buf[1] << 8 | (uint64_t)buf[0]; return std::bit_cast(v); } // deserialize null-terminated string std::string sn_utils::d_str(std::istream &s) { std::string r; r.reserve(32); char c{}; while (true) { s.read(&c, 1); if (c == 0) break; r.push_back(c); } return r; } bool sn_utils::d_bool(std::istream& s) { return ld_uint16(s) == 1; } glm::dvec3 sn_utils::d_dvec3(std::istream& s) { return { ld_float64(s), ld_float64(s), ld_float64(s) }; } glm::vec3 sn_utils::d_vec3( std::istream& s ) { return { ld_float32(s), ld_float32(s), ld_float32(s) }; } glm::vec4 sn_utils::d_vec4( std::istream& s ) { return { ld_float32(s), ld_float32(s), ld_float32(s), ld_float32(s) }; } uint8_t sn_utils::d_uint8( std::istream& s ) { uint8_t buf; s.read((char*)&buf, 1); return buf; } void sn_utils::ls_uint16(std::ostream &s, uint16_t v) { std::array buf{}; buf[0] = static_cast(v); buf[1] = v >> 8; s.write(reinterpret_cast(buf.data()), buf.size()); } void sn_utils::ls_uint32(std::ostream &s, uint32_t v) { std::array buf{}; buf[0] = static_cast(v); buf[1] = static_cast(v >> 8); buf[2] = static_cast(v >> 16); buf[3] = v >> 24; s.write(reinterpret_cast(buf.data()), buf.size()); } void sn_utils::ls_int32(std::ostream &s, int32_t v) { std::array buf{}; buf[0] = static_cast(v); buf[1] = static_cast(v >> 8); buf[2] = static_cast(v >> 16); buf[3] = v >> 24; s.write(reinterpret_cast(buf.data()), buf.size()); } void sn_utils::ls_uint64(std::ostream &s, uint64_t v) { std::array buf{}; buf[0] = static_cast(v); buf[1] = static_cast(v >> 8); buf[2] = static_cast(v >> 16); buf[3] = static_cast(v >> 24); buf[4] = static_cast(v >> 32); buf[5] = static_cast(v >> 40); buf[6] = static_cast(v >> 48); buf[7] = v >> 56; s.write(reinterpret_cast(buf.data()), buf.size()); } void sn_utils::ls_int64(std::ostream &s, int64_t v) { std::array buf{}; buf[0] = static_cast(v); buf[1] = static_cast(v >> 8); buf[2] = static_cast(v >> 16); buf[3] = static_cast(v >> 24); buf[4] = static_cast(v >> 32); buf[5] = static_cast(v >> 40); buf[6] = static_cast(v >> 48); buf[7] = v >> 56; s.write(reinterpret_cast(buf.data()), buf.size()); } void sn_utils::ls_float32(std::ostream &s, float t) { auto v = std::bit_cast(t); std::array buf{}; buf[0] = static_cast(v); buf[1] = static_cast(v >> 8); buf[2] = static_cast(v >> 16); buf[3] = v >> 24; s.write(reinterpret_cast(buf.data()), buf.size()); } void sn_utils::ls_float64(std::ostream &s, double t) { auto v = std::bit_cast(t); std::array buf{}; buf[0] = static_cast(v); buf[1] = static_cast(v >> 8); buf[2] = static_cast(v >> 16); buf[3] = static_cast(v >> 24); buf[4] = static_cast(v >> 32); buf[5] = static_cast(v >> 40); buf[6] = static_cast(v >> 48); buf[7] = v >> 56; s.write(reinterpret_cast(buf.data()), buf.size()); } void sn_utils::s_uint8(std::ostream &s, uint8_t v) { s.write((char*)&v, 1); } void sn_utils::s_str(std::ostream &s, std::string const &v) { const char* buf = v.c_str(); s.write(buf, v.size() + 1); } void sn_utils::s_bool(std::ostream &s, bool v) { ls_uint16( s, true == v ? 1 : 0 ); } void sn_utils::s_dvec3(std::ostream &s, glm::dvec3 const &v) { ls_float64(s, v.x); ls_float64(s, v.y); ls_float64(s, v.z); } void sn_utils::s_vec3(std::ostream &s, glm::vec3 const &v) { ls_float32(s, v.x); ls_float32(s, v.y); ls_float32(s, v.z); } void sn_utils::s_vec4(std::ostream &s, glm::vec4 const &v) { ls_float32(s, v.x); ls_float32(s, v.y); ls_float32(s, v.z); ls_float32(s, v.w); }