aboutsummaryrefslogtreecommitdiff
path: root/src/org/xbill/DNS/DNSOutput.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/org/xbill/DNS/DNSOutput.java')
-rw-r--r--src/org/xbill/DNS/DNSOutput.java203
1 files changed, 203 insertions, 0 deletions
diff --git a/src/org/xbill/DNS/DNSOutput.java b/src/org/xbill/DNS/DNSOutput.java
new file mode 100644
index 0000000..29a8f68
--- /dev/null
+++ b/src/org/xbill/DNS/DNSOutput.java
@@ -0,0 +1,203 @@
+// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)
+
+package org.xbill.DNS;
+
+/**
+ * A class for rendering DNS messages.
+ *
+ * @author Brian Wellington
+ */
+
+
+public class DNSOutput {
+
+private byte [] array;
+private int pos;
+private int saved_pos;
+
+/**
+ * Create a new DNSOutput with a specified size.
+ * @param size The initial size
+ */
+public
+DNSOutput(int size) {
+ array = new byte[size];
+ pos = 0;
+ saved_pos = -1;
+}
+
+/**
+ * Create a new DNSOutput
+ */
+public
+DNSOutput() {
+ this(32);
+}
+
+/**
+ * Returns the current position.
+ */
+public int
+current() {
+ return pos;
+}
+
+private void
+check(long val, int bits) {
+ long max = 1;
+ max <<= bits;
+ if (val < 0 || val > max) {
+ throw new IllegalArgumentException(val + " out of range for " +
+ bits + " bit value");
+ }
+}
+
+private void
+need(int n) {
+ if (array.length - pos >= n) {
+ return;
+ }
+ int newsize = array.length * 2;
+ if (newsize < pos + n) {
+ newsize = pos + n;
+ }
+ byte [] newarray = new byte[newsize];
+ System.arraycopy(array, 0, newarray, 0, pos);
+ array = newarray;
+}
+
+/**
+ * Resets the current position of the output stream to the specified index.
+ * @param index The new current position.
+ * @throws IllegalArgumentException The index is not within the output.
+ */
+public void
+jump(int index) {
+ if (index > pos) {
+ throw new IllegalArgumentException("cannot jump past " +
+ "end of data");
+ }
+ pos = index;
+}
+
+/**
+ * Saves the current state of the output stream.
+ * @throws IllegalArgumentException The index is not within the output.
+ */
+public void
+save() {
+ saved_pos = pos;
+}
+
+/**
+ * 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;
+ saved_pos = -1;
+}
+
+/**
+ * Writes an unsigned 8 bit value to the stream.
+ * @param val The value to be written
+ */
+public void
+writeU8(int val) {
+ check(val, 8);
+ need(1);
+ array[pos++] = (byte)(val & 0xFF);
+}
+
+/**
+ * Writes an unsigned 16 bit value to the stream.
+ * @param val The value to be written
+ */
+public void
+writeU16(int val) {
+ check(val, 16);
+ need(2);
+ array[pos++] = (byte)((val >>> 8) & 0xFF);
+ array[pos++] = (byte)(val & 0xFF);
+}
+
+/**
+ * Writes an unsigned 16 bit value to the specified position in the stream.
+ * @param val The value to be written
+ * @param where The position to write the value.
+ */
+public void
+writeU16At(int val, int where) {
+ check(val, 16);
+ if (where > pos - 2)
+ throw new IllegalArgumentException("cannot write past " +
+ "end of data");
+ array[where++] = (byte)((val >>> 8) & 0xFF);
+ array[where++] = (byte)(val & 0xFF);
+}
+
+/**
+ * Writes an unsigned 32 bit value to the stream.
+ * @param val The value to be written
+ */
+public void
+writeU32(long val) {
+ check(val, 32);
+ need(4);
+ array[pos++] = (byte)((val >>> 24) & 0xFF);
+ array[pos++] = (byte)((val >>> 16) & 0xFF);
+ array[pos++] = (byte)((val >>> 8) & 0xFF);
+ array[pos++] = (byte)(val & 0xFF);
+}
+
+/**
+ * Writes a byte array to the stream.
+ * @param b The array to write.
+ * @param off The offset of the array to start copying data from.
+ * @param len The number of bytes to write.
+ */
+public void
+writeByteArray(byte [] b, int off, int len) {
+ need(len);
+ System.arraycopy(b, off, array, pos, len);
+ pos += len;
+}
+
+/**
+ * Writes a byte array to the stream.
+ * @param b The array to write.
+ */
+public void
+writeByteArray(byte [] b) {
+ writeByteArray(b, 0, b.length);
+}
+
+/**
+ * Writes a counted string from the stream. A counted string is a one byte
+ * value indicating string length, followed by bytes of data.
+ * @param s The string to write.
+ */
+public void
+writeCountedString(byte [] s) {
+ if (s.length > 0xFF) {
+ throw new IllegalArgumentException("Invalid counted string");
+ }
+ need(1 + s.length);
+ array[pos++] = (byte)(s.length & 0xFF);
+ writeByteArray(s, 0, s.length);
+}
+
+/**
+ * Returns a byte array containing the current contents of the stream.
+ */
+public byte []
+toByteArray() {
+ byte [] out = new byte[pos];
+ System.arraycopy(array, 0, out, 0, pos);
+ return out;
+}
+
+}