com.couchbase.client.core.deps.org.xbill.DNS.DNSOutput Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core-io Show documentation
Show all versions of core-io Show documentation
The official Couchbase JVM Core IO Library
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) 1999-2004 Brian Wellington ([email protected])
package com.couchbase.client.core.deps.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;
}
static byte[] toU16(int val) {
return new byte[] {(byte) ((val >>> 8) & 0xFF), (byte) (val & 0xFF)};
}
}