MemoryRead.cpp 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #include "MemoryRead.h"
  2. #include "il2cpp-config.h"
  3. namespace il2cpp
  4. {
  5. namespace utils
  6. {
  7. uint32_t ReadCompressedUInt32(const char** p)
  8. {
  9. uint32_t val = 0;
  10. uint8_t read = Read8(p);
  11. if ((read & 0x80) == 0)
  12. {
  13. // 1 byte written
  14. val = read;
  15. }
  16. else if ((read & 0xC0) == 0x80)
  17. {
  18. // 2 bytes written
  19. val = (read & ~0x80) << 8;
  20. val |= Read8(p);
  21. }
  22. else if ((read & 0xE0) == 0xC0)
  23. {
  24. // 4 bytes written
  25. val = (read & ~0xC0) << 24;
  26. val |= ((uint32_t)Read8(p) << 16);
  27. val |= ((uint32_t)Read8(p) << 8);
  28. val |= Read8(p);
  29. }
  30. else if (read == 0xF0)
  31. {
  32. // 5 bytes written, we had a really large int32!
  33. val = Read32(p);
  34. }
  35. else if (read == 0xFE)
  36. {
  37. // Special encoding for Int32.MaxValue
  38. val = UINT32_MAX - 1;
  39. }
  40. else if (read == 0xFF)
  41. {
  42. // Yes we treat UInt32.MaxValue (and Int32.MinValue, see ReadCompressedInt32) specially
  43. val = UINT32_MAX;
  44. }
  45. else
  46. {
  47. IL2CPP_ASSERT(false && "Invalid compressed integer format");
  48. }
  49. return val;
  50. }
  51. int32_t ReadCompressedInt32(const char** p)
  52. {
  53. uint32_t encoded = ReadCompressedUInt32(p);
  54. // -UINT32_MAX can't be represted safely in an int32_t, so we treat it specially
  55. if (encoded == UINT32_MAX)
  56. return INT32_MIN;
  57. bool isNegative = encoded & 1;
  58. encoded >>= 1;
  59. if (isNegative)
  60. return -(int32_t)(encoded + 1);
  61. return encoded;
  62. }
  63. } /* utils */
  64. } /* il2cpp */