From 3647ae58c0ba4e2cb522d83bf8ccd0b56edb2783 Mon Sep 17 00:00:00 2001 From: adam Date: Fri, 14 Jun 2013 17:24:52 +0700 Subject: [PATCH] #24 --- nejdb/Ejdb.BSON/BSONIterator.cs | 43 ++++++++++++++------- nejdb/Ejdb.JSON/JSONElement.cs | 25 +++++++++++++ nejdb/Ejdb.JSON/JSONReader.cs | 28 +++++++++++++- nejdb/Ejdb.Tests/TestBSON.cs | 82 +++++++++++++++++++++++++++++++++++++++-- nejdb/nejdb.csproj | 1 + 5 files changed, 161 insertions(+), 18 deletions(-) create mode 100644 nejdb/Ejdb.JSON/JSONElement.cs diff --git a/nejdb/Ejdb.BSON/BSONIterator.cs b/nejdb/Ejdb.BSON/BSONIterator.cs index 615a48f..b6895a5 100644 --- a/nejdb/Ejdb.BSON/BSONIterator.cs +++ b/nejdb/Ejdb.BSON/BSONIterator.cs @@ -18,10 +18,11 @@ using System.Text; using System.Diagnostics; using System.IO; using Ejdb.IO; +using System.Collections.Generic; namespace Ejdb.BSON { - public class BSONIterator : IDisposable { + public class BSONIterator : IDisposable, IEnumerable { ExtBinaryReader _input; int _doclen; @@ -38,8 +39,12 @@ namespace Ejdb.BSON { } public int DocumentLength { - get { return this._doclen; } - private set { this._doclen = value; } + get { return _doclen; } + private set { _doclen = value; } + } + + public string CurrentKey { + get { return _entryKey; } } public BSONIterator(BSONDocument doc) : this(doc.ToByteArray()) { @@ -88,10 +93,20 @@ namespace Ejdb.BSON { void CheckDisposed() { if (Disposed) { - throw new Exception("BSONIterator already disposed"); + throw new ObjectDisposedException("BSONIterator"); } } + public IEnumerator GetEnumerator() { + while (Next() != BSONType.EOO) { + yield return _ctype; + } + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + public BSONType Next() { CheckDisposed(); if (_ctype == BSONType.EOO) { @@ -114,6 +129,7 @@ namespace Ejdb.BSON { } switch (_ctype) { case BSONType.EOO: + Dispose(); return BSONType.EOO; case BSONType.UNDEFINED: case BSONType.NULL: @@ -139,19 +155,20 @@ namespace Ejdb.BSON { case BSONType.STRING: case BSONType.CODE: case BSONType.SYMBOL: - _entryLen = 4 + _input.ReadInt32(); + _entryLen = _input.ReadInt32(); break; case BSONType.DBREF: //Unsupported DBREF! - _entryLen = 4 + 12 + _input.ReadInt32(); + _entryLen = 12 + _input.ReadInt32(); break; case BSONType.BINDATA: - _entryLen = 4 + 1 + _input.ReadInt32(); + _entryLen = 1 + _input.ReadInt32(); break; case BSONType.OBJECT: case BSONType.ARRAY: case BSONType.CODEWSCOPE: - _entryLen = 4 + _input.ReadInt32(); + _entryLen = _input.ReadInt32() - 4; + Debug.Assert(_entryLen > 0); break; case BSONType.REGEX: _entryLen = 0; @@ -184,8 +201,8 @@ namespace Ejdb.BSON { case BSONType.CODE: case BSONType.SYMBOL: { - Debug.Assert(_entryLen - 5 >= 0); - string sv = Encoding.UTF8.GetString(_input.ReadBytes(_entryLen - 5)); + Debug.Assert(_entryLen - 1 >= 0); + string sv = Encoding.UTF8.GetString(_input.ReadBytes(_entryLen - 1)); _entryDataValue = new BSONValue(_ctype, _entryKey, sv); Debug.Assert(_input.ReadByte() == 0x00); //trailing zero byte break; @@ -200,7 +217,7 @@ namespace Ejdb.BSON { case BSONType.ARRAY: { BSONDocument doc = (_ctype == BSONType.OBJECT ? new BSONDocument() : new BSONArray()); - BSONIterator sit = new BSONIterator(this._input, _entryLen - 4); + BSONIterator sit = new BSONIterator(this._input, _entryLen + 4); while (sit.Next() != BSONType.EOO) { doc.Add(sit.FetchCurrentValue()); } @@ -236,7 +253,7 @@ namespace Ejdb.BSON { case BSONType.BINDATA: { byte subtype = _input.ReadByte(); - BSONBinData bd = new BSONBinData(subtype, _entryLen - 4, _input); + BSONBinData bd = new BSONBinData(subtype, _entryLen - 1, _input); _entryDataValue = new BSONValue(_ctype, _entryKey, bd); break; } @@ -249,7 +266,7 @@ namespace Ejdb.BSON { } case BSONType.CODEWSCOPE: { - int cwlen = _entryLen - 4; + int cwlen = _entryLen + 4; Debug.Assert(cwlen > 5); int clen = _input.ReadInt32(); //code length string code = Encoding.UTF8.GetString(_input.ReadBytes(clen)); diff --git a/nejdb/Ejdb.JSON/JSONElement.cs b/nejdb/Ejdb.JSON/JSONElement.cs new file mode 100644 index 0000000..39cfad3 --- /dev/null +++ b/nejdb/Ejdb.JSON/JSONElement.cs @@ -0,0 +1,25 @@ +// ============================================================================================ +// .NET API for EJDB database library http://ejdb.org +// Copyright (C) 2012-2013 Softmotions Ltd +// +// This file is part of EJDB. +// EJDB is free software; you can redistribute it and/or modify it under the terms of +// the GNU Lesser General Public License as published by the Free Software Foundation; either +// version 2.1 of the License or any later version. EJDB is distributed in the hope +// that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +// License for more details. +// You should have received a copy of the GNU Lesser General Public License along with EJDB; +// if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, +// Boston, MA 02111-1307 USA. +// ============================================================================================ +using System; + +namespace Ejdb.JSON { + + public class JSONElement { + public JSONElement() { + } + } +} + diff --git a/nejdb/Ejdb.JSON/JSONReader.cs b/nejdb/Ejdb.JSON/JSONReader.cs index 7fc3fd2..ac8f116 100644 --- a/nejdb/Ejdb.JSON/JSONReader.cs +++ b/nejdb/Ejdb.JSON/JSONReader.cs @@ -14,11 +14,35 @@ // Boston, MA 02111-1307 USA. // ============================================================================================ using System; +using System.IO; +using System.Collections.Generic; namespace Ejdb.JSON { - public class JSONReader { - public JSONReader() { + public class JSONReader : IEnumerable, IDisposable { + + BinaryReader _input; + + public JSONReader(Stream jstream) { + this._input = new BinaryReader(jstream); + } + + public IEnumerator GetEnumerator() { + + + + yield return new JSONElement(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { + return GetEnumerator(); + } + + public void Dispose() { + if (_input != null) { + _input.Close(); + _input = null; + } } } } diff --git a/nejdb/Ejdb.Tests/TestBSON.cs b/nejdb/Ejdb.Tests/TestBSON.cs index b376c11..6dfb8bf 100644 --- a/nejdb/Ejdb.Tests/TestBSON.cs +++ b/nejdb/Ejdb.Tests/TestBSON.cs @@ -107,16 +107,92 @@ namespace Ejdb.Tests { doc.ToDebugDataString()); } - [Test] public void TestIterate1() { var doc = new BSONDocument(); doc["a"] = "av"; doc["bb"] = 24; - doc["ccc"] = BSONDocument.ValueOf(new{na1 = 1, nb = "2"}); + //doc["ccc"] = BSONDocument.ValueOf(new{na1 = 1, nb = "2"}); + //doc["d"] = new BSONOid("51b9f3af98195c4600000000"); + + //17-00-00-00 +4 + //02-61-00-03-00-00-00-61-76-00 +10 + //10-62-62-00-18-00-00-00 +8 + //00 +1 + Assert.AreEqual("17-00-00-00-02-61-00-03-00-00-00-61-76-00-10-62-62-00-18-00-00-00-00", + doc.ToDebugDataString()); + BSONIterator it = new BSONIterator(doc); + Assert.AreEqual(doc.ToByteArray().Length, it.DocumentLength); + var c = ""; + while (it.Next() != BSONType.EOO) { + c += it.CurrentKey; + } + Assert.AreEqual("abb", c); + it.Dispose(); + + it = new BSONIterator(doc); + var cnt = 0; + while (it.Next() != BSONType.EOO) { + BSONValue bv = it.FetchCurrentValue(); + Assert.IsNotNull(bv); + if (cnt == 0) { + Assert.IsTrue(bv.BSONType == BSONType.STRING); + Assert.IsTrue(bv.Key == "a"); + Assert.AreEqual("av", bv.Value); + } + if (cnt == 1) { + Assert.IsTrue(bv.BSONType == BSONType.INT); + Assert.IsTrue(bv.Key == "bb"); + Assert.AreEqual(24, bv.Value); + } + cnt++; + } + } + + [Test] + public void testIterate2() { + var doc = new BSONDocument(); + doc["a"] = "av"; + doc["b"] = BSONDocument.ValueOf(new{cc = 1}); doc["d"] = new BSONOid("51b9f3af98195c4600000000"); + Assert.AreEqual(3, doc.KeysCount); + //Console.WriteLine(doc.KeysCount); + //Console.WriteLine(doc.ToDebugDataString()); + //2E-00-00-00 +4 + //02-61-00-03-00-00-00-61-76-00 +10 (14) + //03-62-00 +3 (17) "d" = + //0D-00-00-00 +4 (21) doc len = 13 + //10-63-63-00-01-00-00-00 -00 +9 (30) + //07-64-00 +3 (33) + //51-B9-F3-AF-98-19-5C-46-00-00-00-00 +12 (45) + //00 +1 (46) + Assert.AreEqual("2E-00-00-00-" + + "02-61-00-03-00-00-00-61-76-00-" + + "03-62-00-" + + "0D-00-00-00-" + + "10-63-63-00-01-00-00-00-00-" + + "07-64-00-" + + "51-B9-F3-AF-98-19-5C-46-00-00-00-00-" + + "00", doc.ToDebugDataString()); + BSONIterator it = new BSONIterator(doc); + int c = 0; + foreach (var bt in it) { + if (c == 0) { + Assert.IsTrue(bt == BSONType.STRING); + } + if (c == 1) { + Assert.IsTrue(bt == BSONType.OBJECT); + } + if (c == 2) { + Assert.IsTrue(bt == BSONType.OID); + } + ++c; + } + Assert.IsTrue(it.Disposed); + + + - //todo } } } diff --git a/nejdb/nejdb.csproj b/nejdb/nejdb.csproj index a374e15..88a0bcb 100644 --- a/nejdb/nejdb.csproj +++ b/nejdb/nejdb.csproj @@ -60,6 +60,7 @@ + -- 2.7.4