1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef COMMON_STREAM_H 24 #define COMMON_STREAM_H 25 26 #include "common/endian.h" 27 #include "common/scummsys.h" 28 #include "common/str.h" 29 30 namespace Common { 31 32 /** 33 * @defgroup common_stream Streams 34 * @ingroup common 35 * 36 * @brief API for managing readable and writable data streams. 37 * 38 * @{ 39 */ 40 41 class ReadStream; 42 class SeekableReadStream; 43 44 /** 45 * Virtual base class for both ReadStream and WriteStream. 46 */ 47 class Stream { 48 public: ~Stream()49 virtual ~Stream() {} 50 51 /** 52 * Return true if an I/O failure occurred. 53 * 54 * This flag is never cleared automatically. In order to clear it, 55 * the client code must call clearErr() explicitly. 56 * 57 * @note The semantics of any implementation of this method is 58 * supposed to match that of ISO C ferror(). 59 */ err()60 virtual bool err() const { return false; } 61 62 /** 63 * Reset the I/O error status as returned by err(). 64 * 65 * For a ReadStream, also reset the end-of-stream status returned by eos(). 66 * 67 * @note The semantics of any implementation of this method is 68 * supposed to match that of ISO C clearerr(). 69 */ clearErr()70 virtual void clearErr() {} 71 }; 72 73 /** 74 * Generic interface for a writable data stream. 75 */ 76 class WriteStream : virtual public Stream { 77 public: 78 /** 79 * Write data into the stream. Subclasses must implement this 80 * method. All other write methods are implemented using it. 81 * 82 * @note The semantics of any implementation of this method is 83 * supposed to match that of ISO C fwrite(). 84 * 85 * @param dataPtr Pointer to the data to be written. 86 * @param dataSize Number of bytes to be written. 87 * 88 * @return The number of bytes that were actually written. 89 */ 90 virtual uint32 write(const void *dataPtr, uint32 dataSize) = 0; 91 92 /** 93 * Commit any buffered data to the underlying channel or 94 * storage medium. Unbuffered streams can use the default 95 * implementation. 96 * 97 * @note The semantics of any implementation of this method is 98 * supposed to match that of ISO C fflush(). 99 * 100 * @return True on success, false in case of a failure. 101 */ flush()102 virtual bool flush() { return true; } 103 104 /** 105 * Finalize and close this stream. 106 * 107 * Call this method right before this stream instance is deleted. 108 * The goal is to enable the client code to detect 109 * and handle I/O errors that might occur when closing 110 * (and flushing, if buffered) the stream. 111 * 112 * After this method has been called, no further writes can be 113 * performed on the stream. Calling err() is allowed. 114 * 115 * By default, this just flushes the stream. 116 */ finalize()117 virtual void finalize() { 118 flush(); 119 } 120 121 /** 122 * Obtain the current value of the stream position indicator. 123 * 124 * @return The current position indicator, or -1 if an error occurred. 125 */ 126 virtual int64 pos() const = 0; 127 128 /** 129 * @name Functions for writing data 130 * 131 * The following methods all have default implementations. 132 * Subclasses need not (and should not) overload them. 133 * @{ 134 */ 135 136 /** 137 * Write the given byte to the current position in the stream. 138 */ writeByte(byte value)139 void writeByte(byte value) { 140 write(&value, 1); 141 } 142 /** 143 * Write the given signed byte to the current position in the stream. 144 */ writeSByte(int8 value)145 void writeSByte(int8 value) { 146 write(&value, 1); 147 } 148 /** 149 * Write an unsigned 16-bit word stored in little endian order into the stream. 150 */ writeUint16LE(uint16 value)151 void writeUint16LE(uint16 value) { 152 value = TO_LE_16(value); 153 write(&value, 2); 154 } 155 /** 156 * Write an unsigned 32-bit word stored in little endian order into the stream. 157 */ writeUint32LE(uint32 value)158 void writeUint32LE(uint32 value) { 159 value = TO_LE_32(value); 160 write(&value, 4); 161 } 162 /** 163 * Write an unsigned 64-bit word stored in little endian order into the stream. 164 */ writeUint64LE(uint64 value)165 void writeUint64LE(uint64 value) { 166 value = TO_LE_64(value); 167 write(&value, 8); 168 } 169 /** 170 * Write an unsigned 16-bit word stored in big endian order into the stream. 171 */ writeUint16BE(uint16 value)172 void writeUint16BE(uint16 value) { 173 value = TO_BE_16(value); 174 write(&value, 2); 175 } 176 /** 177 * Write an unsigned 32-bit word stored in big endian order into the stream. 178 */ writeUint32BE(uint32 value)179 void writeUint32BE(uint32 value) { 180 value = TO_BE_32(value); 181 write(&value, 4); 182 } 183 /** 184 * Write an unsigned 64-bit word stored in big endian order into the stream. 185 */ writeUint64BE(uint64 value)186 void writeUint64BE(uint64 value) { 187 value = TO_BE_64(value); 188 write(&value, 8); 189 } 190 /** 191 * Write a signed 16-bit word stored in little endian order into the stream. 192 */ writeSint16LE(int16 value)193 FORCEINLINE void writeSint16LE(int16 value) { 194 writeUint16LE((uint16)value); 195 } 196 /** 197 * Write a signed 32-bit word stored in little endian order into the stream. 198 */ writeSint32LE(int32 value)199 FORCEINLINE void writeSint32LE(int32 value) { 200 writeUint32LE((uint32)value); 201 } 202 /** 203 * Write a signed 64-bit word stored in little endian order into the stream. 204 */ writeSint64LE(int64 value)205 FORCEINLINE void writeSint64LE(int64 value) { 206 writeUint64LE((uint64)value); 207 } 208 /** 209 * Write a signed 16-bit word stored in big endian order into the stream. 210 */ writeSint16BE(int16 value)211 FORCEINLINE void writeSint16BE(int16 value) { 212 writeUint16BE((uint16)value); 213 } 214 /** 215 * Write a signed 32-bit word stored in big endian order into the stream. 216 */ writeSint32BE(int32 value)217 FORCEINLINE void writeSint32BE(int32 value) { 218 writeUint32BE((uint32)value); 219 } 220 /** 221 * Write a signed 64-bit word stored in big endian order into the stream. 222 */ writeSint64BE(int64 value)223 FORCEINLINE void writeSint64BE(int64 value) { 224 writeUint64BE((uint64)value); 225 } 226 227 228 /** 229 * Write a 32-bit floating point value 230 * stored in little endian (LSB first) order into the stream. 231 */ writeFloatLE(float value)232 FORCEINLINE void writeFloatLE(float value) { 233 uint32 n; 234 235 memcpy(&n, &value, 4); 236 237 writeUint32LE(n); 238 } 239 240 241 /** 242 * Write a 32-bit floating point value 243 * stored in big endian order into the stream. 244 */ writeFloatBE(float value)245 FORCEINLINE void writeFloatBE(float value) { 246 uint32 n; 247 248 memcpy(&n, &value, 4); 249 250 writeUint32BE(n); 251 } 252 253 /** 254 * Write a 64-bit floating point value (with decimals) 255 * stored in little endian (LSB first) order into the stream. 256 */ writeDoubleLE(double value)257 FORCEINLINE void writeDoubleLE(double value) { 258 uint64 n; 259 260 memcpy(&n, &value, 8); 261 262 writeUint64LE(n); 263 } 264 265 266 /** 267 * Write the given 64-bit floating point value (with decimals) 268 * stored in big endian order into the stream. 269 */ writeDoubleBE(double value)270 FORCEINLINE void writeDoubleBE(double value) { 271 uint64 n; 272 273 memcpy(&n, &value, 8); 274 275 writeUint64BE(n); 276 } 277 278 /** 279 * Write at most @p dataSize of data from another stream into this one, 280 * starting from the current stream position. 281 * 282 * @return The number of bytes written into the stream. 283 */ 284 uint32 writeStream(ReadStream *stream, uint32 dataSize); 285 /** 286 * Write data from another stream into this one, 287 * starting from its current position to the end of the stream. 288 * 289 * @return The number of bytes written into the stream. 290 */ 291 uint32 writeStream(SeekableReadStream *stream); 292 293 /** 294 * Write the given string to the stream. 295 * This writes str.size() characters, but no terminating zero byte. 296 */ 297 void writeString(const String &str); 298 /** @} */ 299 }; 300 301 /** 302 * Derived abstract base class for write streams that are seekable. 303 */ 304 class SeekableWriteStream : public WriteStream { 305 public: 306 /** 307 * Set the stream position indicator for the stream. 308 * 309 * The new position, measured in bytes, is obtained by adding offset bytes 310 * to the position specified by whence. If whence is set to SEEK_SET, SEEK_CUR, 311 * or SEEK_END, the offset is relative to the start of the file, the current 312 * position indicator, or end-of-stream, respectively. A successful call 313 * to the seek() method clears the end-of-stream indicator for the stream. 314 * 315 * @note The semantics of any implementation of this method is 316 * supposed to match that of ISO C fseek(). 317 * 318 * @param offset The relative offset in bytes. 319 * @param whence The seek reference: SEEK_SET, SEEK_CUR, or SEEK_END. 320 * 321 * @return True on success, false in case of a failure. 322 */ 323 virtual bool seek(int64 offset, int whence = SEEK_SET) = 0; 324 325 /** 326 * Obtain the current size of the stream, measured in bytes. 327 * 328 * If this value is unknown or cannot be computed, -1 is returned. 329 * 330 * @return The size of the stream, or -1 if an error occurred. 331 */ 332 virtual int64 size() const = 0; 333 }; 334 335 /** 336 * Generic interface for a readable data stream. 337 */ 338 class ReadStream : virtual public Stream { 339 public: ReadStream()340 ReadStream() {} 341 342 /** 343 * Return true if a read failed because the stream end has been reached. 344 * 345 * This flag is cleared by clearErr(). 346 * For a SeekableReadStream, the flag is also cleared by a successful seek. 347 * 348 * @note The semantics of any implementation of this method is 349 * supposed to match that of ISO C feof(). In particular, in a stream 350 * with N bytes, reading exactly N bytes from the start should *not* 351 * set eos; only reading *beyond* the available data should set it. 352 */ 353 virtual bool eos() const = 0; 354 355 /** 356 * Read data from the stream. 357 * 358 * Subclasses must implement this method. 359 * All other read methods are implemented using it. 360 * 361 * @note The semantics of any implementation of this method is 362 * supposed to match that of ISO C fread(), in particular where 363 * it concerns setting error and end of file/stream flags. 364 * 365 * @param dataPtr Pointer to a buffer into which the data is read. 366 * @param dataSize Number of bytes to be read. 367 * 368 * @return The number of bytes that were actually read. 369 */ 370 virtual uint32 read(void *dataPtr, uint32 dataSize) = 0; 371 372 /** 373 * @name Functions for reading data 374 * 375 * The following methods all have default implementations. 376 * Subclasses in general should not overload them. 377 * @{ 378 */ 379 380 /** 381 * Read an unsigned byte from the stream and return it. 382 * 383 * Performs no error checking. The return value is undefined 384 * if a read error occurred (for which the client code can check by 385 * calling err() and eos() ). 386 */ readByte()387 byte readByte() { 388 byte b = 0; // FIXME: remove initialisation 389 read(&b, 1); 390 return b; 391 } 392 393 /** 394 * Read a signed byte from the stream and return it. 395 * 396 * Performs no error checking. The return value is undefined 397 * if a read error occurred (for which the client code can check by 398 * calling err() and eos() ). 399 */ readSByte()400 FORCEINLINE int8 readSByte() { 401 return (int8)readByte(); 402 } 403 404 /** 405 * Read an unsigned 16-bit word stored in little endian (LSB first) order 406 * from the stream and return it. 407 * 408 * Performs no error checking. The return value is undefined 409 * if a read error occurred (for which the client code can check by 410 * calling err() and eos() ). 411 */ readUint16LE()412 uint16 readUint16LE() { 413 uint16 val; 414 read(&val, 2); 415 return FROM_LE_16(val); 416 } 417 418 /** 419 * Read an unsigned 32-bit word stored in little endian (LSB first) order 420 * from the stream and return it. 421 * 422 * Performs no error checking. The return value is undefined 423 * if a read error occurred (for which the client code can check by 424 * calling err() and eos() ). 425 */ readUint32LE()426 uint32 readUint32LE() { 427 uint32 val; 428 read(&val, 4); 429 return FROM_LE_32(val); 430 } 431 432 /** 433 * Read an unsigned 64-bit word stored in little endian (LSB first) order 434 * from the stream and return it. 435 * 436 * Performs no error checking. The return value is undefined 437 * if a read error occurred (for which the client code can check by 438 * calling err() and eos() ). 439 */ readUint64LE()440 uint64 readUint64LE() { 441 uint64 val; 442 read(&val, 8); 443 return FROM_LE_64(val); 444 } 445 446 /** 447 * Read an unsigned 16-bit word stored in big endian (MSB first) order 448 * from the stream and return it. 449 * 450 * Performs no error checking. The return value is undefined 451 * if a read error occurred (for which the client code can check by 452 * calling err() and eos() ). 453 */ readUint16BE()454 uint16 readUint16BE() { 455 uint16 val; 456 read(&val, 2); 457 return FROM_BE_16(val); 458 } 459 460 /** 461 * Read an unsigned 32-bit word stored in big endian (MSB first) order 462 * from the stream and return it. 463 * 464 * Performs no error checking. The return value is undefined 465 * if a read error occurred (for which the client code can check by 466 * calling err() and eos() ). 467 */ readUint32BE()468 uint32 readUint32BE() { 469 uint32 val; 470 read(&val, 4); 471 return FROM_BE_32(val); 472 } 473 474 /** 475 * Read an unsigned 64-bit word stored in big endian (MSB first) order 476 * from the stream and return it. 477 * 478 * Performs no error checking. The return value is undefined 479 * if a read error occurred (for which the client code can check by 480 * calling err() and eos() ). 481 */ readUint64BE()482 uint64 readUint64BE() { 483 uint64 val; 484 read(&val, 8); 485 return FROM_BE_64(val); 486 } 487 488 /** 489 * Read a signed 16-bit word stored in little endian (LSB first) order 490 * from the stream and return it. 491 * 492 * Performs no error checking. The return value is undefined 493 * if a read error occurred (for which the client code can check by 494 * calling err() and eos() ). 495 */ readSint16LE()496 FORCEINLINE int16 readSint16LE() { 497 return (int16)readUint16LE(); 498 } 499 500 /** 501 * Read a signed 32-bit word stored in little endian (LSB first) order 502 * from the stream and return it. 503 * 504 * Performs no error checking. The return value is undefined 505 * if a read error occurred (for which the client code can check by 506 * calling err() and eos() ). 507 */ readSint32LE()508 FORCEINLINE int32 readSint32LE() { 509 return (int32)readUint32LE(); 510 } 511 512 /** 513 * Read a signed 64-bit word stored in little endian (LSB first) order 514 * from the stream and return it. 515 * 516 * Performs no error checking. The return value is undefined 517 * if a read error occurred (for which the client code can check by 518 * calling err() and eos() ). 519 */ readSint64LE()520 FORCEINLINE int64 readSint64LE() { 521 return (int64)readUint64LE(); 522 } 523 524 /** 525 * Read a signed 16-bit word stored in big endian (MSB first) order 526 * from the stream and return it. 527 * 528 * Performs no error checking. The return value is undefined 529 * if a read error occurred (for which the client code can check by 530 * calling err() and eos() ). 531 */ readSint16BE()532 FORCEINLINE int16 readSint16BE() { 533 return (int16)readUint16BE(); 534 } 535 536 /** 537 * Read a signed 32-bit word stored in big endian (MSB first) order 538 * from the stream and return it. 539 * 540 * Performs no error checking. The return value is undefined 541 * if a read error occurred (for which the client code can check by 542 * calling err() and eos() ). 543 */ readSint32BE()544 FORCEINLINE int32 readSint32BE() { 545 return (int32)readUint32BE(); 546 } 547 548 /** 549 * Read a signed 64-bit word stored in big endian (MSB first) order 550 * from the stream and return it. 551 * 552 * Performs no error checking. The return value is undefined 553 * if a read error occurred (for which the client code can check by 554 * calling err() and eos() ). 555 */ readSint64BE()556 FORCEINLINE int64 readSint64BE() { 557 return (int64)readUint64BE(); 558 } 559 560 /** 561 * Read a 32-bit floating point value stored in little endian (LSB first) 562 * order from the stream and return it. 563 * 564 * Performs no error checking. The return value is undefined 565 * if a read error occurred (for which the client code can check by 566 * calling err() and eos() ). 567 */ readFloatLE()568 FORCEINLINE float readFloatLE() { 569 uint32 n = readUint32LE(); 570 float f; 571 572 memcpy(&f, &n, 4); 573 574 return f; 575 } 576 577 /** 578 * Read a 32-bit floating point value stored in big endian 579 * order from the stream and return it. 580 * 581 * Performs no error checking. The return value is undefined 582 * if a read error occurred (for which the client code can check by 583 * calling err() and eos() ). 584 */ readFloatBE()585 FORCEINLINE float readFloatBE() { 586 uint32 n = readUint32BE(); 587 float f; 588 589 memcpy(&f, &n, 4); 590 591 return f; 592 } 593 594 595 /** 596 * Read a 64-bit floating point value stored in little endian (LSB first) 597 * order from the stream and return it. 598 * 599 * Performs no error checking. The return value is undefined 600 * if a read error occurred (for which the client code can check by 601 * calling err() and eos() ). 602 */ readDoubleLE()603 FORCEINLINE double readDoubleLE() { 604 uint64 n = readUint64LE(); 605 double d; 606 607 memcpy(&d, &n, 8); 608 609 return d; 610 } 611 612 /** 613 * Read a 64-bit floating point value stored in big endian 614 * order from the stream and return it. 615 * 616 * Performs no error checking. The return value is undefined 617 * if a read error occurred (for which the client code can check by 618 * calling err() and eos() ). 619 */ readDoubleBE()620 FORCEINLINE double readDoubleBE() { 621 uint64 n = readUint64BE(); 622 double d; 623 624 memcpy(&d, &n, 8); 625 626 return d; 627 } 628 629 /** 630 * Read the specified amount of data into a malloc'ed buffer 631 * which is then wrapped into a MemoryReadStream. 632 * 633 * The returned stream might contain less data than requested 634 * if reading more data failed. This is because of an I/O error or because 635 * the end of the stream was reached. It can be determined by 636 * calling err() and eos(). 637 */ 638 SeekableReadStream *readStream(uint32 dataSize); 639 640 /** 641 * Reads in a terminated string. Upon successful completion, 642 * return a string with the content of the line, *without* 643 * the terminating character. 644 * 645 * @param terminator The terminating character to use. 646 * @param len The maximum length to read (includes terminator). 647 */ 648 String readString(char terminator = 0, size_t len = String::npos); 649 650 /** 651 * Read a string in Pascal format, that is, one byte is 652 * string length, followed by string data. 653 * 654 * @param transformCR If set (default), then transform \\r into \\n. 655 */ 656 Common::String readPascalString(bool transformCR = true); 657 /** @} */ 658 }; 659 660 /** 661 * Interface for a seekable and readable data stream. 662 * 663 * @todo Get rid of SEEK_SET, SEEK_CUR, or SEEK_END, use our own constants. 664 */ 665 class SeekableReadStream : virtual public ReadStream { 666 public: 667 668 /** 669 * Obtain the current value of the stream position indicator. 670 * 671 * @return The current position indicator, or -1 if an error occurred. 672 */ 673 virtual int64 pos() const = 0; 674 675 /** 676 * Obtain the total size of the stream, measured in bytes. 677 * If this value is unknown or cannot be computed, -1 is returned. 678 * 679 * @return The size of the stream, or -1 if an error occurred. 680 */ 681 virtual int64 size() const = 0; 682 683 /** 684 * Set the stream position indicator for the stream. 685 * 686 * The new position, measured in bytes, is obtained by adding offset bytes 687 * to the position specified by whence. If whence is set to SEEK_SET, SEEK_CUR, 688 * or SEEK_END, the offset is relative to the start of the file, the current 689 * position indicator, or end-of-stream, respectively. A successful call 690 * to the seek() method clears the end-of-stream indicator for the stream. 691 * 692 * @note The semantics of any implementation of this method is 693 * supposed to match that of ISO C fseek(). 694 * 695 * @param offset Relative offset in bytes. 696 * @param whence Seek reference: SEEK_SET, SEEK_CUR, or SEEK_END. 697 * 698 * @return True on success, false in case of a failure. 699 */ 700 virtual bool seek(int64 offset, int whence = SEEK_SET) = 0; 701 702 /** 703 * Skip the given number of bytes in the stream. 704 * 705 * This is equivalent to calling: 706 * @code 707 * seek(offset, SEEK_CUR) 708 * @endcode 709 * to add the given number of bytes to the current position indicator of the stream. 710 * 711 * @return True on success, false in case of a failure. 712 */ skip(uint32 offset)713 virtual bool skip(uint32 offset) { return seek(offset, SEEK_CUR); } 714 715 /** 716 * Read at most one less than the number of characters specified 717 * by @p bufSize from the stream and store them in the string buffer. 718 * 719 * Reading stops when the end of a line is reached (CR, CR/LF, or LF), 720 * and at end-of-stream or error. The newline, if any, is retained (CR 721 * and CR/LF are translated to ``LF = 0xA = '\n'``). If any characters 722 * are read and there is no error, a `\0` character is appended 723 * to end the string. 724 * 725 * Upon successful completion, return a pointer to the string. If 726 * end-of-stream occurs before any characters are read, returns NULL 727 * and the buffer contents remain unchanged. If an error occurs, 728 * returns NULL and the buffer contents are indeterminate. 729 * This method does not distinguish between end-of-stream and error; 730 * callers must use err() or eos() to determine which occurred. 731 * 732 * @note This method is closely modeled after the standard fgets() 733 * function from stdio.h. 734 * 735 * @param s The buffer to store into. 736 * @param bufSize Size of the buffer. 737 * @param handleCR If set (default), then CR and CR/LF are handled, as well as LF. 738 * 739 * @return Pointer to the read string, or NULL if an error occurred. 740 */ 741 virtual char *readLine(char *s, size_t bufSize, bool handleCR = true); 742 743 744 /** 745 * Read a full line and returns it as a Common::String. 746 * 747 * Reading stops when the end of a line is reached (CR, CR/LF, or LF), 748 * and at end-of-stream or error. 749 * 750 * Upon successful completion, return a string with the content 751 * of the line, *without* the end of a line marker. This method 752 * does not indicate whether an error occurred. Callers must use 753 * err() or eos() to determine whether an exception occurred. 754 * 755 * @param handleCR If set (default), then CR and CR/LF are handled, as well as LF. 756 */ 757 virtual String readLine(bool handleCR = true); 758 759 /** 760 * Print a hexdump of the stream while maintaing position. The number 761 * of bytes per line is customizable. 762 * 763 * @param len Length of this data. 764 * @param bytesPerLine Number of bytes to print per line (default: 16). 765 * @param startOffset Shift the shown offsets by the starting offset (default: 0). 766 */ 767 void hexdump(int len, int bytesPerLine = 16, int startOffset = 0); 768 }; 769 770 /** 771 * ReadStream mixin subclass that adds non-endian read 772 * methods whose endianness is set during the stream creation. 773 */ 774 class ReadStreamEndian : virtual public ReadStream { 775 private: 776 const bool _bigEndian; 777 778 public: 779 /** 780 * Set the endianness of the read stream. 781 * 782 * @param bigEndian If true, create a big endian stream. 783 * If false, create a little endian stream. 784 */ ReadStreamEndian(bool bigEndian)785 ReadStreamEndian(bool bigEndian) : _bigEndian(bigEndian) {} 786 /** 787 * Return true if data is encoded in big endian order. 788 */ isBE()789 bool isBE() const { return _bigEndian; } 790 /** 791 * Read an unsigned 16-bit word using the stream endianness 792 * and return it in native endianness. 793 */ readUint16()794 uint16 readUint16() { 795 uint16 val; 796 read(&val, 2); 797 return (_bigEndian) ? FROM_BE_16(val) : FROM_LE_16(val); 798 } 799 /** 800 * Read an unsigned 32-bit word using the stream endianness 801 * and return it in native endianness. 802 */ readUint32()803 uint32 readUint32() { 804 uint32 val; 805 read(&val, 4); 806 return (_bigEndian) ? FROM_BE_32(val) : FROM_LE_32(val); 807 } 808 /** 809 * Read an unsigned 64-bit word using the stream endianness 810 * and return it in native endianness. 811 */ readUint64()812 uint64 readUint64() { 813 uint64 val; 814 read(&val, 8); 815 return (_bigEndian) ? FROM_BE_64(val) : FROM_LE_64(val); 816 } 817 /** 818 * Read a signed 16-bit word using the stream endianness 819 * and return it in native endianness. 820 */ readSint16()821 FORCEINLINE int16 readSint16() { 822 return (int16)readUint16(); 823 } 824 /** 825 * Read a signed 32-bit word using the stream endianness 826 * and return it in native endianness. 827 */ readSint32()828 FORCEINLINE int32 readSint32() { 829 return (int32)readUint32(); 830 } 831 /** 832 * Read a signed 64-bit word using the stream endianness 833 * and return it in native endianness. 834 */ readSint64()835 FORCEINLINE int64 readSint64() { 836 return (int64)readUint64(); 837 } 838 839 /** 840 * Read a 32-bit floating point value using the stream endianness 841 * and return it in native endianness. 842 */ readFloat()843 FORCEINLINE float readFloat() { 844 uint32 n = readUint32(); 845 float f; 846 847 memcpy(&f, &n, 4); 848 849 return f; 850 } 851 852 /** 853 * Read a 64-bit floating point value using the stream endianness 854 * and return it in native endianness. 855 */ readDouble()856 FORCEINLINE double readDouble() { 857 uint64 n = readUint64(); 858 double d; 859 860 memcpy(&d, &n, 8); 861 862 return d; 863 } 864 }; 865 866 /** 867 * SeekableReadStream subclass that adds non-endian read 868 * methods whose endianness is set during the stream creation. 869 */ 870 class SeekableReadStreamEndian : virtual public SeekableReadStream, virtual public ReadStreamEndian { 871 public: 872 /** 873 * Set the endianness of the read stream. 874 * 875 * @param bigEndian If true, create a big endian stream. 876 * If false, create a little endian stream. 877 */ SeekableReadStreamEndian(bool bigEndian)878 SeekableReadStreamEndian(bool bigEndian) : ReadStreamEndian(bigEndian) {} 879 }; 880 881 /** @} */ 882 883 } // End of namespace Common 884 885 #endif 886