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;
}