diff --git a/core/src/com/riiablo/io/BitUtils.java b/core/src/com/riiablo/io/BitUtils.java index b9a9f0cb..d22f4b48 100644 --- a/core/src/com/riiablo/io/BitUtils.java +++ b/core/src/com/riiablo/io/BitUtils.java @@ -1,10 +1,5 @@ package com.riiablo.io; -import java.util.Arrays; -import org.apache.logging.log4j.Logger; - -import com.riiablo.util.DebugUtils; - public class BitUtils { private BitUtils() {} @@ -29,27 +24,4 @@ public class BitUtils { public static boolean isUnsigned(long value) { return isUnsigned(value, Long.SIZE); } - - public static boolean readSignature(ByteInput in, final byte[] SIGNATURE, Logger log, String tag) { - log.trace("Validating " + tag + " signature"); - if (in.bytesRemaining() < SIGNATURE.length) { - byte[] signature = in.readBytes(in.bytesRemaining()); - throw new InvalidFormat( - in, - String.format(tag + " signature doesn't match expected signature: %s, expected %s", - DebugUtils.toByteArray(signature), - DebugUtils.toByteArray(SIGNATURE))); - } - - byte[] signature = in.readBytes(SIGNATURE.length); - boolean matched = Arrays.equals(signature, SIGNATURE); - if (!matched) { - throw new InvalidFormat( - in, - String.format(tag + " signature doesn't match expected signature: %s, expected %s", - DebugUtils.toByteArray(signature), - DebugUtils.toByteArray(SIGNATURE))); - } - return matched; - } } diff --git a/core/src/com/riiablo/io/ByteInput.java b/core/src/com/riiablo/io/ByteInput.java index 8603a42e..2bfd41ef 100644 --- a/core/src/com/riiablo/io/ByteInput.java +++ b/core/src/com/riiablo/io/ByteInput.java @@ -1,9 +1,11 @@ package com.riiablo.io; import io.netty.buffer.ByteBuf; +import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.util.CharsetUtil; import java.nio.charset.Charset; +import java.util.Arrays; import com.riiablo.util.DebugUtils; @@ -170,6 +172,47 @@ public class ByteInput { return this; } + /** + * Checks if the subsequent bytes match the specified sequence of bytes. + * If they do, they will be consumed by this method call, otherwise an + * {@link InvalidFormat} will be thrown and any bytes read by this method + * will be unread. + * + * @throws InvalidFormat if the next bytes do not match the specified + * signature. + * + * @see InvalidFormat + * @see #skipUntil(byte[]) + */ + public ByteInput readSignature(byte[] signature) { + assert aligned() : "not aligned"; + buffer.markReaderIndex(); + if (buffer.readableBytes() < signature.length) { + final byte[] actual = new byte[buffer.readableBytes()]; + buffer.readBytes(actual); + buffer.resetReaderIndex(); + throw new InvalidFormat( + this, + String.format("Signatures do not match: %s, expected %s", + ByteBufUtil.hexDump(actual), + ByteBufUtil.hexDump(signature))); + } + + final byte[] actual = new byte[signature.length]; + buffer.readBytes(actual); + final boolean match = Arrays.equals(actual, signature); + if (!match) { + buffer.resetReaderIndex(); + throw new InvalidFormat( + this, + String.format("Signatures do not match: %s, expected %s", + ByteBufUtil.hexDump(actual), + ByteBufUtil.hexDump(signature))); + } + incrementBitsRead((long) signature.length * Byte.SIZE); + return this; + } + /** * Reads a slice of this buffer's sub-region starting at the current position * and increases the position by the size of the new slice (= numBytes). diff --git a/core/src/com/riiablo/item/ItemSerializer.java b/core/src/com/riiablo/item/ItemSerializer.java index 762e84db..004ed50f 100644 --- a/core/src/com/riiablo/item/ItemSerializer.java +++ b/core/src/com/riiablo/item/ItemSerializer.java @@ -8,7 +8,6 @@ import com.riiablo.Riiablo; import com.riiablo.codec.excel.Gems; import com.riiablo.codec.util.BitStream; import com.riiablo.io.BitInput; -import com.riiablo.io.BitUtils; import com.riiablo.io.ByteInput; import com.riiablo.log.Log; import com.riiablo.log.LogManager; @@ -44,7 +43,8 @@ public class ItemSerializer { /** FIXME: workaround for {@link Item#loadFromStream(BitStream)} */ final int itemOffset = in.bytesRead(); // TODO: remove when serialization implemented log.trace("Reading item..."); - BitUtils.readSignature(in, SIGNATURE, log, "item"); + log.trace("Validating item signature"); + in.readSignature(SIGNATURE); Item item = new Item(); item.reset(); item.flags = in.read32();