// dnlib: See LICENSE.txt for more info
using dnlib.IO;
using dnlib.PE;
using dnlib.Protection;
using dnlib.Utils;
namespace dnlib.DotNet.Writer {
///
/// Base class of most heaps
///
public abstract class HeapBase : IHeap {
internal const uint ALIGNMENT = 4;
FileOffset offset;
RVA rva;
///
/// true if has been called
///
protected bool isReadOnly;
///
public FileOffset FileOffset => offset;
///
public RVA RVA => rva;
///
public abstract string Name { get; }
///
public bool IsEmpty => GetRawLength() <= 1;
///
/// true if offsets require 4 bytes instead of 2 bytes.
///
public bool IsBig => GetFileLength() > 0xFFFF;
///
public void SetReadOnly() => isReadOnly = true;
///
public virtual void SetOffset(FileOffset offset, RVA rva) {
this.offset = offset;
this.rva = rva;
// NOTE: This method can be called twice by NativeModuleWriter, see Metadata.SetOffset() for more info
}
///
public uint GetFileLength() => Utils.AlignUp(GetRawLength(), ALIGNMENT);
///
public uint GetVirtualSize() => GetFileLength();
///
public uint CalculateAlignment() => 0;
///
/// Gets the raw length of the heap
///
/// Raw length of the heap
public abstract uint GetRawLength();
private void WriteTo0(DataWriter writer) {
WriteToImpl(writer);
writer.WriteZeroes((int)(Utils.AlignUp(GetRawLength(), ALIGNMENT) - GetRawLength()));
}
protected abstract EncryptionMethod GetEncryptionMethod(IEncryption e);
///
public void WriteTo(DataWriter writer) {
EncryptionUtil.WriteWithEncIfNeed(writer, WriteTo0, this.GetEncryptionMethod, EncryptionContext.BigSegmentSize);
}
///
/// Writes all data to at its current location.
///
/// Destination
protected abstract void WriteToImpl(DataWriter writer);
///
public override string ToString() => Name;
}
}