1 | /**************************************************************************** |
---|---|

2 | ** |

3 | ** Copyright (C) 2016 The Qt Company Ltd. |

4 | ** Copyright (C) 2016 Intel Corporation. |

5 | ** Contact: https://www.qt.io/licensing/ |

6 | ** |

7 | ** This file is part of the QtCore module of the Qt Toolkit. |

8 | ** |

9 | ** $QT_BEGIN_LICENSE:LGPL$ |

10 | ** Commercial License Usage |

11 | ** Licensees holding valid commercial Qt licenses may use this file in |

12 | ** accordance with the commercial license agreement provided with the |

13 | ** Software or, alternatively, in accordance with the terms contained in |

14 | ** a written agreement between you and The Qt Company. For licensing terms |

15 | ** and conditions see https://www.qt.io/terms-conditions. For further |

16 | ** information use the contact form at https://www.qt.io/contact-us. |

17 | ** |

18 | ** GNU Lesser General Public License Usage |

19 | ** Alternatively, this file may be used under the terms of the GNU Lesser |

20 | ** General Public License version 3 as published by the Free Software |

21 | ** Foundation and appearing in the file LICENSE.LGPL3 included in the |

22 | ** packaging of this file. Please review the following information to |

23 | ** ensure the GNU Lesser General Public License version 3 requirements |

24 | ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. |

25 | ** |

26 | ** GNU General Public License Usage |

27 | ** Alternatively, this file may be used under the terms of the GNU |

28 | ** General Public License version 2.0 or (at your option) the GNU General |

29 | ** Public license version 3 or any later version approved by the KDE Free |

30 | ** Qt Foundation. The licenses are as published by the Free Software |

31 | ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 |

32 | ** included in the packaging of this file. Please review the following |

33 | ** information to ensure the GNU General Public License requirements will |

34 | ** be met: https://www.gnu.org/licenses/gpl-2.0.html and |

35 | ** https://www.gnu.org/licenses/gpl-3.0.html. |

36 | ** |

37 | ** $QT_END_LICENSE$ |

38 | ** |

39 | ****************************************************************************/ |

40 | |

41 | #include "qbitarray.h" |

42 | #include <qalgorithms.h> |

43 | #include <qdatastream.h> |

44 | #include <qdebug.h> |

45 | #include <qendian.h> |

46 | #include <string.h> |

47 | |

48 | QT_BEGIN_NAMESPACE |

49 | |

50 | /*! |

51 | \class QBitArray |

52 | \inmodule QtCore |

53 | \brief The QBitArray class provides an array of bits. |

54 | |

55 | \ingroup tools |

56 | \ingroup shared |

57 | \reentrant |

58 | |

59 | A QBitArray is an array that gives access to individual bits and |

60 | provides operators (\l{operator&()}{AND}, \l{operator|()}{OR}, |

61 | \l{operator^()}{XOR}, and \l{operator~()}{NOT}) that work on |

62 | entire arrays of bits. It uses \l{implicit sharing} (copy-on-write) |

63 | to reduce memory usage and to avoid the needless copying of data. |

64 | |

65 | The following code constructs a QBitArray containing 200 bits |

66 | initialized to false (0): |

67 | |

68 | \snippet code/src_corelib_tools_qbitarray.cpp 0 |

69 | |

70 | To initialize the bits to true, either pass \c true as second |

71 | argument to the constructor, or call fill() later on. |

72 | |

73 | QBitArray uses 0-based indexes, just like C++ arrays. To access |

74 | the bit at a particular index position, you can use operator[](). |

75 | On non-const bit arrays, operator[]() returns a reference to a |

76 | bit that can be used on the left side of an assignment. For |

77 | example: |

78 | |

79 | \snippet code/src_corelib_tools_qbitarray.cpp 1 |

80 | |

81 | For technical reasons, it is more efficient to use testBit() and |

82 | setBit() to access bits in the array than operator[](). For |

83 | example: |

84 | |

85 | \snippet code/src_corelib_tools_qbitarray.cpp 2 |

86 | |

87 | QBitArray supports \c{&} (\l{operator&()}{AND}), \c{|} |

88 | (\l{operator|()}{OR}), \c{^} (\l{operator^()}{XOR}), |

89 | \c{~} (\l{operator~()}{NOT}), as well as |

90 | \c{&=}, \c{|=}, and \c{^=}. These operators work in the same way |

91 | as the built-in C++ bitwise operators of the same name. For |

92 | example: |

93 | |

94 | \snippet code/src_corelib_tools_qbitarray.cpp 3 |

95 | |

96 | For historical reasons, QBitArray distinguishes between a null |

97 | bit array and an empty bit array. A \e null bit array is a bit |

98 | array that is initialized using QBitArray's default constructor. |

99 | An \e empty bit array is any bit array with size 0. A null bit |

100 | array is always empty, but an empty bit array isn't necessarily |

101 | null: |

102 | |

103 | \snippet code/src_corelib_tools_qbitarray.cpp 4 |

104 | |

105 | All functions except isNull() treat null bit arrays the same as |

106 | empty bit arrays; for example, QBitArray() compares equal to |

107 | QBitArray(0). We recommend that you always use isEmpty() and |

108 | avoid isNull(). |

109 | |

110 | \sa QByteArray, QVector |

111 | */ |

