public static UString Find(this string str, UString what, bool ignoreCase = false) { return(((UString)str).Find(what, ignoreCase)); }
/// <summary>Called by Format to replace named placeholders with numeric /// placeholders in format strings.</summary> /// <returns>A format string that can be used to call string.Format.</returns> /// <seealso cref="FormatCore"/> public static string EliminateNamedArgs(string format, params object[] args) { char c; bool containsNames = false; int highestIndex = -1; for (int i = 0; i < format.Length - 1; i++) { if (format[i] == '{' && format[i + 1] != '{') { int j = ++i; for (; (c = format[i]) >= '0' && c <= '9'; i++) { } if (i == j) { containsNames = true; } else { highestIndex = int.Parse(format.Substring(j, i - j)); } } } if (!containsNames) { return(format); } if (((args.Length - highestIndex) & 1) == 0) { highestIndex++; // so that the number of args left is even } StringBuilder sb = new StringBuilder(format); int correction = 0; for (int i = 0; i < sb.Length - 1; i++) { if (sb[i] == '{' && sb[i + 1] != '{') { int placeholderStart = ++i; // Placeholder name starts here. for (; (c = sb[i]) != '}' && c != ':' && c != ','; i++) { } int placeholderLen = i - placeholderStart; // StringBuilder lacks Substring()! Instead, get the name // from the original string and keep track of a correction // factor so that in subsequent iterations, we get the // substring from the right position in the original string. UString name = format.Slice(placeholderStart + correction, placeholderLen); for (int arg = highestIndex + 1; arg < args.Length; arg += 2) { if (args[arg] != null && name.Equals(args[arg] as string, ignoreCase: true)) { // Matching argument found. Replace name with index: string idxStr = (arg + 1).ToString(); sb.Remove(placeholderStart, placeholderLen); sb.Insert(placeholderStart, idxStr); int dif = placeholderLen - idxStr.Length; correction += dif; i -= dif; break; } } } Debug.Assert(sb[i] == format[i + correction]); } return(sb.ToString()); }
/// <summary>Low-level method that identifies the parts of a float literal /// of arbitrary base (typically base 2, 10, or 16) with no prefix or /// suffix, such as <c>2.Cp0</c> (which means 2.75 in base 16).</summary> /// <param name="radix">Base of the number to parse; must be between 2 /// and 36.</param> /// <param name="mantissa">Integer magnitude of the number.</param> /// <param name="exponentBase2">Base-2 exponent to apply, as specified by /// the 'p' suffix, or 0 if there is no 'p' suffix..</param> /// <param name="exponentBase10">Base-10 exponent to apply, as specified by /// the 'e' suffix, or 0 if there is no 'e' suffix..</param> /// <param name="exponentBaseR">Base-radix exponent to apply. This number /// is based on the front part of the number only (not including the 'p' or /// 'e' suffix). Negative values represent digits after the decimal point, /// while positive numbers represent 64-bit overflow. For example, if the /// input is <c>12.3456</c> with <c>radix=10</c>, the output will be /// <c>mantissa=123456</c> and <c>exponentBaseR=-4</c>. If the input is /// <c>0123_4567_89AB_CDEF_1234.5678</c> with <c>radix=16</c>, the mantissa /// overflows, and the result is <c>mantissa = 0x1234_5678_9ABC_DEF1</c> /// with <c>exponentBaseR=3</c>.</param> /// <param name="numDigits">Set to the number of digits in the number, not /// including the exponent part.</param> /// <param name="flags">Alters parsing behavior, see <see cref="ParseFlags"/>.</param> /// <remarks> /// The syntax required is /// <code> /// ( '+'|'-' )? /// ( Digits ('.' Digits?)? | '.' Digits ) /// ( ('p'|'P') ('-'|'+')? DecimalDigits+ )? /// ( ('e'|'E') ('-'|'+')? DecimalDigits+ )? /// </code> /// where Digits refers to one digits in the requested base, possibly /// including underscores or spaces if the flags allow it; similarly, /// DecimalDigits refers to base-10 digits and is also affected by the /// flags. /// <para/> /// Returns false if there was an error interpreting the input. /// <para/> /// To keep the parser relatively simple, it does not roll back in case of /// error the way the int parser does. For example, given the input "23p", /// the 'p' is consumed and causes the method to return false, even though /// the parse could have been successful if it had ignored the 'p'. /// </remarks> public static bool TryParseFloatParts(ref UString source, int radix, out bool negative, out ulong mantissa, out int exponentBaseR, out int exponentBase2, out int exponentBase10, out int numDigits, ParseFlag flags = 0) { flags |= G.ParseFlag.StopBeforeOverflow; if ((flags & ParseFlag.SkipSpacesInFront) != 0) { source = SkipSpaces(source); } negative = false; char c = source[0, '\0']; if (c == '-' || c == '+') { negative = c == '-'; source = source.Slice(1); } int numDigits2 = 0; mantissa = 0; exponentBase2 = 0; exponentBase10 = 0; exponentBaseR = 0; bool success = TryParseUInt(ref source, ref mantissa, radix, flags, out numDigits); if (!success) // possible overflow, extra digits remain if so { numDigits += (exponentBaseR = SkipExtraDigits(ref source, radix, flags)); } c = source[0, '\0']; if (c == '.' || (c == ',' && (flags & ParseFlag.AllowCommaDecimalPoint) != 0)) { source = source.Slice(1); if (exponentBaseR == 0) { success = TryParseUInt(ref source, ref mantissa, radix, flags, out numDigits2); if ((numDigits += numDigits2) == 0) { return(false); } exponentBaseR = -numDigits2; } else { Debug.Assert(!success); } if (!success) // possible overflow, extra digits remain if so { numDigits += SkipExtraDigits(ref source, radix, flags); } c = source[0, '\0']; } if (numDigits == 0) { return(false); } success = true; if (c == 'p' || c == 'P') { source = source.Slice(1); success = TryParseInt(ref source, out exponentBase2, 10, flags) && success; c = source[0, '\0']; } if (c == 'e' || c == 'E') { source = source.Slice(1); success = TryParseInt(ref source, out exponentBase10, 10, flags) && success; } return(success); }
public static string EscapeCStyle(UString s, EscapeC flags = EscapeC.Default) { return(EscapeCStyle(s, flags, '\0')); }
public static bool TryParseHex(UString s, out int value) { int count = TryParseHex(ref s, out value); return(count > 0 && s.IsEmpty); }
public UString ReplaceOne(UString what, UString replacement, bool ignoreCase = false) { return(Replace(what, replacement, ignoreCase, 1)); }
public bool Equals(UString other) { return(Equals(other, false)); }