Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
bitstreams_p.h
Go to the documentation of this file.
1// Copyright (C) 2018 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:critical reason:network-protocol
4
5#ifndef BITSTREAMS_P_H
6#define BITSTREAMS_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists for the convenience
13// of other Qt classes. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <QtCore/private/qtcoreglobal_p.h>
20#include <QtCore/qassert.h>
21#include <QtCore/qtclasshelpermacros.h>
22#include <QtCore/qtypes.h>
23
24#include <type_traits>
25#include <algorithm>
26#include <vector>
27
28QT_BEGIN_NAMESPACE
29
30class QByteArray;
31class QByteArrayView;
32
33namespace HPack
34{
35
36// BitOStream works with an external buffer,
37// for example, HEADERS frame.
38class Q_AUTOTEST_EXPORT BitOStream
39{
40public:
42
43 // Write 'bitLength' bits from the least significant
44 // bits in 'bits' to bitstream:
46 // HPACK data format, we support:
47 // * 32-bit integers
48 // * strings
49 void write(quint32 src);
51
52 quint64 bitLength() const;
53 quint64 byteLength() const;
54 const uchar *begin() const;
55 const uchar *end() const;
56
57 void clear();
58
59private:
61
64};
65
66class Q_AUTOTEST_EXPORT BitIStream
67{
68public:
69 // Error is set by 'read' functions.
70 // 'peek' does not set the error,
71 // since it just peeks some bits
72 // without the notion of wrong/right.
73 // 'read' functions only change 'streamOffset'
74 // on success.
82
83 BitIStream();
84 BitIStream(const uchar *f, const uchar *l);
85
86 quint64 bitLength() const;
87 bool hasMoreBits() const;
88
89 // peekBits tries to read 'length' bits from the bitstream into
90 // 'dst' ('length' must be <= sizeof(dst) * 8), packing them
91 // starting from the most significant bit of the most significant
92 // byte. It's a template so that we can use it with different
93 // integer types. Returns the number of bits actually read.
94 // Does not change stream's offset.
95
96 template<class T>
98 {
99 static_assert(std::is_unsigned<T>::value, "peekBits: unsigned integer type expected");
100
102 Q_ASSERT(length <= sizeof(T) * 8);
103
104 if (from >= bitLength() || !length)
105 return 0;
106
107 T &dst = *dstPtr;
108 dst = T();
110
111 const uchar *srcByte = first + from / 8;
112 auto bitsToRead = length + from % 8;
113
114 while (bitsToRead > 8) {
115 dst = (dst << 8) | *srcByte;
116 bitsToRead -= 8;
117 ++srcByte;
118 }
119
120 dst <<= bitsToRead;
121 dst |= *srcByte >> (8 - bitsToRead);
122 dst <<= sizeof(T) * 8 - length;
123
124 return length;
125 }
126
128 {
129 return offset;
130 }
131
132 bool skipBits(quint64 nBits);
134
135 bool read(quint32 *dstPtr);
136 bool read(QByteArray *dstPtr);
137
138 Error error() const;
139
140private:
141 void setError(Error newState);
142
143 const uchar *first;
144 const uchar *last;
147};
148
149} // namespace HPack
150
151QT_END_NAMESPACE
152
153#endif