diff --git a/OneSTools.FileDatabase.sln b/OneSTools.FileDatabase.sln
new file mode 100644
index 0000000..91e7956
--- /dev/null
+++ b/OneSTools.FileDatabase.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30804.86
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OneSTools.FileDatabase", "OneSTools.FileDatabase\OneSTools.FileDatabase.csproj", "{EDF41082-9B3F-4AA2-9E60-C18901AFC25A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OneSTools.FileDatabaseTestApp", "OneSTools.FileDatabaseTestApp\OneSTools.FileDatabaseTestApp.csproj", "{40FCEDB2-4C4B-4419-90BB-1BD80840AC05}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {EDF41082-9B3F-4AA2-9E60-C18901AFC25A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EDF41082-9B3F-4AA2-9E60-C18901AFC25A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EDF41082-9B3F-4AA2-9E60-C18901AFC25A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EDF41082-9B3F-4AA2-9E60-C18901AFC25A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {40FCEDB2-4C4B-4419-90BB-1BD80840AC05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {40FCEDB2-4C4B-4419-90BB-1BD80840AC05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {40FCEDB2-4C4B-4419-90BB-1BD80840AC05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {40FCEDB2-4C4B-4419-90BB-1BD80840AC05}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {37516B47-10E9-4C36-B852-487DB3568E24}
+ EndGlobalSection
+EndGlobal
diff --git a/OneSTools.FileDatabase/FileDatabaseConnection.cs b/OneSTools.FileDatabase/FileDatabaseConnection.cs
new file mode 100644
index 0000000..6187708
--- /dev/null
+++ b/OneSTools.FileDatabase/FileDatabaseConnection.cs
@@ -0,0 +1,104 @@
+using OneSTools.FileDatabase.HighLevel;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using OneSTools.FileDatabase.LowLevel;
+using System.Linq;
+using OneSTools.FileDatabase.LowLevel.Pages;
+using OneSTools.FileDatabase.LowLevel.Files;
+using OneSTools.BracketsFile;
+using System.Text;
+using System.Data.Common;
+using System.Collections.ObjectModel;
+using System.Data;
+
+namespace OneSTools.FileDatabase
+{
+ ///
+ /// Provides properties and methods for reading 1C file database data
+ ///
+ public class FileDatabaseConnection : IDisposable
+ {
+ private readonly string _path;
+ private FileDatabaseStream _stream;
+ private HeaderPage _headerPage;
+ private FreePagesPage _freePagesPage;
+ private DatabaseDescriptionFile _databaseDescriptionFile;
+
+ ///
+ /// The flag of database opening
+ ///
+ public bool Opened { get; private set; } = false;
+ ///
+ /// Version of the database file
+ ///
+ public string Version => _headerPage?.Version;
+ ///
+ /// Locale of the database
+ ///
+ public string Language => _databaseDescriptionFile?.Language;
+ ///
+ /// A collection of database tables
+ ///
+ public ReadOnlyCollection
Tables { get; private set; } = null;
+
+ public FileDatabaseConnection(string path)
+ => _path = path;
+
+ ///
+ /// Open database file
+ ///
+ public void Open()
+ {
+ if (!File.Exists(_path))
+ throw new FileNotFoundException("Cannot find a database file", _path);
+
+ var stream = new FileStream(_path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ _stream = new FileDatabaseStream(stream);
+
+ ReadStructure();
+
+ Opened = true;
+ }
+
+ private void ReadStructure()
+ {
+ _headerPage = new HeaderPage();
+ _headerPage.Read(_stream);
+
+ _stream.PageSize = _headerPage.PageSize;
+
+ _stream.CurrentPage = 1;
+ _freePagesPage = new FreePagesPage();
+ _freePagesPage.Read(_stream);
+
+ _databaseDescriptionFile = new DatabaseDescriptionFile(_stream);
+
+ var tables = new List();
+
+ for (int i = 0; i < _databaseDescriptionFile.TablesCount; i++)
+ {
+ var tableDefinitionData = _databaseDescriptionFile.ReadTableDefinitionData();
+ var tableDefinitionStr = Encoding.UTF8.GetString(tableDefinitionData);
+ var tableDefinitionNode = BracketsParser.ParseBlock(tableDefinitionStr);
+
+ var table = new Table(_stream, tableDefinitionNode);
+ tables.Add(table);
+ }
+
+ Tables = tables.AsReadOnly();
+ }
+
+ ///
+ /// Close database file
+ ///
+ public void Close()
+ {
+ Opened = false;
+ _stream?.Dispose();
+ }
+
+ public void Dispose()
+ => Close();
+ }
+}
diff --git a/OneSTools.FileDatabase/HighLevel/Field.cs b/OneSTools.FileDatabase/HighLevel/Field.cs
new file mode 100644
index 0000000..8459cd9
--- /dev/null
+++ b/OneSTools.FileDatabase/HighLevel/Field.cs
@@ -0,0 +1,85 @@
+using System;
+using OneSTools.BracketsFile;
+
+namespace OneSTools.FileDatabase.HighLevel
+{
+ public class Field
+ {
+ ///
+ /// Real size of the value (bytes)
+ ///
+ internal int MaxSize { get; private set; }
+ ///
+ /// Internal name of the field
+ ///
+ public string Name { get; private set; }
+ ///
+ /// Type of the field's value
+ ///
+ public FieldType Type { get; private set; }
+ ///
+ /// If the flag is True a value can be null
+ ///
+ public bool Nullable { get; private set; }
+ ///
+ /// Length of the value
+ ///
+ public int Length { get; private set; }
+ ///
+ /// "Numeric" value only - position of a point in a value
+ ///
+ public int Precision { get; private set; }
+ public string CaseSensitive { get; private set; }
+
+ internal void Read(BracketsNode node)
+ {
+ Name = node[0];
+
+ var type = (string)node[1];
+
+ Type = type switch
+ {
+ "B" => FieldType.Binary,
+ "L" => FieldType.Logical,
+ "N" => FieldType.Numeric,
+ "NC" => FieldType.NChar,
+ "NVC" => FieldType.NVarChar,
+ "RV" => FieldType.RowVersion,
+ "NT" => FieldType.NText,
+ "I" => FieldType.Image,
+ "DT" => FieldType.DateTime,
+ _ => throw new Exception($"{type} is unknown field type"),
+ };
+
+ Nullable = node[2];
+ Length = node[3];
+ Precision = node[4];
+ CaseSensitive = node[5];
+
+ CalculateRealSize();
+ }
+
+ public override string ToString()
+ => $"{Name} ({Type})";
+
+ private void CalculateRealSize()
+ {
+ MaxSize = Type switch
+ {
+ FieldType.Binary => Length,
+ FieldType.Logical => 1,
+ FieldType.Numeric => (Length + 1) / 2 + (Length + 1) % 2,
+ FieldType.NChar => Length * 2,
+ FieldType.NVarChar => Length * 2 + 2,
+ FieldType.RowVersion => 16,
+ FieldType.NText => 8,
+ FieldType.Image => 8,
+ FieldType.DateTime => 7,
+ _ => throw new NotImplementedException($"There is no alghorithm to calculate size of \"{Type}\" type"),
+ };
+
+ if (Nullable)
+ MaxSize++;
+ }
+ }
+}
diff --git a/OneSTools.FileDatabase/HighLevel/FieldType.cs b/OneSTools.FileDatabase/HighLevel/FieldType.cs
new file mode 100644
index 0000000..99cc264
--- /dev/null
+++ b/OneSTools.FileDatabase/HighLevel/FieldType.cs
@@ -0,0 +1,42 @@
+namespace OneSTools.FileDatabase.HighLevel
+{
+ public enum FieldType
+ {
+ ///
+ /// Fixed-length binary data
+ ///
+ Binary,
+ ///
+ /// Boolean value
+ ///
+ Logical,
+ ///
+ /// Fixed point decimal
+ ///
+ Numeric,
+ ///
+ /// Fixed-length Unicode string
+ ///
+ NChar, // Unicode string
+ ///
+ /// Variable-length Unicode string
+ ///
+ NVarChar,
+ ///
+ /// Version of the row
+ ///
+ RowVersion,
+ ///
+ /// Unlimited-length Unicode string (UTF-16)
+ ///
+ NText,
+ ///
+ /// Unlimited-length binary data
+ ///
+ Image,
+ ///
+ /// Date and time
+ ///
+ DateTime
+ }
+}
diff --git a/OneSTools.FileDatabase/HighLevel/Index.cs b/OneSTools.FileDatabase/HighLevel/Index.cs
new file mode 100644
index 0000000..beefa6e
--- /dev/null
+++ b/OneSTools.FileDatabase/HighLevel/Index.cs
@@ -0,0 +1,40 @@
+using OneSTools.BracketsFile;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+namespace OneSTools.FileDatabase.HighLevel
+{
+ public class Index
+ {
+ ///
+ /// Internal name of the index
+ ///
+ public string Name { get; private set; }
+ ///
+ /// Collection of the index fields
+ ///
+ public ReadOnlyCollection Fields { get; private set; } = null;
+
+ internal void Read(BracketsNode node)
+ {
+ var fields = new List();
+
+ Name = (string)node[0];
+
+ for (int i = 2; i < node.Count; i++)
+ {
+ var indexField = new IndexField();
+ indexField.Read(node[i]);
+
+ fields.Add(indexField);
+ }
+
+ Fields = fields.AsReadOnly();
+ }
+
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+}
diff --git a/OneSTools.FileDatabase/HighLevel/IndexField.cs b/OneSTools.FileDatabase/HighLevel/IndexField.cs
new file mode 100644
index 0000000..7d15c52
--- /dev/null
+++ b/OneSTools.FileDatabase/HighLevel/IndexField.cs
@@ -0,0 +1,27 @@
+using OneSTools.BracketsFile;
+
+namespace OneSTools.FileDatabase.HighLevel
+{
+ public class IndexField
+ {
+ ///
+ /// Internal name of the index field
+ ///
+ public string Name { get; private set; }
+ ///
+ /// The length of the value
+ ///
+ public int Length { get; private set; }
+
+ internal void Read(BracketsNode node)
+ {
+ Name = node[0];
+ Length = node[1];
+ }
+
+ public override string ToString()
+ {
+ return Name;
+ }
+ }
+}
diff --git a/OneSTools.FileDatabase/HighLevel/Table.cs b/OneSTools.FileDatabase/HighLevel/Table.cs
new file mode 100644
index 0000000..0156f11
--- /dev/null
+++ b/OneSTools.FileDatabase/HighLevel/Table.cs
@@ -0,0 +1,120 @@
+using OneSTools.BracketsFile;
+using System.Collections.Generic;
+using System.IO;
+using System;
+using OneSTools.FileDatabase.LowLevel;
+using System.Collections.ObjectModel;
+
+namespace OneSTools.FileDatabase.HighLevel
+{
+ public class Table
+ {
+ internal int MaxRowSize { get; private set; }
+ internal uint DataFilePage { get; private set; }
+ internal uint UnlimitedLengthDataFilePage { get; private set; }
+ internal uint IndexFilePage { get; private set; }
+
+ ///
+ /// Internal name of the table
+ ///
+ public string Name { get; private set; }
+ ///
+ /// Collection of table fields
+ ///
+ public ReadOnlyCollection Fields { get; private set; } = null;
+ ///
+ /// Collection of table indexes
+ ///
+ public ReadOnlyCollection Indexes { get; private set; } = null;
+ public bool RecordLock { get; private set; }
+ ///
+ /// Collection of table rows
+ ///
+ public IReadOnlyList