112 | |

113 | /*! |

114 | \fn QBitArray::QBitArray(QBitArray &&other) |

115 | |

116 | Move-constructs a QBitArray instance, making it point at the same |

117 | object that \a other was pointing to. |

118 | |

119 | \since 5.2 |

120 | */ |

121 | |

122 | /*! \fn QBitArray::QBitArray() |

123 | |

124 | Constructs an empty bit array. |

125 | |

126 | \sa isEmpty() |

127 | */ |

128 | |

129 | /* |

130 | * QBitArray construction note: |

131 | * |

132 | * We overallocate the byte array by 1 byte. The first user bit is at |

133 | * d.data()[1]. On the extra first byte, we store the difference between the |

134 | * number of bits in the byte array (including this byte) and the number of |

135 | * bits in the bit array. Therefore, it's always a number between 8 and 15. |

136 | * |

137 | * This allows for fast calculation of the bit array size: |

138 | * inline int size() const { return (d.size() << 3) - *d.constData(); } |

139 | * |

140 | * Note: for an array of zero size, *d.constData() is the QByteArray implicit NUL. |

141 | */ |

142 | |

143 | /*! |

144 | Constructs a bit array containing \a size bits. The bits are |

145 | initialized with \a value, which defaults to false (0). |

146 | */ |

147 | QBitArray::QBitArray(int size, bool value) |

148 | : d(size <= 0 ? 0 : 1 + (size + 7)/8, Qt::Uninitialized) |

149 | { |

150 | Q_ASSERT_X(size >= 0, "QBitArray::QBitArray", "Size must be greater than or equal to 0."); |

151 | if (size <= 0) |

152 | return; |

153 | |

154 | uchar* c = reinterpret_cast<uchar*>(d.data()); |

155 | memset(c + 1, value ? 0xff : 0, d.size() - 1); |

156 | *c = d.size()*8 - size; |

157 | if (value && size && size % 8) |

158 | *(c+1+size/8) &= (1 << (size%8)) - 1; |

159 | } |

160 | |

161 | /*! \fn int QBitArray::size() const |

162 | |

163 | Returns the number of bits stored in the bit array. |

164 | |

165 | \sa resize() |

166 | */ |

167 | |

168 | /*! \fn int QBitArray::count() const |

169 | |

170 | Same as size(). |

171 | */ |

172 | |

173 | /*! |

174 | If \a on is true, this function returns the number of |

175 | 1-bits stored in the bit array; otherwise the number |

176 | of 0-bits is returned. |

177 | */ |

