#region Using #endregion namespace SharpCompress.Compressors.PPMd.I1 { /// /// PPM state. /// /// /// /// 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 PpmState { public uint _address; public byte[] _memory; public static readonly PpmState ZERO = new PpmState(0, null); public const int SIZE = 6; /// /// Initializes a new instance of the structure. /// public PpmState(uint address, byte[] memory) { _address = address; _memory = memory; } /// /// Gets or sets the symbol. /// public byte Symbol { get => _memory[_address]; set => _memory[_address] = value; } /// /// Gets or sets the frequency. /// public byte Frequency { get => _memory[_address + 1]; set => _memory[_address + 1] = value; } /// /// Gets or sets the successor. /// public Model.PpmContext Successor { get => new Model.PpmContext( _memory[_address + 2] | ((uint)_memory[_address + 3]) << 8 | ((uint)_memory[_address + 4]) << 16 | ((uint)_memory[_address + 5]) << 24, _memory); set { _memory[_address + 2] = (byte)value._address; _memory[_address + 3] = (byte)(value._address >> 8); _memory[_address + 4] = (byte)(value._address >> 16); _memory[_address + 5] = (byte)(value._address >> 24); } } /// /// Gets the at the relative to this /// . /// /// /// public PpmState this[int offset] => new PpmState((uint)(_address + offset * SIZE), _memory); /// /// Allow a pointer to be implicitly converted to a PPM state. /// /// /// public static implicit operator PpmState(Pointer pointer) { return new PpmState(pointer._address, pointer._memory); } /// /// Allow pointer-like addition on a PPM state. /// /// /// /// public static PpmState operator +(PpmState state, int offset) { state._address = (uint)(state._address + offset * SIZE); return state; } /// /// Allow pointer-like incrementing on a PPM state. /// /// /// public static PpmState operator ++(PpmState state) { state._address += SIZE; return state; } /// /// Allow pointer-like subtraction on a PPM state. /// /// /// /// public static PpmState operator -(PpmState state, int offset) { state._address = (uint)(state._address - offset * SIZE); return state; } /// /// Allow pointer-like decrementing on a PPM state. /// /// /// public static PpmState operator --(PpmState state) { state._address -= SIZE; return state; } /// /// Compare two PPM states. /// /// /// /// public static bool operator <=(PpmState state1, PpmState state2) { return state1._address <= state2._address; } /// /// Compare two PPM states. /// /// /// /// public static bool operator >=(PpmState state1, PpmState state2) { return state1._address >= state2._address; } /// /// Compare two PPM states. /// /// /// /// public static bool operator ==(PpmState state1, PpmState state2) { return state1._address == state2._address; } /// /// Compare two PPM states. /// /// /// /// public static bool operator !=(PpmState state1, PpmState state2) { return state1._address != state2._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 PpmState) { PpmState state = (PpmState)obj; return state._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(); } } }