// ############################################################################################# // 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( Separator ); int endSubName= domainPath.IndexOf( Separator ); 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 Consume() { // null substring { Substring s= new Substring(); Substring r= new Substring("oldval"); UT_EQ( '\0', s.Consume ( ) ); UT_EQ( 0, s.Consume ( 0 , r) ); UT_TRUE(r.IsNull()); UT_EQ( 0, s.Consume ( 5 , r) ); UT_TRUE(r.IsNull()); UT_EQ( false, s.Consume ( 'a' ) ); UT_EQ( false, s.Consume ( "word" ) ); UT_EQ( '\0', s.ConsumeFromEnd( ) ); UT_EQ( 0, s.ConsumeFromEnd( 0 ) ); UT_EQ( 0, s.ConsumeFromEnd( 5 ) ); UT_EQ( false, s.ConsumeFromEnd( 'a' ) ); UT_EQ( false, s.ConsumeFromEnd( "word" ) ); } // empty substring { Substring s= new Substring("aaaaaaaaaaaa"); Substring r= new Substring("oldval"); s.Start= 5; s.End= 4; UT_EQ( '\0', s.Consume ( ) ); UT_EQ( 0, s.Consume ( 0 ,r ) ); UT_TRUE( r.IsNotNull()); UT_TRUE(r.IsEmpty()); UT_EQ( 0, s.Consume ( 5 ,r ) ); UT_TRUE( r.IsNotNull()); UT_TRUE(r.IsEmpty()); UT_EQ( false, s.Consume ( 'a' ) ); UT_EQ( false, s.Consume ( "word" ) ); UT_EQ( '\0', s.ConsumeFromEnd( ) ); UT_EQ( 0, s.ConsumeFromEnd( 0 ) ); UT_EQ( 0, s.ConsumeFromEnd( 5 ) ); UT_EQ( false, s.ConsumeFromEnd( 'a' ) ); UT_EQ( false, s.ConsumeFromEnd( "word" ) ); } // substring of length 1 { Substring s= new Substring("aaaaaaaaaaaa"); Substring r= new Substring("oldval"); s.Start= s.End= 5; UT_EQ( 'a', s.Consume ( ) ); UT_EQ( 0, s.Length() ); s.Start= s.End= 5; UT_EQ( 1, s.Consume ( 0 ) ); UT_EQ( 1, s.Length() ); s.Start= s.End= 5; UT_EQ( 0, s.Consume ( 1 , r ) ); UT_EQ( 0, s.Length() ); UT_TRUE(r.Equals("a")); s.Start= s.End= 5; UT_EQ( 0, s.Consume ( 5 , r ) ); UT_EQ( 0, s.Length() ); UT_TRUE(r.Equals("a")); s.Start= s.End= 5; UT_EQ( true, s.Consume ( 'a' ) ); UT_EQ( 0, s.Length() ); s.Start= s.End= 5; UT_EQ( false, s.Consume ( 'b' ) ); UT_EQ( 1, s.Length() ); s.Start= s.End= 5; UT_EQ( false, s.Consume ( "word" ) ); UT_EQ( 1, s.Length() ); s.Start= s.End= 5; UT_EQ( 'a', s.ConsumeFromEnd( ) ); UT_EQ( 0, s.Length() ); s.Start= s.End= 5; UT_EQ( 1, s.ConsumeFromEnd( 0 ) ); UT_EQ( 1, s.Length() ); s.Start= s.End= 5; UT_EQ( 0, s.ConsumeFromEnd( 1 ) ); UT_EQ( 0, s.Length() ); s.Start= s.End= 5; UT_EQ( 0, s.ConsumeFromEnd( 5 ) ); UT_EQ( 0, s.Length() ); s.Start= s.End= 5; UT_EQ( true, s.ConsumeFromEnd( 'a' ) ); UT_EQ( 0, s.Length() ); s.Start= s.End= 5; UT_EQ( false, s.ConsumeFromEnd( 'b' ) ); UT_EQ( 1, s.Length() ); s.Start= s.End= 5; UT_EQ( false, s.ConsumeFromEnd( "word" ) ); UT_EQ( 1, s.Length() ); } // substring of length 2 { Substring s= new Substring("12ab3456"); Substring r= new Substring("oldval"); s.Start= 2; s.End= 3; UT_EQ( 'a', s.Consume ( ) ); UT_EQ( 1, s.Length() ); UT_EQ( 'b', s.Consume ( ) ); UT_EQ( 0, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( 'b', s.ConsumeFromEnd( ) ); UT_EQ( 1, s.Length() ); UT_EQ( 'a', s.ConsumeFromEnd( ) ); UT_EQ( 0, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( 2, s.Consume ( 0 , r ) ); UT_EQ( 2, s.Length() ); UT_TRUE(r.IsNotNull()); UT_TRUE(r.IsEmpty()); s.Start= 2; s.End= 3; UT_EQ( 1, s.Consume ( 1 , r ) ); UT_EQ( 1, s.Length() ); UT_TRUE(r.Equals("a")); s.Start= 2; s.End= 3; UT_EQ( 0, s.Consume ( 2 , r ) ); UT_EQ( 0, s.Length() ); UT_TRUE(r.Equals("ab")); s.Start= 2; s.End= 3; UT_EQ( 0, s.Consume ( 3 , r ) ); UT_EQ( 0, s.Length() ); UT_TRUE(r.Equals("ab")); s.Start= 2; s.End= 3; UT_EQ( 2, s.ConsumeFromEnd( 0 , r ) ); UT_EQ( 2, s.Length() ); UT_TRUE(r.IsNotNull()); UT_TRUE(r.IsEmpty()); s.Start= 2; s.End= 3; UT_EQ( 1, s.ConsumeFromEnd( 1 , r ) ); UT_EQ( 1, s.Length() ); UT_TRUE(r.Equals("b")); s.Start= 2; s.End= 3; UT_EQ( 0, s.ConsumeFromEnd( 2 , r ) ); UT_EQ( 0, s.Length() ); UT_TRUE(r.Equals("ab")); s.Start= 2; s.End= 3; UT_EQ( 0, s.ConsumeFromEnd( 3 , r ) ); UT_EQ( 0, s.Length() ); UT_TRUE(r.Equals("ab")); s.Start= 2; s.End= 3; UT_EQ( false, s.Consume ( 'b' ) ); UT_EQ( 2, s.Length() ); UT_EQ( true, s.Consume ( 'a' ) ); UT_EQ( 1, s.Length() ); UT_EQ( true, s.Consume ( 'b' ) ); UT_EQ( 0, s.Length() ); UT_EQ( false, s.Consume ( 'a' ) ); UT_EQ( 0, s.Length() ); UT_EQ( false, s.Consume ( 'b' ) ); UT_EQ( 0, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( false, s.ConsumeFromEnd( 'a' ) ); UT_EQ( 2, s.Length() ); UT_EQ( true, s.ConsumeFromEnd( 'b' ) ); UT_EQ( 1, s.Length() ); UT_EQ( true, s.ConsumeFromEnd( 'a' ) ); UT_EQ( 0, s.Length() ); UT_EQ( false, s.ConsumeFromEnd( 'b' ) ); UT_EQ( 0, s.Length() ); UT_EQ( false, s.ConsumeFromEnd( 'a' ) ); UT_EQ( 0, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( false, s.Consume ( "word" ) ); UT_EQ( 2, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( false, s.Consume ( "AB" ) ); UT_EQ( 2, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( true, s.Consume ( "ab" ) ); UT_EQ( 0, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( false, s.ConsumeFromEnd( "word" ) ); UT_EQ( 2, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( false, s.ConsumeFromEnd( "AB" ) ); UT_EQ( 2, s.Length() ); s.Start= 2; s.End= 3; UT_EQ( true, s.ConsumeFromEnd( "ab" ) ); UT_EQ( 0, s.Length() ); } // 3 words { Substring s= new Substring("word1 word2 word3"); UT_EQ( 'w', s.Consume ( ) ); UT_EQ( 'o', s.Consume ( ) ); UT_EQ( 'r', s.Consume ( ) ); UT_EQ( 'd', s.Consume ( ) ); UT_EQ( '1', s.Consume ( ) ); UT_EQ( false , s.Consume ('w' ) ); UT_EQ( true , s.Consume ('w' , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( true , s.Consume ('o' , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( false , s.Consume ('o' , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( true , s.Consume ('r' , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( false , s.Consume ("D2" , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( false , s.Consume ("D2" ) ); UT_EQ( true , s.Consume ("d2" ) ); UT_EQ( 2 , s.Consume ( 4 ) ); UT_EQ( "d3" , s.ToString() ); s= new Substring("word1 word2 word3"); UT_EQ( '3', s.ConsumeFromEnd( ) ); UT_EQ( 'd', s.ConsumeFromEnd( ) ); UT_EQ( 'r', s.ConsumeFromEnd( ) ); UT_EQ( 'o', s.ConsumeFromEnd( ) ); UT_EQ( 'w', s.ConsumeFromEnd( ) ); UT_EQ( false , s.ConsumeFromEnd('2' ) ); UT_EQ( true , s.ConsumeFromEnd('2' , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( true , s.ConsumeFromEnd('d' , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( false , s.ConsumeFromEnd('d' , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( true , s.ConsumeFromEnd('r' , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( false , s.ConsumeFromEnd("WO" , Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( false , s.ConsumeFromEnd("WO" ) ); UT_EQ( true , s.ConsumeFromEnd("wo" ) ); UT_EQ( 2 , s.ConsumeFromEnd( 4 ) ); UT_EQ( "wo" , s.ToString() ); } // consume AString, Substring { Substring s= new Substring("word1 word2 word3 word4"); Substring sConsume= new Substring( "1234word12", 4, 4 ); AString aConsume= new AString ( "word" ); UT_EQ( true, s.Consume ( sConsume ) ); UT_EQ( false, s.Consume ( sConsume ) ); UT_EQ( '1', s.Consume ( ) ); UT_EQ( false, s.Consume ( sConsume ) ); UT_EQ( true, s.Consume ( sConsume, Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( '2', s.Consume ( ) ); UT_EQ( ' ', s.Consume ( ) ); UT_EQ( true, s.Consume ( aConsume ) ); UT_EQ( false, s.Consume ( aConsume ) ); UT_EQ( '3', s.Consume ( ) ); UT_EQ( false, s.Consume ( aConsume ) ); UT_EQ( true, s.Consume ( aConsume, Case.Sensitive, Whitespaces.Trim ) ); s.Set("1word 2word 3word 4word"); UT_EQ( true, s.ConsumeFromEnd( sConsume ) ); UT_EQ( false, s.ConsumeFromEnd( sConsume ) ); UT_EQ( '4', s.ConsumeFromEnd( ) ); UT_EQ( false, s.ConsumeFromEnd( sConsume ) ); UT_EQ( true, s.ConsumeFromEnd( sConsume, Case.Sensitive, Whitespaces.Trim ) ); UT_EQ( '3', s.ConsumeFromEnd( ) ); UT_EQ( ' ', s.ConsumeFromEnd( ) ); UT_EQ( true, s.ConsumeFromEnd( aConsume ) ); UT_EQ( false, s.ConsumeFromEnd( aConsume ) ); UT_EQ( '2', s.ConsumeFromEnd( ) ); UT_EQ( false, s.ConsumeFromEnd( aConsume ) ); UT_EQ( true, s.ConsumeFromEnd( aConsume, Case.Sensitive, Whitespaces.Trim ) ); } }
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= "Hello 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( "hel", 0 ,Case.Ignore ) ); UT_EQ( -1, subs.IndexOf( "hel", 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 ) ); } }
/** **************************************************************************************** * Checks if this object ends with the given string \p consumable. If it does, this * string is cut from the end of object. * * @param consumable The consumable string * @param sensitivity The sensitivity of the comparison. * @param trimBeforeConsume Determines if the string should be (right-) trimmed before the * consume operation. Defaults to \c Whitespaces.Keep. * @return \c true, if this object was starting with \p consumable and consequently the * string was cut. ******************************************************************************************/ public bool ConsumeFromEnd( Substring consumable, Case sensitivity = Case.Sensitive, Whitespaces trimBeforeConsume = Whitespaces.Keep ) { if ( trimBeforeConsume == Whitespaces.Trim ) TrimEnd(); if ( !EndsWith( consumable, sensitivity ) ) return false; ConsumeFromEnd( consumable.Length() ); return true; }
/** **************************************************************************************** * Search the given \b %Substring in the this. * * @param needle The string to search. * @param startIdx The index to start the search at. Optional and defaults to 0. * @param sensitivity If true, the compare is case insensitive. Optional and defaults to * false. * @return -1 if the string is not found. Otherwise the index of first occurrence. ******************************************************************************************/ public int IndexOf( Substring needle, int startIdx= 0, Case sensitivity= Case.Sensitive ) { int length= Length(); if ( startIdx < 0 ) startIdx= 0; else if ( startIdx >= length ) return -1; int idx= needle != null ? CString.IndexOfString( needle.Buf, needle.Start, needle.Length(), Buf, Start + startIdx, length - startIdx, sensitivity ) : CString.IndexOfString( null, 0, 0, Buf, Start + startIdx, length - startIdx, sensitivity ); if ( idx < 0) return -1; return idx < 0 ? -1 : idx - Start; }
/** **************************************************************************************** * Checks if this AString ends with the given Substring. * @param needle The Substring to be compared with the start of this AString. If this is null or * empty, true is returned. * @param sensitivity Case sensitivity of the comparison. * Optional and defaults to Case.Sensitive. * @return true if this starts with the given Substring, false if not. ******************************************************************************************/ public bool EndsWith ( Substring needle, Case sensitivity= Case.Sensitive ) { if ( needle == null ) return false; return ContainsAt( needle, Length() - needle.Length(), sensitivity ); }
/** ############################################################################################ * @name Set Data ##@{ ########################################################################################*/ /** **************************************************************************************** * Sets the substring to represent a region of the given \b %Substring. * * @param src The substring to copy from. * @param regionStart The start of the region within \p src. Defaults to 0. * @param regionLength The length of the region within \p src. * If negative, length of the provided \e src is used. * Defaults to -1. * @return \c this to allow concatenated calls. ******************************************************************************************/ public Substring Set( Substring src, int regionStart =0, int regionLength =-1 ) { Buf= src.Buf; Start= src.Start + regionStart; End= Start + ( regionLength < 0 ? src.Length() - regionStart : regionLength ) -1; hash= 0; return this; }
/** **************************************************************************************** * Tests and returns true, if the given Substring equals to what this object * represents. True is returned if both are zero length or \c null. * * @param compareString The Substring that is compared to this %AString. * @param sensitivity Case sensitivity of the comparison. * Optional and defaults to Case.Sensitive. * * @return true, if contents of this and the given Substring are equal ******************************************************************************************/ public bool Equals( Substring compareString, Case sensitivity= Case.Sensitive ) { // null? if ( compareString == null ) return IsNull(); // same length? if ( compareString.Length() != Length() ) return false; return ContainsAt( compareString.Buf, compareString.Start, Length(), 0, sensitivity ); }
/** **************************************************************************************** * Checks if the given AString is located at the given position. * @param needle The AString to search. * @param pos The position to look at. * @param sensitivity Case sensitivity of the comparison. * Optional and defaults to Case.Sensitive. * @return True if the given AString is found at the given position. False otherwise. ******************************************************************************************/ public bool ContainsAt( Substring needle, int pos, Case sensitivity= Case.Sensitive ) { if ( pos < 0 ) return false; return needle != null ? CString.ContainsAt( needle.Buf, needle.Start, needle.Length(), Buf, Start + pos, End + 1, sensitivity ) : CString.ContainsAt( null, 0, 0, Buf, Start + pos, End + 1, sensitivity ); }
/** **************************************************************************************** * Compares a Substring with a region of this instance. The region bounds get adjusted * to fit to this AString. (If this is not wanted, external checks have to be made * prior to calling this method.) * @param needle An object of type char[] that is compared to this. * @param sensitivity Case sensitivity of the comparison. * Optional and defaults to Case.Sensitive. * @param regionStart The start of the substring within this string that * is to be compared. Defaults to 0. * @param regionLength The length of the substring within this string that is * to be compared. Defaults to * Integer.MAX_VALUE. * @return * - 0 if this and \p needle are \e nulled or if both have a length of 0 or if both * share the same content * - <0 if this is \e nulled and \p needle is not or if this is smaller than \p needle. * - >0 if this is not \e nulled but \p needle is or if this is greater than \p needle. ******************************************************************************************/ public int CompareTo( Substring needle, Case sensitivity = Case.Sensitive, int regionStart= 0, int regionLength= int.MaxValue ) { // check null argument if ( IsNull() ) return needle == null ? 0 : -1; if ( needle == null) return +1; // adjust source and compare regions CString.AdjustRegion( Length(), ref regionStart, ref regionLength ); return CString.CompareTo( needle.Buf, needle.Start, needle.Length(), Buf, Start + regionStart, regionLength, sensitivity ); }
/** **************************************************************************************** * Reads a prefix string from the ALib configuration system. * This internal method is used when a new domain is created, * * @param dom The domain to set the verbosity for. ******************************************************************************************/ protected void getDomainPrefixFromConfig( Domain dom ) { Variable variable= new Variable( ALox.PREFIXES, GetName() ); if( 0 == variable.Load() ) return; Tokenizer prefixTok= new Tokenizer(); Tokenizer prefixTokInner= new Tokenizer(); Substring domainStr= new Substring(); AString domainStrBuf= new AString(); Substring prefixStr= new Substring(); for( int varNo= 0; varNo< variable.Size(); varNo++ ) { prefixTok.Set( variable.GetString( varNo ), '=' ); domainStr.Set( prefixTok.Next() ); if ( domainStr.StartsWith( "INTERNAL_DOMAINS", DomainSensitivity ) ) { domainStrBuf._()._( domainStr.Buf, domainStr.Start + 16, domainStr.Length() -16 ); while ( domainStrBuf.CharAtStart() == '/' ) domainStrBuf.DeleteStart( 1 ); domainStrBuf.InsertAt( ALox.InternalDomains, 0 ); domainStr.Set( domainStrBuf ); } prefixTokInner.Set( prefixTok.Next(), ',' ); prefixStr.Set( prefixTokInner.Next() ); if ( prefixStr.IsEmpty() ) continue; if ( prefixStr.Consume( '\"' ) ) prefixStr.ConsumeFromEnd( '\"' ); Inclusion otherPLs= Inclusion.Include; prefixTokInner.Next(); if ( prefixTokInner.Actual.IsNotEmpty() ) otherPLs= ALIB.ReadInclusion( prefixTokInner.Actual ); int searchMode= 0; if ( domainStr.Consume ( '*' ) ) searchMode+= 2; if ( domainStr.ConsumeFromEnd( '*' ) ) searchMode+= 1; if( ( searchMode == 0 && dom.FullPath.Equals ( domainStr, DomainSensitivity ) ) || ( searchMode == 1 && dom.FullPath.StartsWith ( domainStr, DomainSensitivity ) ) || ( searchMode == 2 && dom.FullPath.EndsWith ( domainStr, DomainSensitivity ) ) || ( searchMode == 3 && dom.FullPath.IndexOf ( domainStr, 0, DomainSensitivity ) >=0 ) ) { dom.PrefixLogables.Add( new Domain.PL( new AString( prefixStr ), otherPLs ) ); // log info on this intMsg._()._NC( "String \"" )._NC( prefixStr )._NC ( "\" added as prefix logable for domain \'" ) ._NC( dom.FullPath ) ._NC( "\'. (Retrieved from variable" ) ._NC( variable.Fullname )._( ".)" ); logInternal( Verbosity.Info, "PFX", intMsg ); } } }
/** **************************************************************************************** * Reads the verbosity for the given logger and domain from the ALib configuration system. * This internal method is used in two occasions: * - when a new logger is added: recursively for all existing domains (\p configStr is * given) * - when a new domain is created on the fly(\p configStr is not given) * * @param logger The logger to set the verbosity for. * @param dom The domain to set the verbosity for. * @param variable The (already read) variable to set verbosities from. ******************************************************************************************/ protected void getVerbosityFromConfig( Logger logger, Domain dom, Variable variable ) { // get logger number. It may happen that the logger is not existent in this domain tree. int loggerNo= dom.GetLoggerNo( logger ) ; if ( loggerNo < 0 ) return; Tokenizer verbosityTknzr= new Tokenizer(); Substring domainStr= new Substring(); AString domainStrBuf= new AString(); for( int varNo= 0; varNo< variable.Size(); varNo++ ) { verbosityTknzr.Set( variable.GetString( varNo ), '=' ); domainStr.Set( verbosityTknzr.Next() ); if ( domainStr.StartsWith( "INTERNAL_DOMAINS", DomainSensitivity ) ) { domainStrBuf._()._( domainStr.Buf, domainStr.Start + 16, domainStr.Length() -16 ); while ( domainStrBuf.CharAtStart() == '/' ) domainStrBuf.DeleteStart( 1 ); domainStrBuf.InsertAt( ALox.InternalDomains, 0 ); domainStr.Set( domainStrBuf ); } Substring verbosityStr= verbosityTknzr.Next(); if ( verbosityStr.IsEmpty() ) continue; int searchMode= 0; if ( domainStr.Consume ( '*' ) ) searchMode+= 2; if ( domainStr.ConsumeFromEnd( '*' ) ) searchMode+= 1; if( ( searchMode == 0 && dom.FullPath.Equals ( domainStr, DomainSensitivity ) ) || ( searchMode == 1 && dom.FullPath.StartsWith ( domainStr, DomainSensitivity ) ) || ( searchMode == 2 && dom.FullPath.EndsWith ( domainStr, DomainSensitivity ) ) || ( searchMode == 3 && dom.FullPath.IndexOf ( domainStr, 0, DomainSensitivity ) >=0 ) ) { Verbosity verbosity= ALox.ReadVerbosity( verbosityStr); dom.SetVerbosity( loggerNo, verbosity, variable.Priority ); // log info on this intMsg._()._NC( "Logger \"" )._NC( logger.GetName() ) ._NC( "\":" ).Tab(11 + maxLoggerNameLength) ._( '\'' )._NC( dom.FullPath ) ._( '\'' ).InsertChars(' ', maxDomainPathLength - dom.FullPath.Length() + 1 ) ._("= Verbosity." ); ALox.ToString( verbosity, dom.GetPriority(loggerNo), intMsg ).TrimEnd() ._('.'); logInternal( Verbosity.Info, "LGR", intMsg ); } } }