Class: DNSSD::TextRecord

Inherits:
Hash
  • Object
show all
Defined in:
ext/rdnssd_tr.c,
ext/rdnssd_tr.c

Overview

DNSSD::TextRecord is a Hash with the ability to encode its contents into a binary string that can be send over the wire as using the DNSSD protocol.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#DNSSD::TextRecord.newObject #DNSSD::TextRecord.new(binary_string) ⇒ Object

The first form creates an empty text record. The second creates a new text record populated with the key, value pairs found in the encoded string binary_string. See DNSSD::TextRecord.encode() for more information.

tr = DNSSD::TextRecord.new  #=> {}
tr["name"] = "Chad"
tr["port"] = 3871.to_s


107
108
109
110
111
112
113
114
115
116
117
# File 'ext/rdnssd_tr.c', line 107

static VALUE
dnssd_tr_initialize(int argc, VALUE *argv, VALUE self)
{
	VALUE encoded_str;
	rb_scan_args(argc, argv, "01", &encoded_str);
	if (argc == 1) {
		/* try to decode the string */
		dnssd_tr_decode_str(self, encoded_str);
	}
	return self;
}

Class Method Details

.DNSSD::TextRecord.decode(binary_string) ⇒ Object

Create a new DNSSD::TextRecord be decoding the key value pairs contained in binary_string. See DNSSD::TextRecord.encode() for more information.



72
73
74
75
76
77
78
79
80
81
# File 'ext/rdnssd_tr.c', line 72

static VALUE
dnssd_tr_decode(VALUE klass, VALUE str)
{
	/* self needs to be on the stack - we add (allocate)
	 * lots of key, value pairs when decoding and this could
	 * cause the gc to run. */
	volatile VALUE self = rb_obj_alloc(klass);
	dnssd_tr_decode_str(self, str);
	return self;
}

Instance Method Details

#encodeObject

Encodes the contents of text_record into a sequence of binary strings (one for each key, value pair). The each binary string comprises of a length and a payload. The length gives the number of bytes in the payload (must be between 0 and 255). This is an unsigned integer packed into the first byte of the binary string. The payload contains a key, value pair separated by a = character. Because = is used as a separator, keys must not contain any = characters. Here is an example of how the key, value pair "1rst", "Sam" is encoded.

[00][01][02][03][04][05][06][07][08]
\010 1   r   s   t   =   S   a   m

It is recommended to use keys with a length less than or equal to 14 bytes to ensure compatibility with all clients.

text_record = DNSSD::TextRecord.new
text_record["1rst"]="Sam"
text_record["Last"]="Green"
text_record["email"]="[email protected]"
s = text_record.encode      #=> "\nLast=Green\0101rst=Sam\[email protected]"
DNSSD::TextRecord.decode(s) #=> {"Last"=>"Green", "1rst"=>"Sam", "email"=>"[email protected]"}


195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'ext/rdnssd_tr.c', line 195

static VALUE
dnssd_tr_encode(VALUE self)
{
	long i;
	VALUE buf;
	/* Declare ary volatile to prevent it from being reclaimed when:
	 * buf is allocated later, key/values are converted to strings */
	volatile VALUE ary = rb_funcall2(self, rb_intern("to_a"), 0, 0);
	/* array of key, value pairs */
	VALUE *ptr = RARRAY(ary)->ptr;
	
	buf = rb_str_buf_new(dnssd_tr_convert_pairs(ary));
	for(i=0; i<RARRAY(ary)->len; i++) {
		uint8_t len;
		VALUE key = RARRAY(ptr[i])->ptr[0];
		VALUE value = RARRAY(ptr[i])->ptr[1];
		if (!NIL_P(value)) {
			len = (uint8_t)(RSTRING(key)->len + RSTRING(value)->len + 1);
			rb_str_buf_cat(buf, &len, 1);
			rb_str_buf_append(buf, key);
			rb_str_buf_cat(buf, "=", 1);
			rb_str_buf_append(buf, value);	
		} else {
			len = (uint8_t)RSTRING(key)->len;
			rb_str_buf_cat(buf, &len, 1);
			rb_str_buf_append(buf, key);
		}
	}
	return buf;
}