private void Load() { if (TheStore.TheFile.Length >= BitmapToPos(Ix + 1)) { TheStore.TheFile.Position = BitmapToPos(Ix); if (StreamUtils.ReadInt8(TheStore.TheFile) != (byte)Store.SectorTypes.Bitmap) { InitializeBitmapSector(); return; } var nextix = StreamUtils.ReadInt32(TheStore.TheFile); SectorData = StreamUtils.Read(TheStore.TheFile, (int)TheStore.SectorDataSize); if (nextix != Store.LAST_SECTOR_IN_CHAIN) { NextBitmap = new BitmapSector(TheStore, nextix, SectorSize); } else { NextBitmap = null; } } else { InitializeBitmapSector(); } }
/// <summary> /// Truncate the link of sectors starting with sector ix. The sector refering to sector ix (if any) will not be updated. /// </summary> /// <param name="ix"></param> protected void DeleteFrom(int ix) { Bits[ix] = false; if (FreeSectorSearchStartIndex > ix) { FreeSectorSearchStartIndex = ix; } TheFile.Position = BitmapToPos(ix); StreamUtils.WriteUInt8(TheFile, (byte)SectorTypes.Unallocated); var nextsector = StreamUtils.ReadInt32(TheFile); while (nextsector != LAST_SECTOR_IN_CHAIN) { Bits[nextsector] = false; if (FreeSectorSearchStartIndex > nextsector) { FreeSectorSearchStartIndex = nextsector; } TheFile.Position = BitmapToPos(nextsector); StreamUtils.WriteUInt8(TheFile, (byte)SectorTypes.Unallocated); nextsector = StreamUtils.ReadInt32(TheFile); } }
private void InitializeChunksize() { if (TheFile.Length < SECTOR_0_HEADER_SIZE) { if (TheFile.CanWrite) { TheFile.Position = 0; TheFile.WriteInt32(Chunksize); TheFile.WriteUInt64(FILE_FORMAT_VERSION ^ FILE_FORMAT_MASK); } else { throw new IOException("Underlying stream have no Write functionality."); } } else { TheFile.Position = 0; Chunksize = StreamUtils.ReadInt32(TheFile); var fileformattag = StreamUtils.ReadUInt64(TheFile); var fileformatversion = fileformattag ^ FILE_FORMAT_MASK; if (fileformatversion != FILE_FORMAT_VERSION) { throw new IOException($"File format version {fileformatversion} not supported."); } } }
private byte[] ReadInternal(int ix, long maxlen) { TheFile.Position = BitmapToPos(ix); var sectortype = (Store.SectorTypes)StreamUtils.ReadInt8(TheFile); if (sectortype != Store.SectorTypes.Data) { throw new Exception("Trying to read in non data area"); } var nextsector = StreamUtils.ReadInt32(TheFile); var totallen = StreamUtils.ReadInt64(TheFile); if (maxlen > 0) { totallen = Math.Min(totallen, maxlen); } var result = new byte[totallen]; var resultpos = 0; var buflen = FirstSectorDataSize; while (resultpos < totallen) { var len = (int)Math.Min(totallen - resultpos, buflen); var readlen = TheFile.Read(result, resultpos, len); if (nextsector == LAST_SECTOR_IN_CHAIN) { var curlen = resultpos + readlen; if (totallen > curlen) { DebugUtils.LogWarning("Store: Warning! Stored length of the chain is faulty!"); return(result.Copy(0, curlen)); } break; } TheFile.Position = BitmapToPos(nextsector); var stype = (Store.SectorTypes)StreamUtils.ReadInt8(TheFile); if (stype != Store.SectorTypes.Continuation) { throw new Exception("Trying to read in non data area"); } nextsector = StreamUtils.ReadInt32(TheFile); resultpos += readlen; buflen = SectorDataSize; } return(result); }
public StoreStream(Store store, int ix, long offset) { TheStore = store; Ix = ix; if (offset < 0) { throw new ArgumentException("offset must be >= 0!"); } PositionOffset = offset; var file = TheStore.TheFile; // Get current state file.Position = TheStore.BitmapToPos(ix); var sectortype = (Store.SectorTypes)StreamUtils.ReadInt8(file); if (sectortype != Store.SectorTypes.Data) { throw new Exception("Trying to read in non data area"); } var nextsector = StreamUtils.ReadInt32(file); var CurrentLength = StreamUtils.ReadInt64(file); while (sectortype == SectorTypes.Data || sectortype == SectorTypes.Continuation) { Sectors.Add(ix); if (nextsector == LAST_SECTOR_IN_CHAIN) { break; } file.Position = TheStore.BitmapToPos(nextsector); ix = nextsector; sectortype = (Store.SectorTypes)StreamUtils.ReadInt8(file); if (sectortype != Store.SectorTypes.Data && sectortype != SectorTypes.Continuation) { throw new Exception("Trying to read in non data area"); } nextsector = StreamUtils.ReadInt32(file); } }
public long GetDataLength(int ix) { if (!Bits[ix]) { return(0); // Free } TheFile.Position = BitmapToPos(ix); var sectortype = StreamUtils.ReadInt8(TheFile); if ((Store.SectorTypes)sectortype != Store.SectorTypes.Data) { return(0); } var nextsector = StreamUtils.ReadInt32(TheFile); return(StreamUtils.ReadInt64(TheFile)); }
private int ExtendLastSector(int thissector) { var nextsector = AllocateFreeSector(); #if DEBUG TheFile.Position = BitmapToPos(thissector) + 1; var ns = StreamUtils.ReadInt32(TheFile); if (ns != LAST_SECTOR_IN_CHAIN) { throw new ArgumentException("Store: Sector passed is not last in chain!"); } #endif TheFile.Position = BitmapToPos(thissector) + 1; TheFile.WriteInt32(nextsector); TheFile.Position = BitmapToPos(nextsector); TheFile.WriteUInt8((byte)Store.SectorTypes.Continuation); TheFile.WriteInt32(LAST_SECTOR_IN_CHAIN); return(nextsector); }
private void InitializeChunksize() { if (TheFile.Length < 4) { if (TheFile.CanWrite) { TheFile.Position = 0; TheFile.WriteInt32(Chunksize); } else { throw new IOException("Underlying stream have no Write functionality."); } } else { TheFile.Position = 0; Chunksize = StreamUtils.ReadInt32(TheFile); } }
private void WriteInternal(IEnumerable <BufLen> datablocks, int ix) { var thissector = ix; if (!Bits[ix]) { throw new Exception("Cannot update an unallocated sector!"); } TheFile.Position = BitmapToPos(thissector); if ((Store.SectorTypes)StreamUtils.ReadInt8(TheFile) != Store.SectorTypes.Data) { throw new Exception("Trying to write in non data area"); } var nextsector = StreamUtils.ReadInt32(TheFile); TheFile.WriteInt64(datablocks.Sum(r => (long)r.Length)); var sectorspaceleft = FirstSectorDataSize; foreach (var datab in datablocks) { var data = (BufRefLen)datab; while (data.Length > 0) { var len = (int)Math.Min(data.Length, sectorspaceleft); TheFile.Write(data.BaseArray, data.BaseArrayOffset, len); data.Seek(len); sectorspaceleft -= len; if (data.Length == 0) { break; } if (sectorspaceleft == 0) { if (nextsector != LAST_SECTOR_IN_CHAIN) { if (!Bits[nextsector]) { throw new Exception("Cannot update an unallocated sector!"); } TheFile.Position = BitmapToPos(nextsector); if ((Store.SectorTypes)StreamUtils.ReadInt8(TheFile) != Store.SectorTypes.Continuation) { throw new Exception("Trying to update a sector outside of the allocated sector chain!"); } thissector = nextsector; nextsector = StreamUtils.ReadInt32(TheFile); } else { thissector = ExtendLastSector(thissector); nextsector = LAST_SECTOR_IN_CHAIN; } sectorspaceleft = SectorDataSize; } } } }