static LocaleParserState assignLocaleComponent()

in resources/src/main/java/org/robolectric/res/android/ResTable_config.java [1781:1890]


  static LocaleParserState assignLocaleComponent(ResTable_config config,
      final String start, int size, LocaleParserState state) {

    /* It is assumed that this function is not invoked with state.parserState
     * set to IGNORE_THE_REST. The condition is checked by setBcp47Locale
     * function. */

    if (state.parserState == State.UNICODE_EXTENSION) {
      switch (size) {
        case 1:
          /* Other BCP 47 extensions are not supported at the moment */
          state.parserState = State.IGNORE_THE_REST;
          break;
        case 2:
          if (state.unicodeState == UnicodeState.NO_KEY ||
              state.unicodeState == UnicodeState.EXPECT_KEY) {
            /* Analyze Unicode extension key. Currently only 'nu'
             * (numbering system) is supported.*/
            if ((start.charAt(0) == 'n' || start.charAt(0) == 'N') &&
                (start.charAt(1) == 'u' || start.charAt(1) == 'U')) {
              state.unicodeState = UnicodeState.NUMBERING_SYSTEM;
            } else {
              state.unicodeState = UnicodeState.IGNORE_KEY;
            }
          } else {
            /* Keys are not allowed in other state allowed, ignore the rest. */
            state.parserState = State.IGNORE_THE_REST;
          }
          break;
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
          switch (state.unicodeState) {
            case NUMBERING_SYSTEM:
              /* Accept only the first occurrence of the numbering system. */
              if (config.localeNumberingSystem[0] == '\0') {
                for (int i = 0; i < size; ++i) {
                  config.localeNumberingSystem[i] = (byte) Character.toLowerCase(start.charAt(i));
                }
                state.unicodeState = UnicodeState.EXPECT_KEY;
              } else {
                state.parserState = State.IGNORE_THE_REST;
              }
              break;
            case IGNORE_KEY:
              /* Unsupported Unicode keyword. Ignore. */
              state.unicodeState = UnicodeState.EXPECT_KEY;
              break;
            case EXPECT_KEY:
              /* A keyword followed by an attribute is not allowed. */
              state.parserState = State.IGNORE_THE_REST;
              break;
            case NO_KEY:
              /* Extension attribute. Do nothing. */
              break;
          }
          break;
        default:
          /* Unexpected field length - ignore the rest and treat as an error */
          state.parserState = State.IGNORE_THE_REST;
      }
      return state;
    }

    switch (size) {
      case 0:
        state.parserState = State.IGNORE_THE_REST;
        break;
      case 1:
        state.parserState = (start.charAt(0) == 'u' || start.charAt(0) == 'U')
            ? State.UNICODE_EXTENSION
            : State.IGNORE_THE_REST;
        break;
      case 2:
      case 3:
        if (isTruthy(config.language[0])) {
          config.packRegion(start);
        } else {
          config.packLanguage(start);
        }
        break;
      case 4:
        char start0 = start.charAt(0);
        if ('0' <= start0 && start0 <= '9') {
          // this is a variant, so fall through
        } else {
          config.localeScript[0] = (byte) Character.toUpperCase(start0);
          for (int i = 1; i < 4; ++i) {
            config.localeScript[i] = (byte) Character.toLowerCase(start.charAt(i));
          }
          break;
        }
        // fall through
      case 5:
      case 6:
      case 7:
      case 8:
        for (int i = 0; i < size; ++i) {
          config.localeVariant[i] = (byte) Character.toLowerCase(start.charAt(i));
        }
        break;
      default:
        state.parserState = State.IGNORE_THE_REST;
    }

    return state;
  }