text: #include "dvlnet/frame_queue.h"
  
  #include <cstring>
  
  #include "dvlnet/packet.h"
  
  namespace dvl {
  namespace net {
  
  framesize_t frame_queue::size()
  {
  	return current_size;
  }
  
  buffer_t frame_queue::read(framesize_t s)
  {
  	if (current_size < s)
  		throw frame_queue_exception();
  	buffer_t ret;
  	while (s > 0 && s >= buffer_deque.front().size()) {
  		s -= buffer_deque.front().size();
  		current_size -= buffer_deque.front().size();
  		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 += buf.size();
  	buffer_deque.push_back(std::move(buf));
  }
  
  bool frame_queue::packet_ready()
  {
  	if (!nextsize) {
  		if (size() < sizeof(framesize_t))
  			return false;
  		auto szbuf = read(sizeof(framesize_t));
  		std::memcpy(&nextsize, &szbuf[0], sizeof(framesize_t));
  		if (!nextsize)
  			throw frame_queue_exception();
  	}
  	if (size() >= nextsize)
  		return true;
  	else
  		return false;
  }
  
  buffer_t frame_queue::read_packet()
  {
  	if (!nextsize || (size() < nextsize))
  		throw frame_queue_exception();
  	auto ret = read(nextsize);
  	nextsize = 0;
  	return ret;
  }
  
  buffer_t frame_queue::make_frame(buffer_t packetbuf)
  {
  	buffer_t ret;
  	if (packetbuf.size() > max_frame_size)
  		ABORT();
  	framesize_t size = packetbuf.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 dvl
  