public static ContentDatabaseSession OpenDatabase(string path) { //Open file DatabaseFile file = DatabaseFile.LoadFile(path); //Open DB var db = new ContentDatabaseSession(file); //Read TOC if (db.tocPage != -1) { //Read blob byte[] tocBytes = file.ReadBlob(db.tocPage); int count = tocBytes.Length / TOC_ENTRY_LENGTH; BufferBinaryTool reader = new BufferBinaryTool(tocBytes); //Add all for (int i = 0; i < count; i++) { int offset = TOC_ENTRY_LENGTH * i; DatabaseObjectHeader entry = new DatabaseObjectHeader(); entry.object_id = reader.ReadUInt64(offset + 0); entry.page_id = reader.ReadUInt64(offset + 8); entry.commit_id = reader.ReadUInt64(offset + 16); entry.group_id = reader.ReadInt32(offset + 24); entry.commit_type = tocBytes[offset + 28]; entry.flags = tocBytes[offset + 29]; entry.reserved = reader.ReadUInt16(offset + 30); db.objects.Add(entry); } } //Read Name Table if (db.nameTablePage != -1) { //Read blob byte[] ntBytes = file.ReadBlob(db.nameTablePage); BufferBinaryTool reader = new BufferBinaryTool(ntBytes); //Begin reading int index = 0; while (index < ntBytes.Length) { //Read length int length = reader.ReadInt32(index); //Read string db.nameTable.Add(Encoding.ASCII.GetString(ntBytes, index + 4, length)); //Update index += length + 4; } } return(db); }
/// <summary> /// Finds blobs matching the expression. This method is fast, but you need to deserialize it elsewhere. Run this from the worker thread. /// </summary> /// <param name="expression"></param> /// <param name="skip"></param> /// <param name="limit"></param> /// <returns></returns> private FindCommitResults Find(Expression <Func <DatabaseObjectHeader, bool> > expression, int skip = 0, int limit = int.MaxValue) { //Compile var expressionCompiled = expression.Compile(); //Search for objects matching List <DatabaseObjectHeader> matchingHeaders = new List <DatabaseObjectHeader>(); int found = 0; for (int i = 0; i < objects.Count; i++) { //Check if (expressionCompiled(objects[i])) { //Count. This might have to go before the check found++; //Check if we should add if (found > skip) { matchingHeaders.Add(objects[i]); } //Check if we've hit the limit if (matchingHeaders.Count == limit) { break; } } } //Load all FindCommitResults pack = new FindCommitResults(); foreach (var h in matchingHeaders) { //Load blob byte[] blob = file.ReadBlob((long)h.page_id); //Pack FindCommitResultsObject obj = new FindCommitResultsObject { blob = blob, commit_id = h.commit_id, commit_type = h.commit_type, group_id = h.group_id, object_id = h.object_id, nameTable = this }; pack.results.Add(obj); } return(pack); }