private void checkLabelBiDi ( CharSequence label , int labelStart , int labelLength , Info info ) { // IDNA2008 BiDi rule // Get the directionality of the first character. int c ; int i = labelStart ; c = Character . codePointAt ( label , i ) ; i += Character . charCount ( c ) ; int firstMask = U_MASK ( UBiDiProps . INSTANCE . getClass ( c ) ) ; // 1. The first character must be a character with BIDI property L, R // or AL. If it has the R or AL property, it is an RTL label; if it // has the L property, it is an LTR label. if ( ( firstMask & ~ L_R_AL_MASK ) != 0 ) { setNotOkBiDi ( info ) ; } // Get the directionality of the last non-NSM character. int lastMask ; int labelLimit = labelStart + labelLength ; for ( ; ; ) { if ( i >= labelLimit ) { lastMask = firstMask ; break ; } c = Character . codePointBefore ( label , labelLimit ) ; labelLimit -= Character . charCount ( c ) ; int dir = UBiDiProps . INSTANCE . getClass ( c ) ; if ( dir != UCharacterDirection . DIR_NON_SPACING_MARK ) { lastMask = U_MASK ( dir ) ; break ; } } // 3. In an RTL label, the end of the label must be a character with // BIDI property R, AL, EN or AN, followed by zero or more // characters with BIDI property NSM. // 6. In an LTR label, the end of the label must be a character with // BIDI property L or EN, followed by zero or more characters with // BIDI property NSM. if ( ( firstMask & L_MASK ) != 0 ? ( lastMask & ~ L_EN_MASK ) != 0 : ( lastMask & ~ R_AL_EN_AN_MASK ) != 0 ) { setNotOkBiDi ( info ) ; } // Get the directionalities of the intervening characters. int mask = 0 ; while ( i < labelLimit ) { c = Character . codePointAt ( label , i ) ; i += Character . charCount ( c ) ; mask |= U_MASK ( UBiDiProps . INSTANCE . getClass ( c ) ) ; } if ( ( firstMask & L_MASK ) != 0 ) { // 5. In an LTR label, only characters with the BIDI properties L, EN, // ES, CS, ET, ON, BN and NSM are allowed. if ( ( mask & ~ L_EN_ES_CS_ET_ON_BN_NSM_MASK ) != 0 ) { setNotOkBiDi ( info ) ; } } else { // 2. In an RTL label, only characters with the BIDI properties R, AL, // AN, EN, ES, CS, ET, ON, BN and NSM are allowed. if ( ( mask & ~ R_AL_AN_EN_ES_CS_ET_ON_BN_NSM_MASK ) != 0 ) { setNotOkBiDi ( info ) ; } // 4. In an RTL label, if an EN is present, no AN may be present, and // vice versa. if ( ( mask & EN_AN_MASK ) == EN_AN_MASK ) { setNotOkBiDi ( info ) ; } } // An RTL label is a label that contains at least one character of type // R, AL or AN. [...] // A "BIDI domain name" is a domain name that contains at least one RTL // label. [...] // The following rule, consisting of six conditions, applies to labels // in BIDI domain names. if ( ( ( firstMask | mask | lastMask ) & R_AL_AN_MASK ) != 0 ) { setBiDi ( info ) ; } }
processing several earlier labels .