package openmods.utils;
import com.google.common.base.Preconditions;
import com.google.common.base.Throwables;
import com.google.common.collect.UnmodifiableIterator;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Set;
public class ByteUtils {
public abstract static class BitIterator extends UnmodifiableIterator<Boolean> {
private int value;
public BitIterator(int value) {
this.value = value;
}
@Override
public boolean hasNext() {
return value != 0;
}
@Override
public Boolean next() {
boolean result = (value & 1) != 0;
value >>= 1;
return result;
}
}
public abstract static class CountingBitIterator<T> extends UnmodifiableIterator<T> {
private int value;
private int count;
public CountingBitIterator(int value) {
this.value = value;
}
protected abstract T convert(int bit);
@Override
public boolean hasNext() {
return value != 0;
}
@Override
public T next() {
while (value != 0) {
final boolean result = (value & 1) != 0;
value >>= 1;
if (result) return convert(count++);
else count++;
}
throw new IllegalStateException();
}
}
public static int on(int val, int bit) {
return val | (1 << bit);
}
public static int off(int val, int bit) {
return val & ~(1 << bit);
}
public static int set(int val, int bit, boolean flag) {
return flag? (val | (1 << bit)) : (val & ~(1 << bit));
}
public static long set(long val, int bit, boolean flag) {
return flag? (val | (1 << bit)) : (val & ~(1 << bit));
}
public static boolean get(int val, int slot) {
return (val & (1 << slot)) != 0;
}
public static boolean get(long val, int slot) {
return (val & (1 << slot)) != 0;
}
public static void writeVLI(DataOutput output, int value) {
// I'm not touching signed integers.
Preconditions.checkArgument(value >= 0, "Value cannot be negative");
try {
while (true) {
int b = value & 0x7F;
int next = value >> 7;
if (next > 0) {
b |= 0x80;
output.writeByte(b);
value = next;
} else {
output.writeByte(b);
break;
}
}
} catch (IOException e) {
Throwables.propagate(e);
}
}
public static int readVLI(DataInput input) {
int result = 0;
int shift = 0;
int b;
try {
do {
b = input.readByte();
result = result | ((b & 0x7F) << shift);
shift += 7;
} while (b < 0);
} catch (IOException e) {
Throwables.propagate(e);
}
return result;
}
public static int nextPowerOf2(int v) {
v--;
v |= v >> 1;
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v++;
return v;
}
public static boolean isPowerOfTwo(int size) {
return (size & (size - 1)) == 0;
}
public static int enumSetToBits(Set<? extends Enum<?>> dirs) {
int value = 0;
for (Enum<?> e : dirs) {
final int bit = e.ordinal();
Preconditions.checkArgument(bit < Integer.SIZE, "Enum %s has too many values", e.getClass());
value = on(value, bit);
}
return value;
}
}