using System;
using System.Linq;
using System.Text;
namespace Org.SbeTool.Sbe.Dll
{
///
/// Class used to encapsulate values for primitives. Used for nullValue, minValue, maxValue, and constants
///
///
///
///
/// PrimitiveType |
/// Null |
/// Min |
/// Max |
///
///
///
///
/// char |
/// 0 |
/// 0x20 |
/// 0x7E |
///
///
/// int8 |
/// -128 |
/// -127 |
/// 127 |
///
///
/// uint8 |
/// 255 |
/// 0 |
/// 254 |
///
///
/// int16 |
/// -32768 |
/// -32767 |
/// 32767 |
///
///
/// uint16 |
/// 65535 |
/// 0 |
/// 65534 |
///
///
/// int32 |
/// 2^31 |
/// -2^31 + 1 |
/// 2^31 - 1 |
///
///
/// uint32 |
/// 2^32 - 1 |
/// 0 |
/// 2^32 - 2 |
///
///
/// int64 |
/// 2^63 |
/// -2^63 + 1 |
/// 2^63 - 1 |
///
///
/// uint64 |
/// 2^64 - 1 |
/// 0 |
/// 2^64 - 2 |
///
///
///
///
public class PrimitiveValue
{
private enum Representation
{
Long,
Double,
ByteArray,
ULong
}
#region CHAR
///
/// Minimum value for CHAR SBE type
///
public const long MinValueChar = 0x20;
///
/// Maximum value for CHAR SBE type
///
public const long MaxValueChar = 0x7E;
///
/// Null value for CHAR SBE type
///
public const long NullValueChar = 0;
#endregion
///
/// Minimum value for INT8 SBE type
///
public const long MinValueInt8 = -127;
///
/// Maximum value for CHAR SBE type
///
public const long MaxValueInt8 = 127;
///
/// Null value for CHAR SBE type
///
public const long NullValueInt8 = -128;
///
/// Minimum value for UINT8 SBE type
///
public const long MinValueUint8 = 0;
///
/// Maximum value for UINT8 SBE type
///
public const long MaxValueUint8 = 254;
///
/// Null value for UINT8 SBE type
///
public const long NullValueUint8 = 255;
///
/// Minimum value for INT16 SBE type
///
public const long MinValueInt16 = -32767;
///
/// Maximum value for INT16 SBE type
///
public const long MaxValueInt16 = 32767;
///
/// Null value for INT16 SBE type
///
public const long NullValueInt16 = -32768;
///
/// Minimum value for UINT16 SBE type
///
public const long MinValueUint16 = 0;
///
/// Maximum value for UINT16 SBE type
///
public const long MaxValueUint16 = 65534;
///
/// Null value for UINT16 SBE type
///
public const long NullValueUint16 = 65535;
///
/// Minimum value for INT32 SBE type
///
public const long MinValueInt32 = -2147483647;
///
/// Maximum value for INT32 SBE type
///
public const long MaxValueInt32 = 2147483647;
///
/// Null value for INT32 SBE type
///
public const long NullValueInt32 = -2147483648;
///
/// Minimum value for UINT32 SBE type
///
public const long MinValueUint32 = 0;
///
/// Maximum value for UINT32 SBE type
///
public const long MaxValueUint32 = 4294967293L; // 0xFFFFFFFD
///
/// Null value for UINT32 SBE type
///
public const long NullValueUint32 = 4294967294L; // 0xFFFFFFFE
///
/// Minimum value for INT64 SBE type
///
public const long MinValueInt64 = long.MinValue + 1; // -2^63 + 1
///
/// Maximum value for INT64 SBE type
///
public const long MaxValueInt64 = long.MaxValue; // 2^63 - 1 (SBE spec says -2^63 - 1)
///
/// Null value for INT64 SBE type
///
public const long NullValueInt64 = long.MinValue; // -2^63
///
/// Minimum value for UINT64 SBE type
///
public const long MinValueUint64 = 0;
///
/// Maximum value for UINT64 SBE type
///
public const ulong MaxValueUint64 = ulong.MaxValue - 1;
///
/// Null value for UINT64 SBE type
///
public const ulong NullValueUint64 = ulong.MaxValue;
///
/// Minimum value for FLOAT SBE type
///
public const float MinValueFloat = float.Epsilon;
///
/// Maximum value for FLOAT SBE type
///
public const float MaxValueFloat = float.MaxValue;
///
/// Null value for FLOAT SBE type
///
public const float NullValueFloat = float.NaN;
///
/// Minimum value for DOUBLE SBE type
///
public const double MinValueDouble = double.Epsilon;
///
/// Maximum value for DOUBLE SBE type
///
public const double MaxValueDouble = double.MaxValue;
///
/// Null value for DOUBLE SBE type
///
public const double NullValueDouble = double.NaN;
private readonly byte[] _byteArrayValue;
private readonly byte[] _byteArrayValueForLong = new byte[1];
private readonly string _characterEncoding;
private readonly double _doubleValue;
private readonly long _longValue;
private readonly ulong _unsignedLongValue;
private readonly Representation _representation;
private readonly int _size;
///
/// Construct and fill in value as a long.
///
/// in long format
///
public PrimitiveValue(long value, int size)
{
_representation = Representation.Long;
_longValue = value;
_doubleValue = 0.0;
_unsignedLongValue = 0;
_byteArrayValue = null;
_characterEncoding = null;
_size = size;
}
///
/// Construct and fill in value as a double.
///
/// in double format
///
public PrimitiveValue(double value, int size)
{
_representation = Representation.Double;
_longValue = 0;
_unsignedLongValue = 0;
_doubleValue = value;
_byteArrayValue = null;
_characterEncoding = null;
_size = size;
}
///
/// Construct and fill in value as a double.
///
/// in double format
///
public PrimitiveValue(ulong value, int size)
{
_representation = Representation.ULong;
_unsignedLongValue = 0;
_longValue = 0;
_doubleValue = 0;
_byteArrayValue = null;
_characterEncoding = null;
_size = size;
}
///
/// Construct and fill in value as a byte array.
///
/// as a byte array
///
///
public PrimitiveValue(byte[] value, string characterEncoding, int size)
{
_representation = Representation.ByteArray;
_longValue = 0;
_doubleValue = 0.0;
_unsignedLongValue = 0;
_byteArrayValue = value;
_characterEncoding = characterEncoding;
_size = size;
}
///
/// Return size for this PrimitiveValue for serialization purposes.
///
/// size for serialization
public int Size
{
get { return _size; }
}
///
/// The character encoding of the byte array representation.
///
/// the character encoding of te byte array representation.
public string CharacterEncoding
{
get { return _characterEncoding; }
}
///
/// Parse constant value string and set representation based on type
///
/// expressed as a String
/// that this is supposed to be
/// a new for the value.
public static PrimitiveValue Parse(string value, PrimitiveType primitiveType)
{
switch (primitiveType.Type)
{
case SbePrimitiveType.Char:
if (value.Length > 1)
{
throw new ArgumentException("Constant char value malformed: " + value);
}
return new PrimitiveValue(byte.Parse(value), 1);
case SbePrimitiveType.Int8:
return new PrimitiveValue(Convert.ToSByte(value), 1);
case SbePrimitiveType.Int16:
return new PrimitiveValue(Convert.ToInt16(value), 2);
case SbePrimitiveType.Int32:
return new PrimitiveValue(Convert.ToInt32(value), 4);
case SbePrimitiveType.Int64:
return new PrimitiveValue(Convert.ToInt64(value), 8);
case SbePrimitiveType.UInt8:
return new PrimitiveValue(Convert.ToByte(value), 1);
case SbePrimitiveType.UInt16:
return new PrimitiveValue(Convert.ToUInt16(value), 2);
case SbePrimitiveType.UInt32:
return new PrimitiveValue(Convert.ToUInt32(value), 4);
case SbePrimitiveType.UInt64:
return new PrimitiveValue(Convert.ToUInt64(value), 8);
case SbePrimitiveType.Float:
return new PrimitiveValue(Convert.ToDouble(value), 4);
case SbePrimitiveType.Double:
return new PrimitiveValue(Convert.ToDouble(value), 8);
default:
throw new ArgumentException("Unknown PrimitiveType: " + primitiveType);
}
}
///
/// Return long value for this PrimitiveValue
///
/// value expressed as a long
public long LongValue()
{
if (_representation != Representation.Long)
{
throw new InvalidOperationException("PrimitiveValue is not a long representation");
}
return _longValue;
}
///
/// Return unsigned long value for this PrimitiveValue
///
/// value expressed as a ulong
public ulong ULongValue()
{
if (_representation != Representation.ULong)
{
throw new InvalidOperationException("PrimitiveValue is not a ulong representation");
}
return _unsignedLongValue;
}
///
/// Return double value for this PrimitiveValue.
///
/// value expressed as a double
public double DoubleValue()
{
if (_representation != Representation.Double)
{
throw new InvalidOperationException("PrimitiveValue is not a double representation");
}
return _doubleValue;
}
///
/// Return byte array value for this PrimitiveValue.
///
/// value expressed as a byte array
public byte[] ByteArrayValue()
{
if (_representation != Representation.ByteArray)
{
throw new InvalidOperationException("PrimitiveValue is not a byte[] representation");
}
return _byteArrayValue;
}
///
/// Return byte array value for this PrimitiveValue given a particular type
///
/// of this value
/// value expressed as a byte array
public byte[] ByteArrayValue(SbePrimitiveType type)
{
if (_representation == Representation.ByteArray)
{
return _byteArrayValue;
}
if (_representation == Representation.Long && _size == 1 && type == SbePrimitiveType.Char)
{
_byteArrayValueForLong[0] = (byte) _longValue;
return _byteArrayValueForLong;
}
throw new InvalidOperationException("PrimitiveValue is not a byte[] representation");
}
///
/// Return String representation of this object
///
/// String representing object value
public override string ToString()
{
switch (_representation)
{
case Representation.Long:
return Convert.ToString(_longValue);
case Representation.ULong:
return Convert.ToString(_longValue);
case Representation.Double:
return Convert.ToString(_doubleValue);
case Representation.ByteArray:
return Encoding.GetEncoding(_characterEncoding).GetString(_byteArrayValue);
default:
throw new InvalidOperationException("Unsupported Representation: " + _representation);
}
}
///
/// Determine if two values are equivalent.
///
/// to compare this value with
/// equivalence of values
public override bool Equals(object value)
{
if (null != value && this.GetType().Equals(value.GetType()))
{
var rhs = (PrimitiveValue) value;
if (_representation == rhs._representation)
{
switch (_representation)
{
case Representation.Long:
return _longValue == rhs._longValue;
case Representation.ULong:
return _unsignedLongValue == rhs._unsignedLongValue;
case Representation.Double:
return BitConverter.DoubleToInt64Bits(_doubleValue) == BitConverter.DoubleToInt64Bits(rhs._doubleValue);
case Representation.ByteArray:
return _byteArrayValue.SequenceEqual(rhs._byteArrayValue);
}
}
}
return false;
}
///
/// Return hashCode for value. This is the underlying representations hashCode for the value
///
/// int value of the hashCode
public override int GetHashCode()
{
switch (_representation)
{
case Representation.Long:
return _longValue.GetHashCode();
case Representation.ULong:
return _unsignedLongValue.GetHashCode();
case Representation.Double:
return _doubleValue.GetHashCode();
case Representation.ByteArray:
return _byteArrayValue.GetHashCode();
default:
throw new InvalidOperationException("Unrecognised representation: " + _representation);
}
}
}
}