BufferExtension.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. using System;
  2. using System.IO;
  3. namespace ProtoBuf
  4. {
  5. /// <summary>
  6. /// Provides a simple buffer-based implementation of an <see cref="IExtension">extension</see> object.
  7. /// </summary>
  8. public sealed class BufferExtension : IExtension, IExtensionResettable
  9. {
  10. private byte[] buffer;
  11. void IExtensionResettable.Reset()
  12. {
  13. buffer = null;
  14. }
  15. int IExtension.GetLength()
  16. {
  17. return buffer == null ? 0 : buffer.Length;
  18. }
  19. Stream IExtension.BeginAppend()
  20. {
  21. return new MemoryStream();
  22. }
  23. void IExtension.EndAppend(Stream stream, bool commit)
  24. {
  25. using (stream)
  26. {
  27. int len;
  28. if (commit && (len = (int)stream.Length) > 0)
  29. {
  30. MemoryStream ms = (MemoryStream)stream;
  31. if (buffer == null)
  32. { // allocate new buffer
  33. buffer = ms.ToArray();
  34. }
  35. else
  36. { // resize and copy the data
  37. // note: Array.Resize not available on CF
  38. int offset = buffer.Length;
  39. byte[] tmp = new byte[offset + len];
  40. Buffer.BlockCopy(buffer, 0, tmp, 0, offset);
  41. #if PORTABLE // no GetBuffer() - fine, we'll use Read instead
  42. int bytesRead;
  43. long oldPos = ms.Position;
  44. ms.Position = 0;
  45. while (len > 0 && (bytesRead = ms.Read(tmp, offset, len)) > 0)
  46. {
  47. len -= bytesRead;
  48. offset += bytesRead;
  49. }
  50. if(len != 0) throw new EndOfStreamException();
  51. ms.Position = oldPos;
  52. #else
  53. Buffer.BlockCopy(Helpers.GetBuffer(ms), 0, tmp, offset, len);
  54. #endif
  55. buffer = tmp;
  56. }
  57. }
  58. }
  59. }
  60. Stream IExtension.BeginQuery()
  61. {
  62. return buffer == null ? Stream.Null : new MemoryStream(buffer);
  63. }
  64. void IExtension.EndQuery(Stream stream)
  65. {
  66. using (stream) { } // just clean up
  67. }
  68. }
  69. }