#region Using #endregion namespace SharpCompress.Compressors.PPMd.I1 { /// /// A structure containing a single address. The address represents a location in the /// array. That location in the array contains information itself describing a section /// of the array (ie. a block of memory). /// /// /// /// This must be a structure rather than a class because several places in the associated code assume that /// is a value type (meaning that assignment creates a completely new copy of /// the instance rather than just copying a reference to the same instance). /// /// /// MemoryNode /// 4 Stamp /// 4 Next /// 4 UnitCount /// /// /// Note that is a field rather than a property for performance reasons. /// /// internal struct MemoryNode { public uint _address; public byte[] _memory; public static readonly MemoryNode ZERO = new MemoryNode(0, null); public const int SIZE = 12; /// /// Initializes a new instance of the structure. /// public MemoryNode(uint address, byte[] memory) { _address = address; _memory = memory; } /// /// Gets or sets the stamp. /// public uint Stamp { get => _memory[_address] | ((uint)_memory[_address + 1]) << 8 | ((uint)_memory[_address + 2]) << 16 | ((uint)_memory[_address + 3]) << 24; set { _memory[_address] = (byte)value; _memory[_address + 1] = (byte)(value >> 8); _memory[_address + 2] = (byte)(value >> 16); _memory[_address + 3] = (byte)(value >> 24); } } /// /// Gets or sets the next memory node. /// public MemoryNode Next { get => new MemoryNode( _memory[_address + 4] | ((uint)_memory[_address + 5]) << 8 | ((uint)_memory[_address + 6]) << 16 | ((uint)_memory[_address + 7]) << 24, _memory); set { _memory[_address + 4] = (byte)value._address; _memory[_address + 5] = (byte)(value._address >> 8); _memory[_address + 6] = (byte)(value._address >> 16); _memory[_address + 7] = (byte)(value._address >> 24); } } /// /// Gets or sets the unit count. /// public uint UnitCount { get => _memory[_address + 8] | ((uint)_memory[_address + 9]) << 8 | ((uint)_memory[_address + 10]) << 16 | ((uint)_memory[_address + 11]) << 24; set { _memory[_address + 8] = (byte)value; _memory[_address + 9] = (byte)(value >> 8); _memory[_address + 10] = (byte)(value >> 16); _memory[_address + 11] = (byte)(value >> 24); } } /// /// Gets whether there is a next memory node available. /// public bool Available => Next._address != 0; /// /// Link in the provided memory node. /// /// public void Link(MemoryNode memoryNode) { memoryNode.Next = Next; Next = memoryNode; } /// /// Unlink this memory node. /// public void Unlink() { Next = Next.Next; } /// /// Insert the memory node into the linked list. /// /// /// public void Insert(MemoryNode memoryNode, uint unitCount) { Link(memoryNode); memoryNode.Stamp = uint.MaxValue; memoryNode.UnitCount = unitCount; Stamp++; } /// /// Remove this memory node from the linked list. /// /// public MemoryNode Remove() { MemoryNode next = Next; Unlink(); Stamp--; return next; } /// /// Allow a pointer to be implicitly converted to a memory node. /// /// /// public static implicit operator MemoryNode(Pointer pointer) { return new MemoryNode(pointer._address, pointer._memory); } /// /// Allow pointer-like addition on a memory node. /// /// /// /// public static MemoryNode operator +(MemoryNode memoryNode, int offset) { memoryNode._address = (uint)(memoryNode._address + offset * SIZE); return memoryNode; } /// /// Allow pointer-like addition on a memory node. /// /// /// /// public static MemoryNode operator +(MemoryNode memoryNode, uint offset) { memoryNode._address += offset * SIZE; return memoryNode; } /// /// Allow pointer-like subtraction on a memory node. /// /// /// /// public static MemoryNode operator -(MemoryNode memoryNode, int offset) { memoryNode._address = (uint)(memoryNode._address - offset * SIZE); return memoryNode; } /// /// Allow pointer-like subtraction on a memory node. /// /// /// /// public static MemoryNode operator -(MemoryNode memoryNode, uint offset) { memoryNode._address -= offset * SIZE; return memoryNode; } /// /// Compare two memory nodes. /// /// /// /// public static bool operator ==(MemoryNode memoryNode1, MemoryNode memoryNode2) { return memoryNode1._address == memoryNode2._address; } /// /// Compare two memory nodes. /// /// /// /// public static bool operator !=(MemoryNode memoryNode1, MemoryNode memoryNode2) { return memoryNode1._address != memoryNode2._address; } /// /// Indicates whether this instance and a specified object are equal. /// /// true if obj and this instance are the same type and represent the same value; otherwise, false. /// Another object to compare to. public override bool Equals(object obj) { if (obj is MemoryNode) { MemoryNode memoryNode = (MemoryNode)obj; return memoryNode._address == _address; } return base.Equals(obj); } /// /// Returns the hash code for this instance. /// /// A 32-bit signed integer that is the hash code for this instance. public override int GetHashCode() { return _address.GetHashCode(); } } }