Fragments::Fragments(IMC::Message* msg, int mtu) { m_uid = s_uid++; m_num_frags = 0; int frag_size = mtu - sizeof(IMC::Header) - 5; if (frag_size <= 0) { DUNE_ERR("Fragments", "MTU is too small"); return; } Utils::ByteBuffer buff; int size = IMC::Packet::serialize(msg, buff); uint8_t* buffer = buff.getBuffer(); int part = 0, pos = 0; m_num_frags = (int)std::ceil((float)size / (float)mtu); while (pos < size) { int remaining = size - pos; int cur_size = std::min(remaining, mtu); IMC::MessagePart* mpart = new IMC::MessagePart(); mpart->frag_number = part++; mpart->num_frags = m_num_frags; mpart->uid = m_uid; mpart->data.assign(buffer + pos, buffer + pos + cur_size); pos += cur_size; m_fragments.push_back(mpart); } }
Utils::ByteBuffer Decompressor::decompress(char* src, unsigned long src_len) { Utils::ByteBuffer dst; unsigned dst_len = 128 * 1024; dst.setSize(dst_len); decompress(dst.getBufferSigned(), dst.getSize(), src, src_len); dst.setSize(decompressed()); return dst; }
uint16_t Packet::serialize(const Message* msg, Utils::ByteBuffer& bfr) { unsigned size = msg->getSerializationSize(); if (size > 65535) throw InvalidMessageSize(size); bfr.setSize(size); return serialize(msg, bfr.getBuffer(), size); }
void GptPartitionTable::set_name(utils::ByteBuffer& bb, uint64_t _offset, const std::string& name) { std::size_t offset = std::size_t(_offset); auto chars_to_write = std::min(unsigned(name.size()), GPT_PARTITION_NAME_SIZE / 2); for (unsigned i = 0; i < chars_to_write; ++i) { bb.set_le16(offset + i * 2, uint16_t(name[i])); } // fill remaining bytes with zeros for (unsigned i = chars_to_write; i < GPT_PARTITION_NAME_SIZE / 2; ++i) { bb.set_le16(offset + i * 2, 0); } }
std::string GptPartitionTable::get_guid(const utils::ByteBuffer& bb, uint64_t _offset) { std::stringstream str{}; std::size_t offset = std::size_t(_offset); str << std::hex << std::uppercase << std::setfill('0'); str << std::setw(8) << bb.get_le32(offset + 0u) << "-" << std::setw(4) << bb.get_le16(offset + 4u) << "-" << std::setw(4) << bb.get_le16(offset + 6u) << "-" << std::setw(4) << bb.get_be16(offset + 8u) << "-" << std::setw(12) << bb.get_be48(offset + 10u); return str.str(); }
void GptPartitionTable::set_guid(utils::ByteBuffer& bb, uint64_t _offset, const std::string& guid) { std::size_t offset = std::size_t(_offset); static constexpr unsigned EXPECTED_MATCHES = 6; static constexpr int HEX_BASE = 16; std::regex expr("([0-9a-fA-F]{8})-([0-9a-fA-F]{4})-([0-9a-fA-F]{4})-([0-9a-fA-F]{4})-([0-9a-fA-F]{12})"); std::smatch match{}; if (!std::regex_match(guid, match, expr) || match.size() != EXPECTED_MATCHES) { throw std::runtime_error(std::string{"Invalid GUID format: "} + guid); } bb.set_le32(offset + 0, uint32_t(std::stoul(match[1].str(), nullptr, HEX_BASE))); bb.set_le16(offset + 4, uint16_t(std::stoul(match[2].str(), nullptr, HEX_BASE))); bb.set_le16(offset + 6, uint16_t(std::stoul(match[3].str(), nullptr, HEX_BASE))); bb.set_be16(offset + 8, uint16_t(std::stoul(match[4].str(), nullptr, HEX_BASE))); bb.set_be48(offset + 10, std::stoull(match[5].str(), nullptr, HEX_BASE)); }
std::string GptPartitionTable::get_name(const utils::ByteBuffer& bb, uint64_t _offset) { std::stringstream str{}; std::size_t offset = std::size_t(_offset); for (unsigned i = 0; i < GPT_PARTITION_NAME_SIZE / 2; ++i) { // two bytes per one char uint8_t ch = uint8_t(bb.get_le16(offset + i * 2)); if (ch != 0) { str << ch; } } return str.str(); }
void Compressor::compress(Utils::ByteBuffer& dst, char* src, unsigned long src_len) { unsigned bfr_size = compressBound(src_len); bool done = false; while (!done) { dst.setSize(bfr_size); try { compress(dst.getBufferSigned(), dst.getSize(), src, src_len); done = true; } catch (BufferTooShort& e) { (void)e; bfr_size <<= 1; } } dst.setSize(m_compressed); }
void Decompressor::decompress(Utils::ByteBuffer& dst, Utils::ByteBuffer& src) { decompress(dst.getBufferSigned(), dst.getSize(), src.getBufferSigned(), src.getSize()); dst.setSize(decompressed()); }
void Compressor::compress(Utils::ByteBuffer& dst, Utils::ByteBuffer& src) { return compress(dst, src.getBufferSigned(), src.getSize()); }