<s> package org . eclipse . jdt . internal . core . search ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . internal . compiler . parser . ScannerHelper ; public final class StringOperation { private final static int [ ] EMPTY_REGIONS = new int [ 0 ] ; public static final int [ ] getCamelCaseMatchingRegions ( String pattern , int patternStart , int patternEnd , String name , int nameStart , int nameEnd , boolean samePartCount ) { if ( name == null ) return null ; if ( pattern == null ) { return EMPTY_REGIONS ; } if ( patternEnd < 0 ) patternEnd = pattern . length ( ) ; if ( nameEnd < 0 ) nameEnd = name . length ( ) ; if ( patternEnd <= patternStart ) { return nameEnd <= nameStart ? new int [ ] { patternStart , patternEnd - patternStart } : null ; } if ( nameEnd <= nameStart ) return null ; if ( name . charAt ( nameStart ) != pattern . charAt ( patternStart ) ) { return null ; } char patternChar , nameChar ; int iPattern = patternStart ; int iName = nameStart ; int parts = 1 ; for ( int i = patternStart + 1 ; i < patternEnd ; i ++ ) { final char ch = pattern . charAt ( i ) ; if ( ch < ScannerHelper . MAX_OBVIOUS ) { if ( ( ScannerHelper . OBVIOUS_IDENT_CHAR_NATURES [ ch ] & ( ScannerHelper . C_UPPER_LETTER | ScannerHelper . C_DIGIT ) ) != 0 ) { parts ++ ; } } else if ( Character . isJavaIdentifierPart ( ch ) && ( Character . isUpperCase ( ch ) || Character . isDigit ( ch ) ) ) { parts ++ ; } } int [ ] segments = null ; int count = 0 ; int segmentStart = iName ; while ( true ) { iPattern ++ ; iName ++ ; if ( iPattern == patternEnd ) { if ( ! samePartCount || iName == nameEnd ) { if ( segments == null ) { segments = new int [ 2 ] ; } segments [ count ++ ] = segmentStart ; segments [ count ++ ] = iName - segmentStart ; if ( count < segments . length ) { System . arraycopy ( segments , 0 , segments = new int [ count ] , 0 , count ) ; } return segments ; } int segmentEnd = iName ; while ( true ) { if ( iName == nameEnd ) { if ( segments == null ) { segments = new int [ 2 ] ; } segments [ count ++ ] = segmentStart ; segments [ count ++ ] = segmentEnd - segmentStart ; if ( count < segments . length ) { System . arraycopy ( segments , 0 , segments = new int [ count ] , 0 , count ) ; } return segments ; } nameChar = name . charAt ( iName ) ; if ( nameChar < ScannerHelper . MAX_OBVIOUS ) { if ( ( ScannerHelper . OBVIOUS_IDENT_CHAR_NATURES [ nameChar ] & ScannerHelper . C_UPPER_LETTER ) != 0 ) { return null ; } } else if ( ! Character . isJavaIdentifierPart ( nameChar ) || Character . isUpperCase ( nameChar ) ) { return null ; } iName ++ ; } } if ( iName == nameEnd ) { return null ; } if ( ( patternChar = pattern . charAt ( iPattern ) ) == name . charAt ( iName ) ) { continue ; } int segmentEnd = iName ; if ( patternChar < ScannerHelper . MAX_OBVIOUS ) { if ( ( ScannerHelper . OBVIOUS_IDENT_CHAR_NATURES [ patternChar ] & ( ScannerHelper . C_UPPER_LETTER | ScannerHelper . C_DIGIT ) ) == 0 ) { return null ; } } else if ( Character . isJavaIdentifierPart ( patternChar ) && ! Character . isUpperCase ( patternChar ) && ! Character . isDigit ( patternChar ) ) { return null ; } while ( true ) { if ( iName == nameEnd ) { return null ; } nameChar = name . charAt ( iName ) ; if ( nameChar < ScannerHelper . MAX_OBVIOUS ) { int charNature = ScannerHelper . OBVIOUS_IDENT_CHAR_NATURES [ nameChar ] ; if ( ( charNature & ( ScannerHelper . C_LOWER_LETTER | ScannerHelper . C_SPECIAL ) ) != 0 ) { iName ++ ; } else if ( ( charNature & ScannerHelper . C_DIGIT ) != 0 ) { if ( patternChar == nameChar ) break ; iName ++ ; } else if ( patternChar != nameChar ) { return null ; } else { break ; } } else if ( Character . isJavaIdentifierPart ( nameChar ) && ! Character . isUpperCase ( nameChar ) ) { iName ++ ; } else if ( Character . isDigit ( nameChar ) ) { if ( patternChar == nameChar ) break ; iName ++ ; } else if ( patternChar != nameChar ) { return null ; } else { break ; } } if ( segments == null ) { segments = new int [ parts * 2 ] ; } segments [ count ++ ] = segmentStart ; segments [ count ++ ] = segmentEnd - segmentStart ; segmentStart = iName ; } } public static final int [ ] getPatternMatchingRegions ( String pattern , int patternStart , int patternEnd , String name , int nameStart , int nameEnd , boolean isCaseSensitive ) { if ( name == null ) return null ; if ( pattern == null ) { return EMPTY_REGIONS ; } int iPattern = patternStart ; int iName = nameStart ; if ( patternEnd < 0 ) patternEnd = pattern . length ( ) ; if ( nameEnd < 0 ) nameEnd = name . length ( ) ; int questions = 0 ; int parts = 0 ; char previous = 0 ; for ( int i = patternStart ; i < patternEnd ; i ++ ) { char ch = pattern . charAt ( i ) ; switch ( ch ) { case '?' : questions ++ ; break ; case '*' : break ; default : switch ( previous ) { case 0 : case '?' : case '*' : parts ++ ; break ; } } previous = ch ; } if ( parts == 0 ) { if ( questions <= ( nameEnd - nameStart ) ) return EMPTY_REGIONS ; return null ; } int [ ] segments = new int [ parts * 2 ] ; int count = 0 ; int start = iName ; char patternChar = 0 ; previous = 0 ; while ( ( iPattern < patternEnd ) && ( patternChar = pattern . charAt ( iPattern ) ) != '*' ) { if ( iName == nameEnd ) return null ; if ( patternChar == '?' ) { switch ( previous ) { case 0 : case '?' : break ; default : segments [ count ++ ] = start ; segments [ count ++ ] = iPattern - start ; break ; } } else { if ( isCaseSensitive ) { if ( patternChar != name . charAt ( iName ) ) { return null ; } } else if ( ScannerHelper . toLowerCase ( patternChar ) != ScannerHelper . toLowerCase ( name . charAt ( iName ) ) ) { return null ; } switch ( previous ) { case 0 : case '?' : start = iPattern ; break ; } } iName ++ ; iPattern ++ ; previous = patternChar ; } int segmentStart ; if ( patternChar == '*' ) { if ( iPattern > 0 && previous != '?' ) { segments [ count ++ ] = start ; segments [ count ++ ] = iName - start ; start = iName ; } segmentStart = ++ iPattern ; } else { if ( iName == nameEnd ) { if ( count == ( parts * 2 ) ) return segments ; int end = patternEnd ; if ( previous == '?' ) { while ( pattern . charAt ( -- end - 1 ) == '?' ) { if ( end == start ) { return new int [ ] { patternStart , patternEnd - patternStart } ; } } } return new int [ ] { start , end - start } ; } return null ; } int prefixStart = iName ; int previousCount = count ; previous = patternChar ; char previousSegment = patternChar ; checkSegment : while ( iName < nameEnd ) { if ( iPattern == patternEnd ) { iPattern = segmentStart ; iName = ++ prefixStart ; previous = previousSegment ; continue checkSegment ; } if ( ( patternChar = pattern . charAt ( iPattern ) ) == '*' ) { segmentStart = ++ iPattern ; if ( segmentStart == patternEnd ) { if ( count < ( parts * 2 ) ) { segments [ count ++ ] = start ; segments [ count ++ ] = iName - start ; } return segments ; } switch ( previous ) { case '*' : case '?' : break ; default : segments [ count ++ ] = start ; segments [ count ++ ] = iName - start ; break ; } prefixStart = iName ; start = prefixStart ; previous = patternChar ; previousSegment = patternChar ; continue checkSegment ; } previousCount = count ; if ( patternChar == '?' ) { switch ( previous ) { case '*' : case '?' : break ; default : segments [ count ++ ] = start ; segments [ count ++ ] = iName - start ; break ; } } else { boolean mismatch ; if ( isCaseSensitive ) { mismatch = name . charAt ( iName ) != patternChar ; } else { mismatch = ScannerHelper . toLowerCase ( name . charAt ( iName ) ) != ScannerHelper . toLowerCase ( patternChar ) ; } if ( mismatch ) { iPattern = segmentStart ; iName = ++ prefixStart ; start = prefixStart ; count = previousCount ; previous = previousSegment ; continue checkSegment ; } switch ( previous ) { case '?' : start = iName ; break ; } } iName ++ ; iPattern ++ ; previous = patternChar ; } if ( ( segmentStart == patternEnd ) || ( iName == nameEnd && iPattern == patternEnd ) || ( iPattern == patternEnd - 1 && pattern . charAt ( iPattern ) == '*' ) ) { if ( count < ( parts * 2 ) ) { segments [ count ++ ] = start ; segments [ count ++ ] = iName - start ; } return segments ; } return null ; } } </s>