static RawVariantLength RawLengthFromByte(byte length) { Contract.Requires(length > 0 && length <= 4); RawVariantLength l = (RawVariantLength)(--length); return(l); }
static void SetLength(RawVariantLength length, ref uint data) { uint l = (uint)length; l <<= kInfoLengthBitIndex; l &= kInfoLengthBitMask; data |= l; }
static byte RawLengthToByte(RawVariantLength length) { const byte k_rebase = 1; byte l = (byte)length; l += k_rebase; return(l); }
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 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); } }