#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();
}
}
}