Hi,
Firstly, thanks for a very useful library!
Secondly, I noticed when adding TXT records to my service in avahi, that the ServiceInfo.getTextString() doesn't handle the TXT data properly. It assumes everything in the text bytes is a string - actually according to the spec it is a list of strings, with each string having a one byte length. I might just be missing another method for doing this, but I put together some code to parse this format (And also take it a step further to parse out the key/value pairs in the strings). Just in case it's helpful I'll attach below. Please let me know if you would like to use it:
/** * Utility methods for zeroconf */
publicclassZeroconfUtils{privatestaticCharsetcharset=Charset.forName("US-ASCII");/** * Parse the raw bytes of text data into a map of keys and values * @param textBytes Raw text bytes from {@link ServiceInfo#getTextBytes()} * @param strict If true, invalid strings cause an exception, if false * they are just ignored. * @return {@link SortedMap} of String to String, sorted by key. * Note that in the case of duplicate keys, only the one that * comes last in the text will be present. * @throws TextByteDecodeException If data is not a valid DNS text record containing * DNS-SD format key/value pairs */publicstaticSortedMap<String,String>textBytesToMap(byte[]textBytes,booleanstrict)throwsTextByteDecodeException{List<String>strings=textBytesToStrings(textBytes);SortedMap<String,String>map=newTreeMap<String,String>();for(Strings:strings){inti=s.indexOf("=");if(i>=0){Stringkey=s.substring(0,i);Stringvalue="";if(i+1<s.length()){value=s.substring(i+1,s.length());}map.put(key,value);}else{if(strict){thrownewTextByteDecodeException("String is not a key/value pair '"+s+"'");}}}returnmap;}/** * Parse the raw bytes of text data into a list of strings * @param textBytes Raw text bytes from {@link ServiceInfo#getTextBytes()} * @return List of strings * @throws TextByteDecodeException If data is not a valid DNS text record */publicstaticList<String>textBytesToStrings(byte[]textBytes)throwsTextByteDecodeException{//Formatisdefinedat//http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt
//sections6.1and6.2CharsetDecoderdecoder=charset.newDecoder();ByteBufferbuffer=ByteBuffer.wrap(textBytes);List<String>strings=newArrayList<String>();//Whilewehavebytesleft,trytoreadastringlength,thenstring
while(buffer.hasRemaining()){intcount=buffer.get();if(buffer.remaining()>=count){//Readonlyspecifiedcount
buffer.limit(buffer.position()+count);try{CharBuffercbuf=decoder.decode(buffer);//Restorelimitsoweusetherestofthebuffer
buffer.limit(buffer.capacity());strings.add(cbuf.toString());}catch(MalformedInputExceptionmie){thrownewTextByteDecodeException("Can't decode a string",mie);}catch(UnmappableCharacterExceptionuce){thrownewTextByteDecodeException("Can't decode a string",uce);}catch(CharacterCodingExceptioncce){thrownewTextByteDecodeException("Can't decode a string",cce);}}else{thrownewTextByteDecodeException("String length is "+count+" but only "+buffer.remaining()+" bytes left.");}}returnstrings;}}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The method ServiceInfo.getTextString() has now been deprecated. There is no way to make this method return a correct result. To access TXT info either use getTextByte() that will return the raw information of use the properties. You can enumerate on the property names and get each value either as a string or byte array.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
Firstly, thanks for a very useful library!
Secondly, I noticed when adding TXT records to my service in avahi, that the ServiceInfo.getTextString() doesn't handle the TXT data properly. It assumes everything in the text bytes is a string - actually according to the spec it is a list of strings, with each string having a one byte length. I might just be missing another method for doing this, but I put together some code to parse this format (And also take it a step further to parse out the key/value pairs in the strings). Just in case it's helpful I'll attach below. Please let me know if you would like to use it:
The method ServiceInfo.getTextString() has now been deprecated. There is no way to make this method return a correct result. To access TXT info either use getTextByte() that will return the raw information of use the properties. You can enumerate on the property names and get each value either as a string or byte array.