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