178 | int QBitArray::count(bool on) const |

179 | { |

180 | int numBits = 0; |

181 | const quint8 *bits = reinterpret_cast<const quint8 *>(d.data()) + 1; |

182 | |

183 | // the loops below will try to read from *end |

184 | // it's the QByteArray implicit NUL, so it will not change the bit count |

185 | const quint8 *const end = reinterpret_cast<const quint8 *>(d.end()); |

186 | |

187 | while (bits + 7 <= end) { |

188 | quint64 v = qFromUnaligned<quint64>(bits); |

189 | bits += 8; |

190 | numBits += int(qPopulationCount(v)); |

191 | } |

192 | if (bits + 3 <= end) { |

193 | quint32 v = qFromUnaligned<quint32>(bits); |

194 | bits += 4; |

195 | numBits += int(qPopulationCount(v)); |

196 | } |

197 | if (bits + 1 < end) { |

198 | quint16 v = qFromUnaligned<quint16>(bits); |

199 | bits += 2; |

200 | numBits += int(qPopulationCount(v)); |

201 | } |

202 | if (bits < end) |

203 | numBits += int(qPopulationCount(bits[0])); |

204 | |

205 | return on ? numBits : size() - numBits; |

206 | } |

207 | |

208 | /*! |

209 | Resizes the bit array to \a size bits. |

210 | |

211 | If \a size is greater than the current size, the bit array is |

212 | extended to make it \a size bits with the extra bits added to the |

213 | end. The new bits are initialized to false (0). |

214 | |

215 | If \a size is less than the current size, bits are removed from |

216 | the end. |

217 | |

218 | \sa size() |

219 | */ |

220 | void QBitArray::resize(int size) |

221 | { |

222 | if (!size) { |

223 | d.resize(0); |

224 | } else { |

225 | int s = d.size(); |

226 | d.resize(1 + (size+7)/8); |

227 | uchar* c = reinterpret_cast<uchar*>(d.data()); |

228 | if (size > (s << 3)) |

229 | memset(c + s, 0, d.size() - s); |

230 | else if ( size % 8) |

231 | *(c+1+size/8) &= (1 << (size%8)) - 1; |

232 | *c = d.size()*8 - size; |

233 | } |

234 | } |

235 | |

236 | /*! \fn bool QBitArray::isEmpty() const |

237 | |

238 | Returns \c true if this bit array has size 0; otherwise returns |

239 | false. |

240 | |

241 | \sa size() |

242 | */ |

243 | |

244 | /*! \fn bool QBitArray::isNull() const |

245 | |

246 | Returns \c true if this bit array is null; otherwise returns \c false. |

247 | |

248 | Example: |

249 | \snippet code/src_corelib_tools_qbitarray.cpp 5 |

250 | |

251 | Qt makes a distinction between null bit arrays and empty bit |

252 | arrays for historical reasons. For most applications, what |

253 | matters is whether or not a bit array contains any data, |

254 | and this can be determined using isEmpty(). |

255 | |

256 | \sa isEmpty() |

257 | */ |

258 | |

259 | /*! \fn bool QBitArray::fill(bool value, int size = -1) |

260 | |

261 | Sets every bit in the bit array to \a value, returning true if successful; |

262 | otherwise returns \c false. If \a size is different from -1 (the default), |

263 | the bit array is resized to \a size beforehand. |

264 | |

265 | Example: |

266 | \snippet code/src_corelib_tools_qbitarray.cpp 6 |

267 | |

268 | \sa resize() |

269 | */ |

270 | |

271 | /*! |

272 | \overload |

273 | |

274 | Sets bits at index positions \a begin up to (but not including) \a end |

275 | to \a value. |

276 | |

277 | \a begin must be a valid index position in the bit array |

278 | (0 <= \a begin < size()). |

279 | |

280 | \a end must be either a valid index position or equal to size(), in |

281 | which case the fill operation runs until the end of the array |

282 | (0 <= \a end <= size()). |

283 | |

284 | Example: |

285 | \snippet code/src_corelib_tools_qbitarray.cpp 15 |

286 | */ |

