📄 name.java
字号:
* @param src An existing Name * @param n The number of labels to remove from the beginning in the copy */publicName(Name src, int n) { int slabels = src.labels(); if (n > slabels) throw new IllegalArgumentException("attempted to remove too " + "many labels"); name = src.name; setlabels(slabels - n); for (int i = 0; i < MAXOFFSETS && i < slabels - n; i++) setoffset(i, src.offset(i + n));}/** * Creates a new name by concatenating two existing names. * @param prefix The prefix name. * @param suffix The suffix name. * @return The concatenated name. * @throws NameTooLongException The name is too long. */public static Nameconcatenate(Name prefix, Name suffix) throws NameTooLongException { if (prefix.isAbsolute()) return (prefix); Name newname = new Name(); copy(prefix, newname); newname.append(suffix.name, suffix.offset(0), suffix.getlabels()); return newname;}/** * If this name is a subdomain of origin, return a new name relative to * origin with the same value. Otherwise, return the existing name. * @param origin The origin to remove. * @return The possibly relativized name. */public Namerelativize(Name origin) { if (origin == null || !subdomain(origin)) return this; Name newname = new Name(); copy(this, newname); int length = length() - origin.length(); int labels = newname.labels() - origin.labels(); newname.setlabels(labels); newname.name = new byte[length]; System.arraycopy(name, offset(0), newname.name, 0, length); return newname;}/** * Generates a new Name with the first n labels replaced by a wildcard * @return The wildcard name */public Namewild(int n) { if (n < 1) throw new IllegalArgumentException("must replace 1 or more " + "labels"); try { Name newname = new Name(); copy(wild, newname); newname.append(name, offset(n), getlabels() - n); return newname; } catch (NameTooLongException e) { throw new IllegalStateException ("Name.wild: concatenate failed"); }}/** * Generates a new Name to be used when following a DNAME. * @param dname The DNAME record to follow. * @return The constructed name. * @throws NameTooLongException The resulting name is too long. */public NamefromDNAME(DNAMERecord dname) throws NameTooLongException { Name dnameowner = dname.getName(); Name dnametarget = dname.getTarget(); if (!subdomain(dnameowner)) return null; int plabels = labels() - dnameowner.labels(); int plength = length() - dnameowner.length(); int pstart = offset(0); int dlabels = dnametarget.labels(); int dlength = dnametarget.length(); if (plength + dlength > MAXNAME) throw new NameTooLongException(); Name newname = new Name(); newname.setlabels(plabels + dlabels); newname.name = new byte[plength + dlength]; System.arraycopy(name, pstart, newname.name, 0, plength); System.arraycopy(dnametarget.name, 0, newname.name, plength, dlength); for (int i = 0, pos = 0; i < MAXOFFSETS && i < plabels + dlabels; i++) { newname.setoffset(i, pos); pos += (newname.name[pos] + 1); } return newname;}/** * Is this name a wildcard? */public booleanisWild() { if (labels() == 0) return false; return (name[0] == (byte)1 && name[1] == (byte)'*');}/** * Is this name absolute? */public booleanisAbsolute() { if (labels() == 0) return false; return (name[name.length - 1] == 0);}/** * The length of the name. */public shortlength() { if (getlabels() == 0) return 0; return (short)(name.length - offset(0));}/** * The number of labels in the name. */public intlabels() { return getlabels();}/** * Is the current Name a subdomain of the specified name? */public booleansubdomain(Name domain) { int labels = labels(); int dlabels = domain.labels(); if (dlabels > labels) return false; if (dlabels == labels) return equals(domain); return domain.equals(name, offset(labels - dlabels));}private StringbyteString(byte [] array, int pos) { StringBuffer sb = new StringBuffer(); int len = array[pos++]; for (int i = pos; i < pos + len; i++) { int b = array[i] & 0xFF; if (b <= 0x20 || b >= 0x7f) { sb.append('\\'); sb.append(byteFormat.format(b)); } else if (b == '"' || b == '(' || b == ')' || b == '.' || b == ';' || b == '\\' || b == '@' || b == '$') { sb.append('\\'); sb.append((char)b); } else sb.append((char)b); } return sb.toString();}/** * Convert a Name to a String * @return The representation of this name as a (printable) String. */public StringtoString() { int labels = labels(); if (labels == 0) return "@"; else if (labels == 1 && name[offset(0)] == 0) return "."; StringBuffer sb = new StringBuffer(); for (int i = 0, pos = offset(0); i < labels; i++) { int len = name[pos]; if (len > MAXLABEL) throw new IllegalStateException("invalid label"); if (len == 0) break; sb.append(byteString(name, pos)); sb.append('.'); pos += (1 + len); } if (!isAbsolute()) sb.deleteCharAt(sb.length() - 1); return sb.toString();}/** * Retrieve the nth label of a Name. This makes a copy of the label; changing * this does not change the Name. * @param n The label to be retrieved. The first label is 0. */public byte []getLabel(int n) { int pos = offset(n); byte len = (byte)(name[pos] + 1); byte [] label = new byte[len]; System.arraycopy(name, pos, label, 0, len); return label;}/** * Convert the nth label in a Name to a String * @param n The label to be converted to a (printable) String. The first * label is 0. */public StringgetLabelString(int n) { int pos = offset(n); return byteString(name, pos);}/** * Emit a Name in DNS wire format * @param out The output stream containing the DNS message. * @param c The compression context, or null of no compression is desired. * @throws IllegalArgumentException The name is not absolute. */public voidtoWire(DNSOutput out, Compression c) { if (!isAbsolute()) throw new IllegalArgumentException("toWire() called on " + "non-absolute name"); int labels = labels(); for (int i = 0; i < labels - 1; i++) { Name tname; if (i == 0) tname = this; else tname = new Name(this, i); int pos = -1; if (c != null) pos = c.get(tname); if (pos >= 0) { pos |= (LABEL_MASK << 8); out.writeU16(pos); return; } else { if (c != null) c.add(out.current(), tname); int off = offset(i); out.writeByteArray(name, off, name[off] + 1); } } out.writeU8(0);}/** * Emit a Name in DNS wire format * @throws IllegalArgumentException The name is not absolute. */public byte []toWire() { DNSOutput out = new DNSOutput(); toWire(out, null); return out.toByteArray();}/** * Emit a Name in canonical DNS wire format (all lowercase) * @param out The output stream to which the message is written. */public voidtoWireCanonical(DNSOutput out) { byte [] b = toWireCanonical(); out.writeByteArray(b);}/** * Emit a Name in canonical DNS wire format (all lowercase) * @return The canonical form of the name. */public byte []toWireCanonical() { int labels = labels(); if (labels == 0) return (new byte[0]); byte [] b = new byte[name.length - offset(0)]; for (int i = 0, spos = offset(0), dpos = 0; i < labels; i++) { int len = name[spos]; if (len > MAXLABEL) throw new IllegalStateException("invalid label"); b[dpos++] = name[spos++]; for (int j = 0; j < len; j++) b[dpos++] = lowercase[(name[spos++] & 0xFF)]; } return b;}/** * Emit a Name in DNS wire format * @param out The output stream containing the DNS message. * @param c The compression context, or null of no compression is desired. * @param canonical If true, emit the name in canonicalized form * (all lowercase). * @throws IllegalArgumentException The name is not absolute. */public voidtoWire(DNSOutput out, Compression c, boolean canonical) { if (canonical) toWireCanonical(out); else toWire(out, c);}private final booleanequals(byte [] b, int bpos) { int labels = labels(); for (int i = 0, pos = offset(0); i < labels; i++) { if (name[pos] != b[bpos]) return false; int len = name[pos++]; bpos++; if (len > MAXLABEL) throw new IllegalStateException("invalid label"); for (int j = 0; j < len; j++) if (lowercase[(name[pos++] & 0xFF)] != lowercase[(b[bpos++] & 0xFF)]) return false; } return true;}/** * Are these two Names equivalent? */public booleanequals(Object arg) { if (arg == this) return true; if (arg == null || !(arg instanceof Name)) return false; Name d = (Name) arg; if (d.hashcode == 0) d.hashCode(); if (hashcode == 0) hashCode(); if (d.hashcode != hashcode) return false; if (d.labels() != labels()) return false; return equals(d.name, d.offset(0));}/** * Computes a hashcode based on the value */public inthashCode() { if (hashcode != 0) return (hashcode); int code = 0; for (int i = offset(0); i < name.length; i++) code += ((code << 3) + lowercase[(name[i] & 0xFF)]); hashcode = code; return hashcode;}/** * Compares this Name to another Object. * @param o The Object to be compared. * @return The value 0 if the argument is a name equivalent to this name; * a value less than 0 if the argument is less than this name in the canonical * ordering, and a value greater than 0 if the argument is greater than this * name in the canonical ordering. * @throws ClassCastException if the argument is not a Name. */public intcompareTo(Object o) { Name arg = (Name) o; if (this == arg) return (0); int labels = labels(); int alabels = arg.labels(); int compares = labels > alabels ? alabels : labels; for (int i = 1; i <= compares; i++) { int start = offset(labels - i); int astart = arg.offset(alabels - i); int length = name[start]; int alength = arg.name[astart]; for (int j = 0; j < length && j < alength; j++) { int n = lowercase[(name[j + start + 1]) & 0xFF] - lowercase[(arg.name[j + astart + 1]) & 0xFF]; if (n != 0) return (n); } if (length != alength) return (length - alength); } return (labels - alabels);}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -