Example #1
0
        static BsonDocument ToBsonDocument(BsonDocument source, object value, DocumentInput input, IEnumerable <Selector> properties, int depth)
        {
            IncSerializationDepth(ref depth);

            PSObject custom;

            value = BaseObject(value, out custom);

            //_131013_155413 reuse existing document or wrap
            var cd = value as IConvertibleToBsonDocument;

            if (cd != null)
            {
                // reuse
                if (source == null && properties == null)
                {
                    return(cd.ToBsonDocument());
                }

                // wrap
                return(ToBsonDocumentFromDictionary(source, new Dictionary(cd), input, properties, depth));
            }

            var dictionary = value as IDictionary;

            if (dictionary != null)
            {
                return(ToBsonDocumentFromDictionary(source, dictionary, input, properties, depth));
            }

            return(ToBsonDocumentFromProperties(source, custom ?? new PSObject(value), input, properties, depth));
        }
Example #2
0
 //! For external use only.
 public static BsonDocument ToBsonDocument(BsonDocument source, object value, DocumentInput input, IEnumerable <Selector> properties)
 {
     return(ToBsonDocument(source, value, input, properties, 0));
 }
Example #3
0
        //! IConvertibleToBsonDocument (e.g. Mdbc.Dictionary) must be converted before if source and properties are null
        static BsonDocument ToBsonDocumentFromDictionary(BsonDocument source, IDictionary dictionary, DocumentInput input, IEnumerable <Selector> properties, int depth)
        {
            IncSerializationDepth(ref depth);

#if DEBUG
            if (source == null && properties == null && dictionary is IConvertibleToBsonDocument)
            {
                throw new InvalidOperationException("DEBUG: must be converted before.");
            }
#endif

            // use source or new document
            var document = source ?? new BsonDocument();

            if (properties == null)
            {
                foreach (DictionaryEntry de in dictionary)
                {
                    var name = de.Key as string;
                    if (name == null)
                    {
                        throw new InvalidOperationException("Dictionary keys must be strings.");
                    }

                    document.Add(name, ToBsonValue(de.Value, input, depth));
                }
            }
            else
            {
                foreach (var selector in properties)
                {
                    if (selector.PropertyName != null)
                    {
                        if (dictionary.Contains(selector.PropertyName))
                        {
                            document.Add(selector.DocumentName, ToBsonValue(dictionary[selector.PropertyName], input, depth));
                        }
                    }
                    else
                    {
                        document.Add(selector.DocumentName, ToBsonValue(selector.GetValue(dictionary), input, depth));
                    }
                }
            }

            return(document);
        }
Example #4
0
        // Input supposed to be not null
        static BsonDocument ToBsonDocumentFromProperties(BsonDocument source, PSObject value, DocumentInput input, IEnumerable <Selector> properties, int depth)
        {
            IncSerializationDepth(ref depth);

            var type = value.BaseObject.GetType();

            if (type.IsPrimitive || type == typeof(string))
            {
                throw new InvalidCastException(string.Format(null, "Cannot convert {0} to a document.", type));
            }

            // existing or new document
            var document = source ?? new BsonDocument();

            if (properties == null)
            {
                foreach (var pi in value.Properties)
                {
                    try
                    {
                        document.Add(pi.Name, ToBsonValue(pi.Value, input, depth));
                    }
                    catch (GetValueException)                     // .Value may throw, e.g. ExitCode in Process
                    {
                        document.Add(pi.Name, BsonNull.Value);
                    }
                }
            }
            else
            {
                foreach (var selector in properties)
                {
                    if (selector.PropertyName != null)
                    {
                        var pi = value.Properties[selector.PropertyName];
                        if (pi != null)
                        {
                            try
                            {
                                document.Add(selector.DocumentName, ToBsonValue(pi.Value, input, depth));
                            }
                            catch (GetValueException)                             // .Value may throw, e.g. ExitCode in Process
                            {
                                document.Add(selector.DocumentName, BsonNull.Value);
                            }
                        }
                    }
                    else
                    {
                        document.Add(selector.DocumentName, ToBsonValue(selector.GetValue(value), input, depth));
                    }
                }
            }
            return(document);
        }
