/// <summary> /// Parses the entity at the current position. /// Assumes that there is a <c>&</c> at the current position. /// </summary> private static string ParseEntity(Subject subj) { int match; string entity; int numericEntity; var origPos = subj.Position; match = Scanner.scan_entity(subj.Buffer, subj.Position, subj.Length - subj.Position, out entity, out numericEntity); if (match > 0) { subj.Position += match; if (entity != null) { entity = EntityDecoder.DecodeEntity(entity); if (entity != null) { return(entity); } return(subj.Buffer.Substring(origPos, match)); } else if (numericEntity > 0) { entity = EntityDecoder.DecodeEntity(numericEntity); if (entity != null) { return(entity); } } return("\uFFFD"); } else { subj.Position++; return("&"); } }
/// <summary> /// Destructively unescape a string: remove backslashes before punctuation or symbol characters. /// </summary> /// <param name="url">The string data that will be changed by unescaping any punctuation or symbol characters.</param> public static string Unescape(string url) { // remove backslashes before punctuation chars: int searchPos = 0; int lastPos = 0; int match; char c; char[] search = new[] { '\\', '&' }; StringBuilder sb = null; while ((searchPos = url.IndexOfAny(search, searchPos)) != -1) { c = url[searchPos]; if (c == '\\') { searchPos++; if (url.Length == searchPos) { break; } c = url[searchPos]; if (Utilities.IsEscapableSymbol(c)) { if (sb == null) { sb = new StringBuilder(url.Length); } sb.Append(url, lastPos, searchPos - lastPos - 1); lastPos = searchPos; } } else if (c == '&') { string namedEntity; int numericEntity; match = Scanner.scan_entity(url, searchPos, url.Length - searchPos, out namedEntity, out numericEntity); if (match == 0) { searchPos++; } else { searchPos += match; if (namedEntity != null) { var decoded = EntityDecoder.DecodeEntity(namedEntity); if (decoded != null) { if (sb == null) { sb = new StringBuilder(url.Length); } sb.Append(url, lastPos, searchPos - match - lastPos); sb.Append(decoded); lastPos = searchPos; } } else if (numericEntity > 0) { var decoded = EntityDecoder.DecodeEntity(numericEntity); if (decoded != null) { if (sb == null) { sb = new StringBuilder(url.Length); } sb.Append(url, lastPos, searchPos - match - lastPos); sb.Append(decoded); } else { if (sb == null) { sb = new StringBuilder(url.Length); } sb.Append(url, lastPos, searchPos - match - lastPos); sb.Append('\uFFFD'); } lastPos = searchPos; } } } } if (sb == null) { return(url); } sb.Append(url, lastPos, url.Length - lastPos); return(sb.ToString()); }