All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.robolectric.shadows.Converter2 Maven / Gradle / Ivy

package org.robolectric.shadows;

import android.util.TypedValue;
import org.robolectric.res.AttrData;
import org.robolectric.util.Util;

public class Converter2 {
  private static int nextStringCookie = 0xbaaa5;

  synchronized static int getNextStringCookie() {
    return nextStringCookie++;
  }

  public static Converter2 getConverterFor(AttrData attrData, String type) {
    switch (type) {
      case "enum":
        return new EnumConverter(attrData);
      case "flag":
      case "flags": // because {@link ResourceTable#gFormatFlags} uses "flags"
        return new FlagConverter(attrData);
      case "boolean":
        return new FromBoolean();
      case "color":
        return new FromColor();
      case "dimension":
        return new FromDimen();
      case "float":
        return new FromFloat();
      case "integer":
        return new FromInt();
      case "string":
        return new FromCharSequence();
      case "fraction":
        return new FromFraction();
      default:
        throw new UnsupportedOperationException("Type not supported: " + type);
    }
  }

  public boolean fillTypedValue(T data, TypedValue typedValue, boolean throwOnFailure) {
    return false;
  }

  public static class FromCharSequence extends Converter2 {

    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      typedValue.type = TypedValue.TYPE_STRING;
      typedValue.data = 0;
      typedValue.assetCookie = getNextStringCookie();
      typedValue.string = data;
      return true;
    }
  }

  public static class FromColor extends Converter2 {
    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      try {
        typedValue.type = ResourceHelper.getColorType(data);
        typedValue.data = ResourceHelper.getColor(data);
        typedValue.assetCookie = 0;
        typedValue.string = null;
        return true;
      } catch (NumberFormatException nfe) {
        return false;
      }
    }

  }


  private static class FromInt extends Converter2 {
    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      try {
        if (data.startsWith("0x")) {
          typedValue.type = TypedValue.TYPE_INT_HEX;
        } else {
          typedValue.type = TypedValue.TYPE_INT_DEC;
        }
        typedValue.data = convertInt(data);
        typedValue.assetCookie = 0;
        typedValue.string = null;
        return true;
      } catch (NumberFormatException nfe) {
        return false;
      }
    }

  }

  private static class FromFraction extends Converter2 {
    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      return ResourceHelper2.parseFloatAttribute(null, data, typedValue, false);
    }
  }

  private static class FromFloat extends Converter2 {
    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      return ResourceHelper2.parseFloatAttribute(null, data, typedValue, false);
    }
  }

  private static class FromBoolean extends Converter2 {
    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      typedValue.type = TypedValue.TYPE_INT_BOOLEAN;
      typedValue.assetCookie = 0;
      typedValue.string = null;

      if ("true".equalsIgnoreCase(data)) {
        typedValue.data = 1;
        return true;
      } else if ("false".equalsIgnoreCase(data)) {
        typedValue.data = 0;
        return true;
      }
      return false;
    }
  }

  private static class FromDimen extends Converter2 {
    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      return ResourceHelper2.parseFloatAttribute(null, data, typedValue, true);
    }
  }

  private static int convertInt(String rawValue) {
    try {
      // Decode into long, because there are some large hex values in the android resource files
      // (e.g. config_notificationsBatteryLowARGB = 0xFFFF0000 in sdk 14).
      // Integer.decode() does not support large, i.e. negative values in hex numbers.
      // try parsing decimal number
      return (int) Long.parseLong(rawValue);
    } catch (NumberFormatException nfe) {
      // try parsing hex number
      return Long.decode(rawValue).intValue();
    }
  }

  private static class EnumConverter extends EnumOrFlagConverter {
    EnumConverter(AttrData attrData) {
      super(attrData);
    }

    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      typedValue.type = TypedValue.TYPE_INT_HEX;
      if (throwOnFailure) {
        typedValue.data = findValueFor(data);
      } else {
        try {
          typedValue.data = findValueFor(data);
        } catch (Exception e) {
          return false;
        }
      }
      typedValue.assetCookie = 0;
      typedValue.string = null;
      return true;
    }
  }

  private static class FlagConverter extends EnumOrFlagConverter {
    FlagConverter(AttrData attrData) {
      super(attrData);
    }

    @Override
    public boolean fillTypedValue(String data, TypedValue typedValue, boolean throwOnFailure) {
      int flags = 0;
      for (String key : data.split("\\|", 0)) {
        if (throwOnFailure) {
          flags |= findValueFor(key);
        } else {
          try {
            flags |= findValueFor(key);
          } catch (Exception e) {
            return false;
          }
        }
      }

      typedValue.type = TypedValue.TYPE_INT_HEX;
      typedValue.data = flags;
      typedValue.assetCookie = 0;
      typedValue.string = null;
      return true;
    }
  }

  private static class EnumOrFlagConverter extends Converter2 {
    private final AttrData attrData;

    EnumOrFlagConverter(AttrData attrData) {
      this.attrData = attrData;
    }

    int findValueFor(String key) {
      String valueFor = attrData.getValueFor(key);
      if (valueFor == null) {
        // Maybe they have passed in the value directly, rather than the name.
        if (attrData.isValue(key)) {
          valueFor = key;
        } else {
          throw new RuntimeException("no value found for " + key);
        }
      }
      return Util.parseInt(valueFor);
    }
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy