コード例 #1
0
        private static void ResolveRefs(object original, object root, string currentPath)
        {
            if (original is SpeckleAbstract)
            {
                SpeckleAbstract myObj = ( SpeckleAbstract )original;
                if (myObj._type == "ref")
                {
                    Converter.LinkRef(root, myObj._ref, currentPath);
                }
                else
                {
                    foreach (var key in myObj.Properties.Keys)
                    {
                        Converter.ResolveRefs(myObj.Properties[key], root, currentPath + "/" + key);
                    }
                }
            }

            if (original is IDictionary)
            {
                foreach (DictionaryEntry kvp in ( IDictionary )original)
                {
                    Converter.ResolveRefs(kvp.Value, root, currentPath + "/{" + kvp.Key.ToString() + "}");
                }
            }

            if (original is List <object> )
            {
                List <object> myList = (List <object>)original; int index = 0;
                foreach (object obj in myList)
                {
                    Converter.ResolveRefs(obj, root, currentPath + "/[" + index++ + "]");
                }
            }
        }
コード例 #2
0
        private static object ShallowConvert(SpeckleAbstract obj)
        {
            var keys    = obj.Properties.Keys;
            var newDict = new Dictionary <string, object>();

            foreach (string key in keys)
            {
                newDict.Add(key, Converter.ReadValue(obj.Properties[key], obj));
            }
            obj.Properties = newDict;
            return(obj);
        }
コード例 #3
0
        /// <summary>
        /// Serialises an object to a speckle object.
        /// </summary>
        /// <param name="source">The object you want to serialise.</param>
        /// <param name="recursionDepth">Leave this blank, unless you really know what you're doing.</param>
        /// <param name="traversed">Leave this blank, unless you really know what you're doing.</param>
        /// <param name="path">Leave this blank, unless you really know what you're doing.</param>
        /// <returns></returns>
        public static SpeckleObject Serialise(object source, int recursionDepth = 0, Dictionary <int, string> traversed = null, string path = "")
        {
            // null  check
            if (source == null)
            {
                return(new SpeckleNull());
            }

            // init optional parameters
            if (traversed == null)
            {
                traversed = new Dictionary <int, string>();
            }

            if (path == "")
            {
                path = "root";
            }

            // check references
            if (traversed.ContainsKey(source.GetHashCode()))
            {
                return new SpeckleAbstract()
                       {
                           _type = "ref", _ref = traversed[source.GetHashCode()]
                       }
            }
            ;
            else
            {
                traversed.Add(source.GetHashCode(), path);
            }

            // check if it already is a speckle object
            if (source is SpeckleObject)
            {
                return(source as SpeckleObject);
            }

            // check assemblies
            if (toSpeckleMethods.ContainsKey(source.GetType().ToString()))
            {
                return(toSpeckleMethods[source.GetType().ToString()].Invoke(source, new object[] { source }) as SpeckleObject);
            }

            List <Assembly> myAss = System.AppDomain.CurrentDomain.GetAssemblies().ToList().FindAll(s => s.FullName.Contains("Speckle") && s.FullName.Contains("Converter"));

            List <MethodInfo> methods = new List <MethodInfo>();

            foreach (var ass in myAss)
            {
                methods.AddRange(Converter.GetExtensionMethods(ass, source.GetType(), "ToSpeckle"));
            }

            // if we have a "ToSpeckle" extension method, then invoke that and return its result
            if (methods.Count > 0)
            {
                try
                {
                    var obj = methods[0].Invoke(source, new object[] { source });
                    return(obj as SpeckleObject);
                }
                catch
                {
                    return(new SpeckleNull());
                }
            }

            // else just continue with the to abstract part
            SpeckleAbstract result = new SpeckleAbstract();

            result._type     = source.GetType().Name;
            result._assembly = source.GetType().Assembly.FullName;

            Dictionary <string, object> dict = new Dictionary <string, object>();

            var properties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

            foreach (var prop in properties)
            {
                if (!prop.CanWrite)
                {
                    continue;
                }

                try
                {
                    var value = prop.GetValue(source);

                    if (value == null)
                    {
                        continue;
                    }

                    dict[prop.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + prop.Name);
                }
                catch { }
            }

            var fields = source.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);

            foreach (var field in fields)
            {
                if (field.IsNotSerialized)
                {
                    continue;
                }
                try
                {
                    var value = field.GetValue(source);
                    if (value == null)
                    {
                        continue;
                    }
                    dict[field.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + field.Name);
                }
                catch { }
            }

            result.Properties = dict;
            result.Hash       = result.GeometryHash = result.GetMd5FromObject(result.Properties);

            return(result);
        }
