obfuz/Plugins/dnlib/IO/AlignedNativeMemoryDataStre...

120 lines
3.1 KiB
C#

// dnlib: See LICENSE.txt for more info
using System;
using System.Runtime.InteropServices;
using System.Text;
namespace dnlib.IO {
sealed unsafe class AlignedNativeMemoryDataStream : DataStream {
readonly byte* data;
public AlignedNativeMemoryDataStream(byte* data) => this.data = data;
public override void ReadBytes(uint offset, void* destination, int length) {
var ps = data + offset;
var pd = (byte*)destination;
int count = length / 4;
length = length % 4;
for (int i = 0; i < count; i++) {
*pd = *ps;
pd++;
ps++;
*pd = *ps;
pd++;
ps++;
*pd = *ps;
pd++;
ps++;
*pd = *ps;
pd++;
ps++;
}
for (int i = 0; i < length; i++, ps++, pd++)
*pd = *ps;
}
public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) =>
Marshal.Copy((IntPtr)(data + offset), destination, destinationIndex, length);
public override byte ReadByte(uint offset) => *(data + offset);
public override ushort ReadUInt16(uint offset) {
var p = data + offset;
return (ushort)(*p++ | (*p << 8));
}
public override uint ReadUInt32(uint offset) {
var p = data + offset;
return *p++ | ((uint)*p++ << 8) | ((uint)*p++ << 16) | ((uint)*p << 24);
}
public override ulong ReadUInt64(uint offset) {
var p = data + offset;
return *p++ | ((ulong)*p++ << 8) | ((ulong)*p++ << 16) | ((ulong)*p++ << 24) |
((ulong)*p++ << 32) | ((ulong)*p++ << 40) | ((ulong)*p++ << 48) | ((ulong)*p << 56);
}
public override float ReadSingle(uint offset) {
var p = data + offset;
uint value = *p++ | ((uint)*p++ << 8) | ((uint)*p++ << 16) | ((uint)*p << 24);
return *(float*)&value;
}
public override double ReadDouble(uint offset) {
var p = data + offset;
ulong value = *p++ | ((ulong)*p++ << 8) | ((ulong)*p++ << 16) | ((ulong)*p++ << 24) |
((ulong)*p++ << 32) | ((ulong)*p++ << 40) | ((ulong)*p++ << 48) | ((ulong)*p << 56);
return *(double*)&value;
}
public override string ReadUtf16String(uint offset, int chars) => new string((char*)(data + offset), 0, chars);
public override string ReadString(uint offset, int length, Encoding encoding) => new string((sbyte*)(data + offset), 0, length, encoding);
public override bool TryGetOffsetOf(uint offset, uint endOffset, byte value, out uint valueOffset) {
var pd = data;
// If this code gets updated, also update the other DataStream implementations
byte* p = pd + offset;
uint count = (endOffset - offset) / 4;
for (uint i = 0; i < count; i++) {
if (*p == value) {
valueOffset = (uint)(p - pd);
return true;
}
p++;
if (*p == value) {
valueOffset = (uint)(p - pd);
return true;
}
p++;
if (*p == value) {
valueOffset = (uint)(p - pd);
return true;
}
p++;
if (*p == value) {
valueOffset = (uint)(p - pd);
return true;
}
p++;
}
byte* pe = pd + endOffset;
while (p != pe) {
if (*p == value) {
valueOffset = (uint)(p - pd);
return true;
}
p++;
}
valueOffset = 0;
return false;
}
}
}