Quasar/Client/Core/ProtoBuf/BufferExtension.cs

80 lines
2.4 KiB
C#
Raw Normal View History

2014-07-08 12:58:53 +00:00
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)
2014-07-08 12:58:53 +00:00
{
using (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);
2014-07-08 12:58:53 +00:00
#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);
2014-07-08 12:58:53 +00:00
#endif
buffer = tmp;
}
2014-07-08 12:58:53 +00:00
}
}
}
}
Stream IExtension.BeginQuery()
{
return buffer == null ? Stream.Null : new MemoryStream(buffer);
}
void IExtension.EndQuery(Stream stream)
{
// Clean up
if (stream != null)
{
stream.Dispose();
}
2014-07-08 12:58:53 +00:00
}
}
}