diff options
Diffstat (limited to 'src/org/xbill/DNS/DNSInput.java')
-rw-r--r-- | src/org/xbill/DNS/DNSInput.java | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/src/org/xbill/DNS/DNSInput.java b/src/org/xbill/DNS/DNSInput.java new file mode 100644 index 0000000..d3134ed --- /dev/null +++ b/src/org/xbill/DNS/DNSInput.java @@ -0,0 +1,239 @@ +// Copyright (c) 2004 Brian Wellington (bwelling@xbill.org) + +package org.xbill.DNS; + +/** + * An class for parsing DNS messages. + * + * @author Brian Wellington + */ + +public class DNSInput { + +private byte [] array; +private int pos; +private int end; +private int saved_pos; +private int saved_end; + +/** + * Creates a new DNSInput + * @param input The byte array to read from + */ +public +DNSInput(byte [] input) { + array = input; + pos = 0; + end = array.length; + saved_pos = -1; + saved_end = -1; +} + +/** + * Returns the current position. + */ +public int +current() { + return pos; +} + +/** + * Returns the number of bytes that can be read from this stream before + * reaching the end. + */ +public int +remaining() { + return end - pos; +} + +private void +require(int n) throws WireParseException{ + if (n > remaining()) { + throw new WireParseException("end of input"); + } +} + +/** + * Marks the following bytes in the stream as active. + * @param len The number of bytes in the active region. + * @throws IllegalArgumentException The number of bytes in the active region + * is longer than the remainder of the input. + */ +public void +setActive(int len) { + if (len > array.length - pos) { + throw new IllegalArgumentException("cannot set active " + + "region past end of input"); + } + end = pos + len; +} + +/** + * Clears the active region of the string. Further operations are not + * restricted to part of the input. + */ +public void +clearActive() { + end = array.length; +} + +/** + * Returns the position of the end of the current active region. + */ +public int +saveActive() { + return end; +} + +/** + * Restores the previously set active region. This differs from setActive() in + * that restoreActive() takes an absolute position, and setActive takes an + * offset from the current location. + * @param pos The end of the active region. + */ +public void +restoreActive(int pos) { + if (pos > array.length) { + throw new IllegalArgumentException("cannot set active " + + "region past end of input"); + } + end = pos; +} + +/** + * Resets the current position of the input stream to the specified index, + * and clears the active region. + * @param index The position to continue parsing at. + * @throws IllegalArgumentException The index is not within the input. + */ +public void +jump(int index) { + if (index >= array.length) { + throw new IllegalArgumentException("cannot jump past " + + "end of input"); + } + pos = index; + end = array.length; +} + +/** + * Saves the current state of the input stream. Both the current position and + * the end of the active region are saved. + * @throws IllegalArgumentException The index is not within the input. + */ +public void +save() { + saved_pos = pos; + saved_end = end; +} + +/** + * Restores the input stream to its state before the call to {@link #save}. + */ +public void +restore() { + if (saved_pos < 0) { + throw new IllegalStateException("no previous state"); + } + pos = saved_pos; + end = saved_end; + saved_pos = -1; + saved_end = -1; +} + +/** + * Reads an unsigned 8 bit value from the stream, as an int. + * @return An unsigned 8 bit value. + * @throws WireParseException The end of the stream was reached. + */ +public int +readU8() throws WireParseException { + require(1); + return (array[pos++] & 0xFF); +} + +/** + * Reads an unsigned 16 bit value from the stream, as an int. + * @return An unsigned 16 bit value. + * @throws WireParseException The end of the stream was reached. + */ +public int +readU16() throws WireParseException { + require(2); + int b1 = array[pos++] & 0xFF; + int b2 = array[pos++] & 0xFF; + return ((b1 << 8) + b2); +} + +/** + * Reads an unsigned 32 bit value from the stream, as a long. + * @return An unsigned 32 bit value. + * @throws WireParseException The end of the stream was reached. + */ +public long +readU32() throws WireParseException { + require(4); + int b1 = array[pos++] & 0xFF; + int b2 = array[pos++] & 0xFF; + int b3 = array[pos++] & 0xFF; + int b4 = array[pos++] & 0xFF; + return (((long)b1 << 24) + (b2 << 16) + (b3 << 8) + b4); +} + +/** + * Reads a byte array of a specified length from the stream into an existing + * array. + * @param b The array to read into. + * @param off The offset of the array to start copying data into. + * @param len The number of bytes to copy. + * @throws WireParseException The end of the stream was reached. + */ +public void +readByteArray(byte [] b, int off, int len) throws WireParseException { + require(len); + System.arraycopy(array, pos, b, off, len); + pos += len; +} + +/** + * Reads a byte array of a specified length from the stream. + * @return The byte array. + * @throws WireParseException The end of the stream was reached. + */ +public byte [] +readByteArray(int len) throws WireParseException { + require(len); + byte [] out = new byte[len]; + System.arraycopy(array, pos, out, 0, len); + pos += len; + return out; +} + +/** + * Reads a byte array consisting of the remainder of the stream (or the + * active region, if one is set. + * @return The byte array. + */ +public byte [] +readByteArray() { + int len = remaining(); + byte [] out = new byte[len]; + System.arraycopy(array, pos, out, 0, len); + pos += len; + return out; +} + +/** + * Reads a counted string from the stream. A counted string is a one byte + * value indicating string length, followed by bytes of data. + * @return A byte array containing the string. + * @throws WireParseException The end of the stream was reached. + */ +public byte [] +readCountedString() throws WireParseException { + require(1); + int len = array[pos++] & 0xFF; + return readByteArray(len); +} + +} |