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);
            }
        }
Example #11
0
 string ToString(XmbVariant v)
 {
     return(v.ToString(mPool));
 }