Example #5
0
        static BsonValue ToBsonValue(object value, ScriptBlock convert, int depth)
        {
            IncSerializationDepth(ref depth);

            if (value == null)
            {
                return(BsonNull.Value);
            }

            value = BaseObject(value, out PSObject custom);

            // case: custom
            if (custom != null)
            {
                return(ToBsonDocumentFromProperties(null, custom, convert, null, depth));
            }

            // case: BsonValue
            if (value is BsonValue bson)
            {
                return(bson);
            }

            // case: string
            if (value is string text)
            {
                return(new BsonString(text));
            }

            // case: document
            if (value is IConvertibleToBsonDocument cd)
            {
                return(cd.ToBsonDocument());
            }

            // case: dictionary
            if (value is IDictionary dictionary)
            {
                return(ToBsonDocumentFromDictionary(null, dictionary, convert, null, depth));
            }

            // case: bytes or collection
            if (value is IEnumerable en)
            {
                //_191108_183844
                if (en is byte[] bytes)
                {
                    return(new BsonBinaryData(bytes));
                }

                var array = new BsonArray();
                foreach (var it in en)
                {
                    array.Add(ToBsonValue(it, convert, depth));
                }
                return(array);
            }

            // try to map BsonValue
            if (BsonTypeMapper.TryMapToBsonValue(value, out BsonValue bson2))
            {
                return(bson2);
            }

            // try to serialize class
            var type = value.GetType();

            if (TypeIsDriverSerialized(type))
            {
                return(BsonExtensionMethods.ToBsonDocument(value, type));
            }

            // no converter? die
            if (convert == null)
            {
                //! use this type
                throw new ArgumentException(Res.CannotConvert2(type, nameof(BsonValue)));
            }

            try
            {
                value = DocumentInput.ConvertValue(convert, value);
            }
            catch (RuntimeException re)
            {
                //! use this type
                throw new ArgumentException($"Converter script was called for '{type}' and failed with '{re.Message}'.", re);
            }

            // do not pass converter twice
            return(ToBsonValue(value, null, depth));
        }
Example #6
0
        static BsonValue ToBsonValue(object value, DocumentInput input, int depth)
        {
            IncSerializationDepth(ref depth);

            if (value == null)
            {
                return(BsonNull.Value);
            }

            PSObject custom;

            value = BaseObject(value, out custom);

            // case: custom
            if (custom != null)
            {
                return(ToBsonDocumentFromProperties(null, custom, input, null, depth));
            }

            // case: BsonValue
            var bson = value as BsonValue;

            if (bson != null)
            {
                return(bson);
            }

            // case: string
            var text = value as string;

            if (text != null)
            {
                return(new BsonString(text));
            }

            // case: document
            var cd = value as IConvertibleToBsonDocument;

            if (cd != null)
            {
                return(cd.ToBsonDocument());
            }

            // case: dictionary
            var dictionary = value as IDictionary;

            if (dictionary != null)
            {
                return(ToBsonDocumentFromDictionary(null, dictionary, input, null, depth));
            }

            // case: collection
            var enumerable = value as IEnumerable;

            if (enumerable != null)
            {
                var array = new BsonArray();
                foreach (var it in enumerable)
                {
                    array.Add(ToBsonValue(it, input, depth));
                }
                return(array);
            }

            // try to create BsonValue
            try
            {
                return(BsonValue.Create(value));
            }
            catch (ArgumentException ae)
            {
                if (input == null)
                {
                    throw;
                }

                try
                {
                    value = input.ConvertValue(value);
                }
                catch (RuntimeException re)
                {
                    throw new ArgumentException(                     //! use this type
                              string.Format(null, @"Converter script was called on ""{0}"" and failed with ""{1}"".", ae.Message, re.Message), re);
                }

                if (value == null)
                {
                    throw;
                }

                // do not call converter twice
                return(ToBsonValue(value, null, depth));
            }
        }
Example #7
0
        static BsonValue ToBsonValue(object value, DocumentInput input, int depth)
        {
            IncSerializationDepth(ref depth);

            if (value == null)
                return BsonNull.Value;

            PSObject custom;
            value = BaseObject(value, out custom);

            // case: custom
            if (custom != null)
                return ToBsonDocumentFromProperties(null, custom, input, null, depth);

            // case: BsonValue
            var bson = value as BsonValue;
            if (bson != null)
                return bson;

            // case: string
            var text = value as string;
            if (text != null)
                return new BsonString(text);

            // case: document
            var cd = value as IConvertibleToBsonDocument;
            if (cd != null)
                return cd.ToBsonDocument();

            // case: dictionary
            var dictionary = value as IDictionary;
            if (dictionary != null)
                return ToBsonDocumentFromDictionary(null, dictionary, input, null, depth);

            // case: collection
            var enumerable = value as IEnumerable;
            if (enumerable != null)
            {
                var array = new BsonArray();
                foreach (var it in enumerable)
                    array.Add(ToBsonValue(it, input, depth));
                return array;
            }

            // try to create BsonValue
            try
            {
                Register();
                return BsonValue.Create(value);
            }
            catch (ArgumentException ae)
            {
                if (input == null)
                    throw;

                try
                {
                    value = input.ConvertValue(value);
                }
                catch (RuntimeException re)
                {
                    throw new ArgumentException( //! use this type
                        string.Format(null, @"Converter script was called on ""{0}"" and failed with ""{1}"".", ae.Message, re.Message), re);
                }

                if (value == null)
                    throw;

                // do not call converter twice
                return ToBsonValue(value, null, depth);
            }
        }