コード例 #4
0
        /// <summary>
        /// Deserialises a speckle object.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns>an object, a SpeckleAbstract or null.</returns>
        public static object Deserialise(SpeckleObject obj, object root = null)
        {
            try
            {
                // null check
                if (obj == null)
                {
                    return(null);
                }

                // if it's not a speckle abstract object
                if (!(obj is SpeckleAbstract))
                {
                    // assembly check
                    var type = obj.GetType().ToString();

                    if (toNativeMethods.ContainsKey(type))
                    {
                        return(toNativeMethods[obj.GetType().ToString()].Invoke(obj, new object[] { obj }));
                    }

                    List <Assembly> myAss = System.AppDomain.CurrentDomain.GetAssemblies().ToList().FindAll(s => s.FullName.Contains("Speckle") && s.FullName.Contains("Converter"));

                    List <MethodInfo> methods = new List <MethodInfo>();

                    foreach (var ass in myAss)
                    {
                        methods.AddRange(Converter.GetExtensionMethods(ass, obj.GetType(), "ToNative"));
                    }

                    // if we have some ToNative method
                    if (methods.Count > 0)
                    {
                        toNativeMethods.Add(type, methods[0]);
                        var result = methods[0].Invoke(obj, new object[] { obj });
                        if (result != null)
                        {
                            return(result);
                        }
                    }
                    // otherwise return null
                    return(null);
                }
                else
                {
                    // we have a speckle abstract object
                    SpeckleAbstract absObj = obj as SpeckleAbstract;

                    if (absObj._type == "ref")
                    {
                        return(null);
                    }

                    //var shortName = absObj._assembly.Split( ',' )[ 0 ];

                    var assembly = System.AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == absObj._assembly);

                    //try again
                    if (assembly == null)
                    {
                        var shortName = absObj._assembly.Split(',')[0];
                        assembly = System.AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName.Contains(shortName));
                    }

                    if (assembly == null) // we can't deserialise for sure
                    {
                        return(Converter.ShallowConvert(absObj));
                    }

                    var type = assembly.GetTypes().FirstOrDefault(t => t.Name == absObj._type);
                    if (type == null) // type not present in the assembly
                    {
                        return(Converter.ShallowConvert(absObj));
                    }

                    object myObject = null;

                    try
                    {
                        var constructor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[] { }, null);
                        if (constructor != null)
                        {
                            myObject = constructor.Invoke(new object[] { });
                        }
                        if (myObject == null)
                        {
                            myObject = Activator.CreateInstance(type);
                        }
                    }
                    catch
                    {
                        myObject = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(type);
                    }

                    if (myObject == null)
                    {
                        return(null);
                    }

                    if (root == null)
                    {
                        root = myObject;
                    }

                    var keys = absObj.Properties.Keys;
                    foreach (string key in keys)
                    {
                        var prop  = TryGetProperty(type, key);
                        var field = type.GetField(key);

                        if (prop == null && field == null)
                        {
                            continue;
                        }

                        if (absObj.Properties[key] == null)
                        {
                            continue;
                        }

                        var value = ReadValue(absObj.Properties[key], root);

                        // handles both hashsets and lists or whatevers
                        if (value is IEnumerable && !(value is IDictionary) && value.GetType() != typeof(string))
                        {
                            try
                            {
                                if ((prop != null && prop.PropertyType.IsArray) || (field != null && field.FieldType.IsArray))
                                {
                                    value = ((List <object>)value).ToArray();
                                }
                                else
                                {
                                    var mySubList = Activator.CreateInstance(prop != null ? prop.PropertyType : field.FieldType);
                                    foreach (var myObj in ((IEnumerable <object>)value))
                                    {
                                        mySubList.GetType().GetMethod("Add").Invoke(mySubList, new object[] { myObj });
                                    }

                                    value = mySubList;
                                }
                            }
                            catch { }
                        }

                        // handles dictionaries of all sorts (kind-of!)
                        if (value is IDictionary)
                        {
                            try
                            {
                                var MyDict = Activator.CreateInstance(prop != null ? prop.PropertyType : field.FieldType);

                                foreach (DictionaryEntry kvp in ( IDictionary )value)
                                {
                                    MyDict.GetType().GetMethod("Add").Invoke(MyDict, new object[] { Convert.ChangeType(kvp.Key, MyDict.GetType().GetGenericArguments()[0]), kvp.Value });
                                }

                                value = MyDict;
                            }
                            catch (Exception e)
                            {
                                System.Diagnostics.Debug.WriteLine(e.Message);
                            }
                        }

                        // guids are a pain
                        if ((prop != null && prop.PropertyType == typeof(Guid)) || (field != null && field.FieldType == typeof(Guid)))
                        {
                            value = new Guid(( string )value);
                        }

                        // Actually set the value below, whether it's a property or field
                        // if it is a property
                        if (prop != null && prop.CanWrite)
                        {
                            if (prop.PropertyType.IsEnum)
                            {
                                prop.SetValue(myObject, Enum.ToObject(prop.PropertyType, Convert.ChangeType(value, TypeCode.Int32)));
                            }
                            else
                            {
                                try
                                {
                                    prop.SetValue(myObject, value);
                                }
                                catch
                                {
                                    try
                                    {
                                        prop.SetValue(myObject, Convert.ChangeType(value, prop.PropertyType));
                                    }
                                    catch
                                    {
                                    }
                                }
                            }
                        }
                        // if it is a field
                        else if (field != null)
                        {
                            if (field.FieldType.IsEnum)
                            {
                                field.SetValue(myObject, Enum.ToObject(field.FieldType, Convert.ChangeType(value, TypeCode.Int32)));
                            }
                            else
                            {
                                try
                                {
                                    field.SetValue(absObj, value);
                                }
                                catch
                                {
                                    try
                                    {
                                        field.SetValue(myObject, Convert.ChangeType(value, field.FieldType));
                                    }
                                    catch { }
                                }
                            }
                        }
                    }

                    //  set references too.
                    if (root == myObject)
                    {
                        Converter.ResolveRefs(absObj, myObject, "root");
                    }

                    return(myObject);
                }
            }
            catch
            {
                return(null);
            }
        }
