private void RegisterTemplates(SmartFormatter smart)
		{
			var templates = new TemplateFormatter(smart);
			smart.AddExtensions(templates);

			templates.Register("firstLast", "{First} {Last}");
			templates.Register("lastFirst", "{Last}, {First}");
			templates.Register("FIRST", "{First.ToUpper}");
			templates.Register("last", "{Last.ToLower}");

			if (smart.Settings.CaseSensitivity == CaseSensitivityType.CaseSensitive)
			{
				templates.Register("LAST", "{Last.ToUpper}");
			}

			templates.Register("NESTED", "{:template:FIRST} {:template:last}");
		}
 public FormatDetails(SmartFormatter formatter, object[] originalArgs, FormatCache formatCache, IFormatProvider provider)
 {
     Formatter = formatter;
     OriginalArgs = originalArgs;
     FormatCache = formatCache;
     Provider = provider;
 }
		public TemplateFormatter(SmartFormatter formatter)
		{
			_formatter = formatter;

			var stringComparer = (formatter.Settings.CaseSensitivity == CaseSensitivityType.CaseSensitive) ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
			_templates = new Dictionary<string, Format>(stringComparer);
		}
		public DictionarySource(SmartFormatter formatter)
		{
			// Add some special info to the parser:
			formatter.Parser.AddAlphanumericSelectors(); // (A-Z + a-z)
			formatter.Parser.AddAdditionalSelectorChars("_");
			formatter.Parser.AddOperators(".");
		}
		public TemplateFormatter(SmartFormatter formatter)
		{
			this.formatter = formatter;

			var stringComparer = (formatter.Settings.CaseSensitivity == CaseSensitivityType.CaseSensitive) ? StringComparer.InvariantCulture : StringComparer.InvariantCultureIgnoreCase;
			this.templates = new Dictionary<string, Format>(stringComparer);
		}
Example #6
0
        public void Templates_can_be_case_insensitive_and_overwrite_each_other(string format, string expected)
        {
            this._smart = Smart.CreateDefaultSmartFormat();
            this._smart.Settings.CaseSensitivity = CaseSensitivityType.CaseInsensitive;
            RegisterTemplates(this._smart);
            TestWithScottRippey(format, expected);

            // Reset:
            this.SetupSmart();
        }
Example #7
0
        /*********
        ** Protected methods
        *********/
        /// <summary>Construct a formatter instance with the natural time plugins registered.</summary>
        /// <param name="errorAction">How to handle format errors.</param>
        public SmartFormatter GetFormatter(ErrorAction?errorAction = null)
        {
            SmartFormatter formatter = Smart.CreateDefaultSmartFormat().AddExtensionsForNaturalTime();

            if (errorAction.HasValue)
            {
                formatter.ErrorAction = errorAction.Value;
            }
            return(formatter);
        }
 public void Init(SmartFormatter formatter, Format originalFormat, IList <object> originalArgs,
                  FormatCache formatCache, IFormatProvider provider, IOutput output)
 {
     Formatter      = formatter;
     OriginalFormat = originalFormat;
     OriginalArgs   = originalArgs;
     FormatCache    = formatCache;
     Provider       = provider;
     Output         = output;
 }
Example #9
0
 public FormatDetails(SmartFormatter formatter, Format originalFormat, object[] originalArgs,
                      FormatCache?formatCache, IFormatProvider?provider, IOutput output)
 {
     Formatter      = formatter;
     OriginalFormat = originalFormat;
     OriginalArgs   = originalArgs;
     FormatCache    = formatCache;
     Provider       = provider;
     Output         = output;
 }
        public void Format_JsonValue()
        {
            var smart = new SmartFormatter()
                        // removed DefaultSource in order to evaluate JValue
                        .AddExtensions(new NewtonsoftJsonSource())
                        .AddExtensions(new DefaultFormatter());
            var result = smart.Format("{0}", new JValue('v'));

            Assert.AreEqual("v", result);
        }
        private static SmartFormatter GetFormatterWithJsonSource(SmartSettings?settings = null)
        {
            var smart = new SmartFormatter(settings ?? new SmartSettings())
                        // SystemTextJsonSource MUST be registered before ReflectionSource (which is not required here)
                        // We also need the ListFormatter to process arrays
                        .AddExtensions(new ListFormatter(), new DefaultSource(), new SystemTextJsonSource())
                        .AddExtensions(new ListFormatter(), new NullFormatter(), new DefaultFormatter());

            return(smart);
        }
