CustomAttributeDataWriter.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. #pragma once
  2. #include "BlobReader.h"
  3. #include "../CommonDef.h"
  4. #include "utils/MemoryRead.h"
  5. namespace hybridclr
  6. {
  7. namespace metadata
  8. {
  9. class CustomAttributeDataWriter
  10. {
  11. private:
  12. uint8_t* _data;
  13. uint32_t _capacity;
  14. uint32_t _size;
  15. public:
  16. CustomAttributeDataWriter(uint32_t capacity) : _capacity(Round2Exp(capacity)), _size(0)
  17. {
  18. _data = (uint8_t*)HYBRIDCLR_MALLOC_ZERO(_capacity);
  19. }
  20. ~CustomAttributeDataWriter()
  21. {
  22. HYBRIDCLR_FREE(_data);
  23. _data = nullptr;
  24. }
  25. uint32_t Size() const { return _size; }
  26. bool Empty() const { return _size == 0; }
  27. const uint8_t* Data() const { return _data; }
  28. const uint8_t* DataAt(uint32_t offset) { return _data + offset; }
  29. void Reset()
  30. {
  31. _size = 0;
  32. }
  33. void WriteAttributeCount(uint32_t count)
  34. {
  35. WriteCompressedUint32(count);
  36. }
  37. void Skip(int32_t skipBytes)
  38. {
  39. SureRemainSize(skipBytes);
  40. _size += skipBytes;
  41. }
  42. void WriteMethodIndex(int32_t offset, int32_t methodIndex)
  43. {
  44. *(int32_t*)(_data + offset) = methodIndex;
  45. }
  46. void WriteByte(uint8_t n)
  47. {
  48. SureRemainSize(1);
  49. _data[_size++] = n;
  50. }
  51. void WriteCompressedUint32(uint32_t n)
  52. {
  53. SureRemainSize(5);
  54. uint8_t* buf = _data + _size;
  55. if (n < 0x80)
  56. {
  57. buf[0] = (uint8_t)n;
  58. ++_size;
  59. }
  60. else if (n < 0x4000)
  61. {
  62. uint32_t v = n | 0x8000;
  63. buf[0] = uint8_t(v >> 8);
  64. buf[1] = uint8_t(v);
  65. _size += 2;
  66. }
  67. else if (n < 0x20000000)
  68. {
  69. uint32_t v = n | 0xC0000000;
  70. buf[0] = uint8_t(v >> 24);
  71. buf[1] = uint8_t(v >> 16);
  72. buf[2] = uint8_t(v >> 8);
  73. buf[3] = uint8_t(v);
  74. _size += 4;
  75. }
  76. else if (n < UINT32_MAX - 1)
  77. {
  78. buf[0] = 0xF0;
  79. buf[1] = uint8_t(n);
  80. buf[2] = uint8_t(n >> 8);
  81. buf[3] = uint8_t(n >> 16);
  82. buf[4] = uint8_t(n >> 24);
  83. _size += 5;
  84. }
  85. else if (n == UINT32_MAX - 1)
  86. {
  87. buf[0] = 0xFE;
  88. ++_size;
  89. }
  90. else
  91. {
  92. buf[0] = 0xFF;
  93. ++_size;
  94. }
  95. }
  96. void WriteUint32(uint32_t n)
  97. {
  98. WriteData(n);
  99. }
  100. void WriteCompressedInt32(int32_t n)
  101. {
  102. uint32_t v = n >= 0 ? (n << 1) : (((-(n + 1)) << 1) | 0x1U);
  103. WriteCompressedUint32(v);
  104. }
  105. template<typename T>
  106. void WriteData(T x)
  107. {
  108. int32_t n = sizeof(T);
  109. SureRemainSize(n);
  110. std::memcpy(_data + _size, &x, n);
  111. _size += n;
  112. }
  113. void WriteBytes(const uint8_t* data, uint32_t len)
  114. {
  115. SureRemainSize(len);
  116. std::memcpy(_data + _size, data, len);
  117. _size += len;
  118. }
  119. void Write(const CustomAttributeDataWriter& writer)
  120. {
  121. SureRemainSize(writer._size);
  122. std::memcpy(_data + _size, writer._data, writer._size);
  123. _size += writer._size;
  124. }
  125. void Write(BlobReader& reader, int32_t count)
  126. {
  127. SureRemainSize(count);
  128. std::memcpy(_data + _size, reader.GetDataOfReadPosition(), count);
  129. _size += count;
  130. reader.SkipBytes(count);
  131. }
  132. void PopByte()
  133. {
  134. IL2CPP_ASSERT(_size > 0);
  135. --_size;
  136. }
  137. void ReplaceLastByte(byte x)
  138. {
  139. IL2CPP_ASSERT(_size > 0);
  140. _data[_size - 1] = x;
  141. }
  142. private:
  143. uint32_t Round2Exp(uint32_t n)
  144. {
  145. uint32_t s = 64;
  146. for (uint32_t s = 64; ; s *= 2)
  147. {
  148. if (s >= n)
  149. {
  150. return s;
  151. }
  152. }
  153. return n;
  154. }
  155. void SureRemainSize(uint32_t remainSize)
  156. {
  157. uint32_t newSize = _size + remainSize;
  158. if (newSize > _capacity)
  159. {
  160. Resize(newSize);
  161. }
  162. }
  163. void Resize(uint32_t newSize)
  164. {
  165. _capacity = newSize = Round2Exp(newSize);
  166. uint8_t* oldData = _data;
  167. _data = (uint8_t*)HYBRIDCLR_MALLOC(newSize);
  168. std::memcpy(_data, oldData, _size);
  169. HYBRIDCLR_FREE(oldData);
  170. }
  171. };
  172. }
  173. }