internal void Read(Stream stream) { stream.Seek(0, SeekOrigin.Begin); using (var binReader = new BinaryReader(stream, Encoding, true)) { updateTS = new DateTime(binReader.ReadInt64()); persistTS = new DateTime(binReader.ReadInt64()); Status = (CatalogStatus)binReader.ReadByte(); format = (CatalogFormat)binReader.ReadByte(); pageCount = binReader.ReadInt32(); if (pageCount > 0) { binReader.BaseStream.Seek(-pageCount, SeekOrigin.End); // reading in reverse order var revContent = binReader.ReadBytes(pageCount); PageContent = revContent .Reverse() .Select(b => (PageType)b); } } if (updateTS > persistTS) { Status |= CatalogStatus.Dirty; } }
internal static Stream BuilderHeaderBuffer(CatalogStatus status, CatalogFormat format, DateTime update, DateTime persist, params Page[] pages) { var mStream = new MemoryStream(new byte[MaxHeaderSize]); using (var binWriter = new BinaryWriter(mStream, Encoding, true)) { binWriter.Write(update.Ticks); binWriter.Write(persist.Ticks); binWriter.Write((byte)status); binWriter.Write((byte)format); binWriter.Write(pages.Length); if (pages != null && pages.Length > 0) { // with pages (Type) in reverse order create PageDescriptor array var pageTypes = pages.Reverse() .SelectMany(p => { var pgDescr = PageDescriptor.Create(new byte[] { 1 }); pgDescr.Write(0, () => (byte)p.Type); return((byte[])pgDescr); }) .ToArray(); binWriter.Seek(-pageTypes.Length, SeekOrigin.End); binWriter.Write(pageTypes, 0, pageTypes.Length); } } return(mStream); }
internal static FileInfo MakeCatalogFile(string name, CatalogStatus status, CatalogFormat format, DateTime update, DateTime persist, params PageType[] pageContent) { var dbPath = new DirectoryInfo(Path.Combine(DataDirectory.FullName, name)); dbPath.Create(); var length = MaxHeaderSize; var pages = new Page[pageContent.Length]; var i = 0; foreach (var pc in pageContent) { pages[i] = new Page(pc); length += pages[i].MaxSize; ++i; } var headerStream = BuilderHeaderBuffer(status, format, update, persist, pages); headerStream.Position = 0; var filePath = Path.Combine(dbPath.FullName, $"{name}.db"); var file = default(FileInfo); using (var fStream = (file = new FileInfo(filePath)).Create()) { headerStream.CopyTo(fStream); foreach (var p in pages) { fStream.SetLength(fStream.Length + p.MaxSize); } } return(file); }