Open Source Tomb Raider Engine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

binary.cpp 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*!
  2. * \file src/utils/binary.cpp
  3. * \brief Binary file reading utilities
  4. *
  5. * \author xythobuz
  6. */
  7. #include "global.h"
  8. #include "utils/binary.h"
  9. BinaryReader::~BinaryReader() {
  10. }
  11. uint8_t BinaryReader::readU8() {
  12. uint8_t ret;
  13. char* c = reinterpret_cast<char*>(&ret);
  14. read(c, 1);
  15. return ret;
  16. }
  17. uint16_t BinaryReader::readU16() {
  18. uint16_t a = readU8();
  19. uint16_t b = readU8();
  20. return (a | (b << 8));
  21. }
  22. uint32_t BinaryReader::readU32() {
  23. uint32_t a = readU16();
  24. uint32_t b = readU16();
  25. return (a | (b << 16));
  26. }
  27. uint64_t BinaryReader::readU64() {
  28. uint64_t a = readU32();
  29. uint64_t b = readU32();
  30. return (a | (b << 32));
  31. }
  32. float BinaryReader::readFloat() {
  33. uint32_t val = readU32();
  34. char* a = reinterpret_cast<char*>(&val);
  35. float ret;
  36. char* b = reinterpret_cast<char*>(&ret);
  37. for (int i = 0; i < 4; i++)
  38. b[i] = a[i];
  39. return ret;
  40. }
  41. /*! \fixme Left-Shift with signed integer is undefined!
  42. * So we can't use the same method as for unsigned integers.
  43. * Is there a portable way to read multi-byte signed integers,
  44. * without having to detect the endianness at run-time?
  45. */
  46. const static int bigendiandetection = 1;
  47. #define ISBIGENDIAN() ((*reinterpret_cast<const char *>(&bigendiandetection)) == 0)
  48. static void swapByteOrder(char* d, unsigned int n) {
  49. if (ISBIGENDIAN()) {
  50. for (unsigned int i = 0; i < (n / 2); i++) {
  51. char tmp = d[i];
  52. d[i] = d[n - i - 1];
  53. d[n - i - 1] = tmp;
  54. }
  55. }
  56. }
  57. int8_t BinaryReader::read8() {
  58. int8_t ret;
  59. char* p = reinterpret_cast<char*>(&ret);
  60. read(p, sizeof(ret));
  61. return ret;
  62. }
  63. int16_t BinaryReader::read16() {
  64. int16_t ret;
  65. char* p = reinterpret_cast<char*>(&ret);
  66. read(p, sizeof(ret));
  67. swapByteOrder(p, 2);
  68. return ret;
  69. }
  70. int32_t BinaryReader::read32() {
  71. int32_t ret;
  72. char* p = reinterpret_cast<char*>(&ret);
  73. read(p, sizeof(ret));
  74. swapByteOrder(p, 4);
  75. return ret;
  76. }
  77. int64_t BinaryReader::read64() {
  78. int64_t ret;
  79. char* p = reinterpret_cast<char*>(&ret);
  80. read(p, sizeof(ret));
  81. swapByteOrder(p, 8);
  82. return ret;
  83. }
  84. // ----------------------------------------------------------------------------
  85. BinaryFile::BinaryFile(std::string f) {
  86. orAssertEqual(open(f), 0);
  87. }
  88. BinaryFile::~BinaryFile() {
  89. if (file.is_open())
  90. file.close();
  91. }
  92. int BinaryFile::open(std::string f) {
  93. if (file.is_open()) {
  94. return 1;
  95. } else {
  96. if (f == "")
  97. return 0;
  98. file.open(f, std::ios_base::in | std::ios_base::binary);
  99. return (file ? 0 : 1);
  100. }
  101. }
  102. long long BinaryFile::tell() {
  103. orAssert(file.is_open());
  104. return file.tellg();
  105. }
  106. void BinaryFile::seek(long long pos) {
  107. orAssert(file.is_open());
  108. file.seekg(pos);
  109. }
  110. bool BinaryFile::eof() {
  111. file.peek();
  112. return file.eof();
  113. }
  114. void BinaryFile::read(char* d, int c) {
  115. orAssert(file.is_open());
  116. orAssert(file.good());
  117. file.read(d, c);
  118. }
  119. // ----------------------------------------------------------------------------
  120. BinaryMemory::BinaryMemory(const char* d, long long m) : data(nullptr), offset(0), max(-1) {
  121. orAssertEqual(open(d, m), 0);
  122. }
  123. BinaryMemory::~BinaryMemory() {
  124. }
  125. int BinaryMemory::open(const char* d, long long m) {
  126. if (data != nullptr)
  127. return 1;
  128. if (d != nullptr) {
  129. data = d;
  130. offset = 0;
  131. max = m;
  132. }
  133. return 0;
  134. }
  135. long long BinaryMemory::tell() {
  136. orAssertGreaterThanEqual(offset, 0);
  137. return offset;
  138. }
  139. void BinaryMemory::seek(long long pos) {
  140. orAssertGreaterThanEqual(pos, 0);
  141. offset = pos;
  142. }
  143. bool BinaryMemory::eof() {
  144. return (offset >= max);
  145. }
  146. void BinaryMemory::read(char* d, int c) {
  147. orAssertGreaterThanEqual(offset, 0);
  148. orAssertGreaterThan(c, 0);
  149. orAssertLessThanEqual(offset + c, max);
  150. for (int i = 0; i < c; i++) {
  151. d[i] = data[offset + i];
  152. }
  153. offset += c;
  154. }