Example #1
0
        /// <summary>
        /// Converts BSON to CLR value 1:1, without type change
        /// </summary>
        protected virtual object DirectConvertBSONValue(BSONElement element, Func <BSONDocument, BSONElement, bool> filter = null)
        {
            if (element == null || element is BSONNullElement)
            {
                return(null);
            }

            if (element.ElementType == BSONElementType.Document)
            {
                return(BSONDocumentToJSONMap(((BSONDocumentElement)element).Value, filter));
            }

            if (element.ElementType == BSONElementType.Array)
            {
                var bsonArr = (BSONArrayElement)element;
                var lst     = new List <object>();
                foreach (var elm in bsonArr.Value)
                {
                    lst.Add(DirectConvertBSONValue(elm, filter));
                }
                return(lst.ToArray());
            }

            switch (element.ElementType)
            {
            case BSONElementType.ObjectID: return(((BSONObjectIDElement)element).Value.AsGDID);

            case BSONElementType.Binary: return(((BSONBinaryElement)element).Value.Data);
            }

            return(element.ObjectValue);
        }
Example #2
0
        protected override void ReadValueFromStream(Stream stream)
        {
            var  elements  = new List <BSONElement>();
            long start     = stream.Position;
            var  totalSize = BinUtils.ReadInt32(stream);
            long read      = 4;

            while (read < totalSize - 1)
            {
                var et      = BinUtils.ReadElementType(stream);
                var factory = BSONElement.GetElementFactory(et);
                var element = factory(stream);//element made
                element.MarkAsArrayItem();
                elements.Add(element);
                read = stream.Position - start;
            }
            Value = elements.ToArray();

            var terminator = BinUtils.ReadByte(stream);

            if (terminator != BinUtils.TERMINATOR || stream.Position - start != totalSize)
            {
                throw new BSONException(StringConsts.BSON_EOD_ERROR);
            }
        }
Example #3
0
        public TemplateArg(BSONElement element)
        {
            if (element == null || element.IsArrayElement)
            {
                throw new BSONException(StringConsts.ARGUMENT_ERROR + "TemplateArg.ctor(element==null|IsArrayElement)");
            }

            Name     = element.Name;
            BSONType = element.ElementType;
            Value    = element.ObjectValue;
        }
Example #4
0
        protected virtual bool SetAmorphousFieldAsCLR(IAmorphousData amorph, BSONElement bsonElement, string targetName, Func <BSONDocument, BSONElement, bool> filter)
        {
            object clrValue;

            if (!TryConvertBSONtoCLR(typeof(object), bsonElement, targetName, out clrValue, filter))
            {
                return(false);
            }
            amorph.AmorphousData[bsonElement.Name] = clrValue;
            return(true);
        }
Example #5
0
        //public static Amount Amount_BSONtoCLR(BSONDocument bson)
        //{
        //  var iso = bson.GetValue("c", string.Empty).ToString();
        //  var value = Decimal_BSONtoCLR(bson.GetValue("v", 0L).ToString());
        //  return new Amount(iso, value);
        //}


        protected virtual bool TrySetFieldAsCLR(Row row, Schema.FieldDef field, BSONElement value, string targetName, Func <BSONDocument, BSONElement, bool> filter)
        {
            object clrValue;

            if (!TryConvertBSONtoCLR(field.NonNullableType, value, targetName, out clrValue, filter))
            {
                return(false);
            }
            row.SetFieldValue(field, clrValue);
            return(true);
        }
Example #6
0
 public static decimal Decimal_BSONtoCLR(BSONElement el)
 {
     if (el is BSONInt32Element)
     {
         return(Decimal_BSONtoCLR((BSONInt32Element)el));
     }
     if (el is BSONInt64Element)
     {
         return(Decimal_BSONtoCLR((BSONInt64Element)el));
     }
     throw new BSONException(StringConsts.BSON_DECIMAL_INT32_INT64_CONVERTION_ERROR);
 }
