#include "dvlnet/frame_queue.h" #include #include "appfat.h" #include "dvlnet/packet.h" #include "utils/attributes.h" namespace devilution { namespace net { namespace { PacketError FrameQueueError() { return PacketError("Incorrect frame size"); } } // namespace framesize_t frame_queue::Size() const { return current_size; } tl::expected frame_queue::Read(framesize_t s) { if (current_size < s) return tl::make_unexpected(FrameQueueError()); buffer_t ret; while (s > 0 && s >= buffer_deque.front().size()) { framesize_t bufferSize = static_cast(buffer_deque.front().size()); s -= bufferSize; current_size -= bufferSize; ret.insert(ret.end(), buffer_deque.front().begin(), buffer_deque.front().end()); buffer_deque.pop_front(); } if (s > 0) { ret.insert(ret.end(), buffer_deque.front().begin(), buffer_deque.front().begin() + s); buffer_deque.front().erase(buffer_deque.front().begin(), buffer_deque.front().begin() + s); current_size -= s; } return ret; } void frame_queue::Write(buffer_t buf) { current_size += static_cast(buf.size()); buffer_deque.push_back(std::move(buf)); } tl::expected frame_queue::PacketReady() { if (nextsize == 0) { if (Size() < sizeof(framesize_t)) return false; tl::expected szbuf = Read(sizeof(framesize_t)); if (!szbuf.has_value()) return tl::make_unexpected(szbuf.error()); std::memcpy(&nextsize, &(*szbuf)[0], sizeof(framesize_t)); if (nextsize == 0) return tl::make_unexpected(FrameQueueError()); } return Size() >= nextsize; } tl::expected frame_queue::ReadPacket() { if (nextsize == 0 || Size() < nextsize) return tl::make_unexpected(FrameQueueError()); tl::expected ret = Read(nextsize); nextsize = 0; return ret; } tl::expected frame_queue::MakeFrame(buffer_t packetbuf) { buffer_t ret; framesize_t size = static_cast(packetbuf.size()); if (size > max_frame_size) return tl::make_unexpected("Buffer exceeds maximum frame size"); ret.insert(ret.end(), packet_out::begin(size), packet_out::end(size)); ret.insert(ret.end(), packetbuf.begin(), packetbuf.end()); return ret; } } // namespace net } // namespace devilution