public override int Read(byte[] buffer, int offset, int count) { if (count <= 0) return 0; uint bytesRead = 0U; var bytesRemaining = (uint) count; var addr = _ram.VirtualAddressCalculator.New((uint) (_pageSet.Offset + Position)); if (_page == null || _page.PageNumber != addr.PageNumber) _page = _pageSet.Pages.Single(x => x.PageNumber == addr.PageNumber); MemoryStream current = _ram.GetStream(_page); current.Seek(addr.Offset, SeekOrigin.Begin); uint remaining = _page.Size - addr.Offset; while (bytesRemaining > 0) { var read = (uint) current.Read(buffer, offset, (int) Math.Min(remaining, bytesRemaining)); bytesRemaining -= read; bytesRead += read; offset += (int) read; Position += read; _page = _pageSet.Next(_page); if (_page == null) break; current = _ram.GetStream(_page); remaining = _page.Size; } return (int) bytesRead; }
public void Append(Page page) { if (page == null) throw new ArgumentNullException(nameof(page)); if (_page == null) _page = page; _pages.Add(page); }
public PageStream(Ram ram, PageInfo pageSet) { if (ram == null) throw new ArgumentNullException(nameof(ram)); if (pageSet == null) throw new ArgumentNullException(nameof(pageSet)); _ram = ram; _pageSet = pageSet; _page = pageSet.Pages.FirstOrDefault(); }
public VirtualAddress ToVirtualAddress(Page page) { return VirtualAddressCalculator.New(0, (int) page.PageNumber); }
public MemoryStream GetStream(Page page) { return GetStream(page.FrameNumber); }
public void Free(Page page) { var frameList = _pageTable[page.FrameNumber]; var frameIndex = frameList.FindIndex(x => x.PageNumber == page.PageNumber); if (frameIndex == -1) return; if (frameIndex == 0) { var frame = frameList[0]; frame.PageNumber = 0; frame.ProcessId = 0; } else { frameList.RemoveAt(frameIndex); } }
public override void Write(byte[] buffer, int offset, int count) { if (count <= 0) return; var addr = _ram.VirtualAddressCalculator.New((uint) (_pageSet.Offset + Position)); if (_page == null || _page.PageNumber != addr.PageNumber) { _page = _pageSet.Find(addr.PageNumber); } MemoryStream current = _ram.GetStream(_page); current.Seek(addr.Offset, SeekOrigin.Begin); uint remaining = _page.Size - addr.Offset; while (offset < count) { long write = Math.Min(remaining, count - offset); current.Write(buffer, offset, (int) write); offset += (int) write; Position += write; _page = _pageSet.Next(_page); if (_page == null) break; current = _ram.GetStream(_page); remaining = _page.Size; } if ( offset == count ) { return; } throw new InvalidOperationException("Attempt to write past stream boundary"); }
public Page Next(Page page) { var pageIndex = _pages.IndexOf(page) + 1; return pageIndex == _pages.Count ? null : _pages[pageIndex]; }