Example #7
0
        /// <summary>
        /// Converts BSON to CLR value 1:1, without type change
        /// </summary>
        protected virtual object DirectConvertBSONValue(BSONElement element, Func<BSONDocument, BSONElement, bool> filter = null)
        {
          if (element==null) return null;
          
          if (element.ElementType == BSONElementType.Document) return BSONDocumentToJSONMap(((BSONDocumentElement)element).Value, filter);

          if (element.ElementType == BSONElementType.Array)
          {
            var bsonArr = (BSONArrayElement)element;
            var lst = new List<object>();
            foreach(var elm in bsonArr.Value)
              lst.Add( DirectConvertBSONValue(elm, filter) );
            return lst.ToArray();
          }
         
          switch (element.ElementType)
          {
            case BSONElementType.ObjectID: return ((BSONObjectIDElement)element).Value.AsGDID;
            case BSONElementType.Binary: return ((BSONBinaryElement)element).Value.Data;
          }

          return element.ObjectValue;
        }
Example #8
0
        /// <summary>
        /// Tries to convert the BSON value into target CLR type. Returns true if conversion was successfull
        /// </summary>
        protected virtual bool TryConvertBSONtoCLR(Type target, BSONElement element, string targetName, out object clrValue, Func<BSONDocument, BSONElement, bool> filter)
        {
          if (element==null) 
          {
            clrValue = null;
            return true;
          }

          if (target == typeof(object))
          {
            //just unwrap Bson:CLR = 1:1, without type conversion
            clrValue = DirectConvertBSONValue( element, filter );
            return true;
          }

          clrValue = null;

          if (target.IsSubclassOf(typeof(TypedRow)))
          {
            var bsonDocumentElement = element as BSONDocumentElement;
            var doc = bsonDocumentElement != null ? bsonDocumentElement.Value : null;
            if (doc==null) return false;//not document
            var tr = (TypedRow)Activator.CreateInstance(target);
            BSONDocumentToRow(doc, tr, targetName, filter: filter);
            clrValue = tr;
            return true; 
          }

          //ARRAY
          if (target.IsArray && 
              target.GetArrayRank()==1 && 
              target!=typeof(byte[]))//exclude byte[] as it is treated with m_BSONtoCLR
          {
            var bsonArrayElement = element as BSONArrayElement;
            var arr = bsonArrayElement != null ? bsonArrayElement.Value : null;
            if (arr==null) return false;//not array
            var telm = target.GetElementType();
            var clrArray = Array.CreateInstance(telm, arr.Length);
            for(var i=0; i<arr.Length; i++)
            { 
              object clrElement;
              if (!TryConvertBSONtoCLR(telm, arr[i], targetName, out clrElement, filter))
              {
                return false;//could not convert some element of array
              } 
              clrArray.SetValue(clrElement, i);
            }

            clrValue = clrArray;
            return true;
          }

          //LIST<T>
          if (target.IsGenericType && target.GetGenericTypeDefinition() == typeof(List<>))
          {
            var bsonArrayElement = element as BSONArrayElement;
            var arr = bsonArrayElement != null ? bsonArrayElement.Value : null;
            if (arr==null) return false;//not array
            var gargs = target.GetGenericArguments();
            var telm = gargs[0];
            var clrList = Activator.CreateInstance(target) as System.Collections.IList;
            for(var i=0; i<arr.Length; i++)
            {
              object clrElement;
              if (!TryConvertBSONtoCLR(telm, arr[i], targetName, out clrElement, filter))
              {
                return false;//could not convert some element of array into element of List<t>
              } 
              clrList.Add( clrElement );
            }

            clrValue = clrList;
            return true;
          } 

          //JSONDataMap
          if (target==typeof(JSONDataMap))
          {
            var bsonDocumentElement = element as BSONDocumentElement;
            var doc = bsonDocumentElement != null ? bsonDocumentElement.Value : null;
            clrValue = BSONDocumentToJSONMap(doc, filter);
            return true;
          }

          if (target.IsEnum)
          {
            try
            {
              clrValue = Enum.Parse(target, ((BSONStringElement)element).Value, true);
              return true;
            }
            catch
            {
              return false;
            }
          }

          //Primitive type-targeted value
          Func<BSONElement, object> func;
          if (m_BSONtoCLR.TryGetValue(target, out func)) 
          {
            try
            {
              clrValue = func(element);
            }
            catch
            {
              return false;//functor could not convert
            }
            return true;
          }

          return false;//could not convert
        }
