static void SetType(RawVariantType type, ref uint data)
        {
            uint t = (uint)type;

            t <<= kInfoTypeBitIndex;
            t  &= kInfoTypeBitMask;

            data |= t;
        }
        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);
            }
        }
        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;
            }
        }
        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);
            }
        }