Open Source Tomb Raider Engine
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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. }