/// <summary> /// Render a template to a string. /// </summary> /// <param name="template">The template.</param> /// <param name="formatProvider">Culture.</param> /// <param name="parameters">Parameters for the holes.</param> /// <param name="forceTemplateRenderer">Do not fallback to StringBuilder.Format for positional templates.</param> /// <param name="sb">The String Builder destination.</param> /// <param name="messageTemplateParameters">Parameters for the holes.</param> public static void Render(this string template, IFormatProvider formatProvider, object[] parameters, bool forceTemplateRenderer, StringBuilder sb, out IList <MessageTemplateParameter> messageTemplateParameters) { int pos = 0; int holeIndex = 0; messageTemplateParameters = null; TemplateEnumerator holeEnumerator = new TemplateEnumerator(template); while (holeEnumerator.MoveNext()) { var literal = holeEnumerator.Current.Literal; if (holeIndex == 0 && !forceTemplateRenderer && sb.Length == 0 && literal.Skip != 0 && holeEnumerator.Current.Hole.Index != -1) { // Not a template sb.AppendFormat(formatProvider, template, parameters); return; } sb.Append(template, pos, literal.Print); pos += literal.Print; if (literal.Skip == 0) { pos++; } else { pos += literal.Skip; var hole = holeEnumerator.Current.Hole; if (hole.Index != -1) { RenderHole(sb, hole, formatProvider, parameters[hole.Index], true); } else { var holeParameter = parameters[holeIndex]; if (messageTemplateParameters == null) { messageTemplateParameters = new MessageTemplateParameter[parameters.Length]; } messageTemplateParameters[holeIndex++] = new MessageTemplateParameter(hole.Name, holeParameter, hole.Format, hole.CaptureType); RenderHole(sb, hole, formatProvider, holeParameter); } } } if (messageTemplateParameters != null && holeIndex != messageTemplateParameters.Count) { var truncateParameters = new MessageTemplateParameter[holeIndex]; for (int i = 0; i < truncateParameters.Length; ++i) { truncateParameters[i] = messageTemplateParameters[i]; } messageTemplateParameters = truncateParameters; } }
/// <summary> /// Render a template to a string. /// </summary> /// <param name="template">The template.</param> /// <param name="formatProvider">Culture.</param> /// <param name="parameters">Parameters for the holes.</param> /// <param name="forceTemplateRenderer">Do not fallback to StringBuilder.Format for positional templates.</param> /// <param name="sb">The String Builder destination.</param> /// <param name="messageTemplateParameters">Parameters for the holes.</param> public static void Render(this string template, IFormatProvider formatProvider, object[] parameters, bool forceTemplateRenderer, StringBuilder sb, out IList <MessageTemplateParameter> messageTemplateParameters) { int pos = 0; int holeIndex = 0; int holeStartPosition = 0; messageTemplateParameters = null; int originalLength = sb.Length; TemplateEnumerator templateEnumerator = new TemplateEnumerator(template); while (templateEnumerator.MoveNext()) { if (holeIndex == 0 && !forceTemplateRenderer && templateEnumerator.Current.MaybePositionalTemplate && sb.Length == originalLength) { // Not a structured template sb.AppendFormat(formatProvider, template, parameters); return; } var literal = templateEnumerator.Current.Literal; sb.Append(template, pos, literal.Print); pos += literal.Print; if (literal.Skip == 0) { pos++; } else { pos += literal.Skip; var hole = templateEnumerator.Current.Hole; if (hole.Alignment != 0) { holeStartPosition = sb.Length; } if (hole.Index != -1 && messageTemplateParameters == null) { holeIndex++; RenderHole(sb, hole, formatProvider, parameters[hole.Index], true); } else { var holeParameter = parameters[holeIndex]; if (messageTemplateParameters == null) { messageTemplateParameters = new MessageTemplateParameter[parameters.Length]; if (holeIndex != 0) { // rewind and try again templateEnumerator = new TemplateEnumerator(template); sb.Length = originalLength; holeIndex = 0; pos = 0; continue; } } messageTemplateParameters[holeIndex++] = new MessageTemplateParameter(hole.Name, holeParameter, hole.Format, hole.CaptureType); RenderHole(sb, hole, formatProvider, holeParameter); } if (hole.Alignment != 0) { RenderPadding(sb, hole.Alignment, holeStartPosition); } } } if (messageTemplateParameters != null && holeIndex != messageTemplateParameters.Count) { var truncateParameters = new MessageTemplateParameter[holeIndex]; for (int i = 0; i < truncateParameters.Length; ++i) { truncateParameters[i] = messageTemplateParameters[i]; } messageTemplateParameters = truncateParameters; } }
/// <summary> /// Create MessageTemplateParameter from <paramref name="parameters"/> /// </summary> /// <param name="parameters"></param> /// <param name="hasParameters">is <paramref name="parameters"/> filled? (parameter for performance)</param> /// <returns></returns> private MessageTemplateParameter[] CreateParameters(object[] parameters, bool hasParameters) { if (hasParameters) { var templateParameters = new MessageTemplateParameter[parameters.Length]; for (int i = 0; i < parameters.Length; ++i) { string parameterName; switch (i) { //prevent creating a string (int.ToString()) case 0: parameterName = "0"; break; case 1: parameterName = "1"; break; case 2: parameterName = "2"; break; case 3: parameterName = "3"; break; case 4: parameterName = "4"; break; case 5: parameterName = "5"; break; case 6: parameterName = "6"; break; case 7: parameterName = "7"; break; case 8: parameterName = "8"; break; case 9: parameterName = "9"; break; default: parameterName = i.ToString(System.Globalization.CultureInfo.InvariantCulture); break; } templateParameters[i] = new MessageTemplateParameter(parameterName, parameters[i], null); } return(templateParameters); } return(Internal.ArrayHelper.Empty <MessageTemplateParameter>()); }