dnssd 0.7.1 → 1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
-