CharMemoryStream.cs 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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<LuaFileContent> ReadAllAsync(CancellationToken cancellationToken)
  43. {
  44. position = Buffer.Length;
  45. return new( new LuaFileContent(Buffer.ToArray()));
  46. }
  47. public override ValueTask<string?> ReadStringAsync(int count, CancellationToken cancellationToken)
  48. {
  49. cancellationToken .ThrowIfCancellationRequested();
  50. if (position >= Buffer.Length)
  51. {
  52. return new("");
  53. }
  54. var remaining = Buffer[position..];
  55. if (count > remaining.Length)
  56. {
  57. count = remaining.Length;
  58. }
  59. var result = remaining.Slice(0, count).ToString();
  60. position += count;
  61. return new(result);
  62. }
  63. public override void Dispose()
  64. {
  65. onDispose?.Invoke(this);
  66. onDispose = null;
  67. }
  68. public override long Seek(long offset, SeekOrigin origin)
  69. {
  70. unchecked
  71. {
  72. position = origin switch
  73. {
  74. SeekOrigin.Begin => (int)offset,
  75. SeekOrigin.Current => position + (int)offset,
  76. SeekOrigin.End => (int)(Buffer.Length + offset),
  77. _ => (int)IOThrowHelpers.ThrowArgumentExceptionForSeekOrigin()
  78. };
  79. }
  80. IOThrowHelpers.ValidatePosition(position, Buffer.Length);
  81. return position;
  82. }
  83. }