/* * Decompiled with CFR 0.152. * * Could not load the following classes: * com.google.common.hash.HashCode * com.google.common.hash.HashFunction * com.google.common.hash.Hasher * com.google.common.hash.Hashing * com.mojang.datafixers.util.Pair * com.mojang.serialization.DataResult * com.mojang.serialization.DynamicOps * com.mojang.serialization.ListBuilder * com.mojang.serialization.MapLike * com.mojang.serialization.RecordBuilder * com.mojang.serialization.RecordBuilder$AbstractUniversalBuilder */ package net.minecraft.util; import com.google.common.hash.HashCode; import com.google.common.hash.HashFunction; import com.google.common.hash.Hasher; import com.google.common.hash.Hashing; import com.mojang.datafixers.util.Pair; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import com.mojang.serialization.ListBuilder; import com.mojang.serialization.MapLike; import com.mojang.serialization.RecordBuilder; import java.lang.runtime.SwitchBootstraps; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; import java.util.stream.IntStream; import java.util.stream.LongStream; import java.util.stream.Stream; import net.minecraft.util.AbstractListBuilder; public class HashOps implements DynamicOps { private static final byte TAG_EMPTY = 1; private static final byte TAG_MAP_START = 2; private static final byte TAG_MAP_END = 3; private static final byte TAG_LIST_START = 4; private static final byte TAG_LIST_END = 5; private static final byte TAG_BYTE = 6; private static final byte TAG_SHORT = 7; private static final byte TAG_INT = 8; private static final byte TAG_LONG = 9; private static final byte TAG_FLOAT = 10; private static final byte TAG_DOUBLE = 11; private static final byte TAG_STRING = 12; private static final byte TAG_BOOLEAN = 13; private static final byte TAG_BYTE_ARRAY_START = 14; private static final byte TAG_BYTE_ARRAY_END = 15; private static final byte TAG_INT_ARRAY_START = 16; private static final byte TAG_INT_ARRAY_END = 17; private static final byte TAG_LONG_ARRAY_START = 18; private static final byte TAG_LONG_ARRAY_END = 19; private static final byte[] EMPTY_PAYLOAD = new byte[]{1}; private static final byte[] FALSE_PAYLOAD = new byte[]{13, 0}; private static final byte[] TRUE_PAYLOAD = new byte[]{13, 1}; public static final byte[] EMPTY_MAP_PAYLOAD = new byte[]{2, 3}; public static final byte[] EMPTY_LIST_PAYLOAD = new byte[]{4, 5}; private static final DataResult UNSUPPORTED_OPERATION_ERROR = DataResult.error(() -> "Unsupported operation"); private static final Comparator HASH_COMPARATOR = Comparator.comparingLong(HashCode::padToLong); private static final Comparator> MAP_ENTRY_ORDER = Map.Entry.comparingByKey(HASH_COMPARATOR).thenComparing(Map.Entry.comparingByValue(HASH_COMPARATOR)); private static final Comparator> MAPLIKE_ENTRY_ORDER = Comparator.comparing(Pair::getFirst, HASH_COMPARATOR).thenComparing(Pair::getSecond, HASH_COMPARATOR); public static final HashOps CRC32C_INSTANCE = new HashOps(Hashing.crc32c()); private final HashFunction hashFunction; private final HashCode empty; private final HashCode emptyMap; private final HashCode emptyList; private final HashCode trueHash; private final HashCode falseHash; public HashOps(HashFunction hashFunction) { this.hashFunction = hashFunction; this.empty = hashFunction.hashBytes(EMPTY_PAYLOAD); this.emptyMap = hashFunction.hashBytes(EMPTY_MAP_PAYLOAD); this.emptyList = hashFunction.hashBytes(EMPTY_LIST_PAYLOAD); this.falseHash = hashFunction.hashBytes(FALSE_PAYLOAD); this.trueHash = hashFunction.hashBytes(TRUE_PAYLOAD); } public HashCode empty() { return this.empty; } public HashCode emptyMap() { return this.emptyMap; } public HashCode emptyList() { return this.emptyList; } public HashCode createNumeric(Number value) { Number number = value; Objects.requireNonNull(number); Number number2 = number; int n = 0; return switch (SwitchBootstraps.typeSwitch("typeSwitch", new Object[]{Byte.class, Short.class, Integer.class, Long.class, Double.class, Float.class}, (Object)number2, n)) { case 0 -> { Byte v = (Byte)number2; yield this.createByte(v); } case 1 -> { Short v = (Short)number2; yield this.createShort(v); } case 2 -> { Integer v = (Integer)number2; yield this.createInt(v); } case 3 -> { Long v = (Long)number2; yield this.createLong(v); } case 4 -> { Double v = (Double)number2; yield this.createDouble(v); } case 5 -> { Float v = (Float)number2; yield this.createFloat(v.floatValue()); } default -> this.createDouble(value.doubleValue()); }; } public HashCode createByte(byte value) { return this.hashFunction.newHasher(2).putByte((byte)6).putByte(value).hash(); } public HashCode createShort(short value) { return this.hashFunction.newHasher(3).putByte((byte)7).putShort(value).hash(); } public HashCode createInt(int value) { return this.hashFunction.newHasher(5).putByte((byte)8).putInt(value).hash(); } public HashCode createLong(long value) { return this.hashFunction.newHasher(9).putByte((byte)9).putLong(value).hash(); } public HashCode createFloat(float value) { return this.hashFunction.newHasher(5).putByte((byte)10).putFloat(value).hash(); } public HashCode createDouble(double value) { return this.hashFunction.newHasher(9).putByte((byte)11).putDouble(value).hash(); } public HashCode createString(String value) { return this.hashFunction.newHasher().putByte((byte)12).putInt(value.length()).putUnencodedChars((CharSequence)value).hash(); } public HashCode createBoolean(boolean value) { return value ? this.trueHash : this.falseHash; } private static Hasher hashMap(Hasher hasher, Map map) { hasher.putByte((byte)2); map.entrySet().stream().sorted(MAP_ENTRY_ORDER).forEach(e -> hasher.putBytes(((HashCode)e.getKey()).asBytes()).putBytes(((HashCode)e.getValue()).asBytes())); hasher.putByte((byte)3); return hasher; } private static Hasher hashMap(Hasher hasher, Stream> map) { hasher.putByte((byte)2); map.sorted(MAPLIKE_ENTRY_ORDER).forEach(e -> hasher.putBytes(((HashCode)e.getFirst()).asBytes()).putBytes(((HashCode)e.getSecond()).asBytes())); hasher.putByte((byte)3); return hasher; } public HashCode createMap(Stream> map) { return HashOps.hashMap(this.hashFunction.newHasher(), map).hash(); } public HashCode createMap(Map map) { return HashOps.hashMap(this.hashFunction.newHasher(), map).hash(); } public HashCode createList(Stream input) { Hasher hasher = this.hashFunction.newHasher(); hasher.putByte((byte)4); input.forEach(value -> hasher.putBytes(value.asBytes())); hasher.putByte((byte)5); return hasher.hash(); } public HashCode createByteList(ByteBuffer input) { Hasher hasher = this.hashFunction.newHasher(); hasher.putByte((byte)14); hasher.putBytes(input); hasher.putByte((byte)15); return hasher.hash(); } public HashCode createIntList(IntStream input) { Hasher hasher = this.hashFunction.newHasher(); hasher.putByte((byte)16); input.forEach(arg_0 -> ((Hasher)hasher).putInt(arg_0)); hasher.putByte((byte)17); return hasher.hash(); } public HashCode createLongList(LongStream input) { Hasher hasher = this.hashFunction.newHasher(); hasher.putByte((byte)18); input.forEach(arg_0 -> ((Hasher)hasher).putLong(arg_0)); hasher.putByte((byte)19); return hasher.hash(); } public HashCode remove(HashCode input, String key) { return input; } public RecordBuilder mapBuilder() { return new MapHashBuilder(); } public ListBuilder listBuilder() { return new ListHashBuilder(); } public String toString() { return "Hash " + String.valueOf(this.hashFunction); } public U convertTo(DynamicOps outOps, HashCode input) { throw new UnsupportedOperationException("Can't convert from this type"); } public Number getNumberValue(HashCode input, Number defaultValue) { return defaultValue; } public HashCode set(HashCode input, String key, HashCode value) { return input; } public HashCode update(HashCode input, String key, Function function) { return input; } public HashCode updateGeneric(HashCode input, HashCode key, Function function) { return input; } private static DataResult unsupported() { return UNSUPPORTED_OPERATION_ERROR; } public DataResult get(HashCode input, String key) { return HashOps.unsupported(); } public DataResult getGeneric(HashCode input, HashCode key) { return HashOps.unsupported(); } public DataResult getNumberValue(HashCode input) { return HashOps.unsupported(); } public DataResult getBooleanValue(HashCode input) { return HashOps.unsupported(); } public DataResult getStringValue(HashCode input) { return HashOps.unsupported(); } public DataResult mergeToList(HashCode prefix, HashCode value) { return HashOps.unsupported(); } public DataResult mergeToList(HashCode prefix, List values) { return HashOps.unsupported(); } public DataResult mergeToMap(HashCode prefix, HashCode key, HashCode value) { return HashOps.unsupported(); } public DataResult mergeToMap(HashCode prefix, Map values) { return HashOps.unsupported(); } public DataResult mergeToMap(HashCode prefix, MapLike values) { return HashOps.unsupported(); } public DataResult>> getMapValues(HashCode input) { return HashOps.unsupported(); } public DataResult>> getMapEntries(HashCode input) { return HashOps.unsupported(); } public DataResult> getStream(HashCode input) { return HashOps.unsupported(); } public DataResult>> getList(HashCode input) { return HashOps.unsupported(); } public DataResult> getMap(HashCode input) { return HashOps.unsupported(); } public DataResult getByteBuffer(HashCode input) { return HashOps.unsupported(); } public DataResult getIntStream(HashCode input) { return HashOps.unsupported(); } public DataResult getLongStream(HashCode input) { return HashOps.unsupported(); } private final class MapHashBuilder extends RecordBuilder.AbstractUniversalBuilder>> { public MapHashBuilder() { super((DynamicOps)HashOps.this); } protected List> initBuilder() { return new ArrayList>(); } protected List> append(HashCode key, HashCode value, List> builder) { builder.add((Pair)Pair.of((Object)key, (Object)value)); return builder; } protected DataResult build(List> builder, HashCode prefix) { assert (prefix.equals((Object)HashOps.this.empty())); return DataResult.success((Object)HashOps.hashMap(HashOps.this.hashFunction.newHasher(), builder.stream()).hash()); } } private class ListHashBuilder extends AbstractListBuilder { public ListHashBuilder() { super(HashOps.this); } @Override protected Hasher initBuilder() { return HashOps.this.hashFunction.newHasher().putByte((byte)4); } @Override protected Hasher append(Hasher hasher, HashCode value) { return hasher.putBytes(value.asBytes()); } @Override protected DataResult build(Hasher hasher, HashCode prefix) { assert (prefix.equals((Object)HashOps.this.empty)); hasher.putByte((byte)5); return DataResult.success((Object)hasher.hash()); } } }