mirror of https://github.com/quasar/Quasar.git
74 lines
2.2 KiB
C#
74 lines
2.2 KiB
C#
using System;
|
|
using System.IO;
|
|
|
|
namespace ProtoBuf
|
|
{
|
|
/// <summary>
|
|
/// Provides a simple buffer-based implementation of an <see cref="IExtension">extension</see> object.
|
|
/// </summary>
|
|
public sealed class BufferExtension : IExtension
|
|
{
|
|
private byte[] buffer;
|
|
|
|
int IExtension.GetLength()
|
|
{
|
|
return buffer == null ? 0 : buffer.Length;
|
|
}
|
|
|
|
Stream IExtension.BeginAppend()
|
|
{
|
|
return new MemoryStream();
|
|
}
|
|
|
|
void IExtension.EndAppend(Stream stream, bool commit)
|
|
{
|
|
using (stream)
|
|
{
|
|
int len;
|
|
if (commit && (len = (int)stream.Length) > 0)
|
|
{
|
|
MemoryStream ms = (MemoryStream)stream;
|
|
|
|
if (buffer == null)
|
|
{ // allocate new buffer
|
|
buffer = ms.ToArray();
|
|
}
|
|
else
|
|
{ // resize and copy the data
|
|
// note: Array.Resize not available on CF
|
|
int offset = buffer.Length;
|
|
byte[] tmp = new byte[offset + len];
|
|
Helpers.BlockCopy(buffer, 0, tmp, 0, offset);
|
|
|
|
#if PORTABLE || WINRT // no GetBuffer() - fine, we'll use Read instead
|
|
int bytesRead;
|
|
long oldPos = ms.Position;
|
|
ms.Position = 0;
|
|
while (len > 0 && (bytesRead = ms.Read(tmp, offset, len)) > 0)
|
|
{
|
|
len -= bytesRead;
|
|
offset += bytesRead;
|
|
}
|
|
if(len != 0) throw new EndOfStreamException();
|
|
ms.Position = oldPos;
|
|
#else
|
|
Helpers.BlockCopy(ms.GetBuffer(), 0, tmp, offset, len);
|
|
#endif
|
|
buffer = tmp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Stream IExtension.BeginQuery()
|
|
{
|
|
return buffer == null ? Stream.Null : new MemoryStream(buffer);
|
|
}
|
|
|
|
void IExtension.EndQuery(Stream stream)
|
|
{
|
|
using (stream) { } // just clean up
|
|
}
|
|
}
|
|
}
|