Example #9
0
 protected virtual bool SetAmorphousFieldAsCLR(IAmorphousData amorph, BSONElement bsonElement, string targetName, Func<BSONDocument, BSONElement, bool> filter)
 {
   object clrValue;
   if (!TryConvertBSONtoCLR(typeof(object), bsonElement, targetName, out clrValue, filter)) return false;
   amorph.AmorphousData[bsonElement.Name] = clrValue;   
   return true;
 }
Example #10
0
    //public static Amount Amount_BSONtoCLR(BSONDocument bson)
    //{
    //  var iso = bson.GetValue("c", string.Empty).ToString();
    //  var value = Decimal_BSONtoCLR(bson.GetValue("v", 0L).ToString());
    //  return new Amount(iso, value);
    //}


        protected virtual bool TrySetFieldAsCLR(Row row, Schema.FieldDef field, BSONElement value, string targetName, Func<BSONDocument, BSONElement, bool> filter)
        {
          object clrValue;
          if (!TryConvertBSONtoCLR(field.NonNullableType, value, targetName, out clrValue, filter)) return false;
          row.SetFieldValue(field, clrValue);
          return true;
        }
Example #11
0
        /// <summary>
        /// Tries to convert the BSON value into target CLR type. Returns true if conversion was successfull
        /// </summary>
        protected virtual bool TryConvertBSONtoCLR(Type target, BSONElement element, string targetName, out object clrValue, Func <BSONDocument, BSONElement, bool> filter)
        {
            if (element == null || element is BSONNullElement)
            {
                clrValue = null;
                return(true);
            }

            if (target == typeof(object))
            {
                //just unwrap Bson:CLR = 1:1, without type conversion
                clrValue = DirectConvertBSONValue(element, filter);
                return(true);
            }

            clrValue = null;

            if (target.IsSubclassOf(typeof(TypedRow)))
            {
                var bsonDocumentElement = element as BSONDocumentElement;
                var doc = bsonDocumentElement != null ? bsonDocumentElement.Value : null;
                if (doc == null)
                {
                    return(false);      //not document
                }
                var tr = (TypedRow)Activator.CreateInstance(target);
                BSONDocumentToRow(doc, tr, targetName, filter: filter);
                clrValue = tr;
                return(true);
            }

            //ARRAY
            if (target.IsArray &&
                target.GetArrayRank() == 1 &&
                target != typeof(byte[]))//exclude byte[] as it is treated with m_BSONtoCLR
            {
                var bsonArrayElement = element as BSONArrayElement;
                var arr = bsonArrayElement != null ? bsonArrayElement.Value : null;
                if (arr == null)
                {
                    return(false);      //not array
                }
                var telm     = target.GetElementType();
                var clrArray = Array.CreateInstance(telm, arr.Length);
                for (var i = 0; i < arr.Length; i++)
                {
                    object clrElement;
                    if (!TryConvertBSONtoCLR(telm, arr[i], targetName, out clrElement, filter))
                    {
                        return(false);//could not convert some element of array
                    }
                    clrArray.SetValue(clrElement, i);
                }

                clrValue = clrArray;
                return(true);
            }

            //LIST<T>
            if (target.IsGenericType && target.GetGenericTypeDefinition() == typeof(List <>))
            {
                var bsonArrayElement = element as BSONArrayElement;
                var arr = bsonArrayElement != null ? bsonArrayElement.Value : null;
                if (arr == null)
                {
                    return(false);      //not array
                }
                var gargs   = target.GetGenericArguments();
                var telm    = gargs[0];
                var clrList = Activator.CreateInstance(target) as System.Collections.IList;
                for (var i = 0; i < arr.Length; i++)
                {
                    object clrElement;
                    if (!TryConvertBSONtoCLR(telm, arr[i], targetName, out clrElement, filter))
                    {
                        return(false);//could not convert some element of array into element of List<t>
                    }
                    clrList.Add(clrElement);
                }

                clrValue = clrList;
                return(true);
            }

            //JSONDataMap
            if (target == typeof(JSONDataMap))
            {
                var bsonDocumentElement = element as BSONDocumentElement;
                var doc = bsonDocumentElement != null ? bsonDocumentElement.Value : null;
                clrValue = BSONDocumentToJSONMap(doc, filter);
                return(true);
            }

            if (target.IsEnum)
            {
                try
                {
                    clrValue = Enum.Parse(target, ((BSONStringElement)element).Value, true);
                    return(true);
                }
                catch
                {
                    return(false);
                }
            }

            //Primitive type-targeted value
            Func <BSONElement, object> func;

            if (m_BSONtoCLR.TryGetValue(target, out func))
            {
                try
                {
                    clrValue = func(element);
                }
                catch (Exception error)
                {
                    Debug.Fail("Error in BSONRowConverter.TryConvertBSONtoCLR(): " + error.ToMessageWithType());
                    return(false);//functor could not convert
                }
                return(true);
            }

            return(false);//could not convert
        }
