aboutsummaryrefslogtreecommitdiff
path: root/src/org/xbill/DNS/DNSInput.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/xbill/DNS/DNSInput.java')
-rw-r--r--src/org/xbill/DNS/DNSInput.java239
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);
+}
+
+}