4b22b9337f359bfd063322244f5336cc7c6ffcfars/* -*- Mode: Java; tab-width: 4 -*-
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Licensed under the Apache License, Version 2.0 (the "License");
4b22b9337f359bfd063322244f5336cc7c6ffcfars * you may not use this file except in compliance with the License.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * You may obtain a copy of the License at
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * http://www.apache.org/licenses/LICENSE-2.0
4b22b9337f359bfd063322244f5336cc7c6ffcfars *
4b22b9337f359bfd063322244f5336cc7c6ffcfars * Unless required by applicable law or agreed to in writing, software
4b22b9337f359bfd063322244f5336cc7c6ffcfars * distributed under the License is distributed on an "AS IS" BASIS,
4b22b9337f359bfd063322244f5336cc7c6ffcfars * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
4b22b9337f359bfd063322244f5336cc7c6ffcfars * See the License for the specific language governing permissions and
4b22b9337f359bfd063322244f5336cc7c6ffcfars * limitations under the License.
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars To do:
4b22b9337f359bfd063322244f5336cc7c6ffcfars - implement remove()
4b22b9337f359bfd063322244f5336cc7c6ffcfars - fix set() to replace existing values
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfarspackage com.apple.dnssd;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars/**
4b22b9337f359bfd063322244f5336cc7c6ffcfars Object used to construct and parse DNS-SD format TXT records.
4b22b9337f359bfd063322244f5336cc7c6ffcfars For more info see <a href="http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt">DNS-Based Service Discovery</a>, section 6.
4b22b9337f359bfd063322244f5336cc7c6ffcfars*/
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfarspublic class TXTRecord
4b22b9337f359bfd063322244f5336cc7c6ffcfars{
4b22b9337f359bfd063322244f5336cc7c6ffcfars /*
4b22b9337f359bfd063322244f5336cc7c6ffcfars DNS-SD specifies that a TXT record corresponding to an SRV record consist of
4b22b9337f359bfd063322244f5336cc7c6ffcfars a packed array of bytes, each preceded by a length byte. Each string
4b22b9337f359bfd063322244f5336cc7c6ffcfars is an attribute-value pair.
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars The TXTRecord object stores the entire TXT data as a single byte array, traversing it
4b22b9337f359bfd063322244f5336cc7c6ffcfars as need be to implement its various methods.
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars static final protected byte kAttrSep = '=';
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars protected byte[] fBytes;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Constructs a new, empty TXT record. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public TXTRecord()
4b22b9337f359bfd063322244f5336cc7c6ffcfars { fBytes = new byte[0]; }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Constructs a new TXT record from a byte array in the standard format. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public TXTRecord( byte[] initBytes)
4b22b9337f359bfd063322244f5336cc7c6ffcfars { fBytes = (byte[]) initBytes.clone(); }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Set a key/value pair in the TXT record. Setting an existing key will replace its value.<P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars @param key
4b22b9337f359bfd063322244f5336cc7c6ffcfars The key name. Must be ASCII, with no '=' characters.
4b22b9337f359bfd063322244f5336cc7c6ffcfars <P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars @param value
4b22b9337f359bfd063322244f5336cc7c6ffcfars Value to be encoded into bytes using the default platform character set.
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void set( String key, String value)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars byte[] valBytes = (value != null) ? value.getBytes() : null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars this.set( key, valBytes);
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Set a key/value pair in the TXT record. Setting an existing key will replace its value.<P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars @param key
4b22b9337f359bfd063322244f5336cc7c6ffcfars The key name. Must be ASCII, with no '=' characters.
4b22b9337f359bfd063322244f5336cc7c6ffcfars <P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars @param value
4b22b9337f359bfd063322244f5336cc7c6ffcfars Binary representation of the value.
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public void set( String key, byte[] value)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars byte[] keyBytes;
4b22b9337f359bfd063322244f5336cc7c6ffcfars int valLen = (value != null) ? value.length : 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars try {
4b22b9337f359bfd063322244f5336cc7c6ffcfars keyBytes = key.getBytes( "US-ASCII");
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars catch ( java.io.UnsupportedEncodingException uee) {
4b22b9337f359bfd063322244f5336cc7c6ffcfars throw new IllegalArgumentException();
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( int i=0; i < keyBytes.length; i++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( keyBytes[i] == '=')
4b22b9337f359bfd063322244f5336cc7c6ffcfars throw new IllegalArgumentException();
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( keyBytes.length + valLen >= 255)
4b22b9337f359bfd063322244f5336cc7c6ffcfars throw new ArrayIndexOutOfBoundsException();
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars int prevLoc = this.remove( key);
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( prevLoc == -1)
4b22b9337f359bfd063322244f5336cc7c6ffcfars prevLoc = this.size();
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars this.insert( keyBytes, value, prevLoc);
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars protected void insert( byte[] keyBytes, byte[] value, int index)
4b22b9337f359bfd063322244f5336cc7c6ffcfars // Insert a key-value pair at index
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars byte[] oldBytes = fBytes;
4b22b9337f359bfd063322244f5336cc7c6ffcfars int valLen = (value != null) ? value.length : 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars int insertion = 0;
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome int newLen, avLen;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars // locate the insertion point
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( int i=0; i < index && insertion < fBytes.length; i++)
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome insertion += (0xFF & (fBytes[ insertion] + 1));
4b22b9337f359bfd063322244f5336cc7c6ffcfars
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome avLen = keyBytes.length + valLen + (value != null ? 1 : 0);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome newLen = avLen + oldBytes.length + 1;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars fBytes = new byte[ newLen];
4b22b9337f359bfd063322244f5336cc7c6ffcfars System.arraycopy( oldBytes, 0, fBytes, 0, insertion);
4b22b9337f359bfd063322244f5336cc7c6ffcfars int secondHalfLen = oldBytes.length - insertion;
4b22b9337f359bfd063322244f5336cc7c6ffcfars System.arraycopy( oldBytes, insertion, fBytes, newLen - secondHalfLen, secondHalfLen);
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome fBytes[ insertion] = ( byte) avLen;
4b22b9337f359bfd063322244f5336cc7c6ffcfars System.arraycopy( keyBytes, 0, fBytes, insertion + 1, keyBytes.length);
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( value != null)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars fBytes[ insertion + 1 + keyBytes.length] = kAttrSep;
4b22b9337f359bfd063322244f5336cc7c6ffcfars System.arraycopy( value, 0, fBytes, insertion + keyBytes.length + 2, valLen);
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Remove a key/value pair from the TXT record. Returns index it was at, or -1 if not found. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public int remove( String key)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars int avStart = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( int i=0; avStart < fBytes.length; i++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars int avLen = fBytes[ avStart];
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( key.length() <= avLen &&
4b22b9337f359bfd063322244f5336cc7c6ffcfars ( key.length() == avLen || fBytes[ avStart + key.length() + 1] == kAttrSep))
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars String s = new String( fBytes, avStart + 1, key.length());
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( 0 == key.compareToIgnoreCase( s))
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars byte[] oldBytes = fBytes;
4b22b9337f359bfd063322244f5336cc7c6ffcfars fBytes = new byte[ oldBytes.length - avLen - 1];
4b22b9337f359bfd063322244f5336cc7c6ffcfars System.arraycopy( oldBytes, 0, fBytes, 0, avStart);
4b22b9337f359bfd063322244f5336cc7c6ffcfars System.arraycopy( oldBytes, avStart + avLen + 1, fBytes, avStart, oldBytes.length - avStart - avLen - 1);
4b22b9337f359bfd063322244f5336cc7c6ffcfars return i;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome avStart += (0xFF & (avLen + 1));
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars return -1;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Return the number of keys in the TXT record. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public int size()
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars int i, avStart;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( i=0, avStart=0; avStart < fBytes.length; i++)
5ffb0c9b03b5149ff4f5821a62be4a52408ada2aToomas Soome avStart += (0xFF & (fBytes[ avStart] + 1));
4b22b9337f359bfd063322244f5336cc7c6ffcfars return i;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Return true if key is present in the TXT record, false if not. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public boolean contains( String key)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars String s = null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( int i=0; null != ( s = this.getKey( i)); i++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( 0 == key.compareToIgnoreCase( s))
4b22b9337f359bfd063322244f5336cc7c6ffcfars return true;
4b22b9337f359bfd063322244f5336cc7c6ffcfars return false;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Return a key in the TXT record by zero-based index. Returns null if index exceeds the total number of keys. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public String getKey( int index)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars int avStart = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( int i=0; i < index && avStart < fBytes.length; i++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars avStart += fBytes[ avStart] + 1;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( avStart < fBytes.length)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars int avLen = fBytes[ avStart];
4b22b9337f359bfd063322244f5336cc7c6ffcfars int aLen = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( aLen=0; aLen < avLen; aLen++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( fBytes[ avStart + aLen + 1] == kAttrSep)
4b22b9337f359bfd063322244f5336cc7c6ffcfars break;
4b22b9337f359bfd063322244f5336cc7c6ffcfars return new String( fBytes, avStart + 1, aLen);
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars return null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /**
4b22b9337f359bfd063322244f5336cc7c6ffcfars Look up a key in the TXT record by zero-based index and return its value. <P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars Returns null if index exceeds the total number of keys.
4b22b9337f359bfd063322244f5336cc7c6ffcfars Returns null if the key is present with no value.
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public byte[] getValue( int index)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars int avStart = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars byte[] value = null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( int i=0; i < index && avStart < fBytes.length; i++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars avStart += fBytes[ avStart] + 1;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( avStart < fBytes.length)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars int avLen = fBytes[ avStart];
4b22b9337f359bfd063322244f5336cc7c6ffcfars int aLen = 0;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( aLen=0; aLen < avLen; aLen++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( fBytes[ avStart + aLen + 1] == kAttrSep)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars value = new byte[ avLen - aLen - 1];
4b22b9337f359bfd063322244f5336cc7c6ffcfars System.arraycopy( fBytes, avStart + aLen + 2, value, 0, avLen - aLen - 1);
4b22b9337f359bfd063322244f5336cc7c6ffcfars break;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars return value;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Converts the result of getValue() to a string in the platform default character set. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public String getValueAsString( int index)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars byte[] value = this.getValue( index);
4b22b9337f359bfd063322244f5336cc7c6ffcfars return value != null ? new String( value) : null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Get the value associated with a key. Will be null if the key is not defined.
4b22b9337f359bfd063322244f5336cc7c6ffcfars Array will have length 0 if the key is defined with an = but no value.<P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars @param forKey
4b22b9337f359bfd063322244f5336cc7c6ffcfars The left-hand side of the key-value pair.
4b22b9337f359bfd063322244f5336cc7c6ffcfars <P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars @return The binary representation of the value.
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public byte[] getValue( String forKey)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars String s = null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars int i;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( i=0; null != ( s = this.getKey( i)); i++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( 0 == forKey.compareToIgnoreCase( s))
4b22b9337f359bfd063322244f5336cc7c6ffcfars return this.getValue( i);
4b22b9337f359bfd063322244f5336cc7c6ffcfars return null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Converts the result of getValue() to a string in the platform default character set.<P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars @param forKey
4b22b9337f359bfd063322244f5336cc7c6ffcfars The left-hand side of the key-value pair.
4b22b9337f359bfd063322244f5336cc7c6ffcfars <P>
4b22b9337f359bfd063322244f5336cc7c6ffcfars @return The value represented in the default platform character set.
4b22b9337f359bfd063322244f5336cc7c6ffcfars */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public String getValueAsString( String forKey)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars byte[] val = this.getValue( forKey);
4b22b9337f359bfd063322244f5336cc7c6ffcfars return val != null ? new String( val) : null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Return the contents of the TXT record as raw bytes. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public byte[] getRawBytes() { return (byte[]) fBytes.clone(); }
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars /** Return a string representation of the object. */
4b22b9337f359bfd063322244f5336cc7c6ffcfars public String toString()
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars String a, result = null;
4b22b9337f359bfd063322244f5336cc7c6ffcfars
4b22b9337f359bfd063322244f5336cc7c6ffcfars for ( int i=0; null != ( a = this.getKey( i)); i++)
4b22b9337f359bfd063322244f5336cc7c6ffcfars {
4b22b9337f359bfd063322244f5336cc7c6ffcfars String av = String.valueOf( i) + "={" + a;
4b22b9337f359bfd063322244f5336cc7c6ffcfars String val = this.getValueAsString( i);
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( val != null)
4b22b9337f359bfd063322244f5336cc7c6ffcfars av += "=" + val + "}";
4b22b9337f359bfd063322244f5336cc7c6ffcfars else
4b22b9337f359bfd063322244f5336cc7c6ffcfars av += "}";
4b22b9337f359bfd063322244f5336cc7c6ffcfars if ( result == null)
4b22b9337f359bfd063322244f5336cc7c6ffcfars result = av;
4b22b9337f359bfd063322244f5336cc7c6ffcfars else
4b22b9337f359bfd063322244f5336cc7c6ffcfars result = result + ", " + av;
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars return result != null ? result : "";
4b22b9337f359bfd063322244f5336cc7c6ffcfars }
4b22b9337f359bfd063322244f5336cc7c6ffcfars}
4b22b9337f359bfd063322244f5336cc7c6ffcfars