public RingMemoryPage[] GetPages(long offset, long count) { VerifyNotDisposed(); Require.That(count > 0, "Count must be greater than zero", "count"); VerifyCapacityRange(offset, offset + count); long startPage = GetPage(offset); long endPage = GetPage(offset + count - 1); var result = new RingMemoryPage[endPage - startPage + 1]; for (long i = startPage; i <= endPage; i++) { long pageOffset = i == startPage ? offset - GetPageOffset(i) : 0; long pageCount = i == endPage ? (offset + count) - GetPageOffset(i) : BlockSize - pageOffset; result[i] = new RingMemoryPage(_pages[i - _pagesOffset], (int)pageOffset, (int)pageCount); } return result; }
/// <summary> /// Gets a reference to the backing memory pages based on the provided /// offset and count. /// </summary> /// <remarks> /// <see cref="GetPages"/> provides access to the backing pages of the /// stream. Reading from or writing to the stream, this method is preferred /// over <see cref="Read"/> because working with the backing pages limits /// the number of extra memory allocations that need to be made. /// </remarks> /// <param name="offset">The start offset for which to get the backing pages</param> /// <param name="count">The number of bytes the returned pages must span</param> /// <returns>The memory pages describing the requested range</returns> public RingMemoryPage[] GetPages(long offset, long count) { VerifyNotDisposed(); Require.That(count > 0, "Count must be greater than zero", "count"); VerifyCapacityRange(offset, offset + count); // Calculate the complete range of pages based on the data that // is being read. long startPage = GetPage(offset); long endPage = GetPage(offset + count - 1); var result = new RingMemoryPage[endPage - startPage + 1]; // For all returned memory pages, calculate the offset and count // for each separate page and return this including a reference to // the backing memory for that page. for (long i = startPage; i <= endPage; i++) { long pageOffset = i == startPage ? offset - GetPageOffset(i) : 0; long pageCount = i == endPage ? (offset + count) - GetPageOffset(i) : BlockSize - pageOffset; result[i] = new RingMemoryPage(_pages[i - _pagesOffset], (int)pageOffset, (int)pageCount); } return result; }
private bool TryGetSendPage(out RingMemoryPage page) { long pageSize = Math.Min( _sendStream.BlockSize - _sendStream.Head % _sendStream.BlockSize, // Maximum size to stay on the page _sendStream.Length - _sendStream.Head // Maximum size to send at all ); if (pageSize == 0) { page = new RingMemoryPage(); return false; } else { page = _sendStream.GetPage(_sendStream.Head, pageSize); Debug.Assert(_sendStream.Head + pageSize <= _sendStream.Length); return true; } }