⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 name.java

📁 DNS Java 是java实现的DNS
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 1999-2004 Brian Wellington (bwelling@xbill.org)package org.xbill.DNS;import java.io.*;import java.text.*;/** * A representation of a domain name.  It may either be absolute (fully * qualified) or relative. * * @author Brian Wellington */public class Name implements Comparable {private static final int LABEL_NORMAL = 0;private static final int LABEL_COMPRESSION = 0xC0;private static final int LABEL_MASK = 0xC0;/* The name data */private byte [] name;/* * Effectively an 8 byte array, where the low order byte stores the number * of labels and the 7 higher order bytes store per-label offsets. */private long offsets;/* Precomputed hashcode. */private int hashcode;private static final byte [] emptyLabel = new byte[] {(byte)0};private static final byte [] wildLabel = new byte[] {(byte)1, (byte)'*'};/** The root name */public static final Name root;/** The root name */public static final Name empty;/** The maximum length of a Name */private static final int MAXNAME = 255;/** The maximum length of a label a Name */private static final int MAXLABEL = 63;/** The maximum number of labels in a Name */private static final int MAXLABELS = 128;/** The maximum number of cached offsets */private static final int MAXOFFSETS = 7;/* Used for printing non-printable characters */private static final DecimalFormat byteFormat = new DecimalFormat();/* Used to efficiently convert bytes to lowercase */private static final byte lowercase[] = new byte[256];/* Used in wildcard names. */private static final Name wild;static {	byteFormat.setMinimumIntegerDigits(3);	for (int i = 0; i < lowercase.length; i++) {		if (i < 'A' || i > 'Z')			lowercase[i] = (byte)i;		else			lowercase[i] = (byte)(i - 'A' + 'a');	}	root = new Name();	root.appendSafe(emptyLabel, 0, 1);	empty = new Name();	empty.name = new byte[0];	wild = new Name();	wild.appendSafe(wildLabel, 0, 1);}privateName() {}private final voiddump(String prefix) {	String s;	try {		s = toString();	} catch (Exception e) {		s = "<unprintable>";	}	System.out.println(prefix + ": " + s);	int labels = labels();	for (int i = 0; i < labels; i++)		System.out.print(offset(i) + " ");	System.out.println("");	for (int i = 0; name != null && i < name.length; i++)		System.out.print((name[i] & 0xFF) + " ");	System.out.println("");}private final voidsetoffset(int n, int offset) {	if (n >= MAXOFFSETS)		return;	int shift = 8 * (7 - n);	offsets &= (~(0xFFL << shift));	offsets |= ((long)offset << shift);}private final intoffset(int n) {	if (n == 0 && getlabels() == 0)		return 0;	if (n < 0 || n >= getlabels())		throw new IllegalArgumentException("label out of range");	if (n < MAXOFFSETS) {		int shift = 8 * (7 - n);		return ((int)(offsets >>> shift) & 0xFF);	} else {		int pos = offset(MAXOFFSETS - 1);		for (int i = MAXOFFSETS - 1; i < n; i++)			pos += (name[pos] + 1);		return (pos);	}}private final voidsetlabels(int labels) {	offsets &= ~(0xFF);	offsets |= labels;}private final intgetlabels() {	return (int)(offsets & 0xFF);}private static final voidcopy(Name src, Name dst) {	if (src.offset(0) == 0) {		dst.name = src.name;		dst.offsets = src.offsets;	} else {		int offset0 = src.offset(0);		int namelen = src.name.length - offset0;		int labels = src.labels();		dst.name = new byte[namelen];		System.arraycopy(src.name, offset0, dst.name, 0, namelen);		for (int i = 0; i < labels && i < MAXOFFSETS; i++)			dst.setoffset(i, src.offset(i) - offset0);		dst.setlabels(labels);	}}private final voidappend(byte [] array, int start, int n) throws NameTooLongException {	int length = (name == null ? 0 : (name.length - offset(0)));	int alength = 0;	for (int i = 0, pos = start; i < n; i++) {		int len = array[pos];		if (len > MAXLABEL)			throw new IllegalStateException("invalid label");		len++;		pos += len;		alength += len;	}	int newlength = length + alength;	if (newlength > MAXNAME)		throw new NameTooLongException();	int labels = getlabels();	int newlabels = labels + n;	if (newlabels > MAXLABELS)		throw new IllegalStateException("too many labels");	byte [] newname = new byte[newlength];	if (length != 0)		System.arraycopy(name, offset(0), newname, 0, length);	System.arraycopy(array, start, newname, length, alength);	name = newname;	for (int i = 0, pos = length; i < n; i++) {		setoffset(labels + i, pos);		pos += (newname[pos] + 1);	}	setlabels(newlabels);}private static TextParseExceptionparseException(String str, String message) {	return new TextParseException("'" + str + "': " + message);}private final voidappendFromString(String fullName, byte [] array, int start, int n)throws TextParseException{	try {		append(array, start, n);	}	catch (NameTooLongException e) {		throw parseException(fullName, "Name too long");	}}private final voidappendSafe(byte [] array, int start, int n) {	try {		append(array, start, n);	}	catch (NameTooLongException e) {	}}/** * Create a new name from a string and an origin.  This does not automatically * make the name absolute; it will be absolute if it has a trailing dot or an * absolute origin is appended. * @param s The string to be converted * @param origin If the name is not absolute, the origin to be appended. * @throws TextParseException The name is invalid. */publicName(String s, Name origin) throws TextParseException {	if (s.equals(""))		throw parseException(s, "empty name");	else if (s.equals("@")) {		if (origin == null)			copy(empty, this);		else			copy(origin, this);		return;	} else if (s.equals(".")) {		copy(root, this);		return;	}	int labelstart = -1;	int pos = 1;	byte [] label = new byte[MAXLABEL + 1];	boolean escaped = false;	int digits = 0;	int intval = 0;	boolean absolute = false;	for (int i = 0; i < s.length(); i++) {		byte b = (byte) s.charAt(i);		if (escaped) {			if (b >= '0' && b <= '9' && digits < 3) {				digits++;				intval *= 10;				intval += (b - '0');				if (intval > 255)					throw parseException(s, "bad escape");				if (digits < 3)					continue;				b = (byte) intval;			}			else if (digits > 0 && digits < 3)				throw parseException(s, "bad escape");			if (pos > MAXLABEL)				throw parseException(s, "label too long");			labelstart = pos;			label[pos++] = b;			escaped = false;		} else if (b == '\\') {			escaped = true;			digits = 0;			intval = 0;		} else if (b == '.') {			if (labelstart == -1)				throw parseException(s, "invalid empty label");			label[0] = (byte)(pos - 1);			appendFromString(s, label, 0, 1);			labelstart = -1;			pos = 1;		} else {			if (labelstart == -1)				labelstart = i;			if (pos > MAXLABEL)				throw parseException(s, "label too long");			label[pos++] = b;		}	}	if (digits > 0 && digits < 3)		throw parseException(s, "bad escape");	if (escaped)		throw parseException(s, "bad escape");	if (labelstart == -1) {		appendFromString(s, emptyLabel, 0, 1);		absolute = true;	} else {		label[0] = (byte)(pos - 1);		appendFromString(s, label, 0, 1);	}	if (origin != null && !absolute)		appendFromString(s, origin.name, 0, origin.getlabels());}/** * Create a new name from a string.  This does not automatically make the name * absolute; it will be absolute if it has a trailing dot. * @param s The string to be converted * @throws TextParseException The name is invalid. */publicName(String s) throws TextParseException {	this(s, null);}/** * Create a new name from a string and an origin.  This does not automatically * make the name absolute; it will be absolute if it has a trailing dot or an * absolute origin is appended.  This is identical to the constructor, except * that it will avoid creating new objects in some cases. * @param s The string to be converted * @param origin If the name is not absolute, the origin to be appended. * @throws TextParseException The name is invalid. */public static NamefromString(String s, Name origin) throws TextParseException {	if (s.equals("@") && origin != null)		return origin;	else if (s.equals("."))		return (root);	return new Name(s, origin);}/** * Create a new name from a string.  This does not automatically make the name * absolute; it will be absolute if it has a trailing dot.  This is identical * to the constructor, except that it will avoid creating new objects in some * cases. * @param s The string to be converted * @throws TextParseException The name is invalid. */public static NamefromString(String s) throws TextParseException {	return fromString(s, null);}/** * Create a new name from a constant string.  This should only be used when the name is known to be good - that is, when it is constant. * @param s The string to be converted * @throws IllegalArgumentException The name is invalid. */public static NamefromConstantString(String s) {	try {		return fromString(s, null);	}	catch (TextParseException e) {		throw new IllegalArgumentException("Invalid name '" + s + "'");	}}/** * Create a new name from DNS a wire format message * @param in A stream containing the DNS message which is currently * positioned at the start of the name to be read. */publicName(DNSInput in) throws WireParseException {	int len, pos, currentpos;	Name name2;	boolean done = false;	byte [] label = new byte[MAXLABEL + 1];	boolean savedState = false;	while (!done) {		len = in.readU8();		switch (len & LABEL_MASK) {		case LABEL_NORMAL:			if (getlabels() >= MAXLABELS)				throw new WireParseException("too many labels");			if (len == 0) {				append(emptyLabel, 0, 1);				done = true;			} else {				label[0] = (byte)len;				in.readByteArray(label, 1, len);				append(label, 0, 1);			}			break;		case LABEL_COMPRESSION:			pos = in.readU8();			pos += ((len & ~LABEL_MASK) << 8);			if (Options.check("verbosecompression"))				System.err.println("currently " + in.current() +						   ", pointer to " + pos);			if (pos >= in.current() - 2)				throw new WireParseException("bad compression");			if (!savedState) {				in.save();				savedState = true;			}			in.jump(pos);			if (Options.check("verbosecompression"))				System.err.println("current name '" + this +						   "', seeking to " + pos);			break;		default:			throw new WireParseException("bad label type");		}	}	if (savedState) {		in.restore();	}}/** * Create a new name from DNS wire format * @param b A byte array containing the wire format of the name. */publicName(byte [] b) throws IOException {	this(new DNSInput(b));}/** * Create a new name by removing labels from the beginning of an existing Name

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -