78 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C#
		
	
	
			
		
		
	
	
			78 lines
		
	
	
		
			2.3 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, IExtensionResettable
 | |
|     {
 | |
|         private byte[] buffer;
 | |
| 
 | |
|         void IExtensionResettable.Reset()
 | |
|         {
 | |
|             buffer = null;
 | |
|         }
 | |
| 
 | |
|         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];
 | |
|                         Buffer.BlockCopy(buffer, 0, tmp, 0, offset);
 | |
| 
 | |
| #if PORTABLE // 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
 | |
|                         Buffer.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
 | |
|         }
 | |
|     }
 | |
| } |