Poco::BasicUnbufferedStreamBuf

C++中的流,至今依然是模模糊糊,看完模版累BasicUnbufferedStreamBuf后,对流的流程,稍微有点认知了。这是个模版基类,Base64DecoderBuf和Base64EecoderBuf都是继承自这个类。从名字上来看,它是没有缓冲区的。缓冲区的作用,是为了减少I/O操作,提高效率,所以流里面都有一个buffer。BasicUnbufferedStreamBuf的作用是起到流转换作用,包含这个buf的流,只要实现readFromDevice或writeToDevice就让通过这个流的数据发生自己想要的数据转换。Base64Encoder就是对数据进行Base64编码。

一、用做输出流

我们看一段Poco/Base64Test.cpp的测试代码,了解数据转换以及流是如何发生的。

std::ostringstream target;
Base64Encoder encoder(target);
encoder << std::string("\00\01\02\03\04\05", 6);  // 数据进到target流里的buffer时,就已经发生base64编码了
encoder.close();
assert (target.str() == "AAECAwQF");
Poco::BasicUnbufferedStreamBuf_第1张图片

上面代码第三步中的 << 流操作向流中输入数据,但encoder流自身是没有buffer的,这触发了std::streambuf::overflow操作,这是一个虚函数,在Base64Encoder类中是调用writeToDevice实现的,这个操作直接将编码后的数据输送到target中的buf中,所以最后,调用target.str() 可以得到编码后的数据。

BasicUnbufferedStreamBuf的构造函数

	BasicUnbufferedStreamBuf():
		_pb(char_traits::eof()),
		_ispb(false)
	{
		this->setg(0, 0, 0);
		this->setp(0, 0);
	}
将其内部缓冲去设为空,即没有缓冲区,数据直接被overflow到设备,而这里的设备指的是target的缓冲区。

二、用做输入流

这是一段base64解码的代码

std::istringstream istr("QUJDREVG");
Base64Decoder decoder(istr);
std::string s;
decoder >> s;
assert (s == "ABCDEF");

Poco::BasicUnbufferedStreamBuf_第2张图片

上面代码第四行中的 >> 操作会从内部buffer中拿数据,但内部是unbuffer的,所以触发了uflow操作,这个虚函数是内部调用readFromDevice实现的,而readFromDevice是从输入流istr中的缓冲区直接去数据,然后进行解码操作,再将解码后的数据返回。




你可能感兴趣的:(Poco::BasicUnbufferedStreamBuf)