Example #12
0
        public void Parallel_Load_On_Specialized_Pools()
        {
            // Switch to thread safety
            const bool currentThreadSafeMode = true;
            var        savedIsThreadSafeMode = SmartSettings.IsThreadSafeMode;

            SmartSettings.IsThreadSafeMode = currentThreadSafeMode;
            ResetAllPools(currentThreadSafeMode);

            const int maxLoops = 100;
            var       options  = new ParallelOptions {
                MaxDegreeOfParallelism = 10
            };

            SmartSettings.IsThreadSafeMode = true;
            var list = new ConcurrentBag <string>();

            Assert.That(() =>
                        Parallel.For(1L, maxLoops, options, (i, loopState) =>
            {
                using var formatParsed = new Parser().ParseFormat("Number: {0:00000}");
                var smart = new SmartFormatter()
                            .AddExtensions(new DefaultSource())
                            .AddExtensions(new DefaultFormatter());
                list.Add(smart.Format(formatParsed, i));
            }), Throws.Nothing);

            var  result         = list.OrderBy(e => e);
            long compareCounter = 1;

            Assert.That(list.Count, Is.EqualTo(maxLoops - 1));
            Assert.That(result.All(r => r == $"Number: {compareCounter++:00000}"));

            foreach (var p in GetAllPoolCounters())
            {
                if (p.Counters !.CountAll <= 0)
                {
                    continue;
                }

                Console.WriteLine(p.Type + @":");
                Console.WriteLine(@"{0}: {1}", nameof(IPoolCounters.CountActive), p.Counters?.CountActive);
                Console.WriteLine(@"{0}: {1}", nameof(IPoolCounters.CountInactive), p.Counters?.CountInactive);

                Console.WriteLine();
                Assert.That(p.Counters !.CountActive, Is.EqualTo(0), string.Join(" ", nameof(IPoolCounters.CountActive), p.Type?.ToString()));
                Assert.That(p.Counters.CountInactive, Is.GreaterThan(0), string.Join(" ", nameof(IPoolCounters.CountInactive), p.Type?.ToString()));
            }

            // Restore thread safety
            SmartSettings.IsThreadSafeMode = savedIsThreadSafeMode;
            ResetAllPools(savedIsThreadSafeMode);

            Assert.That(PoolRegistry.Items.Count, Is.EqualTo(0), "PoolRegistry.Items");
        }
