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