StringHelper.cs 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. using System.Diagnostics.CodeAnalysis;
  2. using System.Runtime.CompilerServices;
  3. using System.Text;
  4. namespace Lua.Internal;
  5. internal static class StringHelper
  6. {
  7. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  8. public static ReadOnlySpan<char> Slice(string s, int i, int j)
  9. {
  10. if (i < 0) i = s.Length + i + 1;
  11. if (j < 0) j = s.Length + j + 1;
  12. if (i < 1) i = 1;
  13. if (j > s.Length) j = s.Length;
  14. return i > j ? "" : s.AsSpan()[(i - 1)..j];
  15. }
  16. public static bool TryFromStringLiteral(ReadOnlySpan<char> literal, [NotNullWhen(true)] out string? result)
  17. {
  18. var builder = new ValueStringBuilder(literal.Length);
  19. for (int i = 0; i < literal.Length; i++)
  20. {
  21. var c = literal[i];
  22. if (c is '\\' && i < literal.Length - 1)
  23. {
  24. i++;
  25. c = literal[i];
  26. switch (c)
  27. {
  28. case 'a':
  29. builder.Append('\a');
  30. break;
  31. case 'b':
  32. builder.Append('\b');
  33. break;
  34. case 'f':
  35. builder.Append('\f');
  36. break;
  37. case 'n':
  38. builder.Append('\n');
  39. break;
  40. case 'r':
  41. builder.Append('\r');
  42. break;
  43. case 't':
  44. builder.Append('\t');
  45. break;
  46. case 'v':
  47. builder.Append('\v');
  48. break;
  49. case '\\':
  50. builder.Append('\\');
  51. break;
  52. case '\"':
  53. builder.Append('\"');
  54. break;
  55. case '\'':
  56. builder.Append('\'');
  57. break;
  58. case '[':
  59. builder.Append('[');
  60. break;
  61. case ']':
  62. builder.Append(']');
  63. break;
  64. default:
  65. if (char.IsDigit(c))
  66. {
  67. var start = i;
  68. for (int j = 0; j < 3; j++)
  69. {
  70. i++;
  71. if (i >= literal.Length) break;
  72. c = literal[i];
  73. if (!char.IsDigit(c)) break;
  74. }
  75. Console.WriteLine((char)int.Parse(literal[start..i]));
  76. builder.Append((char)int.Parse(literal[start..i]));
  77. i--;
  78. }
  79. else
  80. {
  81. result = null;
  82. return false;
  83. }
  84. break;
  85. }
  86. }
  87. else
  88. {
  89. builder.Append(c);
  90. }
  91. }
  92. result = builder.ToString();
  93. return true;
  94. }
  95. }