PatientFileStream.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. using System.IO;
  2. namespace WinSCP
  3. {
  4. internal class PatientFileStream : Stream
  5. {
  6. public PatientFileStream(Session session, string path, FileMode mode, FileAccess access, FileShare share)
  7. {
  8. _stream = new FileStream(path, mode, access, share);
  9. _session = session;
  10. }
  11. private const int InitialInterval = 50;
  12. public override int Read(byte[] array, int offset, int count)
  13. {
  14. int result;
  15. int interval = InitialInterval;
  16. do
  17. {
  18. result = _stream.Read(array, offset, count);
  19. if (result == 0)
  20. {
  21. Wait(ref interval);
  22. }
  23. else
  24. {
  25. _session.Logger.WriteLineLevel(2, "Read {0} bytes from log", result);
  26. }
  27. }
  28. // We always want to return something.
  29. // No attempt to detect real end of file is needed,
  30. // as we should not try to read beyond the final closing tag
  31. while (result == 0);
  32. return result;
  33. }
  34. private void Wait(ref int interval)
  35. {
  36. _session.Logger.WriteLine("Waiting for log update and dispatching events for {0}", interval);
  37. _session.DispatchEvents(interval);
  38. _session.CheckForTimeout();
  39. if (interval < 500)
  40. {
  41. interval *= 2;
  42. }
  43. }
  44. public override void Flush()
  45. {
  46. throw _session.Logger.WriteException(new System.NotImplementedException());
  47. }
  48. public override long Seek(long offset, SeekOrigin origin)
  49. {
  50. throw _session.Logger.WriteException(new System.NotImplementedException());
  51. }
  52. public override void SetLength(long value)
  53. {
  54. throw _session.Logger.WriteException(new System.NotImplementedException());
  55. }
  56. public override void Write(byte[] buffer, int offset, int count)
  57. {
  58. throw _session.Logger.WriteException(new System.NotImplementedException());
  59. }
  60. public override bool CanRead
  61. {
  62. get
  63. {
  64. bool result = _stream.CanRead;
  65. _session.Logger.WriteLineLevel(2, "Can read = {0}", result);
  66. return result;
  67. }
  68. }
  69. public override bool CanSeek
  70. {
  71. get
  72. {
  73. bool result = _stream.CanSeek;
  74. _session.Logger.WriteLineLevel(2, "Can seek = {0}", result);
  75. return result;
  76. }
  77. }
  78. public override bool CanWrite => false;
  79. public override long Length
  80. {
  81. get
  82. {
  83. long result = _stream.Length;
  84. if (result == 0)
  85. {
  86. _session.Logger.WriteLineLevel(2, "File is empty yet, waiting", result);
  87. int interval = InitialInterval;
  88. do
  89. {
  90. result = _stream.Length;
  91. if (result == 0)
  92. {
  93. Wait(ref interval);
  94. }
  95. else
  96. {
  97. _session.Logger.WriteLineLevel(2, "File length = {0}", result);
  98. }
  99. }
  100. while (result == 0);
  101. }
  102. return result;
  103. }
  104. }
  105. public override long Position
  106. {
  107. get
  108. {
  109. long result = _stream.Length;
  110. _session.Logger.WriteLineLevel(2, "File position = {0}", result);
  111. return result;
  112. }
  113. set
  114. {
  115. _session.Logger.WriteLineLevel(2, "Setting file position to {0}", value);
  116. _stream.Position = value;
  117. }
  118. }
  119. private FileStream _stream;
  120. private Session _session;
  121. }
  122. }