CharMemoryStream.cs 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. using Lua.IO;
  2. namespace Lua.Tests.Helpers;
  3. internal sealed class ReadOnlyCharMemoryLuaIOStream(ReadOnlyMemory<char> buffer, Action<ReadOnlyCharMemoryLuaIOStream>? onDispose =null,object? state =null) : NotSupportedStreamBase
  4. {
  5. public readonly ReadOnlyMemory<char> Buffer = buffer;
  6. int position;
  7. public readonly object? State = state;
  8. Action<ReadOnlyCharMemoryLuaIOStream>? onDispose = onDispose;
  9. public static (string Result, int AdvanceCount) ReadLine(ReadOnlySpan<char> remaining)
  10. {
  11. int advanceCount;
  12. var line = remaining.IndexOfAny('\n', '\r');
  13. if (line == -1)
  14. {
  15. line = remaining.Length;
  16. advanceCount = line;
  17. }
  18. else
  19. {
  20. if (remaining[line] == '\r' && line + 1 < remaining.Length && remaining[line + 1] == '\n')
  21. {
  22. advanceCount = line + 2;
  23. }
  24. else
  25. {
  26. advanceCount = line + 1;
  27. }
  28. }
  29. return new(remaining[..line].ToString(), advanceCount);
  30. }
  31. public override ValueTask<string?> ReadLineAsync(CancellationToken cancellationToken)
  32. {
  33. if (position >= Buffer.Length)
  34. {
  35. return new(default(string));
  36. }
  37. var remaining = Buffer[position..];
  38. var (line, advanceCount) = ReadLine(remaining.Span);
  39. position += advanceCount;
  40. return new(line);
  41. }
  42. public override ValueTask<string> ReadAllAsync(CancellationToken cancellationToken)
  43. {
  44. var remaining = Buffer[position..];
  45. position = Buffer.Length;
  46. return new( remaining.ToString());
  47. }
  48. public override ValueTask<string?> ReadStringAsync(int count, CancellationToken cancellationToken)
  49. {
  50. cancellationToken .ThrowIfCancellationRequested();
  51. if (position >= Buffer.Length)
  52. {
  53. return new("");
  54. }
  55. var remaining = Buffer[position..];
  56. if (count > remaining.Length)
  57. {
  58. count = remaining.Length;
  59. }
  60. var result = remaining.Slice(0, count).ToString();
  61. position += count;
  62. return new(result);
  63. }
  64. public override void Dispose()
  65. {
  66. onDispose?.Invoke(this);
  67. onDispose = null;
  68. }
  69. public override long Seek(long offset, SeekOrigin origin)
  70. {
  71. unchecked
  72. {
  73. position = origin switch
  74. {
  75. SeekOrigin.Begin => (int)offset,
  76. SeekOrigin.Current => position + (int)offset,
  77. SeekOrigin.End => (int)(Buffer.Length + offset),
  78. _ => (int)IOThrowHelpers.ThrowArgumentExceptionForSeekOrigin()
  79. };
  80. }
  81. IOThrowHelpers.ValidatePosition(position, Buffer.Length);
  82. return position;
  83. }
  84. }