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