in binding/SkiaSharp/SKFrontBufferedManagedStream.cs [64:124]
protected override IntPtr OnRead (IntPtr buffer, IntPtr size)
{
var start = offset;
// 1. read any data that was previously buffered
if ((int)size > 0 && offset < bufferedSoFar)
{
var copied = Math.Min ((int)size, bufferedSoFar - offset);
if (buffer != IntPtr.Zero)
{
Marshal.Copy (frontBuffer, offset, buffer, copied);
buffer += copied;
}
offset += copied;
size -= copied;
}
bool isAtEnd = false;
// 2. buffer any more data, and then read it
if ((int)size > 0 && bufferedSoFar < bufferLength)
{
var bytesToBuffer = Math.Min ((int)size, bufferLength - bufferedSoFar);
var tempBuffer = Marshal.AllocCoTaskMem (bytesToBuffer);
var bytesRead = stream.Read (tempBuffer, bytesToBuffer);
Marshal.Copy (tempBuffer, frontBuffer, offset, bytesRead);
Marshal.FreeCoTaskMem (tempBuffer);
isAtEnd = bytesRead < bytesToBuffer;
bufferedSoFar += bytesRead;
if (buffer != IntPtr.Zero)
{
Marshal.Copy (frontBuffer, offset, buffer, bytesRead);
buffer += bytesRead;
}
offset += bytesRead;
size -= bytesRead;
}
// 3. read the rest directly
if ((int)size > 0 && !isAtEnd)
{
var bytesRead = stream.Read (buffer, (int)size);
// past the buffer, so dispose it
if (bytesRead > 0)
{
frontBuffer = null;
}
offset += bytesRead;
size -= bytesRead;
}
return (IntPtr)(offset - start);
}