/* Copyright (C) 2011 Her Majesty the Queen in Right of Canada (Communications Research Center Canada) Copyright (C) 2018 Matthias P. Braendli, matthias.braendli@mpb.li http://opendigitalradio.org */ /* This file is part of ODR-DabMod. ODR-DabMod is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. ODR-DabMod 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 General Public License for more details. You should have received a copy of the GNU General Public License along with ODR-DabMod. If not, see . */ #include "Buffer.h" #include "PcDebug.h" #include #include #include #include #include Buffer::Buffer(size_t len, const void *data) { PDEBUG("Buffer::Buffer(%zu, %p)\n", len, data); m_len = 0; m_capacity = 0; m_data = nullptr; setData(data, len); } Buffer::Buffer(const Buffer& other) { setData(other.m_data, other.m_len); } Buffer::Buffer(Buffer&& other) { m_len = other.m_len; m_capacity = other.m_capacity; m_data = other.m_data; other.m_len = 0; other.m_capacity = 0; other.m_data = nullptr; } Buffer::Buffer(const std::vector& vec) { PDEBUG("Buffer::Buffer(vector [%zu])\n", vec.size()); m_len = 0; m_capacity = 0; m_data = nullptr; setData(vec.data(), vec.size()); } Buffer::~Buffer() { PDEBUG("Buffer::~Buffer() len=%zu, data=%p\n", m_len, m_data); if (m_data) { free(m_data); } } void Buffer::swap(Buffer& other) { std::swap(m_len, other.m_len); std::swap(m_capacity, other.m_capacity); std::swap(m_data, other.m_data); } Buffer& Buffer::operator=(const Buffer& other) { if (&other != this) { setData(other.m_data, other.m_len); } return *this; } Buffer& Buffer::operator=(Buffer&& other) { if (&other != this) { m_len = other.m_len; m_capacity = other.m_capacity; if (m_data != nullptr) { free(m_data); } m_data = other.m_data; other.m_len = 0; other.m_capacity = 0; other.m_data = nullptr; } return *this; } Buffer& Buffer::operator=(const std::vector& buf) { setData(buf.data(), buf.size()); return *this; } Buffer& Buffer::operator+=(const Buffer& other) { appendData(other.m_data, other.m_len); return *this; } void Buffer::setLength(size_t len) { if (len > m_capacity) { void *tmp = m_data; /* Align to 32-byte boundary for AVX. */ const int ret = posix_memalign(&m_data, 32, len); if (ret != 0) { throw std::runtime_error("memory allocation failed: " + std::to_string(ret)); } if (tmp != nullptr) { memcpy(m_data, tmp, m_len); free(tmp); } m_capacity = len; } m_len = len; } void Buffer::setData(const void *data, size_t len) { setLength(0); appendData(data, len); } uint8_t Buffer::operator[](size_t i) const { if (i >= m_len) { throw std::out_of_range("index out of range"); } return reinterpret_cast(m_data)[i]; } void Buffer::appendData(const void *data, size_t len) { size_t offset = m_len; setLength(m_len + len); if (data != nullptr) { memcpy((char*)m_data + offset, data, len); } } void swap(Buffer& buf1, Buffer& buf2) { buf1.swap(buf2); }