62 #include "private/qobject_p.h" |
62 #include "private/qobject_p.h" |
63 #endif |
63 #endif |
64 |
64 |
65 QT_BEGIN_NAMESPACE |
65 QT_BEGIN_NAMESPACE |
66 |
66 |
|
67 #ifndef QIODEVICE_BUFFERSIZE |
|
68 #define QIODEVICE_BUFFERSIZE Q_INT64_C(16384) |
|
69 #endif |
|
70 |
|
71 // This is QIODevice's read buffer, optimised for read(), isEmpty() and getChar() |
|
72 class QIODevicePrivateLinearBuffer |
|
73 { |
|
74 public: |
|
75 QIODevicePrivateLinearBuffer(int) : len(0), first(0), buf(0), capacity(0) { |
|
76 } |
|
77 ~QIODevicePrivateLinearBuffer() { |
|
78 delete [] buf; |
|
79 } |
|
80 void clear() { |
|
81 first = buf; |
|
82 len = 0; |
|
83 } |
|
84 int size() const { |
|
85 return len; |
|
86 } |
|
87 bool isEmpty() const { |
|
88 return len == 0; |
|
89 } |
|
90 void skip(int n) { |
|
91 if (n >= len) { |
|
92 clear(); |
|
93 } else { |
|
94 len -= n; |
|
95 first += n; |
|
96 } |
|
97 } |
|
98 int getChar() { |
|
99 if (len == 0) |
|
100 return -1; |
|
101 int ch = uchar(*first); |
|
102 len--; |
|
103 first++; |
|
104 return ch; |
|
105 } |
|
106 int read(char* target, int size) { |
|
107 int r = qMin(size, len); |
|
108 memcpy(target, first, r); |
|
109 len -= r; |
|
110 first += r; |
|
111 return r; |
|
112 } |
|
113 char* reserve(int size) { |
|
114 makeSpace(size + len, freeSpaceAtEnd); |
|
115 char* writePtr = first + len; |
|
116 len += size; |
|
117 return writePtr; |
|
118 } |
|
119 void chop(int size) { |
|
120 if (size >= len) { |
|
121 clear(); |
|
122 } else { |
|
123 len -= size; |
|
124 } |
|
125 } |
|
126 QByteArray readAll() { |
|
127 char* f = first; |
|
128 int l = len; |
|
129 clear(); |
|
130 return QByteArray(f, l); |
|
131 } |
|
132 int readLine(char* target, int size) { |
|
133 int r = qMin(size, len); |
|
134 char* eol = static_cast<char*>(memchr(first, '\n', r)); |
|
135 if (eol) |
|
136 r = 1+(eol-first); |
|
137 memcpy(target, first, r); |
|
138 len -= r; |
|
139 first += r; |
|
140 return int(r); |
|
141 } |
|
142 bool canReadLine() const { |
|
143 return memchr(first, '\n', len); |
|
144 } |
|
145 void ungetChar(char c) { |
|
146 if (first == buf) { |
|
147 // underflow, the existing valid data needs to move to the end of the (potentially bigger) buffer |
|
148 makeSpace(len+1, freeSpaceAtStart); |
|
149 } |
|
150 first--; |
|
151 len++; |
|
152 *first = c; |
|
153 } |
|
154 |
|
155 private: |
|
156 enum FreeSpacePos {freeSpaceAtStart, freeSpaceAtEnd}; |
|
157 void makeSpace(size_t required, FreeSpacePos where) { |
|
158 size_t newCapacity = qMax(capacity, size_t(QIODEVICE_BUFFERSIZE)); |
|
159 while (newCapacity < required) |
|
160 newCapacity *= 2; |
|
161 int moveOffset = (where == freeSpaceAtEnd) ? 0 : newCapacity - len; |
|
162 if (newCapacity > capacity) { |
|
163 // allocate more space |
|
164 char* newBuf = new char[newCapacity]; |
|
165 memmove(newBuf + moveOffset, first, len); |
|
166 delete [] buf; |
|
167 buf = newBuf; |
|
168 capacity = newCapacity; |
|
169 } else { |
|
170 // shift any existing data to make space |
|
171 memmove(buf + moveOffset, first, len); |
|
172 } |
|
173 first = buf + moveOffset; |
|
174 } |
|
175 |
|
176 private: |
|
177 // length of the unread data |
|
178 int len; |
|
179 // start of the unread data |
|
180 char* first; |
|
181 // the allocated buffer |
|
182 char* buf; |
|
183 // allocated buffer size |
|
184 size_t capacity; |
|
185 }; |
|
186 |
67 class Q_CORE_EXPORT QIODevicePrivate |
187 class Q_CORE_EXPORT QIODevicePrivate |
68 #ifndef QT_NO_QOBJECT |
188 #ifndef QT_NO_QOBJECT |
69 : public QObjectPrivate |
189 : public QObjectPrivate |
70 #endif |
190 #endif |
71 { |
191 { |