BufferedStream.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. //
  2. // System.IO.BufferedStream
  3. //
  4. // Author:
  5. // Matt Kimball ([email protected])
  6. //
  7. namespace System.IO {
  8. public sealed class BufferedStream : Stream {
  9. Stream m_stream;
  10. byte[] m_buffer;
  11. int m_buffer_pos;
  12. int m_buffer_read_ahead;
  13. bool m_buffer_reading;
  14. public BufferedStream(Stream stream) : this(stream, 4096) {
  15. }
  16. public BufferedStream(Stream stream, int buffer_size) {
  17. m_stream = stream;
  18. m_buffer = new byte[buffer_size];
  19. }
  20. public override bool CanRead {
  21. get {
  22. return m_stream.CanRead;
  23. }
  24. }
  25. public override bool CanWrite {
  26. get {
  27. return m_stream.CanWrite;
  28. }
  29. }
  30. public override bool CanSeek {
  31. get {
  32. return m_stream.CanSeek;
  33. }
  34. }
  35. public override long Length {
  36. get {
  37. return m_stream.Length;
  38. }
  39. }
  40. public override long Position {
  41. get {
  42. return m_stream.Position - m_buffer_read_ahead + m_buffer_pos;
  43. }
  44. set {
  45. Flush();
  46. m_stream.Position = value;
  47. }
  48. }
  49. public override void Close() {
  50. Flush();
  51. m_stream.Close();
  52. m_stream = null;
  53. m_buffer = null;
  54. }
  55. public override void Flush() {
  56. if (m_buffer_reading) {
  57. if (CanSeek)
  58. m_stream.Position = Position;
  59. } else {
  60. m_stream.Write(m_buffer, 0, m_buffer_pos);
  61. }
  62. m_buffer_read_ahead = 0;
  63. m_buffer_pos = 0;
  64. }
  65. public override long Seek(long offset, SeekOrigin origin) {
  66. Flush();
  67. return m_stream.Seek(offset, origin);
  68. }
  69. public override void SetLength(long value) {
  70. m_stream.SetLength(value);
  71. }
  72. public override int ReadByte() {
  73. byte[] b = new byte[1];
  74. if (Read(b, 0, 1) == 1) {
  75. return b[0];
  76. } else {
  77. return -1;
  78. }
  79. }
  80. public override void WriteByte(byte value) {
  81. byte[] b = new byte[1];
  82. b[0] = value;
  83. Write(b, 0, 1);
  84. }
  85. public override int Read(byte[] array, int offset, int count) {
  86. if (!m_buffer_reading) {
  87. Flush();
  88. m_buffer_reading = true;
  89. }
  90. if (count <= m_buffer_read_ahead - m_buffer_pos) {
  91. Array.Copy(m_buffer, m_buffer_pos, array, offset, count);
  92. m_buffer_pos += count;
  93. if (m_buffer_pos == m_buffer_read_ahead) {
  94. m_buffer_pos = 0;
  95. m_buffer_read_ahead = 0;
  96. }
  97. return count;
  98. }
  99. int ret = m_buffer_read_ahead - m_buffer_pos;
  100. Array.Copy(m_buffer, m_buffer_pos, array, offset, ret);
  101. m_buffer_pos = 0;
  102. m_buffer_read_ahead = 0;
  103. offset += ret;
  104. count -= ret;
  105. if (count >= m_buffer.Length) {
  106. ret += m_stream.Read(array, offset, count);
  107. } else {
  108. m_buffer_read_ahead = m_stream.Read(m_buffer, 0, m_buffer.Length);
  109. if (count < m_buffer_read_ahead) {
  110. Array.Copy(m_buffer, 0, array, offset, count);
  111. m_buffer_pos = count;
  112. ret += count;
  113. } else {
  114. Array.Copy(m_buffer, 0, array, offset, m_buffer_read_ahead);
  115. ret += m_buffer_read_ahead;
  116. m_buffer_read_ahead = 0;
  117. }
  118. }
  119. return ret;
  120. }
  121. public override void Write(byte[] array, int offset, int count) {
  122. if (m_buffer_reading) {
  123. Flush();
  124. m_buffer_reading = false;
  125. }
  126. if (m_buffer_pos + count >= m_buffer.Length) {
  127. Flush();
  128. m_stream.Write(array, offset, count);
  129. } else {
  130. Array.Copy(array, offset, m_buffer, m_buffer_pos, count);
  131. m_buffer_pos += count;
  132. }
  133. }
  134. }
  135. }