package coloredlightscore.src.asm.transformer.core;
import com.google.common.base.Function;
import com.google.common.base.Supplier;
import com.google.common.collect.AbstractIterator;
import com.google.common.collect.Iterables;
import cpw.mods.fml.common.FMLLog;
import java.lang.reflect.Field;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import static com.google.common.base.Preconditions.checkArgument;
public final class JavaUtils {
private JavaUtils() {
}
public static <T> T safeArrayAccess(T[] array, int index) {
return arrayIndexExists(array, index) ? array[index] : null;
}
public static boolean arrayIndexExists(Object[] array, int index) {
return index >= 0 && index < array.length;
}
public static <T> T defaultedArrayAccess(T[] array, int index, T defaultValue) {
return arrayIndexExists(array, index) ? array[index] : defaultValue;
}
public static boolean listIndexExists(List<?> list, int index) {
return index >= 0 && index < list.size();
}
public static <T> T safeListAccess(List<T> list, int index) {
return listIndexExists(list, index) ? list.get(index) : null;
}
public static <T> Iterator<T> nCallsIterator(final Supplier<T> supplier, final int n) {
return new AbstractIterator<T>() {
private int counter = 0;
@Override
protected T computeNext() {
return ++counter <= n ? supplier.get() : endOfData();
}
};
}
public static <T> Iterable<T> nCalls(final Supplier<T> supplier, final int n) {
return new Iterable<T>() {
@Override
public Iterator<T> iterator() {
return nCallsIterator(supplier, n);
}
};
}
public static <T> List<T> nullToEmpty(List<T> nullable) {
return nullable == null ? Collections.<T>emptyList() : nullable;
}
public static <T> Iterable<T> concatNullable(Iterable<T> a, Iterable<T> b) {
return a == null ? (b == null ? Collections.<T>emptyList() : b) : (b == null ? a : Iterables.concat(a, b));
}
public static <T> void foreach(Iterable<T> it, Consumer<T> c) {
foreach(it.iterator(), c);
}
public static <T> void foreach(Iterator<T> it, Consumer<T> c) {
while (it.hasNext()) {
c.apply(it.next());
}
}
public static <T> void foreach(T[] arr, Consumer<T> c) {
for (T t : arr) {
c.apply(t);
}
}
public static <T, R> R[] transform(T[] in, R[] out, Function<T, R> func) {
int l = in.length;
checkArgument(l == out.length);
for (int i = 0; i < l; ++i) {
out[i] = func.apply(in[i]);
}
return out;
}
public static RuntimeException throwUnchecked(Throwable t) {
JavaUtils.<RuntimeException>throwUnchecked0(t);
throw new AssertionError("unreachable");
}
@SuppressWarnings("unchecked")
private static <T extends Throwable> void throwUnchecked0(Throwable t) throws T {
throw (T) t;
}
public static long encodeInts(int a, int b) {
return (((long) a) << 32) | (b & 0xffffffffL);
}
public static int decodeIntA(long l) {
return (int) (l >> 32);
}
public static int decodeIntB(long l) {
return (int) l;
}
public static <T extends Enum<T>> T[] getEnumValues(Class<T> clazz) {
return ENUM_GETTER.getEnumValues(clazz);
}
public static <T extends Enum<T>> T byOrdinal(Class<T> clazz, int ordinal) {
return safeArrayAccess(getEnumValues(clazz), ordinal);
}
interface EnumValueGetter {
<T extends Enum<T>> T[] getEnumValues(Class<T> clazz);
}
private static EnumValueGetter ENUM_GETTER;
static {
try {
Class.forName("sun.misc.SharedSecrets");
ENUM_GETTER = Class.forName("de.take_weiland.mods.commons.util.EnumGetterShared").asSubclass(EnumValueGetter.class).newInstance();
} catch (Exception e) {
FMLLog.info("sun.misc.SharedSecrets not found. Falling back to default EnumGetter");
ENUM_GETTER = new EnumGetterCloned();
}
}
private static Object unsafe;
private static boolean unsafeChecked;
private static void initUnsafe() {
if (unsafeChecked) {
return;
}
try {
Field field = Class.forName("sun.misc.Unsafe").getDeclaredField("theUnsafe");
field.setAccessible(true);
unsafe = field.get(null);
} catch (Exception e) {
e.printStackTrace();
}
}
public static boolean hasUnsafe() {
initUnsafe();
return unsafe != null;
}
public static Object getUnsafe() {
initUnsafe();
return unsafe;
}
}