public static void parse()

in google-http-client/src/main/java/com/google/api/client/http/UrlEncodedParser.java [127:212]


  public static void parse(Reader reader, Object data) throws IOException {
    Class<?> clazz = data.getClass();
    ClassInfo classInfo = ClassInfo.of(clazz);
    List<Type> context = Arrays.<Type>asList(clazz);
    GenericData genericData = GenericData.class.isAssignableFrom(clazz) ? (GenericData) data : null;
    @SuppressWarnings("unchecked")
    Map<Object, Object> map = Map.class.isAssignableFrom(clazz) ? (Map<Object, Object>) data : null;
    ArrayValueMap arrayValueMap = new ArrayValueMap(data);
    StringWriter nameWriter = new StringWriter();
    StringWriter valueWriter = new StringWriter();
    boolean readingName = true;
    mainLoop: while (true) {
      int read = reader.read();
      switch (read) {
        case -1:
      // falls through
        case '&':
          // parse name/value pair
          String name = CharEscapers.decodeUri(nameWriter.toString());
          if (name.length() != 0) {
            String stringValue = CharEscapers.decodeUri(valueWriter.toString());
            // get the field from the type information
            FieldInfo fieldInfo = classInfo.getFieldInfo(name);
            if (fieldInfo != null) {
              Type type =
                  Data.resolveWildcardTypeOrTypeVariable(context, fieldInfo.getGenericType());
              // type is now class, parameterized type, or generic array type
              if (Types.isArray(type)) {
                // array that can handle repeating values
                Class<?> rawArrayComponentType =
                    Types.getRawArrayComponentType(context, Types.getArrayComponentType(type));
                arrayValueMap.put(fieldInfo.getField(), rawArrayComponentType,
                    parseValue(rawArrayComponentType, context, stringValue));
              } else if (Types.isAssignableToOrFrom(
                  Types.getRawArrayComponentType(context, type), Iterable.class)) {
                // iterable that can handle repeating values
                @SuppressWarnings("unchecked")
                Collection<Object> collection = (Collection<Object>) fieldInfo.getValue(data);
                if (collection == null) {
                  collection = Data.newCollectionInstance(type);
                  fieldInfo.setValue(data, collection);
                }
                Type subFieldType = type == Object.class ? null : Types.getIterableParameter(type);
                collection.add(parseValue(subFieldType, context, stringValue));
              } else {
                // parse into a field that assumes it is a single value
                fieldInfo.setValue(data, parseValue(type, context, stringValue));
              }
            } else if (map != null) {
              // parse into a map: store as an ArrayList of values
              @SuppressWarnings("unchecked")
              ArrayList<String> listValue = (ArrayList<String>) map.get(name);
              if (listValue == null) {
                listValue = new ArrayList<String>();
                if (genericData != null) {
                  genericData.set(name, listValue);
                } else {
                  map.put(name, listValue);
                }
              }
              listValue.add(stringValue);
            }
          }
          // ready to read next name/value pair
          readingName = true;
          nameWriter = new StringWriter();
          valueWriter = new StringWriter();
          if (read == -1) {
            break mainLoop;
          }
          break;
        case '=':
          // finished with name, now read value
          readingName = false;
          break;
        default:
          // read one more character
          if (readingName) {
            nameWriter.write(read);
          } else {
            valueWriter.write(read);
          }
      }
    }
    arrayValueMap.setValues();
  }