Example #13
0
        public void Add_Known_SourceExtensions_In_Recommended_Order()
        {
            var sf = new SmartFormatter();

            // Sources are in arbitrary order
            var allSources = GetExtensions <ISource>();

            // This should add sources to the list in the recommended order
            sf.AddExtensions(allSources.ToArray());

            var orderedSources = allSources.OrderBy(f => WellKnownExtensionTypes.Sources[f.GetType().FullName !])
Example #14
0
        private static Parser GetRegularParser()
        {
            var parser = new SmartFormatter()
            {
                Settings = { ParseErrorAction = ErrorAction.ThrowError }
            }.Parser;

            parser.AddAlphanumericSelectors();
            parser.AddOperators(".");
            return(parser);
        }
Example #15
0
        public void Create_Cache()
        {
            var sf     = new SmartFormatter();
            var format = new Format(sf.Settings, "the base string");
            var fc     = new FormatCache(format);

            Assert.AreEqual(format, fc.Format);
            Assert.IsAssignableFrom <Dictionary <string, object> >(fc.CachedObjects);
            fc.CachedObjects.Add("key", "value");
            Assert.IsTrue(fc.CachedObjects["key"].ToString() == "value");
        }
        public void Nullable_Property_Should_Return_Empty_String()
        {
            var smart = new SmartFormatter();

            smart.AddExtensions(new DefaultSource(), new ReflectionSource());
            smart.AddExtensions(new DefaultFormatter());
            var data = new { Person = new Person() };

            var result = smart.Format("{Person.Address?.City}", data);

            Assert.That(result, Is.Empty);
        }
Example #17
0
        /// <summary>
        /// Initializes the <see cref="FormatDetails"/> instance.
        /// </summary>
        /// <param name="formatter"></param>
        /// <param name="originalFormat"></param>
        /// <param name="originalArgs"></param>
        /// <param name="provider"></param>
        /// <param name="output"></param>
        /// <returns>This <see cref="FormatDetails"/> instance.</returns>
        public FormatDetails Initialize(SmartFormatter formatter, Format originalFormat, IList <object?> originalArgs,
                                        IFormatProvider?provider, IOutput output)
        {
            Formatter           = formatter;
            OriginalFormat      = originalFormat;
            OriginalArgs        = originalArgs;
            Provider            = provider;
            Output              = output;
            FormattingException = null;

            return(this);
        }
        public void TestLiteralStringCs()
        {
            var result = SmartFormatter.LiterallyInCs(Original);

            //should look like this
            var s = "我给你一本书 。" + Environment.NewLine +
                    "This has a   tab and \" quotes but this \t is not an escape";

            //Tab and quote is escaped, line is turned into NewLine
            Assert.AreEqual(@"""我给你一本书 。"" + Environment.NewLine + 
""This has a \t tab and \"" quotes but this \\t is not an escape""", result);
        }
        public void TestLiteralStringWithEmptyLinesVb()
        {
            var result = SmartFormatter.LiterallyInVb(@"
1

2
");

            //No verbatim in VB up to 14, so we just use literals with vbCrLf and line continuation
            //Arguably tab could be vbTab
            //You could use xml literals...
            Assert.AreEqual("\"1\" & vbCrLf & _\r\nvbCrLf & _\r\n\"2\"", result);
        }
Example #20
0
        public TimeFormatterTests()
        {
            _smart = Smart.CreateDefaultSmartFormat();
            _smart.Settings.FormatErrorAction = ErrorAction.ThrowError;
            _smart.Settings.ParseErrorAction  = ErrorAction.ThrowError;

            _timeFormatter = _smart.FormatterExtensions.FirstOrDefault(fmt => fmt.Names.Contains("time")) as TimeFormatter;
            if (_timeFormatter == null)
            {
                _timeFormatter = new TimeFormatter("en");
                _smart.FormatterExtensions.Add(_timeFormatter);
            }
        }
        public void TestCommentCs()
        {
            var result = SmartFormatter.CommentizeInCs(Original);

            //should look like this
            //我给你一本书 。
            //This has a   tab and " quotes but this \t is not an escape

            //don't double quotes, just use line comment prefix
            //there's a trailing line break too
            Assert.AreEqual(@"//我给你一本书 。
//This has a " + "\t tab and \" quotes but this \\t is not an escape\r\n", result);
        }
Example #22
0
 public void Setup()
 {
     _formatter = new SmartFormatter();
     _formatter.AddExtensions(
         new ReflectionSource(_formatter),
         new DictionarySource(_formatter),
         new DefaultSource(_formatter));
     _formatter.AddExtensions(
         new PluralLocalizationFormatter("en"),
         new ConditionalFormatterEx(),
         new DefaultFormatterEx(true));
     _person = new TestPerson();
 }
Example #23
0
        public JsonSource(SmartFormatter formatter)
        {
            // Note: We only have ONE parser at a time.
            // These settings will affect all extensions loaded at the same time

            // Excaped JSON property names and special characters are not supported in
            // order to avoid interference with other extensions
            formatter.Parser.AddAlphanumericSelectors(); // (A-Z + a-z)
            formatter.Parser.AddAdditionalSelectorChars("_");
            // For JsonSource it would be optimal not to have any operators in place,
            // but we have a workaround, if they are set by other extensions
            // formatter.Parser.AddOperators(".");
        }
Example #24
0
        public void Setup()
        {
            _smartNullFormatter = new SmartFormatter();
            _smartNullFormatter.AddExtensions(new DefaultSource());
            _smartNullFormatter.AddExtensions(new NullFormatter(), new DefaultFormatter());

            _smartChooseFormatter = new SmartFormatter();
            _smartChooseFormatter.AddExtensions(new DefaultSource());
            _smartChooseFormatter.AddExtensions(new ChooseFormatter(), new DefaultFormatter());

            _nullFormatCache   = _smartNullFormatter.Parser.ParseFormat("{0:isnull:nothing}");
            _chooseFormatCache = _smartChooseFormatter.Parser.ParseFormat("{0:choose(null):nothing|}");
        }
        public void Test_Parameterless_Methods()
        {
            var format = "{0} {0.ToLower} {ToLower} {ToUpper}";
            //var expected = "Zero zero zero ZERO";

            var smart = new SmartFormatter()
                        .AddExtensions(new ReflectionSource(), new DefaultSource())
                        .AddExtensions(new DefaultFormatter());

            var args = GetArgs();

            Assert.That(() => smart.Format(format, args), Throws.Exception.TypeOf(typeof(FormattingException)).And.Message.Contains("ToLower"));
        }
        public void TestVerbatimStringCs()
        {
            var result = SmartFormatter.StringinizeInCs(Original);

            //should look like this
            var s = @"我给你一本书 。
This has a   tab and "" quotes but this \t is not an escape";

            //The line break is included, the double-quotes are doubled
            //In verbatim, tabs can't be escaped, so it's just included as a raw tab
            //a VS reformat may convert the tab to spaces
            Assert.AreEqual(@"@""我给你一本书 。
This has a " + "\t tab and \"\" quotes but this \\t is not an escape\"", result);
        }
Example #27
0
        public void Null_IList_Nullable_Should_Return_Null()
        {
            var smart = new SmartFormatter()
                        .AddExtensions(new ListFormatter(), new DefaultSource(), new ReflectionSource())
                        .AddExtensions(new DefaultFormatter());

            var data = new { Numbers = default(IList <object>?) };
            // Numbers are marked as nullable
            var indexResult1 = smart.Format(">{Numbers?.0}<", data);  // index method 1
            var indexResult2 = smart.Format(">{Numbers?[0]}<", data); // index method 2

            Assert.That(indexResult1, Is.EqualTo("><"));
            Assert.That(indexResult2, Is.EqualTo("><"));
        }
Example #28
0
        public TimeFormatterTests()
        {
            m_Smart = Smart.CreateDefaultSmartFormat();
            m_Smart.Settings.FormatErrorAction = ErrorAction.ThrowError;
            m_Smart.Settings.ParseErrorAction  = ErrorAction.ThrowError;

            m_TimeFormatter = m_Smart.FormatterExtensions.FirstOrDefault(fmt => fmt.Names.Contains("time")) as TimeFormatter;
            if (m_TimeFormatter == null)
            {
                m_TimeFormatter = new TimeFormatter();
                m_TimeFormatter.DefaultTwoLetterISOLanguageName = "en";
                m_Smart.FormatterExtensions.Add(m_TimeFormatter);
            }
        }
        public void Test_Methods_CaseInsensitive()
        {
            var smart = new SmartFormatter(new SmartSettings {
                CaseSensitivity = CaseSensitivityType.CaseInsensitive
            })
                        .AddExtensions(new ReflectionSource())
                        .AddExtensions(new DefaultFormatter());

            var format = "{0} {0.ToLower} {toloWer} {touPPer}";
            //var expected = "Zero zero zero ZERO";
            var args = GetArgs();

            Assert.That(() => smart.Format(format, args), Throws.Exception.TypeOf(typeof(FormattingException)).And.Message.Contains("ToLower"));
        }
Example #30
0
 public static void Test(this SmartFormatter formatter, string format, object[] args, string expected)
 {
     string actual = null;
     try
     {
         actual = formatter.Format(format, args);
         Assert.AreEqual(expected, actual);
         Console.WriteLine("Success: \"{0}\" => \"{1}\"", format, actual);
     }
     catch (Exception ex)
     {
         Console.WriteLine("Error: \"{0}\" => \"{1}\" - {2}", format, actual, ex.Message);
         throw;
     }
 }
Example #31
0
        public void Objects_Not_Implementing_IList_Are_Not_Processed()
        {
            var items = new[] { "one", "two", "three" };

            var formatter     = new SmartFormatter();
            var listFormatter = new ListFormatter(formatter);

            formatter.SourceExtensions.Add(listFormatter);
            formatter.FormatterExtensions.Add(listFormatter);
            formatter.SourceExtensions.Add(new DefaultSource(formatter));
            formatter.FormatterExtensions.Add(new DefaultFormatter());

            Assert.AreEqual("one, two, and three", formatter.Format("{0:list:{}|, |, and }", new object[] { items }));
            Assert.Throws <FormattingException>(() => formatter.Format("{0:list:{}|, |, and }", new { Index = 100 })); // no formatter found
        }
        public void TestStringBuilderCs()
        {
            var result = SmartFormatter.StringbuilderizeInCs(Original, "sb");

            //should look like this
            var sb = new System.Text.StringBuilder(68);

            sb.AppendLine(@"我给你一本书 。");
            sb.AppendLine(@"This has a   tab and "" quotes but this \t is not an escape");

            //the single " becomes doubled, which becomes 4 here
            Assert.AreEqual(@"var sb = new System.Text.StringBuilder(68);
sb.AppendLine(@""我给你一本书 。"");
sb.AppendLine(@""This has a      tab and """" quotes but this \t is not an escape"");
", result);
        }
        public void TestLiteralStringWithEmptyLinesCs()
        {
            var result = SmartFormatter.LiterallyInCs(@"
1

2
");

            //should look like this
            var s = "1" + Environment.NewLine +
                    Environment.NewLine +
                    "2";

            //Tab and quote is escaped, line is turned into NewLine
            Assert.AreEqual("\"1\" + Environment.NewLine + \r\n\"\" + Environment.NewLine + \r\n\"2\"", result);
        }
Example #34
0
        public void Null_IList_Not_Nullable_Should_Throw()
        {
            var smart = new SmartFormatter()
                        .AddExtensions(new ListFormatter(), new DefaultSource(), new ReflectionSource())
                        .AddExtensions(new DefaultFormatter());

            var data = new { Numbers = default(IList <object>?) };

            // Numbers are NOT marked as nullable
            Assert.That(() => smart.Format(">{Numbers.0}<", data),
                        Throws.Exception.TypeOf <FormattingException>().And.Message
                        .Contains("{Numbers.0}"));
            Assert.That(() => smart.Format(">{Numbers[0]}<", data),
                        Throws.Exception.TypeOf <FormattingException>().And.Message
                        .Contains("{Numbers[0]}"));
        }
        public SubStringFormatterTests()
        {
            _smart = Smart.CreateDefaultSmartFormat();
            _smart.Settings.FormatErrorAction = ErrorAction.ThrowError;
            _smart.Settings.ParseErrorAction  = ErrorAction.ThrowError;

            if (_smart.FormatterExtensions.FirstOrDefault(fmt => fmt.Names.Contains("substr")) == null)
            {
                _smart.FormatterExtensions.Add(new SubStringFormatter());
            }

            _people = new List <object>
            {
                new { Name = "Long John", City = "New York" }, new { Name = "Short Mary", City = "Massachusetts" },
            };
        }
		public void Templates_can_be_case_insensitive_and_overwrite_each_other(string format, string expected)
		{
			this.smart = Smart.CreateDefaultSmartFormat();
			this.smart.Settings.CaseSensitivity = CaseSensitivityType.CaseInsensitive;
			RegisterTemplates(this.smart);
			TestWithScottRippey(format, expected);

			// Reset:
			this.SetupSmart();
		}
		public void EscapingSlashBraces()
		{
			var Smart = new SmartFormatter();
			Smart.Parser.UseAlternativeEscapeChar('\\');
			Smart.AddExtensions(new DefaultFormatter());
			Smart.AddExtensions(new DefaultSource(Smart));

			var args = new object[] { "Zero", "One", "Two", 3 };

			var format = @"{0} \{0\} \{{0}\} {3:00\}} {3:00}\}";
			var expected = "Zero {0} {Zero} 03} 03}";

			var actual = Smart.Format(format, args);
			Assert.AreEqual(expected, actual);
		}
		private SmartFormatter GetCustomFormatter()
		{
			var testFormatter = new SmartFormatter();
			testFormatter.AddExtensions(new TestExtension1(), new TestExtension2(), new DefaultFormatter());
			testFormatter.AddExtensions(new DefaultSource(testFormatter));
			return testFormatter;
		}
		public ListFormatter(SmartFormatter formatter)
		{
			formatter.Parser.AddOperators("[]()");
		}
Example #40
0
        public void PerformanceTest_ComparedTo_StringFormat()
        {
            // Create the most basic formatter:
            //var Smart = new SmartFormatter();
            //Smart.AddExtensions(
            //    new DefaultFormatter(),
            //    new DefaultSource()
            //);

            // Setup the test criteria:
            var tests = new[]{
                new { title = "Test - No Placeholders",
                      format = "No Placeholders",
                      expected = "No Placeholders",
                },
                new { title = "Test - Very simple",
                      format = "Zero: '{0}'",
                      expected = "Zero: 'Zero'",
                },
                new { title = "Test - Format a number",
                      format = "One: {1:N2}",
                      expected = "One: 1.00",
                },
                new { title = "Test - Format a date",
                      format = "Two: {2:d}",
                      expected = "Two: 10/10/2010",
                },
                new { title = "Test - All Three",
                      format = "Zero: '{0}' One: {1:N2} Two: {2:d}",
                      expected = "Zero: 'Zero' One: 1.00 Two: 10/10/2010",
                },
                new { title = "Test - Lengthy format string",
                      format = "Zero: '{0}'    One: {1:N2} / {1:000} / {1:###}    Two: {2:d} / {2:D} / {2:ddd, MMM d, ''yy} / {2:t}           Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ",
                      expected = "Zero: 'Zero'    One: 1.00 / 001 / 001    Two: 10/10/2010 / Sunday, October 10, 2010 / Sun, Oct 10, '10 / 12:00:00 am           Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. ",
                },
            };
            var args = new object[] { "Zero", 1, new DateTime(2010, 10, 10) };

            FormatCache cache = null;
            FormatCache cache2 = null;
            var NoExtensions = new SmartFormatter();
            NoExtensions.AddExtensions(new DefaultFormatter(), new DefaultSource(NoExtensions));

            var formatters = new[] {
                new {
                    Title = "String.Format",
                    Function = new Func<string, object[], string>(string.Format),
                },
                new {
                    Title = "Smart.Format",
                    Function = new Func<string, object[], string>(Smart.Format),
                },
                new {
                    Title = "NoExtensions.Format",
                    Function = new Func<string, object[], string>(NoExtensions.Format),
                },
                new {
                    Title = "Smart.FormatWithCache",
                    Function = new Func<string, object[], string>((format, args2) => Smart.Default.FormatWithCache(ref cache, format, args2)),
                },
                new {
                    Title = "NoExtensions.FormatWithCache",
                    Function = new Func<string, object[], string>((format, args2) => NoExtensions.FormatWithCache(ref cache2, format, args2)),
                },
            };

            const int iterations = 100000;
            foreach (var test in tests)
            {
                cache = null;
                cache2 = null;
                var results = TestHelpers.PerformanceTest(formatters.Select(f => f.Function).ToArray(), test.format, args, iterations);

                // Compare the results:
                Console.WriteLine("{0} Results: \"{1}\" => \"{2}\"", test.title, test.format, test.expected);
                var baseSeconds = results[0].TotalSeconds;
                Console.WriteLine("Test Function        Ratio to String.Format  Actual time taken");
                for (int i = 0; i < formatters.Length; i++)
                {
                    var f = formatters[i];
                    var r = results[i];
                    Console.WriteLine("{0,-25}   1 : {3:N2}   {2:N1}µs per iteration {1:N2}s total)", f.Title, r.TotalSeconds, r.TotalSeconds * (double)1000000 / iterations, r.TotalSeconds / baseSeconds);
                }
                Console.WriteLine();
            }
        }
 public DefaultSource(SmartFormatter formatter)
 {
     formatter.Parser.AddOperators(","); // This is for alignment.
     formatter.Parser.AddAdditionalSelectorChars("-"); // This is for alignment.
 }
		public void SetupSmart()
		{
			this.smart = Smart.CreateDefaultSmartFormat();
			RegisterTemplates(this.smart);
		}
Example #43
-1
		public FormatDetails(SmartFormatter formatter, Format originalFormat, object[] originalArgs, FormatCache formatCache, IFormatProvider provider, IOutput output)
		{
			Formatter = formatter;
			OriginalFormat = originalFormat;
			OriginalArgs = originalArgs;
			FormatCache = formatCache;
			Provider = provider;
			Output = output;
		}