All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.milton.dns.record.DNSOutput Maven / Gradle / Ivy

/*
 * Copied from the DnsJava project
 *
 * Copyright (c) 1998-2011, Brian Wellington.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package io.milton.dns.record;

/**
 * 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;
}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy