content: package com.airbnb.lottie.parser;
  
  import android.graphics.Color;
  import android.graphics.PointF;
  
  import androidx.annotation.ColorInt;
  
  import com.airbnb.lottie.parser.moshi.JsonReader;
  
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.List;
  
  class JsonUtils {
    private JsonUtils() {
    }
  
    /**
     * [r,g,b]
     */
    @ColorInt static int jsonToColor(JsonReader reader) throws IOException {
      reader.beginArray();
      int r = (int) (reader.nextDouble() * 255);
      int g = (int) (reader.nextDouble() * 255);
      int b = (int) (reader.nextDouble() * 255);
      while (reader.hasNext()) {
        reader.skipValue();
      }
      reader.endArray();
      return Color.argb(255, r, g, b);
    }
  
    static List<PointF> jsonToPoints(JsonReader reader, float scale) throws IOException {
      List<PointF> points = new ArrayList<>();
  
      reader.beginArray();
      while (reader.peek() == JsonReader.Token.BEGIN_ARRAY) {
        reader.beginArray();
        points.add(jsonToPoint(reader, scale));
        reader.endArray();
      }
      reader.endArray();
      return points;
    }
  
    static PointF jsonToPoint(JsonReader reader, float scale) throws IOException {
      switch (reader.peek()) {
        case NUMBER:
          return jsonNumbersToPoint(reader, scale);
        case BEGIN_ARRAY:
          return jsonArrayToPoint(reader, scale);
        case BEGIN_OBJECT:
          return jsonObjectToPoint(reader, scale);
        default:
          throw new IllegalArgumentException("Unknown point starts with " + reader.peek());
      }
    }
  
    private static PointF jsonNumbersToPoint(JsonReader reader, float scale) throws IOException {
      float x = (float) reader.nextDouble();
      float y = (float) reader.nextDouble();
      while (reader.hasNext()) {
        reader.skipValue();
      }
      return new PointF(x * scale, y * scale);
    }
  
    private static PointF jsonArrayToPoint(JsonReader reader, float scale) throws IOException {
      float x;
      float y;
      reader.beginArray();
      x = (float) reader.nextDouble();
      y = (float) reader.nextDouble();
      while (reader.peek() != JsonReader.Token.END_ARRAY) {
        reader.skipValue();
      }
      reader.endArray();
      return new PointF(x * scale, y * scale);
    }
  
    private static final JsonReader.Options POINT_NAMES = JsonReader.Options.of("x", "y");
  
    private static PointF jsonObjectToPoint(JsonReader reader, float scale) throws IOException {
      float x = 0f;
      float y = 0f;
      reader.beginObject();
      while (reader.hasNext()) {
        switch (reader.selectName(POINT_NAMES)) {
          case 0:
            x = valueFromObject(reader);
            break;
          case 1:
            y = valueFromObject(reader);
            break;
          default:
            reader.skipName();
            reader.skipValue();
        }
      }
      reader.endObject();
      return new PointF(x * scale, y * scale);
    }
  
    static float valueFromObject(JsonReader reader) throws IOException {
      JsonReader.Token token = reader.peek();
      switch (token) {
        case NUMBER:
          return (float) reader.nextDouble();
        case BEGIN_ARRAY:
          reader.beginArray();
          float val = (float) reader.nextDouble();
          while (reader.hasNext()) {
            reader.skipValue();
          }
          reader.endArray();
          return val;
        default:
          throw new IllegalArgumentException("Unknown value for token of type " + token);
      }
    }
  }
  