private Tuple <string, List <NameValuePair> > ParseElement(ParserContext ctx) { if (ctx.Current != SyslogChars.Lbr) { return(null); } ctx.Position++; var elemName = ctx.ReadWord(); ctx.SkipSpaces(); var paramList = new List <NameValuePair>(); var elem = new Tuple <string, List <NameValuePair> >(elemName, paramList); while (ctx.Current != SyslogChars.Rbr) { var paramName = ctx.ReadWord(); ctx.ReadSymbol('='); var paramValue = ctx.ReadQuotedString(); var prm = new NameValuePair() { Name = paramName, Value = paramValue }; paramList.Add(prm); ctx.SkipSpaces(); } ctx.ReadSymbol(SyslogChars.Rbr); return(elem); }
public static string ReadQuotedString(this ParserContext ctx) { ctx.ReadSymbol(SyslogChars.DQuote); string result = string.Empty; int curr = ctx.Position; while (true) { var next = ctx.Text.IndexOfAny(SyslogChars.QuoteOrEscape, curr); var segment = ctx.Text.Substring(curr, next - curr); result += segment; switch (ctx.CharAt(next)) { case SyslogChars.DQuote: // we are done ctx.Position = next + 1; // after dquote return(result); case SyslogChars.Escape: // it is escape symbol, add next char to result, shift to next char and continue loop result += ctx.CharAt(next + 1); curr = next + 2; break; } //switch } // loop }
/// <summary>Parser standard (for all levels) prefix <n>. </summary> /// <param name="ctx">parser context.</param> /// <returns>True if prefix read correctly; otherwise, false.</returns> public static bool ReadSyslogPrefix(this ParserContext ctx) { try { ctx.Position = 0; ctx.ReadSymbol(SyslogChars.LT); var digits = ctx.ReadDigits(3); ctx.ReadSymbol(SyslogChars.GT); ctx.Prefix = ctx.Text.Substring(0, ctx.Position); return(true); } catch (Exception) { ctx.Position = 0; return(false); } }
} //method private List <NameValuePair> ReadKeyValuePairs(ParserContext ctx) { var prmList = new List <NameValuePair>(); NameValuePair lastPrm = null; /* * 2 troubles here: */ while (!ctx.Eof()) { ctx.SkipSpaces(); var name = ctx.ReadWord(); if (!ctx.ReadSymbol('=', throwIfMismatch: false)) { // Some entries are malformed: double quoted strings // the result is that we do not find '=' after closing the quote. So we just add the rest to a separate param and exit var text = ctx.Text.Substring(ctx.Position); prmList.Add(new NameValuePair() { Name = "Message", Value = text }); return(prmList); } ctx.SkipSpaces(); string value; if (ctx.Current == SyslogChars.DQuote) { // For double-quoted values, some values are malformed - they contain nested d-quoted strings that are not escaped. value = ctx.ReadQuotedString(); } else { // Special case: non quoted empty values, ex: ' a= b=234 '; value of 'a' is Empty. We check the char after we read the value, // and if it is '=', we back off, set value to empty. var saveP = ctx.Position; value = ctx.ReadWord(); if (ctx.Current == '=') { ctx.Position = saveP; value = string.Empty; } } lastPrm = new NameValuePair() { Name = name, Value = value }; prmList.Add(lastPrm); } return(prmList); }