diff options
-rw-r--r-- | nejdb/Ejdb.SON/BSONIterator.cs | 61 | ||||
-rw-r--r-- | nejdb/Ejdb.SON/BSONOid.cs | 79 | ||||
-rw-r--r-- | nejdb/nejdb.csproj | 4 | ||||
-rw-r--r-- | nejdb/nejdb.sln | 192 | ||||
-rw-r--r-- | nejdb/nejdb.userprefs | 9 |
5 files changed, 312 insertions, 33 deletions
diff --git a/nejdb/Ejdb.SON/BSONIterator.cs b/nejdb/Ejdb.SON/BSONIterator.cs index d4f7ac6..d6b955b 100644 --- a/nejdb/Ejdb.SON/BSONIterator.cs +++ b/nejdb/Ejdb.SON/BSONIterator.cs @@ -51,7 +51,7 @@ namespace Ejdb.SON { this._doclen = _input.ReadInt32(); if (this._doclen < 5) { Dispose(); - throw new InvalidBSONDataException(); + throw new InvalidBSONDataException("Unexpected end of BSON document"); } } @@ -67,10 +67,10 @@ namespace Ejdb.SON { } public BSONType Next() { + if (_ctype == BSONType.EOO) { + return BSONType.EOO; + } if (_ctype != BSONType.UNKNOWN) { - if (_ctype == BSONType.EOO) { - return BSONType.EOO; - } SkipData(); } byte bv = _input.ReadByte(); @@ -88,6 +88,7 @@ namespace Ejdb.SON { return BSONType.EOO; case BSONType.UNDEFINED: case BSONType.NULL: + _entryLen = 0; break; case BSONType.BOOL: _entryLen = 1; @@ -107,29 +108,61 @@ namespace Ejdb.SON { case BSONType.STRING: case BSONType.CODE: case BSONType.SYMBOL: + _entryLen = 4 + _input.ReadInt32(); + break; + case BSONType.DBREF: + _entryLen = 4 + 12 + _input.ReadInt32(); + break; + case BSONType.BINDATA: + _entryLen = 4 + 1 + _input.ReadInt32(); + break; + case BSONType.OBJECT: + case BSONType.ARRAY: + case BSONType.CODEWSCOPE: + _entryLen = 4 + _input.ReadInt32(); break; + default: + throw new InvalidBSONDataException("Unknown entry type: " + _ctype); } - return BSONType.EOO; + return _ctype; } - private void SkipData() { + object PeekData() { + //todo implement it + return null; + } + + void SkipData() { if (_entryLen > 0) { - var len = _input.BaseStream.Seek(_entryLen, SeekOrigin.Current); + int cpos = _input.BaseStream.Position; + if ((cpos + _entryLen) != _input.BaseStream.Seek(_entryLen, SeekOrigin.Current)) { + throw new IOException("Inconsitent seek within input BSON stream"); + } _entryLen = 0; + } else if (_ctype == BSONType.REGEX) { + SkipCString(); + SkipCString(); } } - private string ReadKey() { - //todo - return string.Empty; + string ReadKey() { + _entryKey = ReadCString(); + return _entryKey; } - private string ReadCString() { - //todo - return string.Empty; + string ReadCString() { + List<byte> sb = new List<byte>(64); + byte bv; + while ((bv = _input.ReadByte()) != 0x00) { + sb.Add(bv); + } + return Encoding.UTF8.GetString(sb.ToArray()); } - + void SkipCString() { + while ((_input.ReadByte()) != 0x00) + ; + } } } diff --git a/nejdb/Ejdb.SON/BSONOid.cs b/nejdb/Ejdb.SON/BSONOid.cs index 06b22a6..960b8a3 100644 --- a/nejdb/Ejdb.SON/BSONOid.cs +++ b/nejdb/Ejdb.SON/BSONOid.cs @@ -14,14 +14,17 @@ // Boston, MA 02111-1307 USA. // ============================================================================================ using System; +using System.Text; namespace Ejdb.SON { - public sealed class BSONOid { + [Serializable] + public sealed class BSONOid : IComparable<BSONOid> { - private byte[] _bytes; + byte[] _bytes; + string _cachedString; - private BSONOid() { + BSONOid() { } public BSONOid(string val) { @@ -39,7 +42,7 @@ namespace Ejdb.SON { Array.Copy(val, _bytes, 12); } - private bool IsValidOid(string oid) { + bool IsValidOid(string oid) { var i = 0; for (; i < oid.Length && ((oid[i] >= 0x30 && oid[i] <= 0x39) || (oid[i] >= 0x61 && oid[i] <= 0x66)); @@ -48,21 +51,75 @@ namespace Ejdb.SON { return (i == 24); } - private void ParseOIDString(string val) { + void ParseOIDString(string val) { if (!IsValidOid(val)) { throw new ArgumentException("Invalid oid string"); } var vlen = val.Length; _bytes = new byte[vlen / 2]; for (var i = 0; i < vlen; i += 2) { - try { - _bytes[i / 2] = Convert.ToByte(val.Substring(i, 2), 16); - } catch { - //failed to convert these 2 chars, they may contain illegal charracters - _bytes[i / 2] = 0; + _bytes[i / 2] = Convert.ToByte(val.Substring(i, 2), 16); + } + } + + public int CompareTo(BSONOid other) { + if (ReferenceEquals(other, null)) { + return 1; + } + var obytes = other._bytes; + for (var x = 0; x < _bytes.Length; x++) { + if (_bytes[x] < obytes[x]) { + return -1; } + if (_bytes[x] > obytes[x]) { + return 1; + } + } + return 0; + } + + public override string ToString() { + if (_cachedString == null) { + _cachedString = BitConverter.ToString(_bytes).Replace("-", "").ToLower(); } + return _cachedString; + } + + public override bool Equals(object obj) { + if (obj is BSONOid) { + return (CompareTo((BSONOid) obj) == 0); + } + return false; + } + + public override int GetHashCode() { + return ToString().GetHashCode(); + } + + public static bool operator ==(BSONOid a, BSONOid b) { + if (ReferenceEquals(a, b)) { + return true; + } + if (a == null || b == null) { + return false; + } + return a.Equals(b); + } + + public static bool operator !=(BSONOid a, BSONOid b) { + return !(a == b); + } + + public static bool operator >(BSONOid a, BSONOid b) { + return a.CompareTo(b) > 0; + } + + public static bool operator <(BSONOid a, BSONOid b) { + return a.CompareTo(b) < 0; + } + + public static explicit operator BSONOid(string val) { + return new BSONOid(val); } } } - diff --git a/nejdb/nejdb.csproj b/nejdb/nejdb.csproj index 1a68961..aa1d9fb 100644 --- a/nejdb/nejdb.csproj +++ b/nejdb/nejdb.csproj @@ -10,6 +10,7 @@ <RootNamespace>Ejdb</RootNamespace> <AssemblyName>nejdb</AssemblyName> <Description>EJDB .Net binding (http://ejdb.org)</Description> + <ReleaseVersion>1.0.0</ReleaseVersion> </PropertyGroup> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <DebugSymbols>true</DebugSymbols> @@ -31,9 +32,8 @@ </PropertyGroup> <ItemGroup> <Reference Include="System" /> - <Reference Include="nunit.framework, Version=2.6.0.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77"> + <Reference Include="nunit.framework, Version=2.4.8.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77"> <Private>False</Private> - <Package>mono-nunit</Package> </Reference> </ItemGroup> <ItemGroup> diff --git a/nejdb/nejdb.sln b/nejdb/nejdb.sln index 3d9f109..a7b1ce9 100644 --- a/nejdb/nejdb.sln +++ b/nejdb/nejdb.sln @@ -30,5 +30,197 @@ Global $0.DotNetNamingPolicy = $2 $2.DirectoryNamespaceAssociation = Flat $2.ResourceNamePolicy = FileFormatDefault + $0.TextStylePolicy = $3 + $3.inheritsSet = null + $3.scope = text/x-csharp + $0.CSharpFormattingPolicy = $4 + $4.IndentSwitchBody = True + $4.NamespaceBraceStyle = EndOfLine + $4.ClassBraceStyle = EndOfLine + $4.InterfaceBraceStyle = EndOfLine + $4.StructBraceStyle = EndOfLine + $4.EnumBraceStyle = EndOfLine + $4.MethodBraceStyle = EndOfLine + $4.ConstructorBraceStyle = EndOfLine + $4.DestructorBraceStyle = EndOfLine + $4.BeforeMethodDeclarationParentheses = False + $4.BeforeMethodCallParentheses = False + $4.BeforeConstructorDeclarationParentheses = False + $4.BeforeIndexerDeclarationBracket = False + $4.BeforeDelegateDeclarationParentheses = False + $4.NewParentheses = False + $4.SpacesBeforeBrackets = False + $4.SpacesAfterTypecast = True + $4.BlankLinesBeforeFirstDeclaration = 1 + $4.BlankLinesBetweenEventFields = 1 + $4.inheritsSet = Mono + $4.inheritsScope = text/x-csharp + $4.scope = text/x-csharp + $0.TextStylePolicy = $5 + $5.FileWidth = 120 + $5.TabsToSpaces = False + $5.inheritsSet = VisualStudio + $5.inheritsScope = text/plain + $5.scope = text/plain + $0.NameConventionPolicy = $6 + $6.Rules = $7 + $7.NamingRule = $8 + $8.Name = Namespaces + $8.AffectedEntity = Namespace + $8.VisibilityMask = VisibilityMask + $8.NamingStyle = PascalCase + $8.IncludeInstanceMembers = True + $8.IncludeStaticEntities = True + $7.NamingRule = $9 + $9.Name = Types + $9.AffectedEntity = Class, Struct, Enum, Delegate + $9.VisibilityMask = VisibilityMask + $9.NamingStyle = PascalCase + $9.IncludeInstanceMembers = True + $9.IncludeStaticEntities = True + $7.NamingRule = $10 + $10.Name = Interfaces + $10.RequiredPrefixes = $11 + $11.String = I + $10.AffectedEntity = Interface + $10.VisibilityMask = VisibilityMask + $10.NamingStyle = PascalCase + $10.IncludeInstanceMembers = True + $10.IncludeStaticEntities = True + $7.NamingRule = $12 + $12.Name = Attributes + $12.RequiredSuffixes = $13 + $13.String = Attribute + $12.AffectedEntity = CustomAttributes + $12.VisibilityMask = VisibilityMask + $12.NamingStyle = PascalCase + $12.IncludeInstanceMembers = True + $12.IncludeStaticEntities = True + $7.NamingRule = $14 + $14.Name = Event Arguments + $14.RequiredSuffixes = $15 + $15.String = EventArgs + $14.AffectedEntity = CustomEventArgs + $14.VisibilityMask = VisibilityMask + $14.NamingStyle = PascalCase + $14.IncludeInstanceMembers = True + $14.IncludeStaticEntities = True + $7.NamingRule = $16 + $16.Name = Exceptions + $16.RequiredSuffixes = $17 + $17.String = Exception + $16.AffectedEntity = CustomExceptions + $16.VisibilityMask = VisibilityMask + $16.NamingStyle = PascalCase + $16.IncludeInstanceMembers = True + $16.IncludeStaticEntities = True + $7.NamingRule = $18 + $18.Name = Methods + $18.AffectedEntity = Methods + $18.VisibilityMask = VisibilityMask + $18.NamingStyle = PascalCase + $18.IncludeInstanceMembers = True + $18.IncludeStaticEntities = True + $7.NamingRule = $19 + $19.Name = Static Readonly Fields + $19.AffectedEntity = ReadonlyField + $19.VisibilityMask = Internal, Protected, Public + $19.NamingStyle = PascalCase + $19.IncludeInstanceMembers = False + $19.IncludeStaticEntities = True + $7.NamingRule = $20 + $20.Name = Fields (Non Private) + $20.AffectedEntity = Field + $20.VisibilityMask = Internal, Protected, Public + $20.NamingStyle = PascalCase + $20.IncludeInstanceMembers = True + $20.IncludeStaticEntities = True + $7.NamingRule = $21 + $21.Name = ReadOnly Fields (Non Private) + $21.AffectedEntity = ReadonlyField + $21.VisibilityMask = Internal, Protected, Public + $21.NamingStyle = PascalCase + $21.IncludeInstanceMembers = True + $21.IncludeStaticEntities = False + $7.NamingRule = $22 + $22.Name = Fields (Private) + $22.AllowedPrefixes = $23 + $23.String = _ + $23.String = m_ + $22.AffectedEntity = Field, ReadonlyField + $22.VisibilityMask = Private + $22.NamingStyle = CamelCase + $22.IncludeInstanceMembers = True + $22.IncludeStaticEntities = False + $7.NamingRule = $24 + $24.Name = Static Fields (Private) + $24.AffectedEntity = Field + $24.VisibilityMask = Private + $24.NamingStyle = CamelCase + $24.IncludeInstanceMembers = False + $24.IncludeStaticEntities = True + $7.NamingRule = $25 + $25.Name = ReadOnly Fields (Private) + $25.AllowedPrefixes = $26 + $26.String = _ + $26.String = m_ + $25.AffectedEntity = ReadonlyField + $25.VisibilityMask = Private + $25.NamingStyle = CamelCase + $25.IncludeInstanceMembers = True + $25.IncludeStaticEntities = False + $7.NamingRule = $27 + $27.Name = Constant Fields + $27.AffectedEntity = ConstantField + $27.VisibilityMask = VisibilityMask + $27.NamingStyle = PascalCase + $27.IncludeInstanceMembers = True + $27.IncludeStaticEntities = True + $7.NamingRule = $28 + $28.Name = Properties + $28.AffectedEntity = Property + $28.VisibilityMask = VisibilityMask + $28.NamingStyle = PascalCase + $28.IncludeInstanceMembers = True + $28.IncludeStaticEntities = True + $7.NamingRule = $29 + $29.Name = Events + $29.AffectedEntity = Event + $29.VisibilityMask = VisibilityMask + $29.NamingStyle = PascalCase + $29.IncludeInstanceMembers = True + $29.IncludeStaticEntities = True + $7.NamingRule = $30 + $30.Name = Enum Members + $30.AffectedEntity = EnumMember + $30.VisibilityMask = VisibilityMask + $30.NamingStyle = PascalCase + $30.IncludeInstanceMembers = True + $30.IncludeStaticEntities = True + $7.NamingRule = $31 + $31.Name = Parameters + $31.AffectedEntity = Parameter + $31.VisibilityMask = VisibilityMask + $31.NamingStyle = CamelCase + $31.IncludeInstanceMembers = True + $31.IncludeStaticEntities = True + $7.NamingRule = $32 + $32.Name = Type Parameters + $32.RequiredPrefixes = $33 + $33.String = T + $32.AffectedEntity = TypeParameter + $32.VisibilityMask = VisibilityMask + $32.NamingStyle = PascalCase + $32.IncludeInstanceMembers = True + $32.IncludeStaticEntities = True + $0.VersionControlPolicy = $34 + $34.inheritsSet = Mono + $0.ChangeLogPolicy = $35 + $35.UpdateMode = None + $35.MessageStyle = $36 + $36.LineAlign = 0 + $35.inheritsSet = Mono + description = " .NET API for EJDB database library http://ejdb.org" + version = 1.0.0 EndGlobalSection EndGlobal diff --git a/nejdb/nejdb.userprefs b/nejdb/nejdb.userprefs index b39729e..ebfe62c 100644 --- a/nejdb/nejdb.userprefs +++ b/nejdb/nejdb.userprefs @@ -1,11 +1,8 @@ <Properties> <MonoDevelop.Ide.Workspace ActiveConfiguration="Debug" /> - <MonoDevelop.Ide.Workbench ActiveDocument="Ejdb.SON/BSONOid.cs"> + <MonoDevelop.Ide.Workbench ActiveDocument="Ejdb.SON/BSONType.cs"> <Files> - <File FileName="Ejdb.SON/BSONMarshaller.cs" Line="1" Column="1" /> - <File FileName="Ejdb.SON/BSONIterator.cs" Line="93" Column="5" /> - <File FileName="Ejdb.SON/BSONType.cs" Line="31" Column="15" /> - <File FileName="Ejdb.SON/BSONOid.cs" Line="24" Column="1" /> + <File FileName="Ejdb.SON/BSONType.cs" Line="40" Column="15" /> </Files> <Pads> <Pad Id="ProjectPad"> @@ -15,7 +12,7 @@ <Node name="References" expanded="True" /> <Node name="Ejdb.DB" expanded="True" /> <Node name="Ejdb.SON" expanded="True"> - <Node name="BSONOid.cs" selected="True" /> + <Node name="BSONType.cs" selected="True" /> </Node> <Node name="Ejdb.Tests" expanded="True" /> </Node> |