当前位置: 首页 > 工具软件 > Quod Libet > 使用案例 >

基于select模型的windows网络库libet(五)Buffer

乌翰学
2023-12-01

Buffer.h

#pragma once
#include <algorithm>
#include <string>

#include "slice.h"
//#include "Logger.h"

//D_SCL_SECURE_NO_WARNINGS
//_SCL_SECURE_NO_WARNINGS
//std::copy : _DEPRECATE_UNCHECKED

struct Buffer {
	Buffer() : buf_(NULL), b_(0), e_(0), cap_(0), exp_(512) {}
	~Buffer() { delete[] buf_; }
	void clear() {
		/*if (buf_ == nullptr)
			LDebug("buf_ == nullptr");*/
		delete[] buf_;
		buf_ = NULL;
		cap_ = 0;
		b_ = e_ = 0;
	}
	size_t size() const { return e_ - b_; }
	bool empty() const { return e_ == b_; }
	char* data() const { return buf_ + b_; }
	char* begin() const { return buf_ + b_; }
	char* end() const { return buf_ + e_; }
	char* makeRoom(size_t len);
	void makeRoom() {
		if (space() < exp_)
			expand(0);
	}
	size_t space() const { return cap_ - e_; }	//缓存可用空间
	void addSize(size_t len) { e_ += len; }
	char *allocRoom(size_t len) {
		char *p = makeRoom(len);
		addSize(len);
		return p;
	}
	Buffer &append(const char *p, size_t len) {
		memcpy(allocRoom(len), p, len);
		return *this;
	}
	Buffer& append(std::string s) { return append(s.data(), s.size()); }
	Buffer &append(Slice slice) { return append(slice.data(), slice.size()); }
	Buffer &append(const char *p) { return append(p, strlen(p)); }
	template <class T>
	Buffer &appendValue(const T &v) {
		append((const char *)&v, sizeof v);
		return *this;
	}

	Buffer &consume(size_t len) {
		b_ += len;
		if (size() == 0)
			clear();
		return *this;
	}
	Buffer &absorb(Buffer &buf);
	void setSuggestSize(size_t sz) { exp_ = sz; }
	Buffer(const Buffer &b) { copyFrom(b); }
	Buffer &operator=(const Buffer &b) {
		if (this == &b)
			return *this;
		delete[] buf_;
		buf_ = NULL;
		copyFrom(b);
		return *this;
	}
	//转换为Slice
	operator Slice() { return Slice(data(), size()); }

private:
	char *buf_;
	size_t b_, e_, cap_, exp_;
	void moveHead() {
		//_DEPRECATE_UNCHECKED
		std::copy(begin(), end(), buf_);
		//std::copy_if(begin(), end(), buf_, )
		e_ -= b_; b_ = 0;
	}
	void expand(size_t len);	//增加buffer长度,类似于vector
	void copyFrom(const Buffer& b);
};

Buffer.cpp

#include "Buffer.h"

char *Buffer::makeRoom(size_t len)
{
	if (e_ + len <= cap_) {
	}
	else if (size() + len < cap_ / 2)
		moveHead();
	else
		expand(len);

	return end();
}

void Buffer::expand(size_t len) 
{
	size_t ncap = std::max(exp_, std::max(2 * cap_, size() + len));
	char *p = new char[ncap];
	std::copy(begin(), end(), p);
	e_ -= b_;
	b_ = 0;
	delete[] buf_;
	buf_ = p;
	cap_ = ncap;
}

void Buffer::copyFrom(const Buffer &b) 
{
	memcpy(this, &b, sizeof b);
	if (b.buf_) 
	{
		buf_ = new char[cap_];
		memcpy(data(), b.begin(), b.size());
	}
}

Buffer &Buffer::absorb(Buffer &buf) 
{
	if (&buf != this) 
	{
		if (size() == 0) 
		{
			char b[sizeof buf];
			memcpy(b, this, sizeof b);
			memcpy(this, &buf, sizeof b);
			memcpy(&buf, b, sizeof b);
			std::swap(exp_, buf.exp_);  // keep the origin exp_
		}
		else
		{
			append(buf.begin(), buf.size());
			buf.clear();
		}
	}
	return *this;
}

 

 类似资料: