internal MemoryObject(MemoryFileSystem fs, MfsCellId cellId, bool fsInternal) { _fs = fs; _cellId = cellId; _obj = _fs.ReferenceObject(cellId); _fsInternal = fsInternal; if (!_fsInternal) _fs.Reference(); // Prevent users from disposing the root object wrapper. if (_fsInternal) this.DisableOwnership(false); }
internal MfsObjectHeader* ReferenceObject(MfsCellId cellId) { return (MfsObjectHeader*)this.ReferenceCell(cellId); }
private IntPtr ReferenceCell(MfsCellId cellId) { IntPtr block; block = this.ReferenceBlock(cellId.Block); return block.Increment(cellId.Cell * _cellSize); }
internal int ReadDataCell(MfsCellId cellId, System.IO.Stream stream, int length) { MfsDataCell* dc; byte[] buf = new byte[_dataCellDataMaxLength]; int bytesRead = 0; while (length > 0) { MfsCellId newCellId; int readLength; dc = (MfsDataCell*)this.ReferenceCell(cellId); readLength = length > dc->DataLength ? dc->DataLength : length; Marshal.Copy(new IntPtr(&dc->Data), buf, 0, readLength); stream.Write(buf, 0, readLength); bytesRead += readLength; length -= readLength; newCellId = dc->NextCell; this.DereferenceCell(cellId); cellId = newCellId; if (cellId == MfsCellId.Empty) break; } return bytesRead; }
internal int ReadDataCell(MfsCellId cellId, byte[] buffer, int offset, int length) { MfsDataCell* dc; int bytesRead = 0; Utils.ValidateBuffer(buffer, offset, length); while (length > 0) { MfsCellId newCellId; int readLength; dc = (MfsDataCell*)this.ReferenceCell(cellId); readLength = length > dc->DataLength ? dc->DataLength : length; Marshal.Copy(new IntPtr(&dc->Data), buffer, offset, readLength); offset += readLength; bytesRead += readLength; length -= readLength; newCellId = dc->NextCell; this.DereferenceCell(cellId); cellId = newCellId; if (cellId == MfsCellId.Empty) break; } return bytesRead; }
private void InitializeObject(MfsObjectHeader* obj, MfsCellId cellId) { obj->Flink = cellId; obj->Blink = cellId; obj->Parent = MfsCellId.Empty; obj->ChildFlink = cellId; obj->ChildBlink = cellId; obj->DataLength = 0; obj->Data = MfsCellId.Empty; obj->LastData = MfsCellId.Empty; }
internal void DereferenceObject(MfsCellId cellId) { this.DereferenceCell(cellId); }
private void DereferenceCell(MfsCellId cellId) { this.DereferenceBlock(cellId.Block); }
internal MfsCellId CreateObject(MfsCellId parent, string name) { MfsCellId cellId; MfsObjectHeader* obj; if (_readOnly) throw new MfsInvalidOperationException(); obj = (MfsObjectHeader*)this.AllocateCell(out cellId); this.InitializeObject(obj, cellId); this.SetObjectName(obj, name); obj->Parent = parent; MfsObjectHeader* parentObj = this.ReferenceObject(parent); MfsCellId blink; MfsObjectHeader* blinkObj; // Increment the child count. parentObj->ChildCount++; // Insert tail. blink = parentObj->ChildBlink; blinkObj = this.ReferenceObject(blink); obj->Flink = parent; obj->Blink = blink; parentObj->ChildBlink = cellId; // Special case - we are not using linked lists properly, // so we have to use this hack. if (blink == parent) blinkObj->ChildFlink = cellId; else blinkObj->Flink = cellId; this.DereferenceObject(blink); this.DereferenceObject(parent); this.DereferenceObject(cellId); return cellId; }
internal MfsCellId CreateDataCell(MfsCellId prev, byte[] buffer, int offset, int length) { MfsCellId cellId; MfsDataCell* dc; MfsDataCell* prevDc; if (_readOnly) throw new MfsInvalidOperationException(); Utils.ValidateBuffer(buffer, offset, length); if (length > _dataCellDataMaxLength) throw new ArgumentException("length"); dc = (MfsDataCell*)this.AllocateCell(out cellId); dc->NextCell = MfsCellId.Empty; dc->DataLength = length; if (prev != MfsCellId.Empty) { prevDc = (MfsDataCell*)this.ReferenceCell(prev); prevDc->NextCell = cellId; this.DereferenceCell(prev); } Marshal.Copy(buffer, offset, new IntPtr(&dc->Data), length); this.DereferenceCell(cellId); return cellId; }
private IntPtr AllocateCell(out MfsCellId cellIdOut) { ushort blockId; ushort cellId; IntPtr lastBlock; MfsBlockHeader* header; if (_header->NextFreeBlock == 1) { // No blocks except for the FS header. Allocate one. lastBlock = this.AllocateBlock(out blockId); } else { blockId = (ushort)(_header->NextFreeBlock - 1); lastBlock = this.ReferenceBlock(blockId); } header = (MfsBlockHeader*)lastBlock; if (header->NextFreeCell == _cellCount) { // Block full. Allocate a new one. this.DereferenceBlock(lastBlock); // Fix up the cached reference. if (_cachedLastBlockView != null) { this.DereferenceBlock(_cachedLastBlockView.BlockId); _cachedLastBlockView = null; } lastBlock = this.AllocateBlock(out blockId); header = (MfsBlockHeader*)lastBlock; // Add a new cached reference. this.ReferenceBlock(blockId); _cachedLastBlockView = _views[blockId]; } cellId = header->NextFreeCell++; cellIdOut = new MfsCellId(blockId, cellId); return lastBlock.Increment(cellId * _cellSize); }
internal MemoryObject(MemoryFileSystem fs, MfsCellId cellId) : this(fs, cellId, false) { }