CharMemoryStream.cs 2.9 KB

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