コード例 #5
0
        /// <summary>
        /// Serialises an object to a speckle object.
        /// </summary>
        /// <param name="source">The object you want to serialise.</param>
        /// <param name="recursionDepth">Leave this blank, unless you really know what you're doing.</param>
        /// <param name="traversed">Leave this blank, unless you really know what you're doing.</param>
        /// <param name="path">Leave this blank, unless you really know what you're doing.</param>
        /// <param name="excludeAssebmlies">List of speckle kits assembly names to exclude from the search.</param>
        /// <returns></returns>
        public static SpeckleObject Serialise(object source, int recursionDepth = 0, Dictionary <int, string> traversed = null, string path = "", IEnumerable <string> excludeAssebmlies = null)
        {
            if (source == null)
            {
                return(new SpeckleNull());
            }

            //if ( source is IEnumerable ) return Converter.Serialise( source as IEnumerable<object> );

            if (traversed == null)
            {
                traversed = new Dictionary <int, string>();
            }

            if (path == "")
            {
                path = "root";
            }

            // check references
            if (traversed.ContainsKey(source.GetHashCode()))
            {
                return new SpeckleAbstract()
                       {
                           _type = "ref", _ref = traversed[source.GetHashCode()]
                       }
            }
            ;
            else
            {
                traversed.Add(source.GetHashCode(), path);
            }

            // check if it already is a speckle object
            if (source is SpeckleObject)
            {
                return(source as SpeckleObject);
            }

            // check assemblies
            if (toSpeckleMethods.ContainsKey(source.GetType().ToString()))
            {
                return(toSpeckleMethods[source.GetType().ToString()].Invoke(source, new object[] { source }) as SpeckleObject);
            }

            var methods = new List <MethodInfo>();

            foreach (var ass in SpeckleCore.SpeckleInitializer.GetAssemblies().Where(ass => (excludeAssebmlies != null ? !excludeAssebmlies.Contains(ass.FullName) : true)))
            {
                try
                {
                    methods.AddRange(Converter.GetExtensionMethods(ass, source.GetType(), "ToSpeckle"));
                }
                catch { } // handling errors thrown when we're attempting to load something with missing references (ie, dynamo stuff in rhino, or vice-versa).
            }

            // if we have a "ToSpeckle" extension method, then invoke that and return its result
            if (methods.Count > 0)
            {
                try
                {
                    var obj = methods[0].Invoke(source, new object[] { source });
                    if (obj != null)
                    {
                        toSpeckleMethods.Add(source.GetType().ToString(), methods[0]);
                        return(obj as SpeckleObject);
                    }
                    else
                    {
                        return(new SpeckleNull());
                    }
                }
                catch
                {
                    return(new SpeckleNull());
                }
            }

            // else just continue with the to abstract part
            SpeckleAbstract result = new SpeckleAbstract();

            result._type     = source.GetType().Name;
            result._assembly = source.GetType().Assembly.FullName;

            Dictionary <string, object> dict = new Dictionary <string, object>();

            var properties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

            foreach (var prop in properties)
            {
                if (!prop.CanWrite)
                {
                    continue;
                }

                try
                {
                    var value = prop.GetValue(source);

                    if (value == null)
                    {
                        continue;
                    }

                    dict[prop.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + prop.Name);
                }
                catch { }
            }

            var fields = source.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);

            foreach (var field in fields)
            {
                if (field.IsNotSerialized)
                {
                    continue;
                }
                try
                {
                    var value = field.GetValue(source);
                    if (value == null)
                    {
                        continue;
                    }
                    dict[field.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + field.Name);
                }
                catch { }
            }

            result.Properties = dict;
            result.Hash       = result.GeometryHash = result.GetMd5FromObject(result.Properties);

            return(result);
        }