Example #12
0
        public void WriteStringInt32DoubleMixedArray()
        {
            using (var stream = new MemoryStream())
              using (var reader = new BinaryReader(stream))
              {
            var root = new BSONDocument();
            var array = new BSONElement[] { new BSONStringElement("apple"), new BSONInt32Element(3), new BSONDoubleElement(2.14D) };
            root.Set(new BSONArrayElement("stuff", array));
            root.WriteAsBSON(stream);

            Assert.AreEqual(stream.Position, 48); // ensure document length is 48 bytes

            stream.Seek(0, SeekOrigin.Begin);

            CollectionAssert.AreEqual(reader.ReadBytes(4), BitConverter.GetBytes(48));       // document's content length is 48
            Assert.AreEqual(reader.ReadByte(), (byte)BSONElementType.Array);                 // element type is array 0x04
            CollectionAssert.AreEqual(reader.ReadBytes(5), Encoding.UTF8.GetBytes("stuff")); // element name is 'stuff'
            Assert.AreEqual(reader.ReadByte(), (byte)0x00);                                  // string name terminator 0x00 is present
            CollectionAssert.AreEqual(reader.ReadBytes(4), BitConverter.GetBytes(36));       // array's content length is 36

            Assert.AreEqual(reader.ReadByte(), (byte)BSONElementType.String);               // element type is string 0x02
            CollectionAssert.AreEqual(reader.ReadBytes(1), Encoding.UTF8.GetBytes("0"));    // element name is '0'
            Assert.AreEqual(reader.ReadByte(), (byte)0x00);                                 // last byte is terminator 0x00
            CollectionAssert.AreEqual(reader.ReadBytes(4), BitConverter.GetBytes(6));       // string content length is 6
            CollectionAssert.AreEqual(reader.ReadBytes(5),Encoding.UTF8.GetBytes("apple")); // string content length is 'apple'
            Assert.AreEqual(reader.ReadByte(), (byte)0x00);                                 // last byte is terminator 0x00

            Assert.AreEqual(reader.ReadByte(), (byte)BSONElementType.Int32);             // element type is int32 0x10
            CollectionAssert.AreEqual(reader.ReadBytes(1), Encoding.UTF8.GetBytes("1")); // element name is '1'
            Assert.AreEqual(reader.ReadByte(), (byte)0x00);                              // last byte is terminator 0x00
            CollectionAssert.AreEqual(reader.ReadBytes(4), BitConverter.GetBytes(3));    // value is 3

            Assert.AreEqual(reader.ReadByte(), (byte)BSONElementType.Double);             // element type is double 0x01
            CollectionAssert.AreEqual(reader.ReadBytes(1), Encoding.UTF8.GetBytes("2")); // element name is '2'
            Assert.AreEqual(reader.ReadByte(), (byte)0x00);                              // last byte is terminator 0x00
            CollectionAssert.AreEqual(reader.ReadBytes(8), BitConverter.GetBytes(2.14D)); // value is 2.14

            Assert.AreEqual(reader.ReadByte(), (byte)0x00); // ensure last byte is terminator 0x00
            Assert.AreEqual(reader.ReadByte(), (byte)0x00); // ensure last byte is terminator 0x00

            Assert.AreEqual(stream.Position, 48); // ensure whole document readed
              }
        }
Example #13
0
 /// <summary>
 /// Array of strings
 /// { 'stuff': ['apple, 3, 2.14] } --> { 'stuff': { '0': 'apple', '1': 3, '2': 2.14 } }
 /// </summary>
 public void WriteStringInt32DoubleMixedArray(Stream stream)
 {
     var root = new BSONDocument();
       var array = new BSONElement[] { new BSONStringElement("apple"), new BSONInt32Element(3), new BSONDoubleElement(2.14D) };
       root.Set(new BSONArrayElement("stuff", array));
       root.WriteAsBSON(stream);
 }