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的大小呢?
- 恩,一旦調用該成員,將會在堆上分配一個指定大小的字符數組。