Loading...
/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- * * Copyright (c) 2021 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ #include <bit> #include "Defines.h" #include "BitUtils.h" #include "PVLEInt64.h" namespace lsl { void emitPVLEUInt64(uint64_t value, Vector<std::byte>& data) { auto valueBytes = (std::byte*)&value; const uint8_t activeBits = std::max<uint8_t>(lsl::bit_width(value),1); if (activeBits > 56) { data.push_back((std::byte)0); std::copy(&valueBytes[0], &valueBytes[8], std::back_inserter(data)); return; } const uint8_t bytes = (activeBits+6)/7; value <<= bytes; value |= 1<<(bytes-1); std::copy(&valueBytes[0], &valueBytes[bytes], std::back_inserter(data)); } uint64_t readPVLEUInt64(std::span<std::byte>& data) { uint64_t result = 0; contract(data.size() != 0); const uint8_t additionalByteCount = std::countr_zero((uint8_t)data[0]); if (additionalByteCount == 8) { std::copy(&data[1], &data[9], (std::byte*)&result); data = data.last(data.size()-9); return result; } contract(data.size() >= 1+additionalByteCount); const uint8_t extraBitCount = 8 - (additionalByteCount+1); const uint8_t extraBits = (((uint8_t)(data[0]))>>(additionalByteCount+1)) & ((1<<extraBitCount)-1); std::copy(&data[1], &data[additionalByteCount+1], (std::byte*)&result); result <<= extraBitCount; result |= extraBits; data = data.last(data.size()-(additionalByteCount+1)); return result; } void emitPVLEInt64(int64_t value, Vector<std::byte>& data) { emitPVLEUInt64((value >> 63) ^ (value << 1), data); } int64_t readPVLEInt64(std::span<std::byte>& data) { uint64_t value = readPVLEUInt64(data); return ((value & 1) ? (value >> 1) ^ -1 : (value >> 1)); } }; |