Example #8
0
        // Input supposed to be not null
        static BsonDocument ToBsonDocumentFromProperties(BsonDocument source, PSObject value, DocumentInput input, IEnumerable<Selector> properties, int depth)
        {
            IncSerializationDepth(ref depth);

            var type = value.BaseObject.GetType();
            if (type.IsPrimitive || type == typeof(string))
                throw new InvalidCastException(string.Format(null, "Cannot convert {0} to a document.", type));

            // existing or new document
            var document = source ?? new BsonDocument();

            if (properties == null)
            {
                foreach (var pi in value.Properties)
                {
                    try
                    {
                        document.Add(pi.Name, ToBsonValue(pi.Value, input, depth));
                    }
                    catch (GetValueException) // .Value may throw, e.g. ExitCode in Process
                    {
                        document.Add(pi.Name, BsonNull.Value);
                    }
                }
            }
            else
            {
                foreach (var selector in properties)
                {
                    if (selector.PropertyName != null)
                    {
                        var pi = value.Properties[selector.PropertyName];
                        if (pi != null)
                        {
                            try
                            {
                                document.Add(selector.DocumentName, ToBsonValue(pi.Value, input, depth));
                            }
                            catch (GetValueException) // .Value may throw, e.g. ExitCode in Process
                            {
                                document.Add(selector.DocumentName, BsonNull.Value);
                            }
                        }
                    }
                    else
                    {
                        document.Add(selector.DocumentName, ToBsonValue(selector.GetValue(value), input, depth));
                    }
                }
            }
            return document;
        }
Example #9
0
        //! IConvertibleToBsonDocument (e.g. Mdbc.Dictionary) must be converted before if source and properties are null
        static BsonDocument ToBsonDocumentFromDictionary(BsonDocument source, IDictionary dictionary, DocumentInput input, IEnumerable<Selector> properties, int depth)
        {
            IncSerializationDepth(ref depth);

            #if DEBUG
            if (source == null && properties == null && dictionary is IConvertibleToBsonDocument)
                throw new InvalidOperationException("DEBUG: must be converted before.");
            #endif

            // use source or new document
            var document = source ?? new BsonDocument();

            if (properties == null)
            {
                foreach (DictionaryEntry de in dictionary)
                {
                    var name = de.Key as string;
                    if (name == null)
                        throw new InvalidOperationException("Dictionary keys must be strings.");

                    document.Add(name, ToBsonValue(de.Value, input, depth));
                }
            }
            else
            {
                foreach (var selector in properties)
                {
                    if (selector.PropertyName != null)
                    {
                        if (dictionary.Contains(selector.PropertyName))
                            document.Add(selector.DocumentName, ToBsonValue(dictionary[selector.PropertyName], input, depth));
                    }
                    else
                    {
                        document.Add(selector.DocumentName, ToBsonValue(selector.GetValue(dictionary), input, depth));
                    }
                }
            }

            return document;
        }
Example #10
0
        static BsonDocument ToBsonDocument(BsonDocument source, object value, DocumentInput input, IEnumerable<Selector> properties, int depth)
        {
            IncSerializationDepth(ref depth);

            PSObject custom;
            value = BaseObject(value, out custom);

            //_131013_155413 reuse existing document or wrap
            var cd = value as IConvertibleToBsonDocument;
            if (cd != null)
            {
                // reuse
                if (source == null && properties == null)
                    return cd.ToBsonDocument();

                // wrap
                return ToBsonDocumentFromDictionary(source, new Dictionary(cd), input, properties, depth);
            }

            var dictionary = value as IDictionary;
            if (dictionary != null)
                return ToBsonDocumentFromDictionary(source, dictionary, input, properties, depth);

            return ToBsonDocumentFromProperties(source, custom ?? new PSObject(value), input, properties, depth);
        }
Example #11
0
 //! For external use only.
 public static BsonDocument ToBsonDocument(BsonDocument source, object value, DocumentInput input, IEnumerable<Selector> properties)
 {
     return ToBsonDocument(source, value, input, properties, 0);
 }