コード例 #6
0
        /// <summary>
        /// Serialises an object to a speckle object.
        /// </summary>
        /// <param name="source">The object you want to serialise.</param>
        /// <param name="recursionDepth">Leave this blank, unless you really know what you're doing.</param>
        /// <param name="traversed">Leave this blank, unless you really know what you're doing.</param>
        /// <param name="path">Leave this blank, unless you really know what you're doing.</param>
        /// <param name="excludeAssebmlies">List of speckle kits assembly names to exclude from the search.</param>
        /// <returns></returns>
        public static object Serialise(object source, int recursionDepth = 0, Dictionary <int, string> traversed = null, string path = "", IEnumerable <string> excludeAssebmlies = null)
        {
            if (source == null)
            {
                return(new SpeckleNull());
            }

            //if ( source is IEnumerable ) return Converter.Serialise( source as IEnumerable<object> );

            if (traversed == null)
            {
                traversed = new Dictionary <int, string>();
            }

            if (path == "")
            {
                path = "root";
            }

            // check references
            if (traversed.ContainsKey(source.GetHashCode()))
            {
                return new SpeckleAbstract()
                       {
                           _type = "ref", _ref = traversed[source.GetHashCode()]
                       }
            }
            ;
            else
            {
                traversed.Add(source.GetHashCode(), path);
            }

            // check if it already is a speckle object
            if (source is SpeckleObject)
            {
                return(source as SpeckleObject);
            }

            // check assemblies
            if (toSpeckleMethods.ContainsKey(source.GetType().ToString()))
            {
                return(toSpeckleMethods[source.GetType().ToString()].Invoke(source, new object[] { source }));
            }

            var methods     = new List <MethodInfo>();
            var currentType = source.GetType();
            var baseTypes   = new List <Type>();

            // create a list of base types
            while (currentType != null)
            {
                baseTypes.Add(currentType);
                currentType = currentType.BaseType;
            }

            // populate the ToSpeckle method array
            foreach (var ass in SpeckleCore.SpeckleInitializer.GetAssemblies().Where(ass => (excludeAssebmlies != null ? !excludeAssebmlies.Contains(ass.FullName) : true)))
            {
                foreach (var type in baseTypes)
                {
                    try
                    {
                        methods.AddRange(Converter.GetExtensionMethods(ass, type, "ToSpeckle"));
                    }
                    catch { }
                }
            }

            // iterate through the ToSpeckle method array
            if (methods.Count > 0)
            {
                foreach (var method in methods)
                {
                    try
                    {
                        var obj = method.Invoke(source, new object[] { source });
                        if (obj != null)
                        {
                            toSpeckleMethods.Add(source.GetType().ToString(), method);

                            return(obj);
                        }
                    }
                    catch
                    {
                        return(new SpeckleNull());
                    }
                }
            }

            // if we haven't returned anything by this point, we should go abstract
            SpeckleAbstract result = new SpeckleAbstract();

            result._type     = source.GetType().Name;
            result._assembly = source.GetType().Assembly.FullName;

            Dictionary <string, object> dict = new Dictionary <string, object>();

            var properties = source.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);

            foreach (var prop in properties)
            {
                if (!prop.CanWrite)
                {
                    continue;
                }

                try
                {
                    var value = prop.GetValue(source);

                    if (value == null)
                    {
                        continue;
                    }

                    dict[prop.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + prop.Name);
                }
                catch { }
            }

            var fields = source.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public);

            foreach (var field in fields)
            {
                if (field.IsNotSerialized)
                {
                    continue;
                }
                try
                {
                    var value = field.GetValue(source);
                    if (value == null)
                    {
                        continue;
                    }
                    dict[field.Name] = WriteValue(value, recursionDepth, traversed, path + "/" + field.Name);
                }
                catch { }
            }

            result.Properties = dict;
            result.Hash       = result.GeometryHash = result.GetMd5FromObject(result.GetMd5FromObject(result._assembly) + result.GetMd5FromObject(result._type) + result.GetMd5FromObject(result.Properties));

            return(result);
        }