dnssd 0.7.1 → 1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,257 +0,0 @@
1
- /*
2
- * Copyright (c) 2004 Chad Fowler, Charles Mills, Rich Kilmer
3
- * Licenced under the same terms as Ruby.
4
- * This software has absolutely no warrenty.
5
- */
6
- #include "rdnssd.h"
7
- #include <intern.h>
8
- #include <string.h> /* for strchr() */
9
-
10
- static VALUE cDNSSDTextRecord;
11
-
12
- static void
13
- dnssd_tr_decode_buffer(VALUE self, long buf_len, const char *buf_ptr)
14
- {
15
- /* iterate through text record, inserting key, value pairs into hash */
16
- long i = 0;
17
- while(i < buf_len) {
18
- VALUE key, value;
19
- const char *p;
20
- long key_len, len = (long)(uint8_t)buf_ptr[i++];
21
- if (i + len > buf_len)
22
- rb_raise(rb_eArgError, "invalid text record (string longer than buffer)");
23
-
24
- if (len == 0) {
25
- /* 0-length key/value, handle this by skipping over it.
26
- * Probably the RR should have zero-length, but some services have been
27
- * found to advertise a non-zero length TXT record, with a zero-length
28
- * key/value string.
29
- */
30
- continue;
31
- }
32
-
33
- p = memchr(buf_ptr + i, '=', buf_len - i);
34
- if (p == NULL) {
35
- /* key, with no value, this is OK */
36
- key_len = len;
37
- key = rb_str_new(buf_ptr + i, key_len);
38
- value = Qnil;
39
- } else {
40
- key_len = p - (buf_ptr + i);
41
- if(key_len == 0)
42
- rb_raise(rb_eArgError, "invalid text record (zero-length key)");
43
-
44
- key = rb_str_new(buf_ptr + i, key_len);
45
- key_len++; /* step over '=' */
46
- value = rb_str_new(buf_ptr + i + key_len, len - key_len);
47
- }
48
- rb_hash_aset(self, key, value);
49
- i += len;
50
- }
51
- }
52
-
53
- static void
54
- dnssd_tr_decode_str(VALUE self, VALUE str)
55
- {
56
- str = StringValue(str);
57
- /* text records cannot be longer than 65535 (0xFFFF) */
58
- if (RSTRING(str)->len > UINT16_MAX)
59
- rb_raise(rb_eArgError, "string is to large to encode");
60
- dnssd_tr_decode_buffer (self, RSTRING(str)->len, RSTRING(str)->ptr);
61
- }
62
-
63
- /*
64
- * call-seq:
65
- * DNSSD::TextRecord.decode(binary_string) => text_record
66
- *
67
- * Create a new DNSSD::TextRecord be decoding the key
68
- * value pairs contained in _binary_string_. See DNSSD::TextRecord.encode()
69
- * for more information.
70
- */
71
-
72
- static VALUE
73
- dnssd_tr_decode(VALUE klass, VALUE str)
74
- {
75
- /* self needs to be on the stack - we add (allocate)
76
- * lots of key, value pairs when decoding and this could
77
- * cause the gc to run. */
78
- volatile VALUE self = rb_obj_alloc(klass);
79
- dnssd_tr_decode_str(self, str);
80
- return self;
81
- }
82
-
83
- VALUE
84
- dnssd_tr_new(long len, const char *buf)
85
- {
86
- VALUE self = rb_obj_alloc(cDNSSDTextRecord);
87
- dnssd_tr_decode_buffer(self, len, buf);
88
- return self;
89
- }
90
-
91
- /*
92
- * call-seq:
93
- * DNSSD::TextRecord.new() => text_record
94
- * DNSSD::TextRecord.new(binary_string) => text_record
95
- *
96
- * The first form creates an empty text record. The second
97
- * creates a new text record populated with the key, value pairs
98
- * found in the encoded string _binary_string_. See
99
- * DNSSD::TextRecord.encode() for more information.
100
- *
101
- * tr = DNSSD::TextRecord.new #=> {}
102
- * tr["name"] = "Chad"
103
- * tr["port"] = 3871.to_s
104
- *
105
- */
106
-
107
- static VALUE
108
- dnssd_tr_initialize(int argc, VALUE *argv, VALUE self)
109
- {
110
- VALUE encoded_str;
111
- rb_scan_args(argc, argv, "01", &encoded_str);
112
- if (argc == 1) {
113
- /* try to decode the string */
114
- dnssd_tr_decode_str(self, encoded_str);
115
- }
116
- return self;
117
- }
118
-
119
- static void
120
- dnssd_tr_valid_key(const char *key_cstr, long len)
121
- {
122
- /* keys cannot contain '=' */
123
- if (strchr(key_cstr, '='))
124
- rb_raise(rb_eRuntimeError, "key '%s' contains '='", key_cstr);
125
-
126
- if (len <= 0)
127
- rb_raise(rb_eRuntimeError, "empty key given");
128
- }
129
-
130
- static long
131
- dnssd_tr_convert_pairs(volatile VALUE ary)
132
- {
133
- long i, tot_len = 0;
134
- VALUE *ptr = RARRAY(ary)->ptr;
135
- /* iterate over key, value pairs checking if each one is valid */
136
- for(i=0; i<RARRAY(ary)->len; i++) {
137
- VALUE key = RARRAY(ptr[i])->ptr[0];
138
- VALUE value = RARRAY(ptr[i])->ptr[1];
139
- /* checks if key is a valid C String (null terminated)
140
- * note: StringValueCStr takes a pointer to key by &key
141
- * this may cause key to be reassigned. */
142
- const char *key_cstr = StringValueCStr(key);
143
- long len = RSTRING(key)->len;
144
- dnssd_tr_valid_key(key_cstr, len);
145
-
146
- if (!NIL_P(value)) {
147
- value = StringValue(value);
148
- len += 1 + RSTRING(value)->len;
149
- }
150
- /* len == sum(key length, 1 for '=' if value != nil, value length) */
151
- if (len > UINT8_MAX)
152
- rb_raise(rb_eRuntimeError, "key, value pair at '%s' is too large to encode", key_cstr);
153
-
154
- /* now that we know no errors are going to occur */
155
- if (RSTRING(key)->len > 14)
156
- rb_warn("key '%s' is greator than 14 bytes, may not be compatible with all clients", key_cstr);
157
- /* key and value may have been reassigned by StringValue macros */
158
- RARRAY(ptr[i])->ptr[0] = key;
159
- RARRAY(ptr[i])->ptr[1] = value;
160
- tot_len += len + 1; /* plus 1 to hold key, value pair length */
161
- }
162
- return tot_len;
163
- }
164
-
165
- /*
166
- * call-seq:
167
- * text_record.encode => an_encoded_string
168
- *
169
- * Encodes the contents of _text_record_ into a sequence of <em>binary strings</em>
170
- * (one for each key, value pair).
171
- * The each <em>binary string</em> comprises of a <em>length</em> and a <em>payload</em>.
172
- * The <em>length</em> gives the number of bytes in the <em>payload</em>
173
- * (must be between <code>0</code> and <code>255</code>).
174
- * This is an unsigned integer packed into the first byte of the binary string.
175
- * The <em>payload</em> contains a key, value pair separated by a <code>=</code> character.
176
- * Because <code>=</code> is used as a separator, keys must not contain any
177
- * <code>=</code> characters. Here is an example of how the key, value pair
178
- * <code>"1rst"</code>, <code>"Sam"</code> is encoded.
179
- *
180
- * [00][01][02][03][04][05][06][07][08]
181
- * \010 1 r s t = S a m
182
- *
183
- * It is recommended to use keys with a length less than or equal to <code>14</code> bytes
184
- * to ensure compatibility with all clients.
185
- *
186
- * text_record = DNSSD::TextRecord.new
187
- * text_record["1rst"]="Sam"
188
- * text_record["Last"]="Green"
189
- * text_record["email"]="sam@green.org"
190
- * s = text_record.encode #=> "\nLast=Green\0101rst=Sam\023email=sam@green.org"
191
- * DNSSD::TextRecord.decode(s) #=> {"Last"=>"Green", "1rst"=>"Sam", "email"=>"sam@green.org"}
192
- *
193
- */
194
-
195
- static VALUE
196
- dnssd_tr_encode(VALUE self)
197
- {
198
- long i;
199
- VALUE buf;
200
- /* Declare ary volatile to prevent it from being reclaimed when:
201
- * buf is allocated later, key/values are converted to strings */
202
- volatile VALUE ary = rb_funcall2(self, rb_intern("to_a"), 0, 0);
203
- /* array of key, value pairs */
204
- VALUE *ptr = RARRAY(ary)->ptr;
205
-
206
- buf = rb_str_buf_new(dnssd_tr_convert_pairs(ary));
207
- for(i=0; i<RARRAY(ary)->len; i++) {
208
- uint8_t len;
209
- VALUE key = RARRAY(ptr[i])->ptr[0];
210
- VALUE value = RARRAY(ptr[i])->ptr[1];
211
- if (!NIL_P(value)) {
212
- len = (uint8_t)(RSTRING(key)->len + RSTRING(value)->len + 1);
213
- rb_str_buf_cat(buf, &len, 1);
214
- rb_str_buf_append(buf, key);
215
- rb_str_buf_cat(buf, "=", 1);
216
- rb_str_buf_append(buf, value);
217
- } else {
218
- len = (uint8_t)RSTRING(key)->len;
219
- rb_str_buf_cat(buf, &len, 1);
220
- rb_str_buf_append(buf, key);
221
- }
222
- }
223
- return buf;
224
- }
225
-
226
- VALUE
227
- dnssd_tr_to_encoded_str(VALUE v)
228
- {
229
- if (rb_obj_is_kind_of(v, rb_cHash) == Qtrue)
230
- return dnssd_tr_encode(v);
231
- /* allow the user to use arbitrary strings as text records */
232
- return StringValue(v);
233
- }
234
-
235
- /*
236
- * Document-class: DNSSD::TextRecord
237
- *
238
- * DNSSD::TextRecord is a Hash with the ability to encode its contents into
239
- * a binary string that can be send over the wire as using the DNSSD protocol.
240
- *
241
- */
242
-
243
- void
244
- Init_DNSSD_TextRecord(void)
245
- {
246
- /* hack so rdoc documents the project correctly */
247
- #ifdef mDNSSD_RDOC_HACK
248
- mDNSSD = rb_define_module("DNSSD");
249
- #endif
250
- cDNSSDTextRecord = rb_define_class_under(mDNSSD, "TextRecord", rb_cHash);
251
-
252
- rb_define_singleton_method(cDNSSDTextRecord, "decode", dnssd_tr_decode, 1);
253
-
254
- rb_define_method(cDNSSDTextRecord, "initialize", dnssd_tr_initialize, -1);
255
- rb_define_method(cDNSSDTextRecord, "encode", dnssd_tr_encode, 0);
256
- }
257
-
@@ -1,4 +0,0 @@
1
- #!/bin/bash
2
-
3
- rdoc -w 2 -S *.c
4
-