From 85fc73e0151ca42deeb3d7d51e3fe3c4abee1a08 Mon Sep 17 00:00:00 2001 From: BodgeMaster <> Date: Tue, 27 Dec 2022 17:28:11 +0100 Subject: [PATCH] lib/net/conversion/position.hpp: Add library Unit tests tbd --- src/lib/net/conversion/position.hpp | 68 +++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/lib/net/conversion/position.hpp diff --git a/src/lib/net/conversion/position.hpp b/src/lib/net/conversion/position.hpp new file mode 100644 index 0000000..05fc043 --- /dev/null +++ b/src/lib/net/conversion/position.hpp @@ -0,0 +1,68 @@ +// Copyright 2022, FOSS-VG Developers and Contributers +// +// Author(s): +// BodgeMaster, Shwoomple +// +// This program is free software: you can redistribute it and/or modify it +// under the terms of the GNU Affero General Public License as published +// by the Free Software Foundation, version 3. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +// See the GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// version 3 along with this program. +// If not, see https://www.gnu.org/licenses/agpl-3.0.en.html + +#include +#include + +#include "../../error.hpp" + +namespace Position { + struct Location { + // 26 bit integer + int32_t x; + // 12 bit integer + int16_t y; + // 26 bit integer + int32_t z; + } + + Location fromPosition(uint64_t position) { + Location location; + + location.x = (int32_t) ((0xFFFFFFC000000000 & position) >> 38); + if (location.x >= 0x02000000) { + location.x -= 0x04000000; + } + + location.y = (int16_t) ((0x0000000000000FFF & position)); + if (location.y >= 0x0800) { + location.y -= 0x1000; + } + + location.z = (int32_t) ((0x0000003FFFFFF000 & position) >> 12); + if (location.z >= 0x02000000) { + location.z -= 0x04000000; + } + } + + ErrorOr fromPosition(std::vector data, uint64_t initialPosition=0) { + if (inititalPosition >= data.size()) { + return ErrorOr(true, ErrorCodes::OUT_OF_BOUNDS); + } + if (initialPosition+7 >= data.size()) { + return ErrorOr(true, ErrorCodes::OVERRUN); + } + + uint64_t deserialized = 0; + for (uint8_t i=0; i<8; i++) { + deserialized += (uint64_t) data[initialPosition+i] << i*8; + } + + return ErrorOr(fromPosition(deserialized)); + } +}