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.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  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. namespace {
  42. /*! \fixme Left-Shift with signed integer is undefined!
  43. * So we can't use the same method as for unsigned integers.
  44. * Is there a portable way to read multi-byte signed integers,
  45. * without having to detect the endianness at run-time?
  46. */
  47. const int bigendiandetection = 1;
  48. #define ISBIGENDIAN() ((*reinterpret_cast<const char *>(&bigendiandetection)) == 0)
  49. void swapByteOrder(char* d, unsigned int n) {
  50. if (ISBIGENDIAN()) {
  51. for (unsigned int i = 0; i < (n / 2); i++) {
  52. char tmp = d[i];
  53. d[i] = d[n - i - 1];
  54. d[n - i - 1] = tmp;
  55. }
  56. }
  57. }
  58. }
  59. int8_t BinaryReader::read8() {
  60. int8_t ret;
  61. char* p = reinterpret_cast<char*>(&ret);
  62. read(p, sizeof(ret));
  63. return ret;
  64. }
  65. int16_t BinaryReader::read16() {
  66. int16_t ret;
  67. char* p = reinterpret_cast<char*>(&ret);
  68. read(p, sizeof(ret));
  69. swapByteOrder(p, 2);
  70. return ret;
  71. }
  72. int32_t BinaryReader::read32() {
  73. int32_t ret;
  74. char* p = reinterpret_cast<char*>(&ret);
  75. read(p, sizeof(ret));
  76. swapByteOrder(p, 4);
  77. return ret;
  78. }
  79. int64_t BinaryReader::read64() {
  80. int64_t ret;
  81. char* p = reinterpret_cast<char*>(&ret);
  82. read(p, sizeof(ret));
  83. swapByteOrder(p, 8);
  84. return ret;
  85. }
  86. // ----------------------------------------------------------------------------
  87. BinaryFile::BinaryFile(std::string f) {
  88. assert(open(f) == 0);
  89. }
  90. BinaryFile::~BinaryFile() {
  91. if (file.is_open())
  92. file.close();
  93. }
  94. int BinaryFile::open(std::string f) {
  95. if (file.is_open()) {
  96. return 1;
  97. } else {
  98. if (f == "")
  99. return 0;
  100. file.open(f, std::ios_base::in | std::ios_base::binary);
  101. return (file ? 0 : 1);
  102. }
  103. }
  104. long long BinaryFile::tell() {
  105. assert(file.is_open());
  106. return file.tellg();
  107. }
  108. void BinaryFile::seek(long long pos) {
  109. assert(file.is_open());
  110. file.seekg(pos);
  111. }
  112. bool BinaryFile::eof() {
  113. file.peek();
  114. return file.eof();
  115. }
  116. void BinaryFile::read(char* d, int c) {
  117. assert(file.is_open());
  118. assert(file.good());
  119. file.read(d, c);
  120. }
  121. // ----------------------------------------------------------------------------
  122. BinaryMemory::BinaryMemory(const char* d, long long m) : data(nullptr), offset(0), max(-1) {
  123. assert(open(d, m) == 0);
  124. }
  125. BinaryMemory::~BinaryMemory() {
  126. }
  127. int BinaryMemory::open(const char* d, long long m) {
  128. if (data != nullptr)
  129. return 1;
  130. if (d != nullptr) {
  131. data = d;
  132. offset = 0;
  133. max = m;
  134. }
  135. return 0;
  136. }
  137. long long BinaryMemory::tell() {
  138. assert(offset >= 0);
  139. return offset;
  140. }
  141. void BinaryMemory::seek(long long pos) {
  142. assert(pos >= 0);
  143. offset = pos;
  144. }
  145. bool BinaryMemory::eof() {
  146. return (offset > max);
  147. }
  148. void BinaryMemory::read(char* d, int c) {
  149. assert(offset >= 0);
  150. assert(c > 0);
  151. assert((offset + c) <= max);
  152. for (int i = 0; i < c; i++) {
  153. d[i] = data[offset + i];
  154. }
  155. offset += c;
  156. }