/// <summary> /// Process a parsed converter pattern /// </summary> /// <param name="converterName">the name of the converter</param> /// <param name="option">the optional option for the converter</param> /// <param name="formattingInfo">the formatting info for the converter</param> private void ProcessConverter(string converterName, string option, FormattingInfo formattingInfo) { LogLog.Debug(declaringType, "Converter [" + converterName + "] Option [" + option + "] Format [min=" + formattingInfo.Min + ",max=" + formattingInfo.Max + ",leftAlign=" + formattingInfo.LeftAlign + "]"); // Lookup the converter type ConverterInfo converterInfo = (ConverterInfo)m_patternConverters[converterName]; if (converterInfo == null) { LogLog.Error(declaringType, "Unknown converter name [" + converterName + "] in conversion pattern."); } else { // Create the pattern converter PatternConverter pc = null; try { pc = (PatternConverter)Activator.CreateInstance(converterInfo.Type); } catch (Exception createInstanceEx) { LogLog.Error(declaringType, "Failed to create instance of Type [" + converterInfo.Type.FullName + "] using default constructor. Exception: " + createInstanceEx.ToString()); } // formattingInfo variable is an instance variable, occasionally reset // and used over and over again pc.FormattingInfo = formattingInfo; pc.Option = option; pc.Properties = converterInfo.Properties; IOptionHandler optionHandler = pc as IOptionHandler; if (optionHandler != null) { optionHandler.ActivateOptions(); } AddConverter(pc); } }
/// <summary> /// Internal method to parse the specified pattern to find specified matches /// </summary> /// <param name="pattern">the pattern to parse</param> /// <param name="matches">the converter names to match in the pattern</param> /// <remarks> /// <para> /// The matches param must be sorted such that longer strings come before shorter ones. /// </para> /// </remarks> private void ParseInternal(string pattern, string[] matches) { int offset = 0; while (offset < pattern.Length) { int i = pattern.IndexOf('%', offset); if (i < 0 || i == pattern.Length - 1) { ProcessLiteral(pattern.Substring(offset)); offset = pattern.Length; } else { if (pattern[i + 1] == '%') { // Escaped ProcessLiteral(pattern.Substring(offset, i - offset + 1)); offset = i + 2; } else { ProcessLiteral(pattern.Substring(offset, i - offset)); offset = i + 1; FormattingInfo formattingInfo = new FormattingInfo(); // Process formatting options // Look for the align flag if (offset < pattern.Length) { if (pattern[offset] == '-') { // Seen align flag formattingInfo.LeftAlign = true; offset++; } } // Look for the minimum length while (offset < pattern.Length && char.IsDigit(pattern[offset])) { // Seen digit if (formattingInfo.Min < 0) { formattingInfo.Min = 0; } formattingInfo.Min = (formattingInfo.Min * 10) + int.Parse(pattern[offset].ToString(CultureInfo.InvariantCulture), System.Globalization.NumberFormatInfo.InvariantInfo); offset++; } // Look for the separator between min and max if (offset < pattern.Length) { if (pattern[offset] == '.') { // Seen separator offset++; } } // Look for the maximum length while (offset < pattern.Length && char.IsDigit(pattern[offset])) { // Seen digit if (formattingInfo.Max == int.MaxValue) { formattingInfo.Max = 0; } formattingInfo.Max = (formattingInfo.Max * 10) + int.Parse(pattern[offset].ToString(CultureInfo.InvariantCulture), System.Globalization.NumberFormatInfo.InvariantInfo); offset++; } int remainingStringLength = pattern.Length - offset; // Look for pattern for (int m = 0; m < matches.Length; m++) { if (matches[m].Length <= remainingStringLength) { if (String.Compare(pattern, offset, matches[m], 0, matches[m].Length, false, System.Globalization.CultureInfo.InvariantCulture) == 0) { // Found match offset = offset + matches[m].Length; string option = null; // Look for option if (offset < pattern.Length) { if (pattern[offset] == '{') { // Seen option start offset++; int optEnd = pattern.IndexOf('}', offset); if (optEnd < 0) { // error } else { option = pattern.Substring(offset, optEnd - offset); offset = optEnd + 1; } } } ProcessConverter(matches[m], option, formattingInfo); break; } } } } } } }