private static Renderer ParseRenderer(StringEnumerator se) { var character = se.Pop(); var name = ParseRendererName(se); var renderer = CreateRendererInstance(name); character = se.Pop(); while (character != -1 && character != '}') { var parameterName = ParseParameterName(se).Trim(); if (se.Peek() == '=') { // Skip the `=` se.Pop(); var parameterValue = ParseParameterValue(se); SetPropertyValue(renderer, parameterName, parameterValue); } character = se.Pop(); } return(renderer); }
private static char GetUnicode(StringEnumerator se, int maxDigits) { var code = 0; for (var count = 0; count < maxDigits; count++) { var digitCode = se.Peek(); if (digitCode >= '0' && digitCode <= '9') { digitCode = digitCode - '0'; } else if (digitCode >= 'a' && digitCode <= 'f') { digitCode = digitCode - 'a' + 10; } else if (digitCode >= 'A' && digitCode <= 'F') { digitCode = digitCode - 'A' + 10; } else { break; } se.Pop(); code = code * 16 + digitCode; } return((char)code); }
private static string ParseParameterName(StringEnumerator se) { var parameterName = new StringBuilder(); int character; int nestLevel = 0; while ((character = se.Peek()) != -1) { if ((character == '=' || character == '}' || character == ':') && nestLevel == 0) { break; } switch (character) { case '$': se.Pop(); parameterName.Append('$'); if (se.Peek() == '{') { parameterName.Append('{'); nestLevel++; se.Pop(); } continue; case '}': nestLevel--; break; case '\\': // Skip the backslash se.Pop(); // Append next character parameterName.Append((char)se.Pop()); continue; } parameterName.Append((char)character); se.Pop(); } return(parameterName.ToString()); }
private static string ParseRendererName(StringEnumerator se) { var name = new StringBuilder(); int character; while ((character = se.Peek()) != -1) { if (character == ':' || character == '}') { break; } name.Append((char)character); se.Pop(); } return(name.ToString()); }
public static List <Renderer> CompileRenderers(StringEnumerator se, bool isNested, out string text) { var renderers = new List <Renderer>(); var literal = new StringBuilder(); int character; int startPosition = se.Position; while ((character = se.Peek()) != -1) { if (isNested) { // Possible escape char `\` if (character == '\\') { se.Pop(); var nextChar = se.Peek(); // Escape chars if (IsEndOfRenderer(nextChar)) { // Read next char and append se.Pop(); literal.Append((char)nextChar); } else { // Don't treat `\` as escape char literal.Append('\\'); } continue; } if (IsEndOfRenderer(character)) { // End of inner renderer. // `}` is when double nested inner renderer. // `:` when single nested renderer break; } } se.Pop(); // Detect `${` (indicates a new renderer) if (character == '$' && se.Peek() == '{') { AddLiteral(literal, renderers); var newRenderer = ParseRenderer(se); if (CanBeConvertedToLiteral(newRenderer)) { newRenderer = ConvertToLiteral(newRenderer); } renderers.Add(newRenderer); } else { literal.Append((char)character); } } AddLiteral(literal, renderers); var endPosition = se.Position; MergeLiterals(renderers); text = se.Substring(startPosition, endPosition); return(renderers); }
private static string ParseParameterValue(StringEnumerator se) { var value = new StringBuilder(); int character; while ((character = se.Peek()) != -1) { if (character == ':' || character == '}') { break; } // Code in this condition was replaced // to support escape codes e.g. '\r' '\n' '\u003a', // which can not be used directly as they are used as tokens by the parser // All escape codes listed in the following link were included // in addition to "\{", "\}", "\:" which are NLog specific: // http://blogs.msdn.com/b/csharpfaq/archive/2004/03/12/what-character-escape-sequences-are-available.aspx if (character == '\\') { // Skip the backslash se.Pop(); var nextChar = (char)se.Peek(); switch (nextChar) { case ':': case '{': case '}': case '\'': case '"': case '\\': se.Pop(); value.Append(nextChar); break; case '0': se.Pop(); value.Append('\0'); break; case 'a': se.Pop(); value.Append('\a'); break; case 'b': se.Pop(); value.Append('\b'); break; case 'f': se.Pop(); value.Append('\f'); break; case 'n': se.Pop(); value.Append('\n'); break; case 'r': se.Pop(); value.Append('\r'); break; case 't': se.Pop(); value.Append('\t'); break; case 'u': se.Pop(); value.Append(GetUnicode(se, 4)); // 4 digits break; case 'U': se.Pop(); value.Append(GetUnicode(se, 8)); // 8 digits break; case 'x': se.Pop(); value.Append(GetUnicode(se, 4)); // 1-4 digits break; case 'v': se.Pop(); value.Append('\v'); break; } continue; } value.Append((char)character); se.Pop(); } return(value.ToString()); }