QBuffer
这是Qt的一个公有类,manual中说得很清楚:
- 为QByteArray提供了一个QIODevice的接口,使得该QByteArray可以作为一个random-accessed的普通文件对待。
所以,此处没多少可说的了。一个具体的例子(同样取自Qt的manual):
QImage image; QByteArray ba; QBuffer buffer(&ba); buffer.open(QIODevice::WriteOnly); image.save(&buffer, "PNG"); // writes image into ba in PNG format
QIODevicePrivateLinearBuffer
私有类 ./src/corelib/io/qiodevice_p.h
一个线性缓冲区,从头部读取数据,从尾部追加数据,也可以在头部插入数据。
class QIODevicePrivateLinearBuffer { public: QIODevicePrivateLinearBuffer(int); ~QIODevicePrivateLinearBuffer(); void clear(); int size() const; bool isEmpty() const; void skip(int n); int getChar(); int read(char* target, int size); char* reserve(int size); void chop(int size); QByteArray readAll(); int readLine(char* target, int size); bool canReadLine() const; void ungetChar(char c); void ungetBlock(const char* block, int size); };
- ungetChar()/ungetBlock() 用来向缓冲区头部追加数据
- reserve() 用来在尾部申请新的空间,并返回指针
- 一般需要配合chop() 使用,比如申请10个字节空间,只写入8个字节。需要chop(2)
- getChar()/read()/readAll()/readLine() 从头部读取数据
QRingBuffer
私有类 ./src/corelib/tools/qringbuffer_p.h
一个环形buffer,在尾部追加数据,从头部读取数据。适合用作IO的缓冲区
class QRingBuffer { public: inline QRingBuffer(int growth = 4096); inline const char *readPointer() const; inline const char *readPointerAtPosition(qint64 pos, qint64 &length) const; inline void free(int bytes); inline char *reserve(int bytes); inline void truncate(int pos); inline void chop(int bytes); inline bool isEmpty() const; inline int getChar(); inline void putChar(char c); inline void ungetChar(char c); inline int size() const; inline void clear(); inline int indexOf(char c) const; inline int indexOf(char c, int maxLength) const; inline int read(char *data, int maxLength); inline QByteArray read(int maxLength); inline QByteArray readAll(); inline QByteArray read(); inline void append(const QByteArray &qba); inline QByteArray peek(int maxLength) const; inline int skip(int length); inline int readLine(char *data, int maxLength); inline bool canReadLine() const; };
这个类挺复杂,不过多数成员函数,从名字上能猜个大概。
作为常规使用,我们需要从buffer中读取数据,可以使用:
- read()/readLine()/readAll()/getChar()
读数比较简单,而如何添加数据,有点不太直观
- 申请空间 reserve(),可得到一个指针
- 借助该指针,往空间写入数据 ...
- 如果申请了10个字节,而只写了8个字节,一定要用 chop() 切掉后面2个。
本来应该可以直接使用 append() 直接追加数据的,但是由于bug的存在,工作得并不好。
另外:ungetChar()/putChar() 分别是在缓冲区头部和尾部放置一个字符。
注:QRingBuffer内部是使用QList<QByteArray>构架的缓冲区。这样一来可以方便地在头部或尾部插入新的QByteArray.
QByteDataBuffer
Qt的私有类 ./src/corelib/tools/qbytedata_p.h
- this class handles a list of QByteArrays. It is a variant of QRingBuffer that avoid malloc/realloc/memcpy.
class QByteDataBuffer { public: QByteDataBuffer(); ~QByteDataBuffer(); inline void append(QByteDataBuffer& other); inline void append(const QByteArray& bd); inline void prepend(QByteArray& bd); inline QByteArray read(); inline QByteArray readAll(); inline QByteArray read(qint64 amount); qint64 read(char* dst, qint64 amount); inline char getChar(); inline void clear(); inline qint64 byteAmount() const; inline qint64 bufferCount() const; inline bool isEmpty() const; inline qint64 sizeNextBlock() const; inline QByteArray& operator[](int i); inline bool canReadLine() const; };
接口比 QRingBuffer 清晰很多,也更易用。
QDataBuffer
私有的Qt的模板类:./src/gui/painting/qdatabuffer_p.h
template <typename Type> class QDataBuffer { public: QDataBuffer(int res); ~QDataBuffer(); inline void reset(); inline bool isEmpty() const; inline int size() const; inline Type *data() const; inline Type &at(int i); inline const Type &at(int i) const; inline Type &last(); inline const Type &last() const; inline Type &first(); inline const Type &first() const; inline void add(const Type &t); inline void pop_back(); inline void resize(int size); inline void reserve(int size); inline void shrink(int size);; inline void swap(QDataBuffer<Type> &other); inline QDataBuffer &operator<<(const Type &t); };
模板函数,可返回首尾数据。
- first()
- last()
追加和弹出数据,每次一个
- add()
- pop_back()
调整缓冲区
- resize()
- reserve()
- shrink()
QTestCharBuffer
一个私有类: src/testlib/qabstracttestlogger_h
这个东西似乎没有什么功能。分配一个buffer,可以改变其大小,可以获取首地址。仅次而已?
struct QTestCharBuffer { inline QTestCharBuffer(); inline ~QTestCharBuffer(); inline char *data(); inline char **buffer(); inline const char* constData() const; inline int size() const; inline bool reset(int newSize); };
类内在栈上分配了一个固定大小512的字符数组:
- data()/constData() 返回字符数组首地址
- size() 返回字符数组的大小
前面说字符数组分配在栈上,但是为什么有一个reset()来改变buffer的大小呢?
- 恩,一旦调用该成员,将会在堆上分配一个指定大小的字符数组。