void tIndexOfChar(String haystack, char needle, int startPos, int expectedResult) { haystackAString._()._(haystack); haystackSubsPlain.Set(haystack); haystackSubstring.Set("01" + haystack + haystack + "234", 2 + haystack.Length, haystack.Length); UT_EQ(expectedResult, haystackAString.IndexOf(needle, startPos)); UT_EQ(expectedResult, haystackSubsPlain.IndexOf(needle, startPos)); UT_EQ(expectedResult, haystackSubstring.IndexOf(needle, startPos)); }
public void SubstringIndexOf() { var s = new Substring("_Hello", 1, 2); s.IndexOf('_').Should().BeNegative(); s.IndexOf('H').Should().Be(1); s.IndexOf('e').Should().Be(2); s.IndexOf('l').Should().BeNegative(); s.IndexOf('o').Should().BeNegative(); s.IndexOf('m').Should().BeNegative(); }
/** **************************************************************************************** * Returns the next token, which is afterwards also available through field #Actual. * If no further token was available, the returned * \ref cs::aworx::lib::strings::Substring "Substring" will be 'nulled' * (see \ref cs::aworx::lib::strings::Substring::IsNull "Substring.IsNull"). * To prevent this, the availability of a next token should be * checked using method #HasNext(). * * For clarification, see the explanation and sample code in this classes documentation. * * @param trimming Determines if the token is trimmed in respect to the white space * characters defined in field #Whitespaces. * Defaults to \c Whitespaces.Trim. * @param newDelim The delimiter separates the tokens. Defaults to 0, which keeps the * current delimiter intact. * However, it a new delimiter can be provided for every next token. * @return true if a next token was available, false if not. ******************************************************************************************/ public Substring Next(Whitespaces trimming = enums.Whitespaces.Trim, char newDelim = '\0') { if (Rest.IsNull()) { Actual.SetNull(); return(Actual); } // change of delim? if (newDelim != '\0') { delim = newDelim; } // set buf, start and find end Actual.Buf = Rest.Buf; Actual.Start = Rest.Start; int nextDelimiter = Rest.IndexOf(delim); if (nextDelimiter >= 0) { Rest.Start += nextDelimiter + 1; Actual.End = Rest.Start - 2; } else { Actual.End = Rest.End; Rest.SetNull(); } // trim if (trimming == enums.Whitespaces.Trim) { Actual.TrimStart(Whitespaces); Actual.TrimEnd(Whitespaces); } return(Actual); }
// ############################################################################################# // logText // ############################################################################################# /** ******************************************************************************************** * * The implementation of the abstract method of parent class TextLogger. Logs messages to the * application console and/or the VStudio output window. * * @param domain The <em>Log Domain</em>. * @param verbosity The verbosity. This has been checked to be active already on this * stage and is provided to be able to be logged out only. * @param msg The log message * @param scope Information about the scope of the <em>Log Statement</em>.. * @param lineNumber The line number of a multi-line message, starting with 0. For * single line messages this is -1. **********************************************************************************************/ override protected void logText(Domain domain, Verbosity verbosity, AString msg, ScopeInfo scope, int lineNumber) { // loop over message, print the parts between the escape sequences Tokenizer msgParts = new Tokenizer(msg, '\x001B'); Substring actual = msgParts.Actual; Substring rest = msgParts.Rest; int column = 0; for (;;) { msgParts.Next(Whitespaces.Keep); // check if this is an ANSI sequence already if (rest.CharAtStart() == '[') { // read the 'm' int idx = rest.IndexOf('m'); if (idx < 0) // unknown ANSI Code { ALIB.WARNING("Unknown ANSI ESC Code "); textWriter.Write(actual.Buf, actual.Start, actual.Length()); continue; } column += actual.Length(); actual.End = rest.Start + idx; rest.Start += idx + 1; textWriter.Write(actual.Buf, actual.Start, actual.Length()); continue; } else { if (actual.IsNotEmpty()) { textWriter.Write(actual.Buf, actual.Start, actual.Length()); column += actual.Length(); } } // end of loop? if (!msgParts.HasNext()) { break; } // found an ESC sequence char c = rest.Consume(); // Colors bool isForeGround = true; if (c == 'C' || c == 'c') { isForeGround = c == 'c'; c = rest.Consume(); int colNo = c - '0'; ALIB.ASSERT_WARNING(colNo >= 0 && colNo <= 9, "Unknown ESC-c code"); // add bg colNo += isForeGround ? 0 : 10; // add light colNo += (isForeGround ? !IsBackgroundLight : IsBackgroundLight) ? 20 : 0; textWriter.Write(ansiCols[colNo]); } // Styles else if (c == 's') { // bold/italics style not supported in Windows console // reset all if (rest.Consume() == 'a') { textWriter.Write(ANSI_RESET); } } // auto tab / end of meta else if (c == 't' || c == 'A') { bool endOfMeta = c == 'A'; c = rest.Consume(); int extraSpace = c >= '0' && c <= '9' ? (int)(c - '0') : (int)(c - 'A') + 10; int tabStop = AutoSizes.Next(column, extraSpace); Util.WriteSpaces(textWriter, tabStop - column); column = tabStop; if (endOfMeta) { String msgPrefix; switch (verbosity) { case lox.Verbosity.Verbose: msgPrefix = MsgPrefixVerbose; break; case lox.Verbosity.Info: msgPrefix = MsgPrefixInfo; break; case lox.Verbosity.Warning: msgPrefix = MsgPrefixWarning; break; case lox.Verbosity.Error: msgPrefix = MsgPrefixError; break; default: msgPrefix = ""; break; } textWriter.Write(msgPrefix); } } // Link (we just colorize links here) else if (c == 'l') { textWriter.Write(rest.Consume() == 'S' ? (IsBackgroundLight ? ANSI_LIGHT_BLUE : ANSI_LIGHT_BLUE) : ANSI_STD_COL); } else { ALIB.WARNING("Unknown ESC code"); } } // write loop textWriter.WriteLine(MsgSuffix); }
// ############################################################################################# // Internals // ############################################################################################# /** **************************************************************************************** * Internal, recursive helper of #Find. * * @param domainPath Path to search. * @param sensitivity Denotes if domain name search is treated case sensitive or not. * @param maxCreate The maximum number of sub domains that are created if not * found at the end of the path. * @param[out] wasCreated Output parameter that is set \c true if domain was not found * and hence created. * @return The domain found or created. ******************************************************************************************/ protected Domain findRecursive(Substring domainPath, Case sensitivity, int maxCreate, ref bool wasCreated) { //--- get act sub-name and rest of path domainPath.Consume(PathSeparator); int endSubName = domainPath.IndexOf(PathSeparator); ALIB.ASSERT_ERROR(endSubName != 0, "Internal Error"); // find end of actual domain name and save rest Substring restOfDomainPath = tSubstring2; restOfDomainPath.SetNull(); if (endSubName > 0) { domainPath.Split(endSubName, restOfDomainPath, 1); } // search sub-domain Domain subDomain = null; // "." if (domainPath.Equals(".")) { subDomain = this; } // ".." else if (domainPath.Equals("..")) { subDomain = Parent != null ? Parent : this; } // search in sub-domain else { int i; bool fixedOnce = false; for (;;) { for (i = 0; i < SubDomains.Count; i++) { int comparison = SubDomains[i].Name.CompareTo(domainPath, sensitivity); if (comparison >= 0) { if (comparison == 0) { subDomain = SubDomains[i]; } break; } } // domain found? if (subDomain != null) { break; } // try and fix name if (!fixedOnce) { fixedOnce = true; bool illegalCharacterFound = false; for (int cp = 0; cp < domainPath.Length(); ++cp) { char c = domainPath.CharAt(cp); if (c < '-' || c > 'z' || c == '<' || c == '>' || c == '[' || c == ']' || c == '=' || c == '?' || c == ';' || c == ':' || c == '\\' || c == '\'' || c == '.' || c == ',' ) { illegalCharacterFound = true; domainPath.Buf[domainPath.Start + cp] = '#'; } } if (illegalCharacterFound) { continue; } } // create if (maxCreate == 0) { return(null); } wasCreated = true; SubDomains.Insert(i, subDomain = new Domain(this, new AString(domainPath))); maxCreate--; if (maxCreate == 0) { return(subDomain); } break; } } // recursion? if (restOfDomainPath.IsNotEmpty()) { domainPath.Set(restOfDomainPath); return(subDomain.findRecursive(domainPath, sensitivity, maxCreate, ref wasCreated)); } // that's it return(subDomain); }
public void IndexOf() { Substring subs; // indexOf() { subs = new Substring("ABCD"); UT_EQ(-1, subs.IndexOf('X')); UT_EQ(0, subs.IndexOf('A')); UT_EQ(1, subs.IndexOf('B')); UT_EQ(2, subs.IndexOf('C')); UT_EQ(3, subs.IndexOf('D')); } // search characters subs.Set("abc@" + "abcd abcd" + "abc@de", 4, 9); { UT_EQ(-1, subs.IndexOf('@', -5)); UT_EQ(-1, subs.IndexOf('@')); UT_EQ(-1, subs.IndexOf('@', 5)); UT_EQ(-1, subs.IndexOf('@', 150)); UT_EQ(0, subs.IndexOf('a')); UT_EQ(1, subs.IndexOf('b')); UT_EQ(2, subs.IndexOf('c')); UT_EQ(0, subs.IndexOf('a', 0)); UT_EQ(1, subs.IndexOf('b', 0)); UT_EQ(2, subs.IndexOf('c', 0)); UT_EQ(5, subs.IndexOf('a', 1)); UT_EQ(1, subs.IndexOf('b', 1)); UT_EQ(2, subs.IndexOf('c', 1)); UT_EQ(5, subs.IndexOf('a', 2)); UT_EQ(6, subs.IndexOf('b', 2)); UT_EQ(2, subs.IndexOf('c', 2)); UT_EQ(5, subs.IndexOf('a', 3)); UT_EQ(6, subs.IndexOf('b', 3)); UT_EQ(7, subs.IndexOf('c', 3)); UT_EQ(8, subs.IndexOf('d', 7)); UT_EQ(8, subs.IndexOf('d', 8)); UT_EQ(-1, subs.IndexOf('d', 9)); } // search null, empty string subs.Set("abc@" + "abcd abcd" + "abc@de", 4, 9); { UT_EQ(0, subs.IndexOf((AString)null)); UT_EQ(5, subs.IndexOf((AString)null, 5)); UT_EQ(-1, subs.IndexOf((AString)null, 50)); UT_EQ(0, subs.IndexOf((AString)null, -5)); UT_EQ(0, subs.IndexOf((String)null)); UT_EQ(5, subs.IndexOf((String)null, 5)); UT_EQ(-1, subs.IndexOf((String)null, 50)); UT_EQ(0, subs.IndexOf((String)null, -5)); UT_EQ(0, subs.IndexOf("", -5)); UT_EQ(0, subs.IndexOf("", 0)); UT_EQ(4, subs.IndexOf("", 4)); UT_EQ(-1, subs.IndexOf("", 100)); } // search subs.Set("abc@" + "abcd abcd" + "abc@de", 4, 9); { UT_EQ(0, subs.IndexOf("abcd")); UT_EQ(1, subs.IndexOf("b")); UT_EQ(4, subs.IndexOf(" abcd")); UT_EQ(5, subs.IndexOf("abcd", 1)); UT_EQ(0, subs.IndexOf("abcd", -1)); UT_EQ(-1, subs.IndexOf("xyz", -10)); } // ignore case String t = "Hallo A-Worx util"; subs.Set("abc@" + t + "abc@de", 4, t.Length); { UT_EQ(6, subs.IndexOf("a-worx", 0, Case.Ignore)); UT_EQ(6, subs.IndexOf("a-worx", 1, Case.Ignore)); UT_EQ(6, subs.IndexOf("a-worx", -10, Case.Ignore)); UT_EQ(6, subs.IndexOf("a-worx", 6, Case.Ignore)); UT_EQ(-1, subs.IndexOf("a-worx", 7, Case.Ignore)); UT_EQ(-1, subs.IndexOf("a-worx", 100, Case.Ignore)); UT_EQ(0, subs.IndexOf("hal", 0, Case.Ignore)); UT_EQ(-1, subs.IndexOf("hal", 1, Case.Ignore)); UT_EQ(13, subs.IndexOf("util", 1, Case.Ignore)); UT_EQ(13, subs.IndexOf("UTIL", 5, Case.Ignore)); UT_EQ(13, subs.IndexOf("UTIL", 13, Case.Ignore)); UT_EQ(-1, subs.IndexOf("UTIL", 14, Case.Ignore)); } // ------------------ search one of several characters ------------------ subs.Set("abc@" + "abcd abcde" + "abc@de", 4, 10); { // search one of int l = subs.Length(); UT_EQ(4, subs.IndexOfAny(CString.DefaultWhitespaces, Inclusion.Include)); UT_EQ(-1, subs.IndexOfAny("x".ToCharArray(), Inclusion.Include)); UT_EQ(-1, subs.IndexOfAny("xy".ToCharArray(), Inclusion.Include)); UT_EQ(-1, subs.IndexOfAny("xyz".ToCharArray(), Inclusion.Include)); UT_EQ(3, subs.IndexOfAny("xyd".ToCharArray(), Inclusion.Include)); UT_EQ(3, subs.IndexOfAny("d".ToCharArray(), Inclusion.Include)); UT_EQ(3, subs.IndexOfAny("xyd".ToCharArray(), Inclusion.Include, -2)); UT_EQ(8, subs.IndexOfAny("xyd".ToCharArray(), Inclusion.Include, 4)); UT_EQ(-1, subs.IndexOfAny("xyd".ToCharArray(), Inclusion.Include, 20)); UT_EQ(-1, subs.LastIndexOfAny("".ToCharArray(), Inclusion.Include)); UT_EQ(-1, subs.LastIndexOfAny("x".ToCharArray(), Inclusion.Include)); UT_EQ(-1, subs.LastIndexOfAny("xy".ToCharArray(), Inclusion.Include)); UT_EQ(-1, subs.LastIndexOfAny("xyz".ToCharArray(), Inclusion.Include)); UT_EQ(8, subs.LastIndexOfAny("xyd".ToCharArray(), Inclusion.Include)); UT_EQ(-1, subs.LastIndexOfAny("xyd".ToCharArray(), Inclusion.Include, -2)); UT_EQ(-1, subs.LastIndexOfAny("xyd".ToCharArray(), Inclusion.Include, 2)); UT_EQ(3, subs.LastIndexOfAny("xyd".ToCharArray(), Inclusion.Include, 4)); UT_EQ(0, subs.LastIndexOfAny("a".ToCharArray(), Inclusion.Include, 4)); UT_EQ(1, subs.LastIndexOfAny("b".ToCharArray(), Inclusion.Include, 4)); UT_EQ(1, subs.LastIndexOfAny("ba".ToCharArray(), Inclusion.Include, 4)); UT_EQ(0, subs.LastIndexOfAny("xa".ToCharArray(), Inclusion.Include, 4)); UT_EQ(8, subs.LastIndexOfAny("xyd".ToCharArray(), Inclusion.Include, 20)); UT_EQ(8, subs.LastIndexOfAny("d".ToCharArray(), Inclusion.Include, 20)); UT_EQ(9, subs.LastIndexOfAny("e".ToCharArray(), Inclusion.Include, 20)); // search NOT one of UT_EQ(0, subs.IndexOfAny("".ToCharArray(), Inclusion.Exclude)); UT_EQ(0, subs.IndexOfAny("x".ToCharArray(), Inclusion.Exclude)); UT_EQ(0, subs.IndexOfAny("xy".ToCharArray(), Inclusion.Exclude)); UT_EQ(0, subs.IndexOfAny("xyz".ToCharArray(), Inclusion.Exclude)); UT_EQ(1, subs.IndexOfAny("a".ToCharArray(), Inclusion.Exclude)); UT_EQ(2, subs.IndexOfAny("ba".ToCharArray(), Inclusion.Exclude)); UT_EQ(3, subs.IndexOfAny("abc".ToCharArray(), Inclusion.Exclude)); UT_EQ(3, subs.IndexOfAny("acb".ToCharArray(), Inclusion.Exclude)); UT_EQ(3, subs.IndexOfAny("cba".ToCharArray(), Inclusion.Exclude)); UT_EQ(3, subs.IndexOfAny("xcba".ToCharArray(), Inclusion.Exclude)); UT_EQ(l - 1, subs.LastIndexOfAny("".ToCharArray(), Inclusion.Exclude)); UT_EQ(l - 1, subs.LastIndexOfAny("x".ToCharArray(), Inclusion.Exclude)); UT_EQ(l - 1, subs.LastIndexOfAny("xy".ToCharArray(), Inclusion.Exclude)); UT_EQ(l - 2, subs.LastIndexOfAny("e".ToCharArray(), Inclusion.Exclude)); UT_EQ(l - 3, subs.LastIndexOfAny("de".ToCharArray(), Inclusion.Exclude)); UT_EQ(l - 4, subs.LastIndexOfAny("cde".ToCharArray(), Inclusion.Exclude)); UT_EQ(l - 4, subs.LastIndexOfAny("ced".ToCharArray(), Inclusion.Exclude)); UT_EQ(l - 4, subs.LastIndexOfAny("ecd".ToCharArray(), Inclusion.Exclude)); UT_EQ(5, subs.LastIndexOfAny("ecd".ToCharArray(), Inclusion.Exclude, 5)); UT_EQ(4, subs.LastIndexOfAny("ecd".ToCharArray(), Inclusion.Exclude, 4)); UT_EQ(1, subs.LastIndexOfAny("acd".ToCharArray(), Inclusion.Exclude, 3)); UT_EQ(-1, subs.LastIndexOfAny("abc".ToCharArray(), Inclusion.Exclude, 2)); UT_EQ(3, subs.LastIndexOfAny("xay".ToCharArray(), Inclusion.Exclude, 3)); UT_EQ(2, subs.LastIndexOfAny("d".ToCharArray(), Inclusion.Exclude, 3)); UT_EQ(-1, subs.LastIndexOfAny("a".ToCharArray(), Inclusion.Exclude, 0)); } }
public void FrontEnd() { // empty substring { Substring subs = new Substring(); UT_EQ('\0', subs.CharAtStart( )); UT_EQ('\0', subs.CharAt(0)); UT_EQ('\0', subs.CharAt(1)); UT_EQ('\0', subs.CharAt(-1)); UT_EQ('\0', subs.CharAt(2)); UT_EQ('\0', subs.CharAt(-2)); UT_EQ('\0', subs.CharAtEnd( )); UT_EQ('\0', subs.CharAtEnd(0)); UT_EQ('\0', subs.CharAtEnd(1)); UT_EQ('\0', subs.CharAtEnd(-1)); UT_EQ('\0', subs.CharAtEnd(2)); UT_EQ('\0', subs.CharAtEnd(-2)); } // empty substring { Substring subs = new Substring("aaaaaaaaaaaa"); subs.Start = 5; subs.End = 4; UT_EQ('\0', subs.CharAtStart( )); UT_EQ('\0', subs.CharAt(0)); UT_EQ('\0', subs.CharAt(1)); UT_EQ('\0', subs.CharAt(-1)); UT_EQ('\0', subs.CharAt(2)); UT_EQ('\0', subs.CharAt(-2)); UT_EQ('\0', subs.CharAtEnd( )); UT_EQ('\0', subs.CharAtEnd(0)); UT_EQ('\0', subs.CharAtEnd(1)); UT_EQ('\0', subs.CharAtEnd(-1)); UT_EQ('\0', subs.CharAtEnd(2)); UT_EQ('\0', subs.CharAtEnd(-2)); } // substring of length 1 { Substring subs = new Substring("aaaaaaaaaaaa"); subs.Start = subs.End = 5; UT_EQ('a', subs.CharAtStart( )); UT_EQ('a', subs.CharAt(0)); UT_EQ('\0', subs.CharAt(1)); UT_EQ('\0', subs.CharAt(-1)); UT_EQ('\0', subs.CharAt(2)); UT_EQ('\0', subs.CharAt(-2)); UT_EQ('a', subs.CharAtEnd( )); UT_EQ('a', subs.CharAtEnd(0)); UT_EQ('\0', subs.CharAtEnd(1)); UT_EQ('\0', subs.CharAtEnd(-1)); UT_EQ('\0', subs.CharAtEnd(2)); UT_EQ('\0', subs.CharAtEnd(-2)); } // substring of length 2 { Substring subs = new Substring("aaaaabbbbbb"); subs.End = subs.IndexOf('b'); subs.Start = subs.End - 1; UT_EQ('a', subs.CharAtStart( )); UT_EQ('a', subs.CharAt(0)); UT_EQ('b', subs.CharAt(1)); UT_EQ('\0', subs.CharAt(-1)); UT_EQ('\0', subs.CharAt(2)); UT_EQ('\0', subs.CharAt(-2)); UT_EQ('b', subs.CharAtEnd( )); UT_EQ('b', subs.CharAtEnd(0)); UT_EQ('a', subs.CharAtEnd(1)); UT_EQ('\0', subs.CharAtEnd(-1)); UT_EQ('\0', subs.CharAtEnd(2)); UT_EQ('\0', subs.CharAtEnd(-2)); } }
public void IndexOf(string input, char trimChar, int expected) { var actual = Substring.IndexOf(input, trimChar); Assert.Equal(expected, actual); }