13742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Copyright 2003-2005 Arthur van Hoff, Rick Blair 23742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Licensed under Apache License version 2.0 33742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman// Original license LGPL 43742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 53742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpackage javax.jmdns.impl; 63742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 73742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.io.ByteArrayOutputStream; 83742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.io.DataOutputStream; 93742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.io.IOException; 103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Collections; 113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport java.util.Map; 123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.ServiceInfo.Fields; 143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSRecordClass; 153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanimport javax.jmdns.impl.constants.DNSRecordType; 163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman/** 183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * DNS entry with a name, type, and class. This is the base class for questions and records. 193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @author Arthur van Hoff, Pierre Frisch, Rick Blair 213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Romanpublic abstract class DNSEntry { 233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // private static Logger logger = Logger.getLogger(DNSEntry.class.getName()); 243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final String _key; 253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final String _name; 273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final String _type; 293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final DNSRecordType _recordType; 313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final DNSRecordClass _dnsClass; 333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman private final boolean _unique; 353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman final Map<Fields, String> _qualifiedNameMap; 373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Create an entry. 403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DNSEntry(String name, DNSRecordType type, DNSRecordClass recordClass, boolean unique) { 423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _name = name; 433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // _key = (name != null ? name.trim().toLowerCase() : null); 443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _recordType = type; 453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _dnsClass = recordClass; 463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _unique = unique; 473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _qualifiedNameMap = ServiceInfoImpl.decodeQualifiedNameMapForType(this.getName()); 483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String domain = _qualifiedNameMap.get(Fields.Domain); 493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String protocol = _qualifiedNameMap.get(Fields.Protocol); 503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String application = _qualifiedNameMap.get(Fields.Application); 513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String instance = _qualifiedNameMap.get(Fields.Instance).toLowerCase(); 523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _type = (application.length() > 0 ? "_" + application + "." : "") + (protocol.length() > 0 ? "_" + protocol + "." : "") + domain + "."; 533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman _key = ((instance.length() > 0 ? instance + "." : "") + _type).toLowerCase(); 543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see java.lang.Object#equals(java.lang.Object) 593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean equals(Object obj) { 623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman boolean result = false; 633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (obj instanceof DNSEntry) { 643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DNSEntry other = (DNSEntry) obj; 653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman result = this.getKey().equals(other.getKey()) && this.getRecordType().equals(other.getRecordType()) && this.getRecordClass() == other.getRecordClass(); 663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return result; 683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Check if two entries have exactly the same name, type, and class. 723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param entry 743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return <code>true</code> if the two entries have are for the same record, <code>false</code> otherwise 753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isSameEntry(DNSEntry entry) { 773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getKey().equals(entry.getKey()) && this.getRecordType().equals(entry.getRecordType()) && ((DNSRecordClass.CLASS_ANY == entry.getRecordClass()) || this.getRecordClass().equals(entry.getRecordClass())); 783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Check if two entries have the same subtype. 823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param other 843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return <code>true</code> if the two entries have are for the same subtype, <code>false</code> otherwise 853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean sameSubtype(DNSEntry other) { 873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getSubtype().equals(other.getSubtype()); 883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Returns the subtype of this entry 923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return subtype of this entry 943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getSubtype() { 963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String subtype = this.getQualifiedNameMap().get(Fields.Subtype); 973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (subtype != null ? subtype : ""); 983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Returns the name of this entry 1023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 1033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return name of this entry 1043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getName() { 1063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_name != null ? _name : ""); 1073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return the type 1113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getType() { 1133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_type != null ? _type : ""); 1143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Returns the key for this entry. The key is the lower case name. 1183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 1193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return key for this entry 1203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String getKey() { 1223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_key != null ? _key : ""); 1233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return record type 1273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public DNSRecordType getRecordType() { 1293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_recordType != null ? _recordType : DNSRecordType.TYPE_IGNORE); 1303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return record class 1343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public DNSRecordClass getRecordClass() { 1363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (_dnsClass != null ? _dnsClass : DNSRecordClass.CLASS_UNKNOWN); 1373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return true if unique 1413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isUnique() { 1433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _unique; 1443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public Map<Fields, String> getQualifiedNameMap() { 1473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return Collections.unmodifiableMap(_qualifiedNameMap); 1483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isServicesDiscoveryMetaQuery() { 1513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _qualifiedNameMap.get(Fields.Application).equals("dns-sd") && _qualifiedNameMap.get(Fields.Instance).equals("_services"); 1523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isDomainDiscoveryQuery() { 1553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // b._dns-sd._udp.<domain>. 1563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // db._dns-sd._udp.<domain>. 1573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // r._dns-sd._udp.<domain>. 1583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // dr._dns-sd._udp.<domain>. 1593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // lb._dns-sd._udp.<domain>. 1603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (_qualifiedNameMap.get(Fields.Application).equals("dns-sd")) { 1623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman String name = _qualifiedNameMap.get(Fields.Instance); 1633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return "b".equals(name) || "db".equals(name) || "r".equals(name) || "dr".equals(name) || "lb".equals(name); 1643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return false; 1663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isReverseLookup() { 1693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.isV4ReverseLookup() || this.isV6ReverseLookup(); 1703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isV4ReverseLookup() { 1733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _qualifiedNameMap.get(Fields.Domain).endsWith("in-addr.arpa"); 1743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isV6ReverseLookup() { 1773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return _qualifiedNameMap.get(Fields.Domain).endsWith("ip6.arpa"); 1783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 1793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Check if the record is stale, i.e. it has outlived more than half of its TTL. 1823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 1833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param now 1843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * update date 1853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return <code>true</code> is the record is stale, <code>false</code> otherwise. 1863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public abstract boolean isStale(long now); 1883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Check if the record is expired. 1913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 1923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param now 1933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * update date 1943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return <code>true</code> is the record is expired, <code>false</code> otherwise. 1953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 1963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public abstract boolean isExpired(long now); 1973742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 1983742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 1993742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Check that 2 entries are of the same class. 2003742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 2013742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param entry 2023742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return <code>true</code> is the two class are the same, <code>false</code> otherwise. 2033742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2043742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isSameRecordClass(DNSEntry entry) { 2053742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (entry != null) && (entry.getRecordClass() == this.getRecordClass()); 2063742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2073742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2083742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2093742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Check that 2 entries are of the same type. 2103742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 2113742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param entry 2123742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return <code>true</code> is the two type are the same, <code>false</code> otherwise. 2133742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2143742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public boolean isSameType(DNSEntry entry) { 2153742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return (entry != null) && (entry.getRecordType() == this.getRecordType()); 2163742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2173742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2183742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2193742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param dout 2203742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @exception IOException 2213742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2223742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protected void toByteArray(DataOutputStream dout) throws IOException { 2233742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman dout.write(this.getName().getBytes("UTF8")); 2243742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman dout.writeShort(this.getRecordType().indexValue()); 2253742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman dout.writeShort(this.getRecordClass().indexValue()); 2263742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2273742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2283742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2293742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Creates a byte array representation of this record. This is needed for tie-break tests according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2. 2303742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 2313742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return byte array representation 2323742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2333742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protected byte[] toByteArray() { 2343742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman try { 2353742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman ByteArrayOutputStream bout = new ByteArrayOutputStream(); 2363742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman DataOutputStream dout = new DataOutputStream(bout); 2373742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.toByteArray(dout); 2383742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman dout.close(); 2393742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return bout.toByteArray(); 2403742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } catch (IOException e) { 2413742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman throw new InternalError(); 2423742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2433742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2443742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2453742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2463742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Does a lexicographic comparison of the byte array representation of this record and that record. This is needed for tie-break tests according to draft-cheshire-dnsext-multicastdns-04.txt chapter 9.2. 2473742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * 2483742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param that 2493742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object. 2503742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2513742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public int compareTo(DNSEntry that) { 2523742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte[] thisBytes = this.toByteArray(); 2533742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman byte[] thatBytes = that.toByteArray(); 2543742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman for (int i = 0, n = Math.min(thisBytes.length, thatBytes.length); i < n; i++) { 2553742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman if (thisBytes[i] > thatBytes[i]) { 2563742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return 1; 2573742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } else if (thisBytes[i] < thatBytes[i]) { 2583742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return -1; 2593742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2603742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2613742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return thisBytes.length - thatBytes.length; 2623742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2633742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2643742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2653742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * Overriden, to return a value which is consistent with the value returned by equals(Object). 2663742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2673742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2683742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public int hashCode() { 2693742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return this.getKey().hashCode() + this.getRecordType().indexValue() + this.getRecordClass().indexValue(); 2703742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2713742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2723742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /* 2733742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * (non-Javadoc) 2743742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @see java.lang.Object#toString() 2753742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2763742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman @Override 2773742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman public String toString() { 2783742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman StringBuilder aLog = new StringBuilder(200); 2793742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append("[" + this.getClass().getSimpleName() + "@" + System.identityHashCode(this)); 2803742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(" type: " + this.getRecordType()); 2813742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(", class: " + this.getRecordClass()); 2823742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append((_unique ? "-unique," : ",")); 2833742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append(" name: " + _name); 2843742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman this.toString(aLog); 2853742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman aLog.append("]"); 2863742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman return aLog.toString(); 2873742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2883742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2893742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman /** 2903742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman * @param aLog 2913742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman */ 2923742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman protected void toString(StringBuilder aLog) { 2933742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman // Stub 2943742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman } 2953742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman 2963742d9db8b6edb10627b0f89336cca5249f1d15aManuel Roman} 297