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 2.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*!
  2. * \file src/utils/binary.cpp
  3. * \brief Binary file reading utilities
  4. *
  5. * \author xythobuz
  6. */
  7. #include "utils/binary.h"
  8. BinaryFile::BinaryFile(const char *f) {
  9. file.open(f, std::ios_base::in | std::ios_base:: binary);
  10. }
  11. BinaryFile::~BinaryFile() {
  12. file.close();
  13. }
  14. long long BinaryFile::tell() {
  15. return file.tellg();
  16. }
  17. void BinaryFile::seek(long long pos) {
  18. file.seekg(pos);
  19. }
  20. uint8_t BinaryFile::readU8() {
  21. uint8_t ret;
  22. char *c = reinterpret_cast<char *>(&ret);
  23. file.read(c, 1);
  24. return ret;
  25. }
  26. uint16_t BinaryFile::readU16() {
  27. uint8_t a = readU8();
  28. uint8_t b = readU8();
  29. return ((uint16_t)a | (uint16_t)(b << 8));
  30. }
  31. uint32_t BinaryFile::readU32() {
  32. uint16_t a = readU16();
  33. uint16_t b = readU16();
  34. return ((uint32_t)a | (uint32_t)(b << 16));
  35. }
  36. uint64_t BinaryFile::readU64() {
  37. uint32_t a = readU32();
  38. uint32_t b = readU32();
  39. return ((uint64_t)a | ((uint64_t)b << 32));
  40. }
  41. float BinaryFile::readFloat() {
  42. uint32_t val = readU32();
  43. char *a = reinterpret_cast<char *>(&val);
  44. float ret;
  45. char *b = reinterpret_cast<char *>(&ret);
  46. for (int i = 0; i < 4; i++)
  47. b[i] = a[i];
  48. return ret;
  49. }
  50. namespace {
  51. /*! \fixme Left-Shift with signed integer is undefined!
  52. * So we can't use the same method as for unsigned integers.
  53. * Is there a portable way to read multi-byte signed integers,
  54. * without having to detect the endianness at run-time?
  55. */
  56. const int bigendiandetection = 1;
  57. #define ISBIGENDIAN() ((*(char *)&bigendiandetection) == 0)
  58. void swapByteOrder(char *d, unsigned int n) {
  59. if (ISBIGENDIAN()) {
  60. for (unsigned int i = 0; i < (n / 2); i++) {
  61. char tmp = d[i];
  62. d[i] = d[n - i - 1];
  63. d[n - i - 1] = tmp;
  64. }
  65. }
  66. }
  67. }
  68. int8_t BinaryFile::read8() {
  69. int8_t ret;
  70. char *p = reinterpret_cast<char *>(&ret);
  71. file.read(p, sizeof(ret));
  72. return ret;
  73. }
  74. int16_t BinaryFile::read16() {
  75. int16_t ret;
  76. char *p = reinterpret_cast<char *>(&ret);
  77. file.read(p, sizeof(ret));
  78. swapByteOrder(p, 2);
  79. return ret;
  80. }
  81. int32_t BinaryFile::read32() {
  82. int32_t ret;
  83. char *p = reinterpret_cast<char *>(&ret);
  84. file.read(p, sizeof(ret));
  85. swapByteOrder(p, 4);
  86. return ret;
  87. }
  88. int64_t BinaryFile::read64() {
  89. int64_t ret;
  90. char *p = reinterpret_cast<char *>(&ret);
  91. file.read(p, sizeof(ret));
  92. swapByteOrder(p, 8);
  93. return ret;
  94. }