/src/qt/qtbase/src/corelib/tools/qbytedata_p.h

https://gitlab.com/x33n/phantomjs · C Header · 246 lines · 147 code · 35 blank · 64 comment · 18 complexity · 3fef7101d4cf9ba96a3715387f136d25 MD5 · raw file

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
  4. ** Contact: http://www.qt-project.org/legal
  5. **
  6. ** This file is part of the QtCore module of the Qt Toolkit.
  7. **
  8. ** $QT_BEGIN_LICENSE:LGPL$
  9. ** Commercial License Usage
  10. ** Licensees holding valid commercial Qt licenses may use this file in
  11. ** accordance with the commercial license agreement provided with the
  12. ** Software or, alternatively, in accordance with the terms contained in
  13. ** a written agreement between you and Digia. For licensing terms and
  14. ** conditions see http://qt.digia.com/licensing. For further information
  15. ** use the contact form at http://qt.digia.com/contact-us.
  16. **
  17. ** GNU Lesser General Public License Usage
  18. ** Alternatively, this file may be used under the terms of the GNU Lesser
  19. ** General Public License version 2.1 as published by the Free Software
  20. ** Foundation and appearing in the file LICENSE.LGPL included in the
  21. ** packaging of this file. Please review the following information to
  22. ** ensure the GNU Lesser General Public License version 2.1 requirements
  23. ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  24. **
  25. ** In addition, as a special exception, Digia gives you certain additional
  26. ** rights. These rights are described in the Digia Qt LGPL Exception
  27. ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
  28. **
  29. ** GNU General Public License Usage
  30. ** Alternatively, this file may be used under the terms of the GNU
  31. ** General Public License version 3.0 as published by the Free Software
  32. ** Foundation and appearing in the file LICENSE.GPL included in the
  33. ** packaging of this file. Please review the following information to
  34. ** ensure the GNU General Public License version 3.0 requirements will be
  35. ** met: http://www.gnu.org/copyleft/gpl.html.
  36. **
  37. **
  38. ** $QT_END_LICENSE$
  39. **
  40. ****************************************************************************/
  41. #ifndef QBYTEDATA_P_H
  42. #define QBYTEDATA_P_H
  43. //
  44. // W A R N I N G
  45. // -------------
  46. //
  47. // This file is not part of the Qt API. It exists purely as an
  48. // implementation detail. This header file may change from version to
  49. // version without notice, or even be removed.
  50. //
  51. // We mean it.
  52. //
  53. #include <qbytearray.h>
  54. QT_BEGIN_NAMESPACE
  55. // this class handles a list of QByteArrays. It is a variant of QRingBuffer
  56. // that avoid malloc/realloc/memcpy.
  57. class QByteDataBuffer
  58. {
  59. private:
  60. QList<QByteArray> buffers;
  61. qint64 bufferCompleteSize;
  62. qint64 firstPos;
  63. public:
  64. QByteDataBuffer() : bufferCompleteSize(0), firstPos(0)
  65. {
  66. }
  67. ~QByteDataBuffer()
  68. {
  69. clear();
  70. }
  71. static inline void popFront(QByteArray &ba, qint64 n)
  72. {
  73. ba = QByteArray(ba.constData() + n, ba.size() - n);
  74. }
  75. inline void squeezeFirst()
  76. {
  77. if (!buffers.isEmpty() && firstPos > 0) {
  78. popFront(buffers.first(), firstPos);
  79. firstPos = 0;
  80. }
  81. }
  82. inline void append(const QByteDataBuffer& other)
  83. {
  84. if (other.isEmpty())
  85. return;
  86. buffers.append(other.buffers);
  87. bufferCompleteSize += other.byteAmount();
  88. if (other.firstPos > 0)
  89. popFront(buffers[bufferCount() - other.bufferCount()], other.firstPos);
  90. }
  91. inline void append(const QByteArray& bd)
  92. {
  93. if (bd.isEmpty())
  94. return;
  95. buffers.append(bd);
  96. bufferCompleteSize += bd.size();
  97. }
  98. inline void prepend(const QByteArray& bd)
  99. {
  100. if (bd.isEmpty())
  101. return;
  102. squeezeFirst();
  103. buffers.prepend(bd);
  104. bufferCompleteSize += bd.size();
  105. }
  106. // return the first QByteData. User of this function has to free() its .data!
  107. // preferably use this function to read data.
  108. inline QByteArray read()
  109. {
  110. squeezeFirst();
  111. bufferCompleteSize -= buffers.first().size();
  112. return buffers.takeFirst();
  113. }
  114. // return everything. User of this function has to free() its .data!
  115. // avoid to use this, it might malloc and memcpy.
  116. inline QByteArray readAll()
  117. {
  118. return read(byteAmount());
  119. }
  120. // return amount. User of this function has to free() its .data!
  121. // avoid to use this, it might malloc and memcpy.
  122. inline QByteArray read(qint64 amount)
  123. {
  124. amount = qMin(byteAmount(), amount);
  125. QByteArray byteData;
  126. byteData.resize(amount);
  127. read(byteData.data(), byteData.size());
  128. return byteData;
  129. }
  130. // return amount bytes. User of this function has to free() its .data!
  131. // avoid to use this, it will memcpy.
  132. qint64 read(char* dst, qint64 amount)
  133. {
  134. amount = qMin(amount, byteAmount());
  135. qint64 originalAmount = amount;
  136. char *writeDst = dst;
  137. while (amount > 0) {
  138. const QByteArray &first = buffers.first();
  139. qint64 firstSize = first.size() - firstPos;
  140. if (amount >= firstSize) {
  141. // take it completely
  142. bufferCompleteSize -= firstSize;
  143. amount -= firstSize;
  144. memcpy(writeDst, first.constData() + firstPos, firstSize);
  145. writeDst += firstSize;
  146. firstPos = 0;
  147. buffers.takeFirst();
  148. } else {
  149. // take a part of it & it is the last one to take
  150. bufferCompleteSize -= amount;
  151. memcpy(writeDst, first.constData() + firstPos, amount);
  152. firstPos += amount;
  153. amount = 0;
  154. }
  155. }
  156. return originalAmount;
  157. }
  158. inline char getChar()
  159. {
  160. char c;
  161. read(&c, 1);
  162. return c;
  163. }
  164. inline void clear()
  165. {
  166. buffers.clear();
  167. bufferCompleteSize = 0;
  168. firstPos = 0;
  169. }
  170. // The byte count of all QByteArrays
  171. inline qint64 byteAmount() const
  172. {
  173. return bufferCompleteSize;
  174. }
  175. // the number of QByteArrays
  176. inline qint64 bufferCount() const
  177. {
  178. return buffers.length();
  179. }
  180. inline bool isEmpty() const
  181. {
  182. return byteAmount() == 0;
  183. }
  184. inline qint64 sizeNextBlock() const
  185. {
  186. if(buffers.isEmpty())
  187. return 0;
  188. else
  189. return buffers.first().size() - firstPos;
  190. }
  191. inline QByteArray& operator[](int i)
  192. {
  193. if (i == 0)
  194. squeezeFirst();
  195. return buffers[i];
  196. }
  197. inline bool canReadLine() const {
  198. int i = 0;
  199. if (i < buffers.length()) {
  200. if (buffers.at(i).indexOf('\n', firstPos) != -1)
  201. return true;
  202. ++i;
  203. for (; i < buffers.length(); i++)
  204. if (buffers.at(i).contains('\n'))
  205. return true;
  206. }
  207. return false;
  208. }
  209. };
  210. QT_END_NAMESPACE
  211. #endif // QBYTEDATA_P_H