12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273 |
- 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(Helpers.GetBuffer(ms), 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
- }
- }
- }
|