protected override IntPtr OnRead()

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);
		}