public static void Int24FromVariant(XmbVariant v, out uint data) { data = Bitwise.Int24.GetNumber(v.Int); if (!v.IsUnsigned) { data = Bitwise.Int24.SetSigned(data, true); } }
public static void Int24ToVariant(ref XmbVariant v, RawVariantFlags f, uint data) { v.Type = XmbVariantType.Int; v.IsUnsigned = (f & RawVariantFlags.Unsigned) != 0; if (!v.IsUnsigned && Bitwise.Int24.IsSigned(data)) { data |= 0xFF000000; } v.Int = data; }
static void DecomposeInt(XmbVariant v, out RawVariantType t, ref RawVariantFlags f, out uint data) { t = RawVariantType.Int; if (v.IsUnsigned) { f |= RawVariantFlags.Unsigned; } data = v.Int; if (Bitwise.Int24.InRange(v.Int)) { t = RawVariantType.Int24; Int24FromVariant(v, out data); } }
public static void Write(IO.EndianWriter s, XmbVariant v) { uint data = 0; RawVariantType t; RawVariantLength l; RawVariantFlags f; Decompose(v, out t, out l, out f, out data); SetType(t, ref data); SetLength(l, ref data); SetFlags(f, ref data); s.Write(data); }
static void StringToVariant(ref XmbVariant v, uint data) { if (v.IsIndirect) { v.Offset = data; } else if (v.IsUnicode) { throw new System.IO.InvalidDataException("Unicode should always be indirect"); //v.Char0 = (char)data; } else { v.Char0 = (byte)((data >> 0) & 0xFF); v.Char1 = (byte)((data >> 8) & 0xFF); v.Char2 = (byte)((data >> 16) & 0xFF); } }
static void StringFromVariant(XmbVariant v, ref uint data) { if (v.IsIndirect) { data |= v.Offset & kValueBitMask; } else if (v.IsUnicode) { throw new System.IO.InvalidDataException("Unicode should always be indirect"); //data |= (ushort)v.Char0; } else { data |= (uint)(v.Char0 << 0); data |= (uint)(v.Char1 << 8); data |= (uint)(v.Char2 << 16); } }
static void Decompose(XmbVariant v, out RawVariantType t, out RawVariantLength l, out RawVariantFlags f, out uint data) { t = RawVariantType.Null; l = (RawVariantLength)byte.MinValue; f = (RawVariantFlags)byte.MinValue; data = 0; bool is_indirect = v.IsIndirect; bool is_unsigned = v.Type == XmbVariantType.Int && v.IsUnsigned; switch (v.Type) { case XmbVariantType.Single: DecomposeSingle(v, out t, out data); break; case XmbVariantType.Int: DecomposeInt(v, out t, ref f, out data); break; case XmbVariantType.Double: // double is always indirect t = RawVariantType.Double; break; case XmbVariantType.Bool: t = RawVariantType.Bool; data = v.Bool ? 1U : 0U; break; case XmbVariantType.String: t = v.IsUnicode ? RawVariantType.StringUnicode : RawVariantType.StringAnsi; StringFromVariant(v, ref data); break; case XmbVariantType.Vector: // Vector is always indirect t = RawVariantType.Vector; l = RawLengthFromByte(v.VectorLength); break; } if (is_indirect) { data = v.Offset & kValueBitMask; } }
static void DecomposeSingle(XmbVariant v, out RawVariantType t, out uint data) { t = RawVariantType.Single; float single = v.Single; if (SingleFixedPoint.InRange(single)) { t = RawVariantType.FixedPoint; data = SingleFixedPoint.FromSingle(single); } else if (Bitwise.Single24.InRange(single)) { t = RawVariantType.Single24; data = Bitwise.Single24.FromSingle(single); } else { data = v.Offset; } }
public static void Read(IO.EndianReader s, out XmbVariant v) { uint data = s.ReadUInt32(); Compose(out v, data); }
static void Compose(out XmbVariant v, uint data) { v = XmbVariant.Empty; RawVariantType type = GetType(data); RawVariantLength length = GetLength(data); RawVariantFlags flags = GetFlags(data); // Get the actual data value data &= kValueBitMask; switch (type) { #region Single case RawVariantType.Single24: v.Type = XmbVariantType.Single; v.Single = Bitwise.Single24.ToSingle(data); break; case RawVariantType.Single: v.Type = XmbVariantType.Single; v.IsIndirect = (flags & RawVariantFlags.Offset) != 0; // should always be true v.Offset = data; break; case RawVariantType.FixedPoint: v.Type = XmbVariantType.Single; v.Single = SingleFixedPoint.ToSingle(data); break; #endregion #region Int case RawVariantType.Int24: Int24ToVariant(ref v, flags, data); break; case RawVariantType.Int: v.Type = XmbVariantType.Int; v.IsUnsigned = (flags & RawVariantFlags.Unsigned) != 0; v.IsIndirect = (flags & RawVariantFlags.Offset) != 0; // should always be true v.Offset = data; break; #endregion #region Double case RawVariantType.Double: v.Type = XmbVariantType.Double; v.IsIndirect = (flags & RawVariantFlags.Offset) != 0; // should always be true v.Offset = data; break; #endregion #region Bool case RawVariantType.Bool: v.Type = XmbVariantType.Bool; v.Bool = data != 0; break; #endregion #region String case RawVariantType.StringAnsi: v.Type = XmbVariantType.String; v.IsIndirect = (flags & RawVariantFlags.Offset) != 0; v.IsUnicode = false; break; case RawVariantType.StringUnicode: v.Type = XmbVariantType.String; v.IsIndirect = (flags & RawVariantFlags.Offset) != 0; v.IsUnicode = true; break; #endregion #region Vector case RawVariantType.Vector: v.Type = XmbVariantType.Vector; v.VectorLength = RawLengthToByte(length); v.IsIndirect = (flags & RawVariantFlags.Offset) != 0; // should always be true v.Offset = data; break; #endregion } if (v.Type == XmbVariantType.String) { StringToVariant(ref v, data); } }
string ToString(XmbVariant v) { return(v.ToString(mPool)); }