public FileReaderV7(Stream stream, string password)
        {
            _stream = stream;

            // only userVersion was avaiable in old file format versions
            _header = this.ReadPage(0);

            if (password == null && _header["salt"].AsBinary.IsFullZero() == false)
            {
                throw new LiteDB.LiteException("Current data file requires password");
            }
        }
        /// <summary>
        /// Read a BsonDocument from reader
        /// </summary>
        public LiteDB.BsonDocument ReadDocument(ByteReader reader)
        {
            var length = reader.ReadInt32();
            var end    = reader.Position + length - 5;
            var obj    = new LiteDB.BsonDocument();

            while (reader.Position < end)
            {
                var value = this.ReadElement(reader, out string name);
                obj.RawValue[name] = value;
            }

            reader.ReadByte(); // zero

            return(obj);
        }
Exemple #3
0
        public string Get(string query)
        {
            LiteDB.BsonDocument document = _database.GetCollection("game").Find(LiteDB.Query.EQ("STRING", query)).Where(x => x[_culture] != null).FirstOrDefault();

            LiteDB.BsonValue value = null;

            if (document != null)
            {
                value = document[_culture];
            }

            if (value == null)
            {
                value = _database.GetCollection("game").Find(LiteDB.Query.EQ("STRING", query)).Where(x => x["EN"] != null).First()["EN"];
            }

            return(value.AsString);
        }
        public Tuple <string, byte[]> Post(byte[] body, ControllerSession session)
        {
            var parts = TLVParser.Parse(body);

            var state  = parts.GetTypeAsInt(Constants.State);
            var method = parts.GetTypeAsInt(Constants.Method);

            Console.WriteLine("***********************");
            Console.WriteLine("* Pairings Controller *");
            Console.WriteLine($"* State: {state}           *");
            Console.WriteLine($"* Method: {state}         *");
            Console.WriteLine("***********************");

            TLV responseTLV = new TLV();

            if (state == 1)
            {
                if (method == 3) // Add Pairing
                {
                    Console.WriteLine("* Add Pairing");

                    var identifier  = parts.GetType(Constants.Identifier);
                    var publickey   = parts.GetType(Constants.PublicKey);
                    var permissions = parts.GetType(Constants.Permissions);

                    LiteDB.LiteDatabase database = new LiteDB.LiteDatabase("Filename=Hap.db");

                    var pairingsCollection = database.GetCollection("pairings");

                    var existingPairing = pairingsCollection.FindById(Encoding.UTF8.GetString(identifier));

                    if (existingPairing == null)
                    {
                        var pairing = new LiteDB.BsonDocument();
                        var doc     = new LiteDB.BsonDocument();
                        doc.Add("publickey", new LiteDB.BsonValue(publickey));
                        doc.Add("permissions", new LiteDB.BsonValue(permissions));

                        pairing.Add(Encoding.UTF8.GetString(identifier), doc);

                        pairingsCollection.Insert(pairing);
                    }
                    else
                    {
                        // TODO DO something here.
                    }

                    responseTLV.AddType(Constants.State, 2);

                    byte[] output1 = TLVParser.Serialise(responseTLV);

                    return(new Tuple <string, byte[]>("application/pairing+tlv8", output1));
                }
                else if (method == 4) // Remove Pairing
                {
                    Console.WriteLine("* Remove Pairing");

                    responseTLV = new TLV();

                    responseTLV.AddType(Constants.State, 2);

                    byte[] output2 = TLVParser.Serialise(responseTLV);

                    return(new Tuple <string, byte[]>("application/pairing+tlv8", output2));
                }
                if (method == 5) // List Pairing
                {
                    Console.WriteLine("* List Pairings");

                    responseTLV = new TLV();

                    responseTLV.AddType(Constants.State, 2);

                    byte[] output3 = TLVParser.Serialise(responseTLV);

                    return(new Tuple <string, byte[]>("application/pairing+tlv8", output3));
                }
            }

            responseTLV.AddType(Constants.State, 2);
            responseTLV.AddType(Constants.Error, ErrorCodes.Busy);

            byte[] output = TLVParser.Serialise(responseTLV);

            return(new Tuple <string, byte[]>("application/pairing+tlv8", output));
        }
        /// <summary>
        /// Read all database pages from v7 structure into a flexible BsonDocument - only read what really needs
        /// </summary>
        private LiteDB.BsonDocument ReadPage(uint pageID)
        {
            if (pageID * V7_PAGE_SIZE > _stream.Length)
            {
                return(null);
            }

            _stream.Position = pageID * V7_PAGE_SIZE; // v7 uses 4k page size

            _stream.Read(_buffer, 0, V7_PAGE_SIZE);

            // decrypt encrypted page (except header page - header are plain data)
            var reader = new ByteReader(_buffer);

            // reading page header
            var page = new LiteDB.BsonDocument
            {
                ["pageID"]     = (int)reader.ReadUInt32(),
                ["pageType"]   = (int)reader.ReadByte(),
                ["prevPageID"] = (int)reader.ReadUInt32(),
                ["nextPageID"] = (int)reader.ReadUInt32(),
                ["itemCount"]  = (int)reader.ReadUInt16()
            };

            // skip freeByte + reserved
            reader.ReadBytes(2 + 8);

            #region Header (1)

            // read header
            if (page["pageType"] == 1)
            {
                var info = reader.ReadString(27);
                var ver  = reader.ReadByte();

                if (string.CompareOrdinal(info, HeaderPage_HEADER_INFO) != 0 || ver != 7)
                {
                    throw new LiteDB.LiteException("");
                }

                // skip ChangeID + FreeEmptyPageID + LastPageID
                reader.ReadBytes(2 + 4 + 4);
                page["userVersion"] = (int)reader.ReadUInt16();
                page["password"]    = reader.ReadBytes(20);
                page["salt"]        = reader.ReadBytes(16);
                page["collections"] = new LiteDB.BsonDocument();

                var cols = reader.ReadByte();

                for (var i = 0; i < cols; i++)
                {
                    var name      = reader.ReadString();
                    var colPageID = reader.ReadUInt32();

                    page["collections"].WriteIndex(name, (int)colPageID);
                }
            }

            #endregion

            #region Collection (2)

            // collection page
            else if (page["pageType"] == 2)
            {
                page["collectionName"] = reader.ReadString();
                page["indexes"]        = new LiteDB.BsonArray();
                reader.ReadBytes(12);

                for (var i = 0; i < 16; i++)
                {
                    var index = new LiteDB.BsonDocument();

                    var field = reader.ReadString();
                    var eq    = field.IndexOf('=');

                    if (eq > 0)
                    {
                        index["name"]       = field.Substring(0, eq);
                        index["expression"] = field.Substring(eq + 1);
                    }
                    else
                    {
                        index["name"]       = field;
                        index["expression"] = "$." + field;
                    }

                    index["unique"]     = reader.ReadBoolean();
                    index["headPageID"] = (int)reader.ReadUInt32();

                    // skip HeadNode (index) + TailNode + FreeIndexPageID
                    reader.ReadBytes(2 + 6 + 4);

                    if (field.Length > 0)
                    {
                        page["indexes"].AsArray.Add(index);
                    }
                }
            }

            #endregion

            #region Index (3)
            else if (page["pageType"] == 3)
            {
                page["nodes"] = new LiteDB.BsonArray();

                for (var i = 0; i < page["itemCount"].AsInt32; i++)
                {
                    var node = new LiteDB.BsonDocument
                    {
                        ["index"] = (int)reader.ReadUInt16()
                    };

                    var levels = reader.ReadByte();

                    // skip Slot + PrevNode + NextNode
                    reader.ReadBytes(1 + 6 + 6);

                    var length = reader.ReadUInt16();

                    // skip DataType + KeyValue
                    reader.ReadBytes(1 + length);

                    node["dataBlock"] = new LiteDB.BsonDocument
                    {
                        ["pageID"] = (int)reader.ReadUInt32(),
                        ["index"]  = (int)reader.ReadUInt16()
                    };

                    // reading Prev[0]
                    node["prev"] = new LiteDB.BsonDocument
                    {
                        ["pageID"] = (int)reader.ReadUInt32(),
                        ["index"]  = (int)reader.ReadUInt16()
                    };

                    // reading Next[0]
                    node["next"] = new LiteDB.BsonDocument
                    {
                        ["pageID"] = (int)reader.ReadUInt32(),
                        ["index"]  = (int)reader.ReadUInt16()
                    };

                    // skip Prev/Next[1..N]
                    reader.ReadBytes((levels - 1) * (6 + 6));

                    page["nodes"].AsArray.Add(node);
                }
            }

            #endregion

            #region Data (4)
            else if (page["pageType"] == 4)
            {
                page["blocks"] = new LiteDB.BsonArray();

                for (var i = 0; i < page["itemCount"].AsInt32; i++)
                {
                    var block = new LiteDB.BsonDocument
                    {
                        ["index"]        = (int)reader.ReadUInt16(),
                        ["extendPageID"] = (int)reader.ReadUInt32()
                    };

                    var length = reader.ReadUInt16();

                    block["data"] = reader.ReadBytes(length);

                    page["blocks"].AsArray.Add(block);
                }
            }

            #endregion

            #region Extend (5)
            else if (page["pageType"] == 5)
            {
                page["data"] = reader.ReadBytes(page["itemCount"].AsInt32);
            }

            #endregion

            return(page);
        }
        /// <summary>
        /// Get all document using an indexInfo as start point (_id index).
        /// </summary>
        public IEnumerable <LiteDB.BsonDocument> GetDocuments(string collection)
        {
            var colPageID  = (uint)_header["collections"].AsDocument[collection].AsInt32;
            var col        = this.ReadPage(colPageID);
            var headPageID = (uint)col.Index("indexes").Index(0).Index("headPageID").AsInt32;

            var indexPages = this.VisitIndexPages(headPageID);

            foreach (var indexPageID in indexPages)
            {
                var indexPage = this.ReadPage(indexPageID);

                foreach (var node in indexPage["nodes"].AsArray)
                {
                    var dataBlock = node.Index("dataBlock");

                    // if datablock link to a data page
                    if (dataBlock.Index("pageID").AsInt32 != -1)
                    {
                        // read dataPage and data block
                        var dataPage = this.ReadPage((uint)dataBlock.Index("pageID").AsInt32);

                        if (dataPage["pageType"].AsInt32 != 4)
                        {
                            continue;
                        }

                        var block = dataPage["blocks"].AsArray.FirstOrDefault(x => x.Index("index") == dataBlock.Index("index"))?.AsDocument;

                        if (block == null)
                        {
                            continue;
                        }

                        // read byte[] from block or from extend pages
                        var data = block["extendPageID"] == -1 ?
                                   block["data"].AsBinary :
                                   this.ReadExtendData((uint)block["extendPageID"].AsInt32);

                        if (data.Length == 0)
                        {
                            continue;
                        }

                        // BSON format still same from all version
                        var doc = LiteDB.BsonSerializer.Deserialize(data);

                        // change _id PK in _chunks collection
                        if (collection == "_chunks")
                        {
                            var parts = doc["_id"].AsString.Split('\\');

                            if (!int.TryParse(parts[1], out var n))
                            {
                                throw new LiteDB.LiteException("_id");
                            }

                            doc["_id"] = new LiteDB.BsonDocument
                            {
                                ["f"] = parts[0],
                                ["n"] = n
                            };
                        }

                        yield return(doc);
                    }
                }
            }
        }