BufferedStream.cs 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. m_stream.Position = Position;
  58. } else {
  59. m_stream.Write(m_buffer, 0, m_buffer_pos);
  60. }
  61. m_buffer_read_ahead = 0;
  62. m_buffer_pos = 0;
  63. }
  64. public override long Seek(long offset, SeekOrigin origin) {
  65. Flush();
  66. return m_stream.Seek(offset, origin);
  67. }
  68. public override void SetLength(long value) {
  69. m_stream.SetLength(value);
  70. }
  71. public override int ReadByte() {
  72. byte[] b = new byte[1];
  73. if (Read(b, 0, 1) == 1) {
  74. return b[0];
  75. } else {
  76. return -1;
  77. }
  78. }
  79. public override void WriteByte(byte value) {
  80. byte[] b = new byte[1];
  81. b[0] = value;
  82. Write(b, 0, 1);
  83. }
  84. public override int Read(byte[] array, int offset, int count) {
  85. if (!m_buffer_reading) {
  86. Flush();
  87. m_buffer_reading = true;
  88. }
  89. if (count <= m_buffer_read_ahead - m_buffer_pos) {
  90. Array.Copy(m_buffer, m_buffer_pos, array, offset, count);
  91. m_buffer_pos += count;
  92. if (m_buffer_pos == m_buffer_read_ahead) {
  93. m_buffer_pos = 0;
  94. m_buffer_read_ahead = 0;
  95. }
  96. return count;
  97. }
  98. int ret = m_buffer_read_ahead - m_buffer_pos;
  99. Array.Copy(m_buffer, m_buffer_pos, array, offset, ret);
  100. m_buffer_pos = 0;
  101. m_buffer_read_ahead = 0;
  102. offset += ret;
  103. count -= ret;
  104. if (count >= m_buffer.Length) {
  105. ret += m_stream.Read(array, offset, count);
  106. } else {
  107. m_buffer_read_ahead = m_stream.Read(m_buffer, 0, m_buffer.Length);
  108. if (count < m_buffer_read_ahead) {
  109. Array.Copy(m_buffer, 0, array, offset, count);
  110. m_buffer_pos = count;
  111. ret += count;
  112. } else {
  113. Array.Copy(m_buffer, 0, array, offset, m_buffer_read_ahead);
  114. ret += m_buffer_read_ahead;
  115. m_buffer_read_ahead = 0;
  116. }
  117. }
  118. return ret;
  119. }
  120. public override void Write(byte[] array, int offset, int count) {
  121. if (m_buffer_reading) {
  122. Flush();
  123. m_buffer_reading = false;
  124. }
  125. if (m_buffer_pos + count >= m_buffer.Length) {
  126. Flush();
  127. m_stream.Write(array, offset, count);
  128. } else {
  129. Array.Copy(array, offset, m_buffer, m_buffer_pos, count);
  130. m_buffer_pos += count;
  131. }
  132. }
  133. }
  134. }