X-Git-Url: https://git.saurik.com/apple/mdnsresponder.git/blobdiff_plain/8e92c31c9a45a66732f5bc7afbc9f5596c17e91d..1877dd22192c77d6b24225dde98f46d08062a99b:/mDNSShared/Java/TXTRecord.java diff --git a/mDNSShared/Java/TXTRecord.java b/mDNSShared/Java/TXTRecord.java index 97bcea9..8d9df7a 100644 --- a/mDNSShared/Java/TXTRecord.java +++ b/mDNSShared/Java/TXTRecord.java @@ -1,35 +1,18 @@ -/* +/* -*- Mode: Java; tab-width: 4 -*- + * * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. * - * @APPLE_LICENSE_HEADER_START@ - * - * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. + * http://www.apache.org/licenses/LICENSE-2.0 * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - - Change History (most recent first): - -$Log: TXTRecord.java,v $ -Revision 1.2 2004/04/30 21:48:27 rpantos -Change line endings for CVS. - -Revision 1.1 2004/04/30 16:29:35 rpantos -First checked in. To do: - implement remove() @@ -42,7 +25,7 @@ package com.apple.dnssd; /** Object used to construct and parse DNS-SD format TXT records. - For more info see DNS-SD TXT record format. + For more info see DNS-Based Service Discovery, section 6. */ public class TXTRecord @@ -90,10 +73,8 @@ public class TXTRecord */ public void set( String key, byte[] value) { - byte[] oldBytes = fBytes; byte[] keyBytes; int valLen = (value != null) ? value.length : 0; - byte newLen; try { keyBytes = key.getBytes( "US-ASCII"); @@ -108,26 +89,75 @@ public class TXTRecord if ( keyBytes.length + valLen >= 255) throw new ArrayIndexOutOfBoundsException(); - newLen = (byte) ( keyBytes.length + valLen + (valLen > 0 ? 1 : 0)); - fBytes = new byte[ oldBytes.length + newLen + 1]; - System.arraycopy( oldBytes, 0, fBytes, 0, oldBytes.length); - fBytes[ oldBytes.length] = newLen; - System.arraycopy( keyBytes, 0, fBytes, oldBytes.length + 1, keyBytes.length); - if ( valLen > 0) + int prevLoc = this.remove( key); + if ( prevLoc == -1) + prevLoc = this.size(); + + this.insert( keyBytes, value, prevLoc); + } + + protected void insert( byte[] keyBytes, byte[] value, int index) + // Insert a key-value pair at index + { + byte[] oldBytes = fBytes; + int valLen = (value != null) ? value.length : 0; + int insertion = 0; + int newLen, avLen; + + // locate the insertion point + for ( int i=0; i < index && insertion < fBytes.length; i++) + insertion += (0xFF & (fBytes[ insertion] + 1)); + + avLen = keyBytes.length + valLen + (value != null ? 1 : 0); + newLen = avLen + oldBytes.length + 1; + + fBytes = new byte[ newLen]; + System.arraycopy( oldBytes, 0, fBytes, 0, insertion); + int secondHalfLen = oldBytes.length - insertion; + System.arraycopy( oldBytes, insertion, fBytes, newLen - secondHalfLen, secondHalfLen); + fBytes[ insertion] = ( byte) avLen; + System.arraycopy( keyBytes, 0, fBytes, insertion + 1, keyBytes.length); + if ( value != null) { - fBytes[ oldBytes.length + 1 + keyBytes.length] = kAttrSep; - System.arraycopy( value, 0, fBytes, oldBytes.length + keyBytes.length + 2, value.length); + fBytes[ insertion + 1 + keyBytes.length] = kAttrSep; + System.arraycopy( value, 0, fBytes, insertion + keyBytes.length + 2, valLen); } } + /** Remove a key/value pair from the TXT record. Returns index it was at, or -1 if not found. */ + public int remove( String key) + { + int avStart = 0; + + for ( int i=0; avStart < fBytes.length; i++) + { + int avLen = fBytes[ avStart]; + if ( key.length() <= avLen && + ( key.length() == avLen || fBytes[ avStart + key.length() + 1] == kAttrSep)) + { + String s = new String( fBytes, avStart + 1, key.length()); + if ( 0 == key.compareToIgnoreCase( s)) + { + byte[] oldBytes = fBytes; + fBytes = new byte[ oldBytes.length - avLen - 1]; + System.arraycopy( oldBytes, 0, fBytes, 0, avStart); + System.arraycopy( oldBytes, avStart + avLen + 1, fBytes, avStart, oldBytes.length - avStart - avLen - 1); + return i; + } + } + avStart += (0xFF & (avLen + 1)); + } + return -1; + } + /** Return the number of keys in the TXT record. */ public int size() { int i, avStart; for ( i=0, avStart=0; avStart < fBytes.length; i++) - avStart += fBytes[ avStart] + 1; + avStart += (0xFF & (fBytes[ avStart] + 1)); return i; } @@ -187,6 +217,7 @@ public class TXTRecord { value = new byte[ avLen - aLen - 1]; System.arraycopy( fBytes, avStart + aLen + 2, value, 0, avLen - aLen - 1); + break; } } } @@ -234,5 +265,26 @@ public class TXTRecord /** Return the contents of the TXT record as raw bytes. */ public byte[] getRawBytes() { return (byte[]) fBytes.clone(); } + + /** Return a string representation of the object. */ + public String toString() + { + String a, result = null; + + for ( int i=0; null != ( a = this.getKey( i)); i++) + { + String av = String.valueOf( i) + "={" + a; + String val = this.getValueAsString( i); + if ( val != null) + av += "=" + val + "}"; + else + av += "}"; + if ( result == null) + result = av; + else + result = result + ", " + av; + } + return result != null ? result : ""; + } }