/// <summary> /// Unescapes a substring to the given string builder. /// </summary> static public void Unescape(string inString, int inStartIndex, int inLength, StringBuilder ioBuilder, ICustomEscapeEvaluator inCustomEscape = null) { if (inString == null || inLength <= 0) { return; } if (inStartIndex < 0 || inStartIndex >= inString.Length) { throw new ArgumentOutOfRangeException("Starting index is out of range"); } if (inStartIndex + inLength > inString.Length) { throw new ArgumentOutOfRangeException("Length extends beyond end of string"); } for (int idx = 0; idx < inLength; ++idx) { int realIdx = inStartIndex + idx; char c = inString[realIdx]; if (inCustomEscape != null) { int advance = 0; if (inCustomEscape.TryUnescape(c, inString, realIdx, out advance, ioBuilder)) { idx += advance; continue; } } if (c == '\\') { ++idx; ++realIdx; c = inString[realIdx]; switch (c) { case '0': ioBuilder.Append('\0'); break; case 'a': ioBuilder.Append('\a'); break; case 'v': ioBuilder.Append('\v'); break; case 't': ioBuilder.Append('\t'); break; case 'r': ioBuilder.Append('\r'); break; case 'n': ioBuilder.Append('\n'); break; case 'b': ioBuilder.Append('\b'); break; case 'f': ioBuilder.Append('\f'); break; case 'u': { string unicode = inString.Substring(realIdx + 1, 4); char code = (char)int.Parse(unicode, NumberStyles.AllowHexSpecifier); ioBuilder.Append(code); idx += 4; break; } default: ioBuilder.Append(c); break; } } else { ioBuilder.Append(c); } } }