/* Copyright (C) 2014-2019 de4dot@gmail.com This file is part of dnSpy dnSpy is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. dnSpy is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with dnSpy. If not, see . */ using System; using System.IO; namespace dnSpy.Debugger.DotNet.Metadata { /// /// Data stream /// public abstract class DmdDataStream : IDisposable { /// /// Gets/sets the position /// public abstract long Position { get; set; } /// /// Gets the stream length /// public abstract long Length { get; } /// /// Reads a /// /// public abstract byte ReadByte(); /// /// Reads a /// /// public abstract ushort ReadUInt16(); /// /// Reads a /// /// public abstract uint ReadUInt32(); /// /// Reads a /// /// public abstract ulong ReadUInt64(); /// /// Reads a /// /// public abstract float ReadSingle(); /// /// Reads a /// /// public abstract double ReadDouble(); /// /// Reads bytes /// /// Number of bytes to read /// public abstract byte[] ReadBytes(int length); /// /// Reads a /// /// public sbyte ReadSByte() => (sbyte)ReadByte(); /// /// Reads a /// /// public short ReadInt16() => (short)ReadUInt16(); /// /// Reads a /// /// public int ReadInt32() => (int)ReadUInt32(); /// /// Reads a /// /// public long ReadInt64() => (long)ReadUInt64(); /// /// Reads a compressed /// /// public uint ReadCompressedUInt32() => ReadCompressedUInt32(ReadByte()); internal uint ReadCompressedUInt32(byte b) { if ((b & 0x80) == 0) return b; if ((b & 0xC0) == 0x80) return (uint)(((b & 0x3F) << 8) | ReadByte()); return (uint)(((b & 0x1F) << 24) | (ReadByte() << 16) | (ReadByte() << 8) | ReadByte()); } /// /// Reads a compressed /// /// public int ReadCompressedInt32() { byte b = ReadByte(); if ((b & 0x80) == 0) { if ((b & 1) != 0) return -0x40 | (b >> 1); return b >> 1; } if ((b & 0xC0) == 0x80) { uint tmp = (uint)(((b & 0x3F) << 8) | ReadByte()); if ((tmp & 1) != 0) return -0x2000 | (int)(tmp >> 1); return (int)(tmp >> 1); } if ((b & 0xE0) == 0xC0) { uint tmp = (uint)(((b & 0x1F) << 24) | (ReadByte() << 16) | (ReadByte() << 8) | ReadByte()); if ((tmp & 1) != 0) return -0x10000000 | (int)(tmp >> 1); return (int)(tmp >> 1); } throw new IOException(); } /// /// Disposes this instance /// public abstract void Dispose(); } }