Skip to content

Commit 8847fc2

Browse files
author
Hugo Bonacci
committed
Inital Commit
0 parents  commit 8847fc2

File tree

80 files changed

+8080
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

80 files changed

+8080
-0
lines changed

Bson/BsonAnonymousTypeParser.cs

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
using System.Text.RegularExpressions;
5+
6+
namespace CSMongo.Bson {
7+
8+
//<summary>
9+
//Class designed to use an AnonymousType as a template
10+
//for a return value using a BsonObject for a data source
11+
//Really shouldn't be used for anything else since it
12+
//only works with the BsonObjects
13+
internal class BsonAnonymousTypeParser {
14+
15+
#region Constructors
16+
17+
/// <summary>
18+
/// Creates a new parser for the provided information
19+
/// </summary>
20+
public BsonAnonymousTypeParser(BsonObject data) {
21+
this._Data = data;
22+
}
23+
24+
#endregion
25+
26+
#region Fields
27+
28+
//houses the information to use
29+
private BsonObject _Data;
30+
31+
#endregion
32+
33+
#region Parsing
34+
35+
//handles reading a node of anonymous type and
36+
//returns the values for the type - This section
37+
//is heavily commented to try and explain what it
38+
//doing
39+
public object ReadType(string parent, object section) {
40+
41+
//create a list of values for the constructor
42+
List<object> values = new List<object>();
43+
44+
//and also get this type so we know how to create a
45+
//new instance using the constructor
46+
Type type = section.GetType();
47+
48+
//start checking each of the properties
49+
foreach (PropertyInfo property in type.GetProperties()) {
50+
51+
//get the path to the value in the document
52+
//but only if this isn't the first set
53+
string path = string.IsNullOrEmpty(parent)
54+
? property.Name
55+
: string.Concat(parent, ".", property.Name);
56+
57+
//get the value to use
58+
object value = property.GetValue(section, null);
59+
60+
//if this is anonymous type, parse it
61+
if (BsonAnonymousTypeParser.IsAnonymousType(value)) {
62+
value = this.ReadType(path, value);
63+
}
64+
//if it is not, check to see if there is an existing value
65+
else {
66+
67+
//try and get the value to use
68+
value = this._Data.Get(path, value);
69+
}
70+
71+
//add this to the list of values
72+
values.Add(value);
73+
74+
}
75+
76+
//now that our object is created, try and create the instance
77+
//but if it fails just give up and return the template value
78+
try {
79+
return Activator.CreateInstance(type, values.ToArray());
80+
}
81+
catch {
82+
return section;
83+
}
84+
85+
}
86+
87+
#endregion
88+
89+
#region Static Methods
90+
91+
/// <summary>
92+
/// Attempts to distingusing anonymous types from
93+
/// other object types
94+
/// </summary>
95+
public static bool IsAnonymousType(object value) {
96+
97+
//make sure this has a value
98+
if (value == null) { return false; }
99+
100+
//check if this is anonymous type using the name and
101+
//some values that hint it might be anonymous - This
102+
//could probably be better though if a better way of
103+
//checking for anonymous types becomes available
104+
Type type = value.GetType();
105+
return Regex.IsMatch(type.FullName, "^(<>f__AnonymousType|VB\\$AnonymousType)") &&
106+
type.IsSealed &&
107+
type.IsGenericType &&
108+
type.BaseType.Equals(typeof(object));
109+
110+
}
111+
112+
/// <summary>
113+
/// Attempts to assign the values of a BsonObject into new Anonymous Type values
114+
/// </summary>
115+
public static T PopulateAnonymousType<T>(BsonObject data, T template) {
116+
return BsonAnonymousTypeParser.PopulateAnonymousType<T>(data, string.Empty, template);
117+
}
118+
119+
/// <summary>
120+
/// Attempts to assign the values of a BsonObject into new Anonymous Type values
121+
/// </summary>
122+
public static T PopulateAnonymousType<T>(BsonObject data, string parent, T template) {
123+
BsonAnonymousTypeParser parser = new BsonAnonymousTypeParser(data);
124+
return (T)parser.ReadType(parent, template);
125+
}
126+
127+
#endregion
128+
129+
}
130+
131+
}

Bson/BsonCollection.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace CSMongo.Bson {
7+
8+
public class BsonCollection : BsonObject {
9+
}
10+
11+
}

