#region Using using System; #endregion namespace SharpCompress.Compressors.PPMd.I1 { /// /// A structure containing a single address representing a position in the array. This /// is intended to mimic the behaviour of a pointer in C/C++. /// /// /// /// 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). /// /// /// Note that is a field rather than a property for performance reasons. /// /// internal struct Pointer { public uint _address; public byte[] _memory; public static readonly Pointer ZERO = new Pointer(0, null); public const int SIZE = 1; /// /// Initializes a new instance of the structure. /// public Pointer(uint address, byte[] memory) { _address = address; _memory = memory; } /// /// Gets or sets the byte at the given . /// /// /// public byte this[int offset] { get { #if DEBUG if (_address == 0) { throw new InvalidOperationException("The pointer being indexed is a null pointer."); } #endif return _memory[_address + offset]; } set { #if DEBUG if (_address == 0) { throw new InvalidOperationException("The pointer being indexed is a null pointer."); } #endif _memory[_address + offset] = value; } } /// /// Allow a to be implicitly converted to a . /// /// /// public static implicit operator Pointer(MemoryNode memoryNode) { return new Pointer(memoryNode._address, memoryNode._memory); } /// /// Allow a to be implicitly converted to a . /// /// /// public static implicit operator Pointer(Model.PpmContext context) { return new Pointer(context._address, context._memory); } /// /// Allow a to be implicitly converted to a . /// /// /// public static implicit operator Pointer(PpmState state) { return new Pointer(state._address, state._memory); } /// /// Increase the address of a pointer by the given number of bytes. /// /// /// /// public static Pointer operator +(Pointer pointer, int offset) { #if DEBUG if (pointer._address == 0) { throw new InvalidOperationException("The pointer is a null pointer."); } #endif pointer._address = (uint)(pointer._address + offset); return pointer; } /// /// Increase the address of a pointer by the given number of bytes. /// /// /// /// public static Pointer operator +(Pointer pointer, uint offset) { #if DEBUG if (pointer._address == 0) { throw new InvalidOperationException("The pointer is a null pointer."); } #endif pointer._address += offset; return pointer; } /// /// Increment the address of a pointer. /// /// /// public static Pointer operator ++(Pointer pointer) { #if DEBUG if (pointer._address == 0) { throw new InvalidOperationException("The pointer being incremented is a null pointer."); } #endif pointer._address++; return pointer; } /// /// Decrease the address of a pointer by the given number of bytes. /// /// /// /// public static Pointer operator -(Pointer pointer, int offset) { #if DEBUG if (pointer._address == 0) { throw new InvalidOperationException("The pointer is a null pointer."); } #endif pointer._address = (uint)(pointer._address - offset); return pointer; } /// /// Decrease the address of a pointer by the given number of bytes. /// /// /// /// public static Pointer operator -(Pointer pointer, uint offset) { #if DEBUG if (pointer._address == 0) { throw new InvalidOperationException("The pointer is a null pointer."); } #endif pointer._address -= offset; return pointer; } /// /// Decrement the address of a pointer. /// /// /// public static Pointer operator --(Pointer pointer) { #if DEBUG if (pointer._address == 0) { throw new InvalidOperationException("The pointer being decremented is a null pointer."); } #endif pointer._address--; return pointer; } /// /// Subtract two pointers. /// /// /// /// The number of bytes between the two pointers. public static uint operator -(Pointer pointer1, Pointer pointer2) { #if DEBUG if (pointer1._address == 0) { throw new InvalidOperationException( "The pointer to the left of the subtraction operator is a null pointer."); } if (pointer2._address == 0) { throw new InvalidOperationException( "The pointer to the right of the subtraction operator is a null pointer."); } #endif return pointer1._address - pointer2._address; } /// /// Compare pointers. /// /// /// /// public static bool operator <(Pointer pointer1, Pointer pointer2) { #if DEBUG if (pointer1._address == 0) { throw new InvalidOperationException( "The pointer to the left of the less than operator is a null pointer."); } if (pointer2._address == 0) { throw new InvalidOperationException( "The pointer to the right of the less than operator is a null pointer."); } #endif return pointer1._address < pointer2._address; } /// /// Compare two pointers. /// /// /// /// public static bool operator <=(Pointer pointer1, Pointer pointer2) { #if DEBUG if (pointer1._address == 0) { throw new InvalidOperationException( "The pointer to the left of the less than or equal to operator is a null pointer."); } if (pointer2._address == 0) { throw new InvalidOperationException( "The pointer to the right of the less than or equal to operator is a null pointer."); } #endif return pointer1._address <= pointer2._address; } /// /// Compare two pointers. /// /// /// /// public static bool operator >(Pointer pointer1, Pointer pointer2) { #if DEBUG if (pointer1._address == 0) { throw new InvalidOperationException( "The pointer to the left of the greater than operator is a null pointer."); } if (pointer2._address == 0) { throw new InvalidOperationException( "The pointer to the right of the greater than operator is a null pointer."); } #endif return pointer1._address > pointer2._address; } /// /// Compare two pointers. /// /// /// /// public static bool operator >=(Pointer pointer1, Pointer pointer2) { #if DEBUG if (pointer1._address == 0) { throw new InvalidOperationException( "The pointer to the left of the greater than or equal to operator is a null pointer."); } if (pointer2._address == 0) { throw new InvalidOperationException( "The pointer to the right of the greater than or equal to operator is a null pointer."); } #endif return pointer1._address >= pointer2._address; } /// /// Compare two pointers. /// /// /// /// public static bool operator ==(Pointer pointer1, Pointer pointer2) { return pointer1._address == pointer2._address; } /// /// Compare two pointers. /// /// /// /// public static bool operator !=(Pointer pointer1, Pointer pointer2) { return pointer1._address != pointer2._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 Pointer) { Pointer pointer = (Pointer)obj; return pointer._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(); } } }