public string ToString(int fieldCount) => fieldCount == 0 ? string.Empty : fieldCount == 1 ? _Major.ToString() : StringBuilderCache.GetStringAndRelease(ToCachedStringBuilder(fieldCount));
public static void Log(String switchName, LogLevel level, params Object[] messages) { if (AppDomain.CurrentDomain.IsUnloadingForcedFinalize()) { return; } //Add code to check if logging is enabled in the registry. LogSwitch logSwitch; if (!m_registryChecked) { CheckRegistry(); } if (!CheckEnabled(switchName, level, out logSwitch)) { return; } StringBuilder sb = StringBuilderCache.Acquire(); for (int i = 0; i < messages.Length; i++) { String s; try { if (messages[i] == null) { s = "<null>"; } else { s = messages[i].ToString(); } } catch { s = "<unable to convert>"; } sb.Append(s); } System.Diagnostics.Log.LogMessage((LoggingLevels)((int)level), logSwitch, StringBuilderCache.GetStringAndRelease(sb)); }
/// <summary> /// Helper function that reads a string token from the serialized text. The function /// updates <see cref="_currentTokenStartIndex"/> to point to the next token on exit. /// Also <see cref="_state"/> is set to either <see cref="State.StartOfToken"/> or /// <see cref="State.EndOfLine"/> on exit. /// </summary> private string GetNextStringValue() { // first verify the internal state of the object if (_state == State.EndOfLine) { throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData")); } if (_currentTokenStartIndex < 0 || _currentTokenStartIndex >= _serializedText.Length) { throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData")); } State tokenState = State.NotEscaped; StringBuilder token = StringBuilderCache.Acquire(InitialCapacityForString); // walk the serialized text, building up the token as we go... for (int i = _currentTokenStartIndex; i < _serializedText.Length; i++) { if (tokenState == State.Escaped) { VerifyIsEscapableCharacter(_serializedText[i]); token.Append(_serializedText[i]); tokenState = State.NotEscaped; } else if (tokenState == State.NotEscaped) { switch (_serializedText[i]) { case Esc: tokenState = State.Escaped; break; case Lhs: // '[' is an unexpected character throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData")); case Rhs: // ']' is an unexpected character throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData")); case Sep: _currentTokenStartIndex = i + 1; if (_currentTokenStartIndex >= _serializedText.Length) { _state = State.EndOfLine; } else { _state = State.StartOfToken; } return(StringBuilderCache.GetStringAndRelease(token)); case '\0': // invalid character throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData")); default: token.Append(_serializedText[i]); break; } } } // // we are at the end of the line // if (tokenState == State.Escaped) { // we are at the end of the serialized text but we are in an escaped state throw new SerializationException(Environment.GetResourceString("Serialization_InvalidEscapeSequence", string.Empty)); } throw new SerializationException(Environment.GetResourceString("Serialization_InvalidData")); }
private static String InternalFlagsFormat(RuntimeType eT, TypeValuesAndNames entry, ulong result) { Contract.Requires(eT != null); String[] names = entry.Names; ulong[] values = entry.Values; Debug.Assert(names.Length == values.Length); int index = values.Length - 1; StringBuilder sb = StringBuilderCache.Acquire(); bool firstTime = true; ulong saveResult = result; // We will not optimize this code further to keep it maintainable. There are some boundary checks that can be applied // to minimize the comparsions required. This code works the same for the best/worst case. In general the number of // items in an enum are sufficiently small and not worth the optimization. while (index >= 0) { if ((index == 0) && (values[index] == 0)) { break; } if ((result & values[index]) == values[index]) { result -= values[index]; if (!firstTime) { sb.Insert(0, enumSeparatorString); } sb.Insert(0, names[index]); firstTime = false; } index--; } string returnString; if (result != 0) { // We were unable to represent this number as a bitwise or of valid flags returnString = null; // return null so the caller knows to .ToString() the input } else if (saveResult == 0) { // For the cases when we have zero if (values.Length > 0 && values[0] == 0) { returnString = names[0]; // Zero was one of the enum values. } else { returnString = "0"; } } else { returnString = sb.ToString(); // Return the string representation } StringBuilderCache.Release(sb); return(returnString); }
private static string FormatCustomized(DateTime dateTime, string format, DateTimeFormatInfo dtfi, TimeSpan offset) { Calendar calendar = dtfi.Calendar; StringBuilder stringBuilder1 = StringBuilderCache.Acquire(16); bool flag = calendar.ID == 8; bool timeOnly = true; int index1 = 0; while (index1 < format.Length) { char patternChar = format[index1]; int num1; if ((uint)patternChar <= 75U) { if ((uint)patternChar <= 47U) { if ((uint)patternChar <= 37U) { if ((int)patternChar != 34) { if ((int)patternChar == 37) { int nextChar = DateTimeFormat.ParseNextChar(format, index1); if (nextChar < 0 || nextChar == 37) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } stringBuilder1.Append(DateTimeFormat.FormatCustomized(dateTime, ((char)nextChar).ToString(), dtfi, offset)); num1 = 2; goto label_85; } else { goto label_84; } } } else if ((int)patternChar != 39) { if ((int)patternChar == 47) { stringBuilder1.Append(dtfi.DateSeparator); num1 = 1; goto label_85; } else { goto label_84; } } StringBuilder result = new StringBuilder(); num1 = DateTimeFormat.ParseQuoteString(format, index1, result); stringBuilder1.Append((object)result); goto label_85; } else if ((uint)patternChar <= 70U) { if ((int)patternChar != 58) { if ((int)patternChar != 70) { goto label_84; } } else { stringBuilder1.Append(dtfi.TimeSeparator); num1 = 1; goto label_85; } } else if ((int)patternChar != 72) { if ((int)patternChar == 75) { num1 = 1; DateTimeFormat.FormatCustomizedRoundripTimeZone(dateTime, offset, stringBuilder1); goto label_85; } else { goto label_84; } } else { num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); DateTimeFormat.FormatDigits(stringBuilder1, dateTime.Hour, num1); goto label_85; } } else if ((uint)patternChar <= 109U) { if ((uint)patternChar <= 92U) { if ((int)patternChar != 77) { if ((int)patternChar == 92) { int nextChar = DateTimeFormat.ParseNextChar(format, index1); if (nextChar < 0) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } stringBuilder1.Append((char)nextChar); num1 = 2; goto label_85; } else { goto label_84; } } else { num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); int month = calendar.GetMonth(dateTime); if (num1 <= 2) { if (flag) { DateTimeFormat.HebrewFormatDigits(stringBuilder1, month); } else { DateTimeFormat.FormatDigits(stringBuilder1, month, num1); } } else if (flag) { stringBuilder1.Append(DateTimeFormat.FormatHebrewMonthName(dateTime, month, num1, dtfi)); } else if ((dtfi.FormatFlags & DateTimeFormatFlags.UseGenitiveMonth) != DateTimeFormatFlags.None && num1 >= 4) { stringBuilder1.Append(dtfi.internalGetMonthName(month, DateTimeFormat.IsUseGenitiveForm(format, index1, num1, 'd') ? MonthNameStyles.Genitive : MonthNameStyles.Regular, false)); } else { stringBuilder1.Append(DateTimeFormat.FormatMonth(month, num1, dtfi)); } timeOnly = false; goto label_85; } } else { switch (patternChar) { case 'd': num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); if (num1 <= 2) { int dayOfMonth = calendar.GetDayOfMonth(dateTime); if (flag) { DateTimeFormat.HebrewFormatDigits(stringBuilder1, dayOfMonth); } else { DateTimeFormat.FormatDigits(stringBuilder1, dayOfMonth, num1); } } else { int dayOfWeek = (int)calendar.GetDayOfWeek(dateTime); stringBuilder1.Append(DateTimeFormat.FormatDayOfWeek(dayOfWeek, num1, dtfi)); } timeOnly = false; goto label_85; case 'f': break; case 'g': num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); stringBuilder1.Append(dtfi.GetEraName(calendar.GetEra(dateTime))); goto label_85; case 'h': num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); int num2 = dateTime.Hour % 12; if (num2 == 0) { num2 = 12; } DateTimeFormat.FormatDigits(stringBuilder1, num2, num1); goto label_85; case 'm': num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); DateTimeFormat.FormatDigits(stringBuilder1, dateTime.Minute, num1); goto label_85; default: goto label_84; } } } else if ((uint)patternChar <= 116U) { if ((int)patternChar != 115) { if ((int)patternChar == 116) { num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); if (num1 == 1) { if (dateTime.Hour < 12) { if (dtfi.AMDesignator.Length >= 1) { stringBuilder1.Append(dtfi.AMDesignator[0]); goto label_85; } else { goto label_85; } } else if (dtfi.PMDesignator.Length >= 1) { stringBuilder1.Append(dtfi.PMDesignator[0]); goto label_85; } else { goto label_85; } } else { stringBuilder1.Append(dateTime.Hour < 12 ? dtfi.AMDesignator : dtfi.PMDesignator); goto label_85; } } else { goto label_84; } } else { num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); DateTimeFormat.FormatDigits(stringBuilder1, dateTime.Second, num1); goto label_85; } } else if ((int)patternChar != 121) { if ((int)patternChar == 122) { num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); DateTimeFormat.FormatCustomizedTimeZone(dateTime, offset, format, num1, timeOnly, stringBuilder1); goto label_85; } else { goto label_84; } } else { int year = calendar.GetYear(dateTime); num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); if (dtfi.HasForceTwoDigitYears) { DateTimeFormat.FormatDigits(stringBuilder1, year, num1 <= 2 ? num1 : 2); } else if (calendar.ID == 8) { DateTimeFormat.HebrewFormatDigits(stringBuilder1, year); } else if (num1 <= 2) { DateTimeFormat.FormatDigits(stringBuilder1, year % 100, num1); } else { string format1 = "D" + (object)num1; stringBuilder1.Append(year.ToString(format1, (IFormatProvider)CultureInfo.InvariantCulture)); } timeOnly = false; goto label_85; } num1 = DateTimeFormat.ParseRepeatPattern(format, index1, patternChar); if (num1 > 7) { throw new FormatException(Environment.GetResourceString("Format_InvalidString")); } long num3 = dateTime.Ticks % 10000000L / (long)Math.Pow(10.0, (double)(7 - num1)); if ((int)patternChar == 102) { stringBuilder1.Append(((int)num3).ToString(DateTimeFormat.fixedNumberFormats[num1 - 1], (IFormatProvider)CultureInfo.InvariantCulture)); goto label_85; } else { int num4; for (num4 = num1; num4 > 0 && num3 % 10L == 0L; --num4) { num3 /= 10L; } if (num4 > 0) { stringBuilder1.Append(((int)num3).ToString(DateTimeFormat.fixedNumberFormats[num4 - 1], (IFormatProvider)CultureInfo.InvariantCulture)); goto label_85; } else if (stringBuilder1.Length > 0) { StringBuilder stringBuilder2 = stringBuilder1; int index2 = stringBuilder2.Length - 1; if ((int)stringBuilder2[index2] == 46) { StringBuilder stringBuilder3 = stringBuilder1; int startIndex = stringBuilder3.Length - 1; int length = 1; stringBuilder3.Remove(startIndex, length); goto label_85; } else { goto label_85; } } else { goto label_85; } } label_84: stringBuilder1.Append(patternChar); num1 = 1; label_85: index1 += num1; } return(StringBuilderCache.GetStringAndRelease(stringBuilder1)); }
/// <summary>Evaluates a terminfo formatting string, using the supplied arguments and processing data structures.</summary> /// <param name="format">The format string.</param> /// <param name="pos">The position in <paramref name="format"/> to start processing.</param> /// <param name="args">The arguments to the format string.</param> /// <param name="stack">The stack to use as the format string is evaluated.</param> /// <param name="dynamicVars">A lazily-initialized collection of variables.</param> /// <param name="staticVars">A lazily-initialized collection of variables.</param> /// <returns> /// The formatted string; this may be empty if the evaluation didn't yield any output. /// The evaluation stack will have a 1 at the top if all processing was completed at invoked level /// of recursion, and a 0 at the top if we're still inside of a conditional that requires more processing. /// </returns> private static string EvaluateInternal( string format, ref int pos, FormatParam[] args, LowLevelStack <FormatParam> stack, ref FormatParam[] dynamicVars, ref FormatParam[] staticVars) { // Create a StringBuilder to store the output of this processing. We use the format's length as an // approximation of an upper-bound for how large the output will be, though with parameter processing, // this is just an estimate, sometimes way over, sometimes under. StringBuilder output = StringBuilderCache.Acquire(format.Length); // Format strings support conditionals, including the equivalent of "if ... then ..." and // "if ... then ... else ...", as well as "if ... then ... else ... then ..." // and so on, where an else clause can not only be evaluated for string output but also // as a conditional used to determine whether to evaluate a subsequent then clause. // We use recursion to process these subsequent parts, and we track whether we're processing // at the same level of the initial if clause (or whether we're nested). bool sawIfConditional = false; // Process each character in the format string, starting from the position passed in. for (; pos < format.Length; pos++) { // '%' is the escape character for a special sequence to be evaluated. // Anything else just gets pushed to output. if (format[pos] != '%') { output.Append(format[pos]); continue; } // We have a special parameter sequence to process. Now we need // to look at what comes after the '%'. ++pos; switch (format[pos]) { // Output appending operations case '%': // Output the escaped '%' output.Append('%'); break; case 'c': // Pop the stack and output it as a char output.Append((char)stack.Pop().Int32); break; case 's': // Pop the stack and output it as a string output.Append(stack.Pop().String); break; case 'd': // Pop the stack and output it as an integer output.Append(stack.Pop().Int32); break; case 'o': case 'X': case 'x': case ':': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': // printf strings of the format "%[[:]flags][width[.precision]][doxXs]" are allowed // (with a ':' used in front of flags to help differentiate from binary operations, as flags can // include '-' and '+'). While above we've special-cased common usage (e.g. %d, %s), // for more complicated expressions we delegate to printf. int printfEnd = pos; for (; printfEnd < format.Length; printfEnd++) // find the end of the printf format string { char ec = format[printfEnd]; if (ec == 'd' || ec == 'o' || ec == 'x' || ec == 'X' || ec == 's') { break; } } if (printfEnd >= format.Length) { throw new InvalidOperationException(SR.IO_TermInfoInvalid); } string printfFormat = format.Substring(pos - 1, printfEnd - pos + 2); // extract the format string if (printfFormat.Length > 1 && printfFormat[1] == ':') { printfFormat = printfFormat.Remove(1, 1); } output.Append(FormatPrintF(printfFormat, stack.Pop().Object)); // do the printf formatting and append its output break; // Stack pushing operations case 'p': // Push the specified parameter (1-based) onto the stack pos++; Debug.Assert(format[pos] >= '0' && format[pos] <= '9'); stack.Push(args[format[pos] - '1']); break; case 'l': // Pop a string and push its length stack.Push(stack.Pop().String.Length); break; case '{': // Push integer literal, enclosed between braces pos++; int intLit = 0; while (format[pos] != '}') { Debug.Assert(format[pos] >= '0' && format[pos] <= '9'); intLit = (intLit * 10) + (format[pos] - '0'); pos++; } stack.Push(intLit); break; case '\'': // Push literal character, enclosed between single quotes stack.Push((int)format[pos + 1]); Debug.Assert(format[pos + 2] == '\''); pos += 2; break; // Storing and retrieving "static" and "dynamic" variables case 'P': // Pop a value and store it into either static or dynamic variables based on whether the a-z variable is capitalized pos++; int setIndex; FormatParam[] targetVars = GetDynamicOrStaticVariables(format[pos], ref dynamicVars, ref staticVars, out setIndex); targetVars[setIndex] = stack.Pop(); break; case 'g': // Push a static or dynamic variable; which is based on whether the a-z variable is capitalized pos++; int getIndex; FormatParam[] sourceVars = GetDynamicOrStaticVariables(format[pos], ref dynamicVars, ref staticVars, out getIndex); stack.Push(sourceVars[getIndex]); break; // Binary operations case '+': case '-': case '*': case '/': case 'm': case '^': // arithmetic case '&': case '|': // bitwise case '=': case '>': case '<': // comparison case 'A': case 'O': // logical int second = stack.Pop().Int32; // it's a stack... the second value was pushed last int first = stack.Pop().Int32; char c = format[pos]; stack.Push( c == '+' ? (first + second) : c == '-' ? (first - second) : c == '*' ? (first * second) : c == '/' ? (first / second) : c == 'm' ? (first % second) : c == '^' ? (first ^ second) : c == '&' ? (first & second) : c == '|' ? (first | second) : c == '=' ? AsInt(first == second) : c == '>' ? AsInt(first > second) : c == '<' ? AsInt(first < second) : c == 'A' ? AsInt(AsBool(first) && AsBool(second)) : c == 'O' ? AsInt(AsBool(first) || AsBool(second)) : 0); // not possible; we just validated above break; // Unary operations case '!': case '~': int value = stack.Pop().Int32; stack.Push( format[pos] == '!' ? AsInt(!AsBool(value)) : ~value); break; // Some terminfo files appear to have a fairly liberal interpretation of %i. The spec states that %i increments the first two arguments, // but some uses occur when there's only a single argument. To make sure we accomodate these files, we increment the values // of up to (but not requiring) two arguments. case 'i': if (args.Length > 0) { args[0] = 1 + args[0].Int32; if (args.Length > 1) { args[1] = 1 + args[1].Int32; } } break; // Conditional of the form %? if-part %t then-part %e else-part %; // The "%e else-part" is optional. case '?': sawIfConditional = true; break; case 't': // We hit the end of the if-part and are about to start the then-part. // The if-part left its result on the stack; pop and evaluate. bool conditionalResult = AsBool(stack.Pop().Int32); // Regardless of whether it's true, run the then-part to get past it. // If the conditional was true, output the then results. pos++; string thenResult = EvaluateInternal(format, ref pos, args, stack, ref dynamicVars, ref staticVars); if (conditionalResult) { output.Append(thenResult); } Debug.Assert(format[pos] == 'e' || format[pos] == ';'); // We're past the then; the top of the stack should now be a Boolean // indicating whether this conditional has more to be processed (an else clause). if (!AsBool(stack.Pop().Int32)) { // Process the else clause, and if the conditional was false, output the else results. pos++; string elseResult = EvaluateInternal(format, ref pos, args, stack, ref dynamicVars, ref staticVars); if (!conditionalResult) { output.Append(elseResult); } // Now we should be done (any subsequent elseif logic will have been handled in the recursive call). if (!AsBool(stack.Pop().Int32)) { throw new InvalidOperationException(SR.IO_TermInfoInvalid); } } // If we're in a nested processing, return to our parent. if (!sawIfConditional) { stack.Push(1); return(StringBuilderCache.GetStringAndRelease(output)); } // Otherwise, we're done processing the conditional in its entirety. sawIfConditional = false; break; case 'e': case ';': // Let our caller know why we're exiting, whether due to the end of the conditional or an else branch. stack.Push(AsInt(format[pos] == ';')); return(StringBuilderCache.GetStringAndRelease(output)); // Anything else is an error default: throw new InvalidOperationException(SR.IO_TermInfoInvalid); } } stack.Push(1); return(StringBuilderCache.GetStringAndRelease(output)); }
/// <summary> /// Helper function for retrieving a localized string resource via MUI. /// The function expects a string in the form: "@resource.dll, -123" /// /// "resource.dll" is a language-neutral portable executable (LNPE) file in /// the %windir%\system32 directory. The OS is queried to find the best-fit /// localized resource file for this LNPE (ex: %windir%\system32\en-us\resource.dll.mui). /// If a localized resource file exists, we LoadString resource ID "123" and /// return it to our caller. /// </summary> private static string TryGetLocalizedNameByMuiNativeResource(string resource) { if (string.IsNullOrEmpty(resource)) { return(string.Empty); } // parse "@tzres.dll, -100" // // filePath = "C:\Windows\System32\tzres.dll" // resourceId = -100 // string[] resources = resource.Split(','); if (resources.Length != 2) { return(string.Empty); } string filePath; int resourceId; // get the path to Windows\System32 string system32 = Environment.SystemDirectory; // trim the string "@tzres.dll" => "tzres.dll" string tzresDll = resources[0].TrimStart('@'); try { filePath = Path.Combine(system32, tzresDll); } catch (ArgumentException) { // there were probably illegal characters in the path return(string.Empty); } if (!int.TryParse(resources[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out resourceId)) { return(string.Empty); } resourceId = -resourceId; try { StringBuilder fileMuiPath = StringBuilderCache.Acquire(Path.MaxPath); fileMuiPath.Length = Path.MaxPath; int fileMuiPathLength = Path.MaxPath; int languageLength = 0; long enumerator = 0; bool succeeded = UnsafeNativeMethods.GetFileMUIPath( Win32Native.MUI_PREFERRED_UI_LANGUAGES, filePath, null /* language */, ref languageLength, fileMuiPath, ref fileMuiPathLength, ref enumerator); if (!succeeded) { StringBuilderCache.Release(fileMuiPath); return(string.Empty); } return(TryGetLocalizedNameByNativeResource(StringBuilderCache.GetStringAndRelease(fileMuiPath), resourceId)); } catch (EntryPointNotFoundException) { return(string.Empty); } }