ReadOnlyBufferedStream.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. using Best.HTTP.Shared.PlatformSupport.Memory;
  2. using System;
  3. using System.IO;
  4. namespace Best.HTTP.Shared.Streams
  5. {
  6. public sealed class ReadOnlyBufferedStream : Stream
  7. {
  8. Stream stream;
  9. public const int READBUFFER = 8192;
  10. byte[] buf;
  11. int available = 0;
  12. int pos = 0;
  13. public ReadOnlyBufferedStream(Stream nstream)
  14. :this(nstream, READBUFFER)
  15. {
  16. }
  17. public ReadOnlyBufferedStream(Stream nstream, int bufferSize)
  18. {
  19. stream = nstream;
  20. buf = BufferPool.Get(bufferSize, true);
  21. }
  22. public override int Read(byte[] buffer, int offset, int size)
  23. {
  24. if (available > 0)
  25. {
  26. // copy & return
  27. int copyCount = Math.Min(available, size);
  28. Array.Copy(buf, pos, buffer, offset, copyCount);
  29. pos += copyCount;
  30. available -= copyCount;
  31. return copyCount;
  32. }
  33. else
  34. {
  35. if (size >= buf.Length)
  36. {
  37. // read directly to buffer
  38. return stream.Read(buffer, offset, size);
  39. }
  40. else
  41. {
  42. // read to buf and copy
  43. pos = 0;
  44. available = stream.Read(buf, 0, buf.Length);
  45. if (available > 0)
  46. return Read(buffer, offset, size);
  47. else
  48. return 0;
  49. }
  50. }
  51. }
  52. public override int ReadByte()
  53. {
  54. if (available > 0)
  55. {
  56. available -= 1;
  57. pos += 1;
  58. return buf[pos - 1];
  59. }
  60. else
  61. {
  62. try
  63. {
  64. available = stream.Read(buf, 0, buf.Length);
  65. pos = 0;
  66. }
  67. catch
  68. {
  69. return -1;
  70. }
  71. if (available < 1)
  72. {
  73. return -1;
  74. }
  75. else
  76. {
  77. available -= 1;
  78. pos += 1;
  79. return buf[pos - 1];
  80. }
  81. }
  82. }
  83. protected override void Dispose(bool disposing)
  84. {
  85. if (disposing && buf != null)
  86. BufferPool.Release(buf);
  87. buf = null;
  88. }
  89. public override bool CanRead
  90. {
  91. get { return true; }
  92. }
  93. public override bool CanSeek
  94. {
  95. get { throw new NotImplementedException(); }
  96. }
  97. public override bool CanWrite
  98. {
  99. get { throw new NotImplementedException(); }
  100. }
  101. public override long Length
  102. {
  103. get { throw new NotImplementedException(); }
  104. }
  105. public override long Position
  106. {
  107. get { throw new NotImplementedException(); }
  108. set { throw new NotImplementedException(); }
  109. }
  110. public override void Flush()
  111. {
  112. throw new NotImplementedException();
  113. }
  114. public override long Seek(long offset, SeekOrigin origin)
  115. {
  116. throw new NotImplementedException();
  117. }
  118. public override void SetLength(long value)
  119. {
  120. throw new NotImplementedException();
  121. }
  122. public override void Write(byte[] buffer, int offset, int count)
  123. {
  124. throw new NotImplementedException();
  125. }
  126. }
  127. }