| File: StringHelpers.cs | Web Access |
| Project: src\runtime\src\tools\ilasm\src\ILAssembler\ILAssembler.csproj (ILAssembler) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Text; namespace ILAssembler; /// <summary> /// Helper methods for parsing IL string literals. /// </summary> public static class StringHelpers { /// <summary> /// Parses an IL string literal, handling escape sequences. /// </summary> /// <param name="rawText">The raw token text including surrounding quotes.</param> /// <returns>The unescaped string value.</returns> public static string ParseQuotedString(string rawText) { if (rawText.Length < 2) { return string.Empty; } // Strip the surrounding quotes char quote = rawText[0]; if (quote != '"' && quote != '\'') { return rawText; } ReadOnlySpan<char> content = rawText.AsSpan(1, rawText.Length - 2); // Fast path: if no backslashes, return as-is if (!content.Contains('\\')) { return content.ToString(); } StringBuilder result = new(content.Length); int i = 0; while (i < content.Length) { char c = content[i]; if (c == '\\' && i + 1 < content.Length) { char next = content[i + 1]; switch (next) { case 't': result.Append('\t'); i += 2; break; case 'n': result.Append('\n'); i += 2; break; case 'r': result.Append('\r'); i += 2; break; case 'b': result.Append('\b'); i += 2; break; case 'f': result.Append('\f'); i += 2; break; case 'v': result.Append('\v'); i += 2; break; case 'a': result.Append('\a'); i += 2; break; case '?': result.Append('?'); i += 2; break; case '\\': result.Append('\\'); i += 2; break; case '"': result.Append('"'); i += 2; break; case '\'': result.Append('\''); i += 2; break; case '0': case '1': case '2': case '3': // Octal escape sequence (up to 3 digits) if (i + 3 < content.Length && IsOctalDigit(content[i + 2]) && IsOctalDigit(content[i + 3])) { int value = (next - '0') * 64 + (content[i + 2] - '0') * 8 + (content[i + 3] - '0'); result.Append((char)value); i += 4; } else if (next == '0') { // \0 alone is null character result.Append('\0'); i += 2; } else { // Not a valid octal sequence, just output the character result.Append(next); i += 2; } break; case '\n': // Line continuation - skip the backslash, newline, and any following whitespace i += 2; while (i < content.Length && char.IsWhiteSpace(content[i])) { i++; } break; default: // Unknown escape sequence - just output the character after backslash result.Append(next); i += 2; break; } } else { result.Append(c); i++; } } return result.ToString(); } private static bool IsOctalDigit(char c) => c >= '0' && c <= '7'; }