private const int Width_Limit = 1000000; // Note: -Width_Limit < ArgAlign < Width_Limit internal StringBuilder AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args) { if (format == null) { throw new ArgumentNullException("format"); } Contract.Ensures(Contract.Result<StringBuilder>() != null); Contract.EndContractBlock(); int pos = 0; int len = format.Length; char ch = '\x0'; StringBuilder unescapedItemFormat = null; ICustomFormatter cf = null; if (provider != null) { cf = (ICustomFormatter)provider.GetFormat(typeof(ICustomFormatter)); } while (true) { while (pos < len) { ch = format[pos]; pos++; // Is it a closing brace? if (ch == '}') { // Check next character (if there is one) to see if it is escaped. eg }} if (pos < len && format[pos] == '}') pos++; else // Otherwise treat it as an error (Mismatched closing brace) FormatError(); } // Is it a opening brace? if (ch == '{') { // Check next character (if there is one) to see if it is escaped. eg {{ if (pos < len && format[pos] == '{') pos++; else { // Otherwise treat it as the opening brace of an Argument Hole. pos--; break; } } // If it neither then treat the character as just text. Append(ch); } // // Start of parsing of Argument Hole. // Argument Hole ::= { Index (, WS* Alignment WS*)? (: Formatting)? } // if (pos == len) break; // // Start of parsing required Index parameter. // Index ::= ('0'-'9')+ WS* // pos++; // If reached end of text then error (Unexpected end of text) // or character is not a digit then error (Unexpected Character) if (pos == len || (ch = format[pos]) < '0' || ch > '9') FormatError(); int index = 0; do { index = index * 10 + ch - '0'; pos++; // If reached end of text then error (Unexpected end of text) if (pos == len) FormatError(); ch = format[pos]; // so long as character is digit and value of the index is less than 1000000 ( index limit ) } while (ch >= '0' && ch <= '9' && index < Index_Limit); // If value of index is not within the range of the arguments passed in then error (Index out of range) if (index >= args.Length) throw new FormatException(Environment.GetResourceString("Format_IndexOutOfRange")); // Consume optional whitespace. while (pos < len && (ch = format[pos]) == ' ') pos++; // End of parsing index parameter. // // Start of parsing of optional Alignment // Alignment ::= comma WS* minus? ('0'-'9')+ WS* // bool leftJustify = false; int width = 0; // Is the character a comma, which indicates the start of alignment parameter. if (ch == ',') { pos++; // Consume Optional whitespace while (pos < len && format[pos] == ' ') pos++; // If reached the end of the text then error (Unexpected end of text) if (pos == len) FormatError(); // Is there a minus sign? ch = format[pos]; if (ch == '-') { // Yes, then alignment is left justified. leftJustify = true; pos++; // If reached end of text then error (Unexpected end of text) if (pos == len) FormatError(); ch = format[pos]; } // If current character is not a digit then error (Unexpected character) if (ch < '0' || ch > '9') FormatError(); // Parse alignment digits. do { width = width * 10 + ch - '0'; pos++; // If reached end of text then error. (Unexpected end of text) if (pos == len) FormatError(); ch = format[pos]; // So long a current character is a digit and the value of width is less than 100000 ( width limit ) } while (ch >= '0' && ch <= '9' && width < Width_Limit); // end of parsing Argument Alignment } // Consume optional whitespace while (pos < len && (ch = format[pos]) == ' ') pos++; // // Start of parsing of optional formatting parameter. // Object arg = args[index]; String itemFormat = null; // Is current character a colon? which indicates start of formatting parameter. if (ch == ':') { pos++; int startPos = pos; while (true) { // If reached end of text then error. (Unexpected end of text) if (pos == len) FormatError(); ch = format[pos]; pos++; // Is character a opening or closing brace? if (ch == '}' || ch == '{') { if (ch == '{') { // Yes, is next character also a opening brace, then treat as escaped. eg {{ if (pos < len && format[pos] == '{') pos++; else // Error Argument Holes can not be nested. FormatError(); } else { // Yes, is next character also a closing brace, then treat as escaped. eg }} if (pos < len && format[pos] == '}') pos++; else { // No, then treat it as the closing brace of an Arg Hole. pos--; break; } } // Reaching here means the brace has been escaped // so we need to build up the format string in segments if (unescapedItemFormat == null) { unescapedItemFormat = new StringBuilder(); } unescapedItemFormat.Append(format, startPos, pos - startPos - 1); startPos = pos; } } if (unescapedItemFormat == null || unescapedItemFormat.Length == 0) { if (startPos != pos) { // There was no brace escaping, extract the item format as a single string itemFormat = format.Substring(startPos, pos - startPos); } } else { unescapedItemFormat.Append(format, startPos, pos - startPos); itemFormat = unescapedItemFormat.ToString(); unescapedItemFormat.Clear(); } } // If current character is not a closing brace then error. (Unexpected Character) if (ch != '}') FormatError(); // Construct the output for this arg hole. pos++; String s = null; if (cf != null) { s = cf.Format(itemFormat, arg, provider); } if (s == null) { IFormattable formattableArg = arg as IFormattable; if (formattableArg != null) { s = formattableArg.ToString(itemFormat, provider); } else if (arg != null) { s = arg.ToString(); } } // Append it to the final output of the Format String. if (s == null) s = String.Empty; int pad = width - s.Length; if (!leftJustify && pad > 0) Append(' ', pad); Append(s); if (leftJustify && pad > 0) Append(' ', pad); // Continue to parse other characters. } return this; }
public static string Format(IFormatProvider provider, string format, params /* 0x00000001800D4E50-0x00000001800D4E60 */ object[] args) => default; // 0x00000001808C5630-0x00000001808C5710 private static string FormatHelper(IFormatProvider provider, string format, ParamsArray args) => default; // 0x00000001808C51F0-0x00000001808C52D0
internal StringBuilder AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args) { if (format == null) { throw new ArgumentNullException("format"); } Contract.Ensures(Contract.Result<StringBuilder>() != null); Contract.EndContractBlock(); int pos = 0; int len = format.Length; char ch = '\x0'; ICustomFormatter cf = null; if (provider != null) { cf = (ICustomFormatter)provider.GetFormat(typeof(ICustomFormatter)); } while (true) { while (pos < len) { ch = format[pos]; pos++; if (ch == '}') { if (pos < len && format[pos] == '}') // Treat as escape character for }} pos++; else FormatError(); } if (ch == '{') { if (pos < len && format[pos] == '{') // Treat as escape character for {{ pos++; else { pos--; break; } } Append(ch); } if (pos == len) break; pos++; if (pos == len || (ch = format[pos]) < '0' || ch > '9') FormatError(); int index = 0; do { index = index * 10 + ch - '0'; pos++; if (pos == len) FormatError(); ch = format[pos]; } while (ch >= '0' && ch <= '9' && index < 1000000); if (index >= args.Length) throw new FormatException(Environment.GetResourceString("Format_IndexOutOfRange")); while (pos < len && (ch = format[pos]) == ' ') pos++; bool leftJustify = false; int width = 0; if (ch == ',') { pos++; while (pos < len && format[pos] == ' ') pos++; if (pos == len) FormatError(); ch = format[pos]; if (ch == '-') { leftJustify = true; pos++; if (pos == len) FormatError(); ch = format[pos]; } if (ch < '0' || ch > '9') FormatError(); do { width = width * 10 + ch - '0'; pos++; if (pos == len) FormatError(); ch = format[pos]; } while (ch >= '0' && ch <= '9' && width < 1000000); } while (pos < len && (ch = format[pos]) == ' ') pos++; Object arg = args[index]; StringBuilder fmt = null; if (ch == ':') { pos++; while (true) { if (pos == len) FormatError(); ch = format[pos]; pos++; if (ch == '{') { if (pos < len && format[pos] == '{') // Treat as escape character for {{ pos++; else FormatError(); } else if (ch == '}') { if (pos < len && format[pos] == '}') // Treat as escape character for }} pos++; else { pos--; break; } } if (fmt == null) { fmt = new StringBuilder(); } fmt.Append(ch); } } if (ch != '}') FormatError(); pos++; String sFmt = null; String s = null; if (cf != null) { if (fmt != null) { sFmt = fmt.ToString(); } s = cf.Format(sFmt, arg, provider); } if (s == null) { IFormattable formattableArg = arg as IFormattable; if (formattableArg != null) { if (sFmt == null && fmt != null) { sFmt = fmt.ToString(); } s = formattableArg.ToString(sFmt, provider); } else if (arg != null) { s = arg.ToString(); } } if (s == null) s = String.Empty; int pad = width - s.Length; if (!leftJustify && pad > 0) Append(' ', pad); Append(s); if (leftJustify && pad > 0) Append(' ', pad); } return this; }
internal StringBuilder AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args) { if (format == null) throw new ArgumentNullException("format"); int pos = 0; int len = format.Length; char ch = '\x0'; StringBuilder unescapedItemFormat = null; ICustomFormatter cf = null; if (provider != null) { cf = (ICustomFormatter)provider.GetFormat(typeof(ICustomFormatter)); } while (true) { while (pos < len) { ch = format[pos]; pos++; if (ch == '}') { if (pos < len && format[pos] == '}') // Treat as escape character for }} pos++; else FormatError(); } if (ch == '{') { if (pos < len && format[pos] == '{') // Treat as escape character for {{ pos++; else { pos--; break; } } Append(ch); } if (pos == len) break; pos++; if (pos == len || (ch = format[pos]) < '0' || ch > '9') FormatError(); int index = 0; do { index = index * 10 + ch - '0'; pos++; if (pos == len) FormatError(); ch = format[pos]; } while (ch >= '0' && ch <= '9' && index < 1000000); if (index >= args.Length) throw new FormatException(SR.Format_IndexOutOfRange); while (pos < len && (ch = format[pos]) == ' ') pos++; bool leftJustify = false; int width = 0; if (ch == ',') { pos++; while (pos < len && format[pos] == ' ') pos++; if (pos == len) FormatError(); ch = format[pos]; if (ch == '-') { leftJustify = true; pos++; if (pos == len) FormatError(); ch = format[pos]; } if (ch < '0' || ch > '9') FormatError(); do { width = width * 10 + ch - '0'; pos++; if (pos == len) FormatError(); ch = format[pos]; } while (ch >= '0' && ch <= '9' && width < 1000000); } while (pos < len && (ch = format[pos]) == ' ') pos++; Object arg = args[index]; String itemFormat = null; if (ch == ':') { pos++; int startPos = pos; while (true) { if (pos == len) FormatError(); ch = format[pos]; pos++; if (ch == '}' || ch == '{') { if (ch == '{') { if (pos < len && format[pos] == '{') // Treat as escape character for {{ pos++; else FormatError(); } else { if (pos < len && format[pos] == '}') // Treat as escape character for }} pos++; else { pos--; break; } } // Reaching here means the brace has been escaped // so we need to build up the format string in segments if (unescapedItemFormat == null) { unescapedItemFormat = new StringBuilder(); } unescapedItemFormat.Append(format, startPos, pos - startPos - 1); startPos = pos; } } if (unescapedItemFormat == null || unescapedItemFormat.Length == 0) { if (startPos != pos) { // There was no brace escaping, extract the item format as a single string itemFormat = format.Substring(startPos, pos - startPos); } } else { unescapedItemFormat.Append(format, startPos, pos - startPos); itemFormat = unescapedItemFormat.ToString(); unescapedItemFormat.Clear(); } } if (ch != '}') FormatError(); pos++; String s = null; if (cf != null) { s = cf.Format(itemFormat, arg, provider); } if (s == null) { IFormattable formattableArg = arg as IFormattable; if (formattableArg != null) { s = formattableArg.ToString(itemFormat, provider); } else if (arg != null) { s = arg.ToString(); } } if (s == null) s = String.Empty; int pad = width - s.Length; if (!leftJustify && pad > 0) Append(' ', pad); Append(s); if (leftJustify && pad > 0) Append(' ', pad); } return this; }