Bson/BsonDocument.cs

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using CSMongo.IO;
6+
using System.IO;
7+
8+
namespace CSMongo.Bson {
9+
10+
/// <summary>
11+
/// Creates a BSON document where the field order is managed
12+
/// </summary>
13+
public class BsonDocument : BsonObject {
14+
15+
#region Constants
16+
17+
private const int DOCUMENT_LENGTH_COUNT = 4;
18+
private const int DOCUMENT_TERMINATOR_COUNT = 1;
19+
20+
#endregion
21+
22+
#region Constructors
23+
24+
/// <summary>
25+
/// Creates a new empty BSON document
26+
/// </summary>
27+
public BsonDocument()
28+
: base() {
29+
}
30+
31+
/// <summary>
32+
/// Creates a new BSON document based on the source provided
33+
/// </summary>
34+
public BsonDocument(object source)
35+
: base(source) {
36+
}
37+
38+
#endregion
39+
40+
#region Operators
41+
42+
/// <summary>
43+
/// Merges another object with this object - Same as calling Merge
44+
/// </summary>
45+
public static BsonDocument operator +(BsonDocument target, object value) {
46+
target.Merge(value);
47+
return target;
48+
}
49+
50+
/// <summary>
51+
/// Merges another DynamicObject with this object - Same as calling Merge
52+
/// </summary>
53+
public static BsonDocument operator +(BsonDocument target, BsonObject value) {
54+
target.Merge(value);
55+
return target;
56+
}
57+
58+
/// <summary>
59+
/// Removes the field provided - Same as calling Remove
60+
/// </summary>
61+
public static BsonDocument operator -(BsonDocument target, string field) {
62+
target.Remove(field);
63+
return target;
64+
}
65+
66+
/// <summary>
67+
/// Removes the field provided - Same as calling Remove
68+
/// </summary>
69+
public static BsonDocument operator -(BsonDocument target, string[] fields) {
70+
target.Remove(fields);
71+
return target;
72+
}
73+
74+
#endregion
75+
76+
#region Rendering Changes
77+
78+
/// <summary>
79+
/// Renders the bytes required to create a document
80+
/// </summary>
81+
public override byte[] ToBsonByteArray() {
82+
83+
//create the default size
84+
DynamicStream stream = new DynamicStream(5);
85+
86+
//generate the bytes
87+
stream.InsertAt(4, base.ToBsonByteArray());
88+
89+
//update the length
90+
stream.WriteAt(0, BsonTranslator.AsInt32(stream.Length));
91+
92+
//and return the bytes to use
93+
return stream.ToArray();
94+
95+
}
96+
97+
#endregion
98+
99+
#region Static Creation
100+
101+
/// <summary>
102+
/// Reads an incoming BSON document from a stream
103+
/// </summary>
104+
public static BsonDocument FromStream(Stream stream) {
105+
106+
//read the first byte to determine the type
107+
BinaryReader reader = new BinaryReader(stream);
108+
109+
//get the length of this document and the amount
110+
//that should be read into the parsing stream.
111+
//removes 4 bytes to account for the length value
112+
//and an additional 1 byte to account for the
113+
//terminator value
114+
int length = reader.ReadInt32();
115+
int read = length - (DOCUMENT_LENGTH_COUNT + DOCUMENT_TERMINATOR_COUNT);
116+
117+
//read out the bytes to use and the terminator
118+
byte[] bytes = reader.ReadBytes(read);
119+
reader.ReadByte();
120+
121+
//use the bytes to generate the document
122+
using (MemoryStream content = new MemoryStream(bytes)) {
123+
124+
//read the content
125+
Dictionary<string, object> values = BsonTranslator.FromStream(content);
126+
127+
//fill and return the object
128+
BsonDocument document = new BsonDocument();
129+
document.Merge(values);
130+
return document;
131+
132+
}
133+
134+
}
135+
136+
#endregion
137+
138+
}
139+
140+
}

Bson/BsonFieldDetail.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using CSMongo.DataTypes;
6+
7+
namespace CSMongo.Bson {
8+
9+
/// <summary>
10+
/// Information about a BSON field after it has
11+
/// been rendered into bytes
12+
/// </summary>
13+
public class BsonFieldDetail {
14+
15+
#region Constructors
16+
17+
/// <summary>
18+
/// Creates a new set of details for a BSON field
19+
/// </summary>
20+
public BsonFieldDetail(string field, byte[] bytes, MongoDataType type) {
21+
this.Field = field;
22+
this.Bytes = bytes;
23+
this.Type = type;
24+
}
25+
26+
#endregion
27+
28+
#region Properties
29+
30+
/// <summary>
31+
/// The string name for this field
32+
/// </summary>
33+
public string Field { get; private set; }
34+
35+
/// <summary>
36+
/// The original MongoDataType for this field
37+
/// </summary>
38+
public MongoDataType Type { get; private set; }
39+
40+
/// <summary>
41+
/// The bytes that create this object
42+
/// </summary>
43+
public byte[] Bytes { get; private set; }
44+
45+
/// <summary>
46+
/// Returns the total length of the bytes in the set
47+
/// </summary>
48+
public int Length {
49+
get { return this.Bytes is byte[] ? this.Bytes.Length : 0; }
50+
}
51+
52+
#endregion
53+
54+
}
55+
}

Bson/BsonMongoDictionary.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using CSMongo.DataTypes;
6+
7+
namespace CSMongo.Bson {
8+
9+
/// <summary>
10+
/// General container for holding Mongo fields in a document
11+
/// </summary>
12+
public class BsonMongoDictionary : Dictionary<string, MongoDataType> {
13+
}
14+
15+
}

Bson/BsonMongoFieldReference.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using CSMongo.Bson;
6+
using CSMongo.DataTypes;
7+
8+
namespace CSMongo.Bson {
9+
10+
/// <summary>
11+
/// Details about a MongoDataType and the location
12+
/// </summary>
13+
public class MongoFieldReference {
14+
15+
/// <summary>
16+
/// The parent object for this field
17+
/// </summary>
18+
public BsonObject Parent { get; set; }
19+
20+
/// <summary>
21+
/// The name of the field that holds this value
22+
/// </summary>
23+
public string Name { get; set; }
24+
25+
/// <summary>
26+
/// The actual field controller for this type
27+
/// </summary>
28+
public MongoDataType Field { get; set; }
29+
30+
}
31+
32+
}

0 commit comments

Comments
 (0)