287 | |

288 | void QBitArray::fill(bool value, int begin, int end) |

289 | { |

290 | while (begin < end && begin & 0x7) |

291 | setBit(begin++, value); |

292 | int len = end - begin; |

293 | if (len <= 0) |

294 | return; |

295 | int s = len & ~0x7; |

296 | uchar *c = reinterpret_cast<uchar*>(d.data()); |

297 | memset(c + (begin >> 3) + 1, value ? 0xff : 0, s >> 3); |

298 | begin += s; |

299 | while (begin < end) |

300 | setBit(begin++, value); |

301 | } |

302 | |

303 | /*! |

304 | \fn const char *QBitArray::bits() const |

305 | \since 5.11 |

306 | |

307 | Returns a pointer to a dense bit array for this QBitArray. Bits are counted |

308 | upwards from the least significant bit in each byte. The the number of bits |

309 | relevant in the last byte is given by \c{size() % 8}. |

310 | |

311 | \sa fromBits(), size() |

312 | */ |

313 | |

314 | /*! |

315 | \since 5.11 |

316 | |

317 | Creates a QBitArray with the dense bit array located at \a data, with \a |

318 | size bits. The byte array at \a data must be at least \a size / 8 (rounded up) |

319 | bytes long. |

320 | |

321 | If \a size is not a multiple of 8, this function will include the lowest |

322 | \a size % 8 bits from the last byte in \a data. |

323 | |

324 | \sa bits() |

325 | */ |

326 | QBitArray QBitArray::fromBits(const char *data, qsizetype size) |

327 | { |

328 | QBitArray result; |

329 | qsizetype nbytes = (size + 7) / 8; |

330 | |

331 | result.d = QByteArray(nbytes + 1, Qt::Uninitialized); |

332 | char *bits = result.d.data(); |

333 | memcpy(bits + 1, data, nbytes); |

334 | |

335 | // clear any unused bits from the last byte |

336 | if (size & 7) |

337 | bits[nbytes] &= 0xffU >> (size & 7); |

338 | |

339 | *bits = result.d.size() * 8 - size; |

340 | return result; |

341 | } |

342 | |

343 | /*! \fn bool QBitArray::isDetached() const |

344 | |

345 | \internal |

346 | */ |

347 | |

348 | /*! \fn void QBitArray::detach() |

349 | |

350 | \internal |

351 | */ |

352 | |

353 | /*! \fn void QBitArray::clear() |

354 | |

355 | Clears the contents of the bit array and makes it empty. |

356 | |

357 | \sa resize(), isEmpty() |

358 | */ |

359 | |

360 | /*! \fn void QBitArray::truncate(int pos) |

361 | |

362 | Truncates the bit array at index position \a pos. |

363 | |

364 | If \a pos is beyond the end of the array, nothing happens. |

365 | |

366 | \sa resize() |

367 | */ |

368 | |

369 | /*! \fn bool QBitArray::toggleBit(int i) |

370 | |

371 | Inverts the value of the bit at index position \a i, returning the |

372 | previous value of that bit as either true (if it was set) or false (if |

373 | it was unset). |

374 | |

375 | If the previous value was 0, the new value will be 1. If the |

376 | previous value was 1, the new value will be 0. |

377 | |

378 | \a i must be a valid index position in the bit array (i.e., 0 <= |

379 | \a i < size()). |

380 | |

381 | \sa setBit(), clearBit() |

382 | */ |

383 | |

384 | /*! \fn bool QBitArray::testBit(int i) const |

385 | |

386 | Returns \c true if the bit at index position \a i is 1; otherwise |

387 | returns \c false. |

388 | |

389 | \a i must be a valid index position in the bit array (i.e., 0 <= |

390 | \a i < size()). |

391 | |

392 | \sa setBit(), clearBit() |

393 | */ |

394 | |

395 | /*! \fn bool QBitArray::setBit(int i) |

396 | |

397 | Sets the bit at index position \a i to 1. |

398 | |

399 | \a i must be a valid index position in the bit array (i.e., 0 <= |

400 | \a i < size()). |

401 | |

402 | \sa clearBit(), toggleBit() |

403 | */ |

404 | |

405 | /*! \fn void QBitArray::setBit(int i, bool value) |

406 | |

407 | \overload |

408 | |

409 | Sets the bit at index position \a i to \a value. |

410 | */ |

411 | |

412 | /*! \fn void QBitArray::clearBit(int i) |

413 | |

414 | Sets the bit at index position \a i to 0. |

415 | |

416 | \a i must be a valid index position in the bit array (i.e., 0 <= |

417 | \a i < size()). |

418 | |

419 | \sa setBit(), toggleBit() |

420 | */ |

421 | |

422 | /*! \fn bool QBitArray::at(int i) const |

423 | |

424 | Returns the value of the bit at index position \a i. |

425 | |

426 | \a i must be a valid index position in the bit array (i.e., 0 <= |

427 | \a i < size()). |

428 | |

429 | \sa operator[]() |

430 | */ |

431 | |

432 | /*! \fn QBitRef QBitArray::operator[](int i) |

433 | |

434 | Returns the bit at index position \a i as a modifiable reference. |

435 | |

436 | \a i must be a valid index position in the bit array (i.e., 0 <= |

437 | \a i < size()). |

438 | |

439 | Example: |

440 | \snippet code/src_corelib_tools_qbitarray.cpp 7 |

441 | |

442 | The return value is of type QBitRef, a helper class for QBitArray. |

443 | When you get an object of type QBitRef, you can assign to |

444 | it, and the assignment will apply to the bit in the QBitArray |

445 | from which you got the reference. |

446 | |

447 | The functions testBit(), setBit(), and clearBit() are slightly |

448 | faster. |

449 | |

450 | \sa at(), testBit(), setBit(), clearBit() |

451 | */ |

452 | |

453 | /*! \fn bool QBitArray::operator[](int i) const |

454 | |

455 | \overload |

456 | */ |

457 | |

458 | /*! \fn QBitRef QBitArray::operator[](uint i) |

459 | |

460 | \overload |

461 | */ |

462 | |

463 | /*! \fn bool QBitArray::operator[](uint i) const |

464 | |

465 | \overload |

466 | */ |

467 | |

468 | /*! \fn QBitArray::QBitArray(const QBitArray &other) |

469 | |

470 | Constructs a copy of \a other. |

471 | |

472 | This operation takes \l{constant time}, because QBitArray is |

473 | \l{implicitly shared}. This makes returning a QBitArray from a |

474 | function very fast. If a shared instance is modified, it will be |

475 | copied (copy-on-write), and that takes \l{linear time}. |

476 | |

477 | \sa operator=() |

478 | */ |

479 | |

480 | /*! \fn QBitArray &QBitArray::operator=(const QBitArray &other) |

481 | |

482 | Assigns \a other to this bit array and returns a reference to |

483 | this bit array. |

484 | */ |

485 | |

486 | /*! \fn QBitArray &QBitArray::operator=(QBitArray &&other) |

487 | \since 5.2 |

488 | |

489 | Moves \a other to this bit array and returns a reference to |

490 | this bit array. |

491 | */ |

492 | |

493 | /*! \fn void QBitArray::swap(QBitArray &other) |

494 | \since 4.8 |

495 | |

496 | Swaps bit array \a other with this bit array. This operation is very |

497 | fast and never fails. |

498 | */ |

499 | |

500 | /*! \fn bool QBitArray::operator==(const QBitArray &other) const |

501 | |

502 | Returns \c true if \a other is equal to this bit array; otherwise |

503 | returns \c false. |

504 | |

505 | \sa operator!=() |

506 | */ |

507 | |

508 | /*! \fn bool QBitArray::operator!=(const QBitArray &other) const |

509 | |

510 | Returns \c true if \a other is not equal to this bit array; |

511 | otherwise returns \c false. |

512 | |

513 | \sa operator==() |

514 | */ |

515 | |

516 | /*! |

517 | Performs the AND operation between all bits in this bit array and |

518 | \a other. Assigns the result to this bit array, and returns a |

519 | reference to it. |

520 | |

521 | The result has the length of the longest of the two bit arrays, |

522 | with any missing bits (if one array is shorter than the other) |

523 | taken to be 0. |

524 | |

525 | Example: |

526 | \snippet code/src_corelib_tools_qbitarray.cpp 8 |

527 | |

528 | \sa operator&(), operator|=(), operator^=(), operator~() |

529 | */ |

530 | |

531 | QBitArray &QBitArray::operator&=(const QBitArray &other) |

532 | { |

533 | resize(qMax(size(), other.size())); |

534 | uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1; |

535 | const uchar *a2 = reinterpret_cast<const uchar*>(other.d.constData()) + 1; |

536 | int n = other.d.size() -1 ; |

537 | int p = d.size() - 1 - n; |

538 | while (n-- > 0) |

539 | *a1++ &= *a2++; |

540 | while (p-- > 0) |

541 | *a1++ = 0; |

542 | return *this; |

543 | } |

544 | |

545 | /*! |

546 | Performs the OR operation between all bits in this bit array and |

547 | \a other. Assigns the result to this bit array, and returns a |

548 | reference to it. |

549 | |

550 | The result has the length of the longest of the two bit arrays, |

551 | with any missing bits (if one array is shorter than the other) |

552 | taken to be 0. |

553 | |

554 | Example: |

555 | \snippet code/src_corelib_tools_qbitarray.cpp 9 |

556 | |

557 | \sa operator|(), operator&=(), operator^=(), operator~() |

558 | */ |

559 | |

560 | QBitArray &QBitArray::operator|=(const QBitArray &other) |

561 | { |

562 | resize(qMax(size(), other.size())); |

563 | uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1; |

564 | const uchar *a2 = reinterpret_cast<const uchar *>(other.d.constData()) + 1; |

565 | int n = other.d.size() - 1; |

566 | while (n-- > 0) |

567 | *a1++ |= *a2++; |

568 | return *this; |

569 | } |

570 | |

571 | /*! |

572 | Performs the XOR operation between all bits in this bit array and |

573 | \a other. Assigns the result to this bit array, and returns a |

574 | reference to it. |

575 | |

576 | The result has the length of the longest of the two bit arrays, |

577 | with any missing bits (if one array is shorter than the other) |

578 | taken to be 0. |

579 | |

580 | Example: |

581 | \snippet code/src_corelib_tools_qbitarray.cpp 10 |

582 | |

583 | \sa operator^(), operator&=(), operator|=(), operator~() |

584 | */ |

585 | |

586 | QBitArray &QBitArray::operator^=(const QBitArray &other) |

587 | { |

588 | resize(qMax(size(), other.size())); |

589 | uchar *a1 = reinterpret_cast<uchar*>(d.data()) + 1; |

590 | const uchar *a2 = reinterpret_cast<const uchar *>(other.d.constData()) + 1; |

591 | int n = other.d.size() - 1; |

592 | while (n-- > 0) |

593 | *a1++ ^= *a2++; |

594 | return *this; |

595 | } |

596 | |

597 | /*! |

598 | Returns a bit array that contains the inverted bits of this bit |

599 | array. |

600 | |

601 | Example: |

602 | \snippet code/src_corelib_tools_qbitarray.cpp 11 |

603 | |

604 | \sa operator&(), operator|(), operator^() |

605 | */ |

606 | |

607 | QBitArray QBitArray::operator~() const |

608 | { |

609 | int sz = size(); |

610 | QBitArray a(sz); |

611 | const uchar *a1 = reinterpret_cast<const uchar *>(d.constData()) + 1; |

612 | uchar *a2 = reinterpret_cast<uchar*>(a.d.data()) + 1; |

613 | int n = d.size() - 1; |

614 | |

615 | while (n-- > 0) |

616 | *a2++ = ~*a1++; |

617 | |

618 | if (sz && sz%8) |

619 | *(a2-1) &= (1 << (sz%8)) - 1; |

620 | return a; |

621 | } |

622 | |

623 | /*! |

624 | \relates QBitArray |

625 | |

626 | Returns a bit array that is the AND of the bit arrays \a a1 and \a |

627 | a2. |

628 | |

629 | The result has the length of the longest of the two bit arrays, |

630 | with any missing bits (if one array is shorter than the other) |

631 | taken to be 0. |

632 | |

633 | Example: |

634 | \snippet code/src_corelib_tools_qbitarray.cpp 12 |

635 | |

636 | \sa {QBitArray::}{operator&=()}, {QBitArray::}{operator|()}, {QBitArray::}{operator^()} |

637 | */ |

638 | |

639 | QBitArray operator&(const QBitArray &a1, const QBitArray &a2) |

640 | { |

641 | QBitArray tmp = a1; |

642 | tmp &= a2; |

643 | return tmp; |

644 | } |

645 | |

646 | /*! |

647 | \relates QBitArray |

648 | |

649 | Returns a bit array that is the OR of the bit arrays \a a1 and \a |

650 | a2. |

651 | |

652 | The result has the length of the longest of the two bit arrays, |

653 | with any missing bits (if one array is shorter than the other) |

654 | taken to be 0. |

655 | |

656 | Example: |

657 | \snippet code/src_corelib_tools_qbitarray.cpp 13 |

658 | |

659 | \sa QBitArray::operator|=(), operator&(), operator^() |

660 | */ |

661 | |

662 | QBitArray operator|(const QBitArray &a1, const QBitArray &a2) |

663 | { |

664 | QBitArray tmp = a1; |

665 | tmp |= a2; |

666 | return tmp; |

667 | } |

668 | |

669 | /*! |

670 | \relates QBitArray |

671 | |

672 | Returns a bit array that is the XOR of the bit arrays \a a1 and \a |

673 | a2. |

674 | |

675 | The result has the length of the longest of the two bit arrays, |

676 | with any missing bits (if one array is shorter than the other) |

677 | taken to be 0. |

678 | |

679 | Example: |

680 | \snippet code/src_corelib_tools_qbitarray.cpp 14 |

681 | |

682 | \sa {QBitArray}{operator^=()}, {QBitArray}{operator&()}, {QBitArray}{operator|()} |

683 | */ |

684 | |

685 | QBitArray operator^(const QBitArray &a1, const QBitArray &a2) |

686 | { |

687 | QBitArray tmp = a1; |

688 | tmp ^= a2; |

689 | return tmp; |

690 | } |

691 | |

692 | /*! |

693 | \class QBitRef |

694 | \inmodule QtCore |

695 | \reentrant |

696 | \brief The QBitRef class is an internal class, used with QBitArray. |

697 | |

698 | \internal |

699 | |

700 | The QBitRef is required by the indexing [] operator on bit arrays. |

701 | It is not for use in any other context. |

702 | */ |

703 | |

704 | /*! \fn QBitRef::QBitRef (QBitArray& a, int i) |

705 | |

706 | Constructs a reference to element \a i in the QBitArray \a a. |

707 | This is what QBitArray::operator[] constructs its return value |

708 | with. |

709 | */ |

710 | |

711 | /*! \fn QBitRef::operator bool() const |

712 | |

713 | Returns the value referenced by the QBitRef. |

714 | */ |

715 | |

716 | /*! \fn bool QBitRef::operator!() const |

717 | |

718 | \internal |

719 | */ |

720 | |

721 | /*! \fn QBitRef& QBitRef::operator= (const QBitRef& v) |

722 | |

723 | Sets the value referenced by the QBitRef to that referenced by |

724 | QBitRef \a v. |

725 | */ |

726 | |

727 | /*! \fn QBitRef& QBitRef::operator= (bool v) |

728 | \overload |

729 | |

730 | Sets the value referenced by the QBitRef to \a v. |

731 | */ |

732 | |

733 | |

734 | /***************************************************************************** |

735 | QBitArray stream functions |

736 | *****************************************************************************/ |

737 | |

738 | #ifndef QT_NO_DATASTREAM |

739 | /*! |

740 | \relates QBitArray |

741 | |

742 | Writes bit array \a ba to stream \a out. |

743 | |

744 | \sa {Serializing Qt Data Types}{Format of the QDataStream operators} |

745 | */ |

746 | |

747 | QDataStream &operator<<(QDataStream &out, const QBitArray &ba) |

748 | { |

749 | quint32 len = ba.size(); |

750 | out << len; |

751 | if (len > 0) |

752 | out.writeRawData(ba.d.constData() + 1, ba.d.size() - 1); |

753 | return out; |

754 | } |

755 | |

756 | /*! |

757 | \relates QBitArray |

758 | |

759 | Reads a bit array into \a ba from stream \a in. |

760 | |

761 | \sa {Serializing Qt Data Types}{Format of the QDataStream operators} |

762 | */ |

763 | |

764 | QDataStream &operator>>(QDataStream &in, QBitArray &ba) |

765 | { |

766 | ba.clear(); |

767 | quint32 len; |

768 | in >> len; |

769 | if (len == 0) { |

770 | ba.clear(); |

771 | return in; |

772 | } |

773 | |

774 | const quint32 Step = 8 * 1024 * 1024; |

775 | quint32 totalBytes = (len + 7) / 8; |

776 | quint32 allocated = 0; |

777 | |

778 | while (allocated < totalBytes) { |

779 | int blockSize = qMin(Step, totalBytes - allocated); |

780 | ba.d.resize(allocated + blockSize + 1); |

781 | if (in.readRawData(ba.d.data() + 1 + allocated, blockSize) != blockSize) { |

782 | ba.clear(); |

783 | in.setStatus(QDataStream::ReadPastEnd); |

784 | return in; |

785 | } |

786 | allocated += blockSize; |

787 | } |

788 | |

789 | int paddingMask = ~((0x1 << (len & 0x7)) - 1); |

790 | if (paddingMask != ~0x0 && (ba.d.constData()[ba.d.size() - 1] & paddingMask)) { |

791 | ba.clear(); |

792 | in.setStatus(QDataStream::ReadCorruptData); |

793 | return in; |

794 | } |

795 | |

796 | *ba.d.data() = ba.d.size() * 8 - len; |

797 | return in; |

798 | } |

799 | #endif // QT_NO_DATASTREAM |

800 | |

801 | #ifndef QT_NO_DEBUG_STREAM |

802 | QDebug operator<<(QDebug dbg, const QBitArray &array) |

803 | { |

804 | QDebugStateSaver saver(dbg); |

805 | dbg.nospace() << "QBitArray("; |

806 | for (int i = 0; i < array.size();) { |

807 | if (array.testBit(i)) |

808 | dbg << '1'; |

809 | else |

810 | dbg << '0'; |

811 | i += 1; |

812 | if (!(i % 4) && (i < array.size())) |

813 | dbg << ' '; |

814 | } |

815 | dbg << ')'; |

816 | return dbg; |

817 | } |

818 | #endif |

819 | |

820 | /*! |

821 | \fn DataPtr &QBitArray::data_ptr() |

822 | \internal |

823 | */ |

824 | |

825 | /*! |

826 | \typedef QBitArray::DataPtr |

827 | \internal |

828 | */ |

829 | |

830 | QT_END_NAMESPACE |

831 |