Ejemplo n.º 1
0
Archivo: Value.cs Proyecto: ynkbt/moon
        public static unsafe object ToObject(Type type, Value *value)
        {
            if (value == null || value->IsNull)
            {
                return(null);
            }

            if (value->boxed_valuetype.IsAllocated)
            {
                return(value->boxed_valuetype.Target);
            }

            if (value->IsGCHandle)
            {
                IntPtr   managed_object = value->u.p;
                GCHandle handle         = GCHandle.FromIntPtr(managed_object);
                return(handle.Target);
            }

            switch (value->Kind)
            {
            case Kind.INVALID:
                return(null);

            case Kind.DEPENDENCYPROPERTY:
                return(DependencyProperty.Lookup(value->u.p));

            case Kind.BOOL:
                return(value->u.i32 != 0);

            case Kind.DOUBLE:
                return(value->u.d);

            case Kind.FLOAT:
                return(value->u.f);

            case Kind.UINT64:
                return(value->u.ui64);

            case Kind.INT64:
                return(value->u.i64);

            case Kind.TIMESPAN:
                return(new TimeSpan(value->u.i64));

            case Kind.CURSORTYPE:
                return(Cursors.FromEnum((CursorType)value->u.i32));

            case Kind.TEXTDECORATIONS:
                return((value->u.i32 == (int)TextDecorationKind.Underline) ? TextDecorations.Underline : null);

            case Kind.INT32:
                return(value->u.i32);

            case Kind.UINT32:
                return(value->u.ui32);

            case Kind.CHAR:
                return((char)value->u.ui32);

            case Kind.SURFACE:
                return(NativeDependencyObjectHelper.FromIntPtr(value->u.p));

            case Kind.STRING: {
                return(Marshal.PtrToStringAuto(value->u.p));
            }

            case Kind.URI:
                return(UriHelper.FromNativeUri(value->u.p));

            case Kind.XMLLANGUAGE: {
                string str = Marshal.PtrToStringAuto(value->u.p);
                return(XmlLanguage.GetLanguage(str));
            }

            case Kind.FONTFAMILY: {
                UnmanagedFontFamily *family = (UnmanagedFontFamily *)value->u.p;
                return(new FontFamily(family == null ? null : Marshal.PtrToStringAuto(family->source)));
            }

            case Kind.FONTSTRETCH: {
                UnmanagedFontStretch *stretch = (UnmanagedFontStretch *)value->u.p;
                return(new FontStretch(stretch == null ? FontStretchKind.Normal : stretch->stretch));
            }

            case Kind.FONTSTYLE: {
                UnmanagedFontStyle *style = (UnmanagedFontStyle *)value->u.p;
                return(new FontStyle(style == null ? FontStyleKind.Normal : style->style));
            }

            case Kind.FONTWEIGHT: {
                UnmanagedFontWeight *weight = (UnmanagedFontWeight *)value->u.p;
                return(new FontWeight(weight == null ? FontWeightKind.Normal : weight->weight));
            }

            case Kind.FONTSOURCE: {
                UnmanagedFontSource *  fs = (UnmanagedFontSource *)value->u.p;
                ManagedStreamCallbacks callbacks;
                GlyphTypeface          typeface;
                StreamWrapper          wrapper;

                switch (fs->type)
                {
                case FontSourceType.ManagedStream:
                    callbacks = (ManagedStreamCallbacks)Marshal.PtrToStructure(fs->source.stream, typeof(ManagedStreamCallbacks));

                    wrapper = (StreamWrapper)GCHandle.FromIntPtr(callbacks.handle).Target;

                    return(new FontSource(wrapper.stream));

                case FontSourceType.GlyphTypeface:
                    typeface = new GlyphTypeface(fs->source.typeface);
                    return(new FontSource(typeface));

                default:
                    throw new Exception(String.Format("Do not know how to create a FontSource of type {0}",
                                                      fs->type.ToString()));
                }
            }

            case Kind.GLYPHTYPEFACE: {
                return(new GlyphTypeface(value->u.p));
            }

            case Kind.PROPERTYPATH: {
                UnmanagedPropertyPath *propertypath = (UnmanagedPropertyPath *)value->u.p;
                if (propertypath == null)
                {
                    return(new PropertyPath(null));
                }
                if (propertypath->property != IntPtr.Zero)
                {
                    return(null);
                }
                return(new PropertyPath(Marshal.PtrToStringAuto(propertypath->pathString), Marshal.PtrToStringAuto(propertypath->expandedPathString)));
            }

            case Kind.POINT: {
                Point *point = (Point *)value->u.p;
                return((point == null) ? new Point(0, 0) : *point);
            }

            case Kind.RECT: {
                Rect *rect = (Rect *)value->u.p;
                return((rect == null) ? new Rect(0, 0, 0, 0) : *rect);
            }

            case Kind.SIZE: {
                Size *size = (Size *)value->u.p;
                return((size == null) ? new Size(0, 0) : *size);
            }

            case Kind.CORNERRADIUS: {
                CornerRadius *corner = (CornerRadius *)value->u.p;
                return((corner == null) ? new CornerRadius(0) : *corner);
            }

            case Kind.AUDIOFORMAT: {
                UnmanagedAudioFormat *format = (UnmanagedAudioFormat *)value->u.p;
                return((format == null) ? new AudioFormat() : format->ToAudioFormat());
            }

            case Kind.VIDEOFORMAT: {
                UnmanagedVideoFormat *format = (UnmanagedVideoFormat *)value->u.p;
                return((format == null) ? new VideoFormat() : format->ToVideoFormat());
            }

            case Kind.THICKNESS: {
                Thickness *thickness = (Thickness *)value->u.p;
                return((thickness == null) ? new Thickness(0) : *thickness);
            }

            case Kind.COLOR: {
                UnmanagedColor *color = (UnmanagedColor *)value->u.p;
                if (color == null)
                {
                    return(new Color());
                }
                return(color->ToColor());
            }

            case Kind.MATRIX:
            case Kind.UNMANAGEDMATRIX: {
                return(new Matrix(value->u.p));
            }

            case Kind.MATRIX3D:
            case Kind.UNMANAGEDMATRIX3D: {
                return(new Matrix3D(value->u.p));
            }

            case Kind.STYLUSPOINT:
            case Kind.UNMANAGEDSTYLUSPOINT: {
                var kind     = value->Kind;
                var ptr      = value->u.p;
                var x        = (double)Value.ToObject(typeof(double), NativeMethods.dependency_object_get_value(ptr, UnmanagedStylusPoint.XProperty.Native));
                var y        = (double)Value.ToObject(typeof(double), NativeMethods.dependency_object_get_value(ptr, UnmanagedStylusPoint.YProperty.Native));
                var pressure = (double)Value.ToObject(typeof(double), NativeMethods.dependency_object_get_value(ptr, UnmanagedStylusPoint.PressureFactorProperty.Native));
                return(new StylusPoint {
                        X = x, Y = y, PressureFactor = (float)pressure
                    });
            }

            case Kind.DURATION: {
                Duration *duration = (Duration *)value->u.p;
                return((duration == null) ? Duration.Automatic : *duration);
            }

            case Kind.KEYTIME: {
                KeyTime *keytime = (KeyTime *)value->u.p;
                return((keytime == null) ? KeyTime.FromTimeSpan(TimeSpan.Zero) : *keytime);
            }

            case Kind.GRIDLENGTH: {
                GridLength *gridlength = (GridLength *)value->u.p;
                return((gridlength == null) ? new GridLength() : *gridlength);
            }

            case Kind.REPEATBEHAVIOR: {
                RepeatBehavior *repeat = (RepeatBehavior *)value->u.p;
                return((repeat == null) ? new RepeatBehavior() : *repeat);
            }

            case Kind.MEDIAATTRIBUTE_COLLECTION: {
                IntPtr p = value->u.p;
                if (p == IntPtr.Zero)
                {
                    return(null);
                }

                int count = NativeMethods.collection_get_count(p);
                var dict  = new Dictionary <string, string> ();
                for (int i = 0; i < count; i++)
                {
                    IntPtr map = NativeMethods.collection_get_value_at(p, i);
                    if (map == IntPtr.Zero)
                    {
                        continue;
                    }
                    Value *attribute = (Value *)map;
                    if (attribute->Kind != Kind.MEDIAATTRIBUTE || attribute->u.p == IntPtr.Zero)
                    {
                        continue;
                    }
                    string name = NativeMethods.media_attribute_get_name(attribute->u.p);
                    string val  = NativeMethods.media_attribute_get_value(attribute->u.p);

                    dict.Add(name, val);
                }
                return(dict);
            }

            case Kind.MANAGEDTYPEINFO: {
                ManagedTypeInfo *type_info = (ManagedTypeInfo *)value->u.p;
                if (type_info == null)
                {
                    return(null);
                }
                return(Deployment.Current.Types.KindToType(type_info->Kind));
            }

            default:
                Type tt = Deployment.Current.Types.KindToType(value->Kind);
                if (tt != null && tt.IsEnum)
                {
                    return(Enum.ToObject(tt, value->u.i32));
                }
                break;
            }

            if (NativeMethods.type_is_event_object(value->Kind))
            {
                if (value->u.p == IntPtr.Zero)
                {
                    return(null);
                }

                return(NativeDependencyObjectHelper.Lookup(value->u.p));
            }

            throw new Exception(String.Format("Do not know how to convert {0}  {1}. Managed type: {2}",
                                              value->Kind, (int)value->Kind, Deployment.Current.Types.KindToType(value->Kind)));
        }
Ejemplo n.º 2
0
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (destinationType == typeof(object))
            {
                return(value);
            }

            if (destinationType == typeof(string))
            {
                return(value.ToString());
            }

            if (destinationType.IsInstanceOfType(value))
            {
                return(value);
            }

            string str_val = value as String;

            if (str_val != null)
            {
                if (destinationType.IsEnum)
                {
                    return(Enum.Parse(destinationType, str_val, true));
                }

                if (destinationType == typeof(GridLength))
                {
                    if (String.Compare(str_val, "Auto", true) == 0)
                    {
                        return(new GridLength(1, GridUnitType.Auto));
                    }
                    else
                    {
                        str_val = str_val.Trim();
                        var length = 1.0;
                        var type   = str_val.EndsWith("*") ? GridUnitType.Star : GridUnitType.Pixel;
                        if (str_val.Length == 0)
                        {
                            length = 0.0;
                        }
                        if (type == GridUnitType.Star)
                        {
                            str_val = str_val.Substring(0, str_val.Length - 1);
                        }
                        if (str_val.Length > 0)
                        {
                            length = double.Parse(str_val, Helper.DefaultCulture);
                        }

                        return(new GridLength(length, type));
                    }
                }

                if (destinationType == typeof(int))
                {
                    return(int.Parse(str_val, NumberStyles.Any, Helper.DefaultCulture));
                }

                if (destinationType == typeof(double) && str_val == "Auto")
                {
                    return(Double.NaN);
                }

                if (destinationType == typeof(TimeSpan))
                {
                    TimeSpan span;
                    if (TimeSpan.TryParse(str_val, out span))
                    {
                        return(span);
                    }
                }

                if (destinationType == typeof(FontWeight))
                {
                    return(new FontWeight((FontWeightKind)Enum.Parse(typeof(FontWeightKind), str_val, true)));
                }

                if (destinationType == typeof(FontStyle))
                {
                    return(new FontStyle((FontStyleKind)Enum.Parse(typeof(FontStyleKind), str_val, true)));
                }

                if (destinationType == typeof(FontStretch))
                {
                    return(new FontStretch((FontStretchKind)Enum.Parse(typeof(FontStretchKind), str_val, true)));
                }

                if (destinationType == typeof(Cursor))
                {
                    return(Cursors.FromEnum((CursorType)Enum.Parse(typeof(CursorType), str_val, true)));
                }

                if (destinationType == typeof(CacheMode))
                {
                    if (str_val == "BitmapCache")
                    {
                        return(new BitmapCache());
                    }
                }

                if (destinationType == typeof(Rect))
                {
                    return(Rect.FromString(str_val));
                }

                if (destinationType == typeof(Point))
                {
                    return(Point.FromString(str_val));
                }

                if (destinationType == typeof(FontFamily))
                {
                    return(new FontFamily(str_val));
                }

                if (destinationType == typeof(TextDecorationCollection))
                {
                    if (str_val == "Underline")
                    {
                        return(TextDecorations.Underline);
                    }
                    else if (str_val == "None")
                    {
                        return(null);
                    }
                }

                if (destinationType == typeof(System.Globalization.CultureInfo))
                {
                    return(CultureInfo.GetCultureInfo(str_val));
                }

                if (destinationType == typeof(ImageSource) ||
                    destinationType == typeof(BitmapSource) ||
                    destinationType == typeof(BitmapImage))
                {
                    return(new BitmapImage(new Uri(str_val, UriKind.RelativeOrAbsolute)));
                }
            }

            if (value is Color && destinationType.IsAssignableFrom(typeof(SolidColorBrush)))
            {
                return(new SolidColorBrush((Color)value));
            }

            // FontStretch/Style/Weight and enums are stored as uint32 in 2.0
            if (Deployment.Current.RuntimeVersion[0] == '2' && value is UInt32)
            {
                if (destinationType == typeof(FontStyle))
                {
                    return(new FontStyle((FontStyleKind)value));
                }

                if (destinationType == typeof(FontStretch))
                {
                    return(new FontStretch((FontStretchKind)value));
                }

                if (destinationType == typeof(FontWeight))
                {
                    return(new FontWeight((FontWeightKind)value));
                }

                if (destinationType.IsEnum)
                {
                    try {
                        object v = Enum.ToObject(destinationType, value);

                        if (Enum.IsDefined(destinationType, v))
                        {
                            return(v);
                        }
                    } catch (Exception) {
                    }
                }
            }

            if (IsAssignableToIConvertible(value.GetType()) && IsAssignableToIConvertible(destinationType))
            {
                return(ValueFromConvertible(destinationType, (IConvertible)value));
            }

            if (value is Thickness)
            {
                if (destinationType == typeof(CornerRadius))
                {
                    Thickness thickness = (Thickness)value;

                    // Give the same results as if we did Thickness.ToString() and then parsed that as a CornerRadius
                    return(new CornerRadius(thickness.Left, thickness.Top, thickness.Right, thickness.Bottom));
                }
                else if (destinationType == typeof(double))
                {
                    return(((Thickness)value).Left);
                }
            }

            if (str_val != null)
            {
                Kind k = destinationKind;

                IntPtr unmanaged_value = IntPtr.Zero;
                try {
                    if (NativeMethods.value_from_str(k,
                                                     propertyName,
                                                     str_val,
                                                     out unmanaged_value))
                    {
                        value = Value.ToObject(destinationType, unmanaged_value);
                        return(value);
                    }
                } finally {
                    NativeMethods.value_delete_value2(unmanaged_value);
                }
            }

            if (destinationType.IsAssignableFrom(value.GetType()))
            {
                return(value);
            }

            // The base implementation doesn't do anything but
            // throw, so throw here instead so we have more
            // context.
            throw new NotImplementedException(String.Format("Unimplemented type conversion from {0} to {1}",
                                                            value.GetType().ToString(),
                                                            destinationType.ToString()));

            return(base.ConvertFrom(context, culture, value));
        }