Files
RedHotRoast-ios/HybridCLRData/LocalIl2CppData-OSXEditor/il2cpp/libil2cpp/hybridclr/metadata/BlobReader.h
T

201 lines
4.7 KiB
C++
Raw Normal View History

2026-07-17 14:03:00 +08:00
#pragma once
#include "../CommonDef.h"
#include "MetadataUtil.h"
namespace hybridclr
{
namespace metadata
{
class BlobReader
{
public:
BlobReader(const byte* buf, uint32_t length) : _buf(buf), _length(length), _readPos(0)
{
}
const byte* GetData() const
{
return _buf;
}
uint32_t GetLength() const
{
return _length;
}
uint32_t GetReadPosition() const
{
return _readPos;
}
const byte* GetDataOfReadPosition() const
{
return _buf + _readPos;
}
bool IsEmpty() const
{
return _readPos >= _length;
}
bool NonEmpty() const
{
return _readPos < _length;
}
int32_t ReadCompressedInt32()
{
uint32_t unsignedValue = ReadCompressedUint32();
uint32_t value = unsignedValue >> 1;
if (!(unsignedValue & 0x1))
{
return value;
}
if (value < 0x40)
{
return value - 0x40;
}
if (value < 0x2000)
{
return value - 0x2000;
}
if (value < 0x10000000)
{
return value - 0x10000000;
}
IL2CPP_ASSERT(value < 0x20000000);
return value - 0x20000000;
}
static uint32_t ReadCompressedUint32(const byte* buf, uint32_t& lengthSize)
{
uint32_t firstByte = buf[0];
if (firstByte < 128)
{
lengthSize = 1;
return firstByte;
}
else if (firstByte < 192)
{
lengthSize = 2;
return ((firstByte & 0x3f) << 8) | buf[1];
}
else if (firstByte < 224)
{
lengthSize = 4;
return ((firstByte & 0x1f) << 24) | (((uint32_t)buf[1]) << 16) | ((uint32_t)buf[2] << 8) | (uint32_t)buf[3];
}
else
{
RaiseExecutionEngineException("bad metadata data. ReadEncodeLength fail");
return 0;
}
}
uint32_t ReadCompressedUint32()
{
uint32_t lengthSize;
uint32_t value = ReadCompressedUint32(_buf + _readPos, lengthSize);
_readPos += lengthSize;
return value;
}
uint8_t ReadByte()
{
IL2CPP_ASSERT(_readPos < _length);
return _buf[_readPos++];
}
uint16_t Read16()
{
IL2CPP_ASSERT(_readPos + 2 <= _length);
uint16_t value = GetU2LittleEndian(_buf + _readPos);
_readPos += 2;
return value;
}
uint32_t Read32()
{
IL2CPP_ASSERT(_readPos + 4 <= _length);
uint32_t value = (uint32_t)GetI4LittleEndian(_buf + _readPos);
_readPos += 4;
return value;
}
bool TryRead32(uint32_t& value)
{
if (_readPos + 4 <= _length)
{
value = Read32();
return true;
}
return false;
}
uint64_t Read64()
{
IL2CPP_ASSERT(_readPos + 8 <= _length);
uint64_t value = (uint64_t)GetI8LittleEndian(_buf + _readPos);
_readPos += 8;
return value;
}
float ReadFloat()
{
uint32_t x = Read32();
return *(float*)&x;
}
double ReadDouble()
{
uint64_t x = Read64();
return *(double*)&x;
}
//template<typename T>
//T Read()
//{
// IL2CPP_ASSERT(_readPos + sizeof(T) <= _length);
// T value = *(T*)(_buf + _readPos);
// _readPos += sizeof(T);
// return value;
//}
uint8_t PeekByte()
{
IL2CPP_ASSERT(_readPos < _length);
return _buf[_readPos];
}
void SkipByte()
{
IL2CPP_ASSERT(_readPos < _length);
++_readPos;
}
void SkipBytes(uint32_t len)
{
IL2CPP_ASSERT(_readPos + len <= _length);
const byte* data = _buf + _readPos;
_readPos += len;
}
const byte* GetAndSkipCurBytes(uint32_t len)
{
IL2CPP_ASSERT(_readPos + len <= _length);
const byte* data = _buf + _readPos;
_readPos += len;
return data;
}
private:
const byte* const _buf;
const uint32_t _length;
uint32_t _readPos;
};
}
}