dnssd 0.6.0 → 0.7.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.
Binary file
@@ -5,16 +5,8 @@
5
5
  */
6
6
  #include "rdnssd.h"
7
7
 
8
- /* for if_indextoname() */
9
- #include <sys/types.h>
10
- #include <sys/socket.h>
11
- #include <net/if.h>
12
-
13
8
  static VALUE cDNSSDFlags;
14
9
  static VALUE cDNSSDReply;
15
- static VALUE cDNSSDBrowseReply;
16
- static VALUE cDNSSDResolveReply;
17
- static VALUE cDNSSDRegisterReply;
18
10
 
19
11
  static ID dnssd_iv_flags;
20
12
  static ID dnssd_iv_interface;
@@ -28,6 +20,10 @@ static ID dnssd_iv_domain;
28
20
  static ID dnssd_iv_service;
29
21
 
30
22
  #define IsDNSSDFlags(obj) (rb_obj_is_kind_of(obj,cDNSSDFlags)==Qtrue)
23
+ #define VerifyDNSSDFlags(obj) \
24
+ do { \
25
+ if(!IsDNSSDFlags(obj)) rb_fatal(__FILE__":%d: bug in DNSSD",__LINE__); \
26
+ } while (0)
31
27
 
32
28
  /* dns sd flags, flag ID's, flag names */
33
29
  #define DNSSD_MAX_FLAGS 9
@@ -49,7 +45,13 @@ static const DNSServiceFlags dnssd_flag[DNSSD_MAX_FLAGS] = {
49
45
  kDNSServiceFlagsLongLivedQuery
50
46
  };
51
47
 
52
- static ID dnssd_flag_iv[DNSSD_MAX_FLAGS];
48
+ /* used to make sure only valid bits are set in a flag. */
49
+ #define DNSSD_FLAGS_MASK(f) \
50
+ ( (f) & (kDNSServiceFlagsMoreComing | \
51
+ kDNSServiceFlagsAdd | kDNSServiceFlagsDefault | \
52
+ kDNSServiceFlagsNoAutoRename | kDNSServiceFlagsShared | \
53
+ kDNSServiceFlagsUnique | kDNSServiceFlagsBrowseDomains | \
54
+ kDNSServiceFlagsRegistrationDomains | kDNSServiceFlagsLongLivedQuery) )
53
55
 
54
56
  static const char *dnssd_flag_name[DNSSD_MAX_FLAGS] = {
55
57
  "more_coming",
@@ -63,126 +65,54 @@ static const char *dnssd_flag_name[DNSSD_MAX_FLAGS] = {
63
65
  "long_lived_query"
64
66
  };
65
67
 
66
- static VALUE
67
- dnssd_struct_inspect(VALUE self, volatile VALUE data)
68
- {
69
- VALUE buf = rb_str_buf_new(0);
70
- rb_str_buf_cat2(buf, "#<");
71
- rb_str_buf_cat2(buf, rb_obj_classname(self));
72
- if (RSTRING(data)->len > 0) {
73
- rb_str_buf_cat2(buf, " ");
74
- rb_str_buf_append(buf, data);
75
- }
76
- rb_str_buf_cat2(buf, ">");
77
- return buf;
78
- }
79
-
80
- VALUE
81
- dnssd_create_fullname(VALUE name, VALUE regtype, VALUE domain, int err_flag)
82
- {
83
- char buffer[kDNSServiceMaxDomainName];
84
- int ret_val = DNSServiceConstructFullName(buffer,
85
- NIL_P(name) ? NULL : StringValueCStr(name),
86
- StringValueCStr(regtype),
87
- StringValueCStr(domain) );
88
- if (ret_val) {
89
- static const char msg[] = "could not construct full service name";
90
- if (err_flag) rb_raise(rb_eArgError, msg);
91
- /* else */
92
- rb_warn(msg);
93
- return name;
94
- }
95
- buffer[kDNSServiceMaxDomainName - 1] = '\000'; /* just in case */
96
- return rb_str_new2(buffer);
97
- }
98
-
99
- static VALUE
100
- dnssd_get_fullname(VALUE self, int flag)
101
- {
102
- return dnssd_create_fullname( rb_ivar_get(self, dnssd_iv_name),
103
- rb_ivar_get(self, dnssd_iv_type),
104
- rb_ivar_get(self, dnssd_iv_domain), flag );
105
- }
106
-
107
- /*
108
- * call-seq:
109
- * reply.fullname => string
110
- *
111
- * The fullname of the resource the reply is associated with.
112
- * See DNSSD::Service.fullname() for more information.
113
- */
114
-
115
- static VALUE
116
- dnssd_reply_fullname(VALUE self)
117
- {
118
- return dnssd_get_fullname(self, 1);
119
- }
120
-
121
- static void
122
- dnssd_add_names(volatile VALUE self, const char *name,
123
- const char *regtype, const char *domain)
124
- {
125
- rb_ivar_set(self, dnssd_iv_name, rb_str_new2(name));
126
- rb_ivar_set(self, dnssd_iv_type, rb_str_new2(regtype));
127
- rb_ivar_set(self, dnssd_iv_domain, rb_str_new2(domain));
128
- }
129
-
130
68
  static void
131
- dnssd_init_flag_iv(void)
69
+ dnssd_init_flags_methods(VALUE klass)
132
70
  {
133
- /* initialize flag instance variable ids. */
134
- char buffer[32];
71
+ char buffer[128];
135
72
  int i;
136
73
  for (i=0; i<DNSSD_MAX_FLAGS; i++) {
137
- snprintf(buffer, sizeof(buffer), "@%s", dnssd_flag_name[i]);
138
- dnssd_flag_iv[i] = rb_intern(buffer);
74
+ unsigned long flag = (unsigned long)dnssd_flag[i];
75
+ const char *flag_name = dnssd_flag_name[i];
76
+ VALUE str;
77
+ size_t len;
78
+ len = snprintf(buffer, sizeof(buffer),
79
+ "def %s?; self & %lu end",
80
+ flag_name, flag);
81
+ str = rb_str_new(buffer, (long)len);
82
+ rb_mod_module_eval(1, &str, klass);
83
+
84
+ /* similar to attr_writer method for each flag */
85
+ len = snprintf(buffer, sizeof(buffer),
86
+ "def %s=(val); "
87
+ "if val then self.set_flag(%lu) else self.clear_flag(%lu) end; "
88
+ "val end", /* return val */
89
+ flag_name, flag, flag);
90
+ str = rb_str_new(buffer, (long)len);
91
+ rb_mod_module_eval(1, &str, klass);
139
92
  }
140
93
  }
141
94
 
142
- static void
143
- dnssd_init_flags_methods(VALUE class)
95
+ static VALUE
96
+ dnssd_flags_alloc(VALUE klass)
144
97
  {
145
- char buffer[128];
146
- int i;
147
- for (i=0; i<DNSSD_MAX_FLAGS; i++) {
148
- volatile VALUE str;
149
- size_t len = snprintf(buffer, sizeof(buffer),
150
- "def %s?; @%s end",
151
- dnssd_flag_name[i],
152
- dnssd_flag_name[i]);
153
- str = rb_str_new(buffer, (long)len);
154
- rb_mod_module_eval(1, (VALUE *)&str, class);
155
- /* attr_writer method for each flag */
156
- rb_define_attr(class, dnssd_flag_name[i], 0, 1);
157
- }
98
+ /* no free function or mark function, initialize flags/data to 0 */
99
+ return Data_Wrap_Struct(klass, 0, 0, 0);
158
100
  }
159
101
 
160
102
  static VALUE
161
103
  dnssd_flags_init(VALUE self, DNSServiceFlags flags)
162
104
  {
163
- int i;
164
- for (i=0; i<DNSSD_MAX_FLAGS; i++) {
165
- /* check each flag using binary and, set to Qtrue of exists */
166
- if (flags & dnssd_flag[i]) {
167
- rb_ivar_set(self, dnssd_flag_iv[i], Qtrue);
168
- } else {
169
- rb_ivar_set(self, dnssd_flag_iv[i], Qfalse);
170
- }
171
- }
105
+ VerifyDNSSDFlags(self);
106
+ /* note DNSSD_FLAGS_MASK() here */
107
+ RDATA(self)->data = (void*)DNSSD_FLAGS_MASK(flags);
172
108
  return self;
173
109
  }
174
110
 
175
111
  static DNSServiceFlags
176
112
  dnssd_get_flags(VALUE self)
177
113
  {
178
- DNSServiceFlags flags = 0;
179
- int i;
180
- for (i=0; i<DNSSD_MAX_FLAGS; i++) {
181
- if (RTEST(rb_ivar_get(self, dnssd_flag_iv[i]))) {
182
- flags |= dnssd_flag[i];
183
- }
184
- }
185
- return flags;
114
+ VerifyDNSSDFlags(self);
115
+ return (DNSServiceFlags)RDATA(self)->data;
186
116
  }
187
117
 
188
118
  DNSServiceFlags
@@ -192,49 +122,146 @@ dnssd_to_flags(VALUE obj)
192
122
  if (IsDNSSDFlags(obj)) {
193
123
  flags = dnssd_get_flags(obj);
194
124
  } else {
195
- flags = NUM2ULONG(obj);
125
+ /* don't want to include any bits that aren't flags */
126
+ flags = DNSSD_FLAGS_MASK((DNSServiceFlags)NUM2ULONG(obj));
196
127
  }
197
128
  return flags;
198
129
  }
199
130
 
200
131
  /*
201
132
  * call-seq:
202
- * DNSSD::Flags.new() => flags
203
- * DNSSD::Flags.new(integer) => flags
204
- * DNSSD::Flags.new(flags) => dup_of_flags
133
+ * DNSSD::Flags.new() => flags
134
+ * DNSSD::Flags.new(flag1, flag2, ...) => union_of_flags
205
135
  *
206
- * Returns a new group of flags. In the first form,
207
- * none of the new flags are set.
208
- * In the second the flags corresponding to the bits of _integer_ are set.
209
- * In the third the flags set in _flags_ are set.
136
+ * Returns a new set of flags.
137
+ * In the first form an empty set of flags is created.
138
+ * In the second a set of flags containing the union of
139
+ * each flag (or set of flags) given is created.
210
140
  *
211
141
  * flags = Flags.new()
212
142
  * flags.more_coming = true
213
143
  * flags.to_i #=> DNSSD::Flags::MoreComing
214
144
  * f.shared = true
215
145
  * flags.to_i #=> Flags::MoreComing | Flags::Shared
146
+ *
216
147
  * same_flags = Flags.new(Flags::MoreComing | Flags::Shared)
217
148
  * flags == same_flags #=> true
218
149
  *
150
+ * same_flags_again = Flags.new(Flags::MoreComing, Flags::Shared)
151
+ * flags == same_flags_again #=> true
152
+ *
219
153
  */
220
154
 
221
155
  static VALUE
222
156
  dnssd_flags_initialize(int argc, VALUE *argv, VALUE self)
223
157
  {
224
- VALUE def_val = Qnil;
158
+ int i;
225
159
  DNSServiceFlags flags = 0;
226
-
227
- rb_scan_args(argc, argv, "01", &def_val);
228
- if (def_val != Qnil) {
229
- flags = dnssd_to_flags(def_val);
160
+
161
+ for (i=0; i<argc; i++) {
162
+ flags |= dnssd_to_flags(argv[i]);
230
163
  }
231
164
  return dnssd_flags_init(self, flags);
232
165
  }
233
166
 
167
+ static VALUE
168
+ dnssd_flags_new2(VALUE klass, DNSServiceFlags flags)
169
+ {
170
+ return dnssd_flags_init(dnssd_flags_alloc(klass), flags);
171
+ }
172
+
234
173
  static VALUE
235
174
  dnssd_flags_new(DNSServiceFlags flags)
236
175
  {
237
- return dnssd_flags_init(rb_obj_alloc(cDNSSDFlags), flags);
176
+ return dnssd_flags_new2(cDNSSDFlags, flags);
177
+ }
178
+
179
+ /*
180
+ * call-seq:
181
+ * flags.set_flag(f)
182
+ *
183
+ * Set the flag _f_ in _flags_.
184
+ *
185
+ * flags = Flags.new() #=> #<DNSSD::Flags>
186
+ * flags.set_flag(Flags::MoreComing) #=> #<DNSSD::Flags more_coming>
187
+ *
188
+ */
189
+
190
+ static VALUE
191
+ dnssd_flags_set(VALUE self, VALUE num)
192
+ {
193
+ DNSServiceFlags flags;
194
+ VerifyDNSSDFlags(self);
195
+ flags = (DNSServiceFlags)RDATA(self)->data;
196
+ flags |= dnssd_to_flags(num);
197
+ RDATA(self)->data = (void*)flags;
198
+ return self;
199
+ }
200
+
201
+ /*
202
+ * call-seq:
203
+ * flags.clear_flag(f)
204
+ *
205
+ * Clear the flag _f_ in _flags_.
206
+ *
207
+ * flags = Flags.new(Flags::MoreComing) #=> #<DNSSD::Flags more_coming>
208
+ * flags.clear_flag(Flags::MoreComing) #=> #<DNSSD::Flags>
209
+ *
210
+ */
211
+
212
+ static VALUE
213
+ dnssd_flags_clear(VALUE self, VALUE num)
214
+ {
215
+ DNSServiceFlags flags;
216
+ VerifyDNSSDFlags(self);
217
+ /* flags should stay masked here (see DNSSD_FLAGS_MASK() macro) */
218
+ flags = (DNSServiceFlags)RDATA(self)->data;
219
+ flags &= ~dnssd_to_flags(num);
220
+ RDATA(self)->data = (void*)flags;
221
+ return self;
222
+ }
223
+
224
+ /*
225
+ * call-seq:
226
+ * flags1 & flags2 => flags
227
+ *
228
+ * Returns the set of flags included in <i>flags1</i> and <i>flags2</i>.
229
+ *
230
+ */
231
+
232
+ static VALUE
233
+ dnssd_flags_and(VALUE self, VALUE num)
234
+ {
235
+ return dnssd_flags_new2(CLASS_OF(self), dnssd_get_flags(self) & dnssd_to_flags(num));
236
+ }
237
+
238
+ /*
239
+ * call-seq:
240
+ * flags1 | flags2 => flags
241
+ *
242
+ * Returns the set of flags included in <i>flags1</i> or <i>flags2</i>.
243
+ *
244
+ */
245
+
246
+ static VALUE
247
+ dnssd_flags_or(VALUE self, VALUE num)
248
+ {
249
+ return dnssd_flags_new2(CLASS_OF(self), dnssd_get_flags(self) | dnssd_to_flags(num));
250
+ }
251
+
252
+ /*
253
+ * call-seq:
254
+ * ~flags => unset_flags
255
+ *
256
+ * Returns the set of flags not included in _flags_.
257
+ *
258
+ */
259
+
260
+ static VALUE
261
+ dnssd_flags_not(VALUE self)
262
+ {
263
+ /* doesn't totally make sence to return a set of flags here... */
264
+ return dnssd_flags_new2(CLASS_OF(self), ~dnssd_get_flags(self));
238
265
  }
239
266
 
240
267
  /*
@@ -243,6 +270,7 @@ dnssd_flags_new(DNSServiceFlags flags)
243
270
  *
244
271
  * Get the integer representation of _flags_ by bitwise or'ing
245
272
  * each of the set flags.
273
+ *
246
274
  */
247
275
 
248
276
  static VALUE
@@ -254,18 +282,34 @@ dnssd_flags_to_i(VALUE self)
254
282
  static VALUE
255
283
  dnssd_flags_list(VALUE self)
256
284
  {
285
+ DNSServiceFlags flags = dnssd_get_flags(self);
257
286
  VALUE buf = rb_str_buf_new(0);
258
287
  int i;
259
288
  for (i=0; i<DNSSD_MAX_FLAGS; i++) {
260
- if (rb_ivar_get(self, dnssd_flag_iv[i])) {
289
+ if (flags & dnssd_flag[i]) {
261
290
  rb_str_buf_cat2(buf, dnssd_flag_name[i]);
262
291
  rb_str_buf_cat2(buf, ",");
263
292
  }
264
293
  }
265
294
  /* get rid of trailing comma */
266
295
  if (RSTRING(buf)->len > 0) {
267
- RSTRING(buf)->len--;
296
+ long len = --(RSTRING(buf)->len);
297
+ RSTRING(buf)->ptr[len] = '\000';
298
+ }
299
+ return buf;
300
+ }
301
+
302
+ static VALUE
303
+ dnssd_struct_inspect(VALUE self, VALUE data)
304
+ {
305
+ VALUE buf = rb_str_buf_new(20 + RSTRING(data)->len);
306
+ rb_str_buf_cat2(buf, "#<");
307
+ rb_str_buf_cat2(buf, rb_obj_classname(self));
308
+ if (RSTRING(data)->len > 0) {
309
+ rb_str_buf_cat2(buf, " ");
310
+ rb_str_buf_append(buf, data);
268
311
  }
312
+ rb_str_buf_cat2(buf, ">");
269
313
  return buf;
270
314
  }
271
315
 
@@ -279,21 +323,20 @@ dnssd_flags_list(VALUE self)
279
323
  * flags.add = true
280
324
  * flags.default = true
281
325
  * flags.inspect # => "#<DNSSD::Flags add,default>"
326
+ *
282
327
  */
283
328
 
284
329
  static VALUE
285
330
  dnssd_flags_inspect(VALUE self)
286
331
  {
287
- volatile VALUE data = dnssd_flags_list(self);
288
- return dnssd_struct_inspect(self, data);
332
+ return dnssd_struct_inspect(self, dnssd_flags_list(self));
289
333
  }
290
334
 
291
335
  /*
292
336
  * call-seq:
293
337
  * flags == obj => true or false
294
338
  *
295
- * Equality--Two groups of flags are equal if the flags underlying integers
296
- * are equal.
339
+ * Equality--Two sets of flags are equal if they contain the same flags.
297
340
  *
298
341
  * flags = Flags.new()
299
342
  * flags.more_coming = true
@@ -311,95 +354,183 @@ dnssd_flags_equal(VALUE self, VALUE obj)
311
354
  return flags == obj_flags ? Qtrue : Qfalse;
312
355
  }
313
356
 
314
- static VALUE
315
- dnssd_interface_name(uint32_t interface)
357
+ VALUE
358
+ dnssd_create_fullname(const char *name, const char *regtype, const char *domain, int err_flag)
316
359
  {
317
- char buffer[IF_NAMESIZE];
318
- if (if_indextoname(interface, buffer)) {
319
- return rb_str_new2(buffer);
320
- } else {
321
- return ULONG2NUM(interface);
360
+ char buffer[kDNSServiceMaxDomainName];
361
+ if ( DNSServiceConstructFullName(buffer, name, regtype, domain) ) {
362
+ static const char msg[] = "could not construct full service name";
363
+ if (err_flag) {
364
+ rb_raise(rb_eArgError, msg);
365
+ } else {
366
+ VALUE buf;
367
+ rb_warn(msg);
368
+ /* just join them all */
369
+ buf = rb_str_buf_new2(name);
370
+ rb_str_buf_cat2(buf, regtype);
371
+ rb_str_buf_cat2(buf, domain);
372
+ return buf;
373
+ }
322
374
  }
375
+ buffer[kDNSServiceMaxDomainName - 1] = '\000'; /* just in case */
376
+ return rb_str_new2(buffer);
323
377
  }
324
378
 
325
- static VALUE
326
- dnssd_get_interface(VALUE self)
379
+ VALUE
380
+ dnssd_split_fullname(VALUE fullname)
327
381
  {
328
- return rb_String(rb_ivar_get(self, dnssd_iv_interface));
382
+ static const char re[] = "(?:\\\\.|[^\\.])+\\.";
383
+ VALUE regexp = rb_reg_new(re, sizeof(re)-1, 0);
384
+ return rb_funcall2(fullname, rb_intern("scan"), 1, &regexp);
329
385
  }
330
386
 
331
- /*
332
- * call-seq:
333
- * register_reply.inspect => string
334
- *
335
- */
387
+ #if 0
388
+ static void
389
+ quote_and_append(VALUE buf, VALUE str)
390
+ {
391
+ const char *ptr;
392
+ long i, last_mark, len;
393
+
394
+ ptr = RSTRING(str)->ptr;
395
+ len = RSTRING(str)->len;
396
+ last_mark = 0;
397
+ /* last character should be '.' */
398
+ for (i=0; i<len-1; i++) {
399
+ if (ptr[i] == '.') {
400
+ /* write 1 extra character and replace it with '\\' */
401
+ rb_str_buf_cat(buf, ptr + last_mark, i + 1 - last_mark);
402
+ RSTRING(buf)->ptr[i] = '\\';
403
+ last_mark = i;
404
+ }
405
+ }
406
+ rb_str_buf_cat(buf, ptr + last_mark, len - last_mark);
407
+ }
408
+ #endif
336
409
 
337
410
  static VALUE
338
- dnssd_register_inspect(VALUE self)
411
+ dnssd_join_names(int argc, VALUE *argv)
339
412
  {
340
- volatile VALUE data = dnssd_get_fullname(self, 0);
341
- return dnssd_struct_inspect(self, data);
413
+ int i;
414
+ VALUE buf;
415
+ long len = 0;
416
+
417
+ for (i=0; i<argc; i++) {
418
+ argv[i] = StringValue(argv[i]);
419
+ len += RSTRING(argv[i])->len;
420
+ }
421
+ buf = rb_str_buf_new(len);
422
+ for (i=0; i<argc; i++) {
423
+ rb_str_buf_append(buf, argv[i]);
424
+ }
425
+ return buf;
342
426
  }
343
427
 
344
- VALUE
345
- dnssd_register_new(VALUE service, DNSServiceFlags flags, const char *name,
346
- const char *regtype, const char *domain )
428
+ static void
429
+ reply_add_names(VALUE self, const char *name,
430
+ const char *regtype, const char *domain)
347
431
  {
348
- volatile VALUE self = rb_obj_alloc(cDNSSDRegisterReply);
349
- rb_ivar_set(self, dnssd_iv_flags, dnssd_flags_new(flags));
350
- rb_ivar_set(self, dnssd_iv_service, service);
351
- dnssd_add_names(self, name, regtype, domain);
352
- return self;
432
+ rb_ivar_set(self, dnssd_iv_name, rb_str_new2(name));
433
+ rb_ivar_set(self, dnssd_iv_type, rb_str_new2(regtype));
434
+ rb_ivar_set(self, dnssd_iv_domain, rb_str_new2(domain));
435
+ rb_ivar_set(self, dnssd_iv_fullname, dnssd_create_fullname(name, regtype, domain, 0));
353
436
  }
354
437
 
355
- /*
356
- * call-seq:
357
- * browse_reply.inspect => string
358
- *
359
- */
438
+ static void
439
+ reply_add_names2(VALUE self, const char *fullname)
440
+ {
441
+ VALUE fn = rb_str_new2(fullname);
442
+ VALUE ary = dnssd_split_fullname(fn);
443
+ VALUE type[2] = { rb_ary_entry(ary, 1), rb_ary_entry(ary, 2) };
444
+
445
+ rb_ivar_set(self, dnssd_iv_name, rb_ary_entry(ary, 0));
446
+ rb_ivar_set(self, dnssd_iv_type, dnssd_join_names(2, type));
447
+ rb_ivar_set(self, dnssd_iv_domain, rb_ary_entry(ary, -1));
448
+ rb_ivar_set(self, dnssd_iv_fullname, fn);
449
+ }
450
+
451
+
452
+ static void
453
+ reply_set_interface(VALUE self, uint32_t interface)
454
+ {
455
+ VALUE if_value;
456
+ char buffer[IF_NAMESIZE];
457
+ if (if_indextoname(interface, buffer)) {
458
+ if_value = rb_str_new2(buffer);
459
+ } else {
460
+ if_value = ULONG2NUM(interface);
461
+ }
462
+ rb_ivar_set(self, dnssd_iv_interface, if_value);
463
+ }
464
+
465
+ static void
466
+ reply_set_tr(VALUE self, uint16_t txt_len, const char *txt_rec)
467
+ {
468
+ rb_ivar_set(self, dnssd_iv_text_record, dnssd_tr_new((long)txt_len, txt_rec));
469
+ }
360
470
 
361
471
  static VALUE
362
- dnssd_browse_inspect(VALUE self)
472
+ reply_new(VALUE service, DNSServiceFlags flags)
363
473
  {
364
- volatile VALUE data = rb_str_buf_new(0);
365
- rb_str_buf_append(data, dnssd_get_fullname(self, 0));
366
- rb_str_buf_cat2(data, " interface:");
367
- rb_str_buf_append(data, dnssd_get_interface(self));
368
- return dnssd_struct_inspect(self, data);
474
+ VALUE self = rb_obj_alloc(cDNSSDReply);
475
+ rb_ivar_set(self, dnssd_iv_service, service);
476
+ rb_ivar_set(self, dnssd_iv_flags, dnssd_flags_new(flags));
477
+ return self;
478
+ }
479
+
480
+ VALUE
481
+ dnssd_domain_enum_new(VALUE service, DNSServiceFlags flags,
482
+ uint32_t interface, const char *domain)
483
+ {
484
+ VALUE d, self = reply_new(service, flags);
485
+ reply_set_interface(self, interface);
486
+ d = rb_str_new2(domain);
487
+ rb_ivar_set(self, dnssd_iv_domain, d);
488
+ rb_ivar_set(self, dnssd_iv_fullname, d);
489
+ return self;
369
490
  }
370
491
 
371
492
  VALUE
372
493
  dnssd_browse_new(VALUE service, DNSServiceFlags flags, uint32_t interface,
373
494
  const char *name, const char *regtype, const char *domain)
374
495
  {
375
- volatile VALUE self = rb_obj_alloc(cDNSSDBrowseReply);
376
- rb_ivar_set(self, dnssd_iv_flags, dnssd_flags_new(flags));
377
- rb_ivar_set(self, dnssd_iv_interface, dnssd_interface_name(interface));
378
- rb_ivar_set(self, dnssd_iv_service, service);
379
- dnssd_add_names(self, name, regtype, domain);
496
+ VALUE self = reply_new(service, flags);
497
+ reply_set_interface(self, interface);
498
+ reply_add_names(self, name, regtype, domain);
380
499
  return self;
381
500
  }
382
501
 
383
- /*
384
- * call-seq:
385
- * resolve_reply.inspect => string
386
- *
387
- */
388
-
502
+ #if 0
389
503
  static VALUE
390
- dnssd_resolve_inspect(VALUE self)
504
+ dnssd_gethostname(void)
391
505
  {
392
- volatile VALUE data = rb_str_buf_new(0);
393
- rb_str_buf_append(data, rb_ivar_get(self, dnssd_iv_fullname));
394
- rb_str_buf_cat2(data, " interface:");
395
- rb_str_buf_append(data, dnssd_get_interface(self));
396
- rb_str_buf_cat2(data, " target:");
397
- rb_str_buf_append(data, rb_ivar_get(self, dnssd_iv_target));
398
- rb_str_buf_cat2(data, ":");
399
- rb_str_buf_append(data, rb_inspect(rb_ivar_get(self, dnssd_iv_port)));
400
- rb_str_buf_cat2(data, " ");
401
- rb_str_buf_append(data, rb_inspect(rb_ivar_get(self, dnssd_iv_text_record)));
402
- return dnssd_struct_inspect(self, data);
506
+ #if HAVE_GETHOSTNAME
507
+ #ifndef MAXHOSTNAMELEN
508
+ #define MAXHOSTNAMELEN 256
509
+ #endif
510
+ char buffer[MAXHOSTNAMELEN + 1];
511
+ if (gethostname(buffer, MAXHOSTNAMELEN))
512
+ return Qnil;
513
+ buffer[MAXHOSTNAMELEN] = '\000';
514
+ return rb_str_new2(buffer);
515
+ #else
516
+ return Qnil;
517
+ #endif
518
+ }
519
+ #endif
520
+
521
+ VALUE
522
+ dnssd_register_new(VALUE service, DNSServiceFlags flags, const char *name,
523
+ const char *regtype, const char *domain )
524
+ {
525
+ VALUE self = reply_new(service, flags);
526
+ reply_add_names(self, name, regtype, domain);
527
+ /* HACK */
528
+ /* See HACK in rdnssd_service.c */
529
+ rb_ivar_set(self, dnssd_iv_interface, rb_ivar_get(service, dnssd_iv_interface));
530
+ rb_ivar_set(self, dnssd_iv_port, rb_ivar_get(service, dnssd_iv_port));
531
+ rb_ivar_set(self, dnssd_iv_text_record, rb_ivar_get(service, dnssd_iv_text_record));
532
+ /********/
533
+ return self;
403
534
  }
404
535
 
405
536
  VALUE
@@ -408,24 +539,34 @@ dnssd_resolve_new(VALUE service, DNSServiceFlags flags, uint32_t interface,
408
539
  uint16_t opaqueport, uint16_t txt_len, const char *txt_rec)
409
540
  {
410
541
  uint16_t port = ntohs(opaqueport);
411
- volatile VALUE self = rb_obj_alloc(cDNSSDResolveReply);
412
- rb_ivar_set(self, dnssd_iv_flags, dnssd_flags_new(flags));
413
- rb_ivar_set(self, dnssd_iv_interface, dnssd_interface_name(interface));
414
- rb_ivar_set(self, dnssd_iv_fullname, rb_str_new2(fullname));
542
+ VALUE self = reply_new(service, flags);
543
+ reply_set_interface(self, interface);
544
+ reply_add_names2(self, fullname);
415
545
  rb_ivar_set(self, dnssd_iv_target, rb_str_new2(host_target));
416
546
  rb_ivar_set(self, dnssd_iv_port, UINT2NUM(port));
417
- rb_ivar_set(self, dnssd_iv_text_record, dnssd_tr_new((long)txt_len, txt_rec));
418
- rb_ivar_set(self, dnssd_iv_service, service);
547
+ reply_set_tr(self, txt_len, txt_rec);
419
548
  return self;
420
549
  }
421
550
 
551
+ /*
552
+ * call-seq:
553
+ * reply.inspect => string
554
+ *
555
+ */
556
+ static VALUE
557
+ reply_inspect(VALUE self)
558
+ {
559
+ VALUE fullname = rb_ivar_get(self, dnssd_iv_fullname);
560
+ return dnssd_struct_inspect(self, StringValue(fullname));
561
+ }
562
+
422
563
  /*
423
564
  * call-seq:
424
565
  * DNSSD::Reply.new() => raises a RuntimeError
425
566
  *
426
567
  */
427
568
  static VALUE
428
- dnssd_reply_initialize(int argc, VALUE *argv, VALUE reply)
569
+ reply_initialize(int argc, VALUE *argv, VALUE reply)
429
570
  {
430
571
  dnssd_instantiation_error(rb_obj_classname(reply));
431
572
  return Qnil;
@@ -450,71 +591,54 @@ Init_DNSSD_Replies(void)
450
591
  dnssd_iv_domain = rb_intern("@domain");
451
592
  dnssd_iv_service = rb_intern("@service");
452
593
 
453
- dnssd_init_flag_iv();
454
-
455
594
  cDNSSDFlags = rb_define_class_under(mDNSSD, "Flags", rb_cObject);
595
+ rb_define_alloc_func(cDNSSDFlags, dnssd_flags_alloc);
456
596
  rb_define_method(cDNSSDFlags, "initialize", dnssd_flags_initialize, -1);
457
- /* this creates all the attr_accessor and flag? methods */
597
+ /* this creates all the attr_writer and flag? methods */
458
598
  dnssd_init_flags_methods(cDNSSDFlags);
459
599
  rb_define_method(cDNSSDFlags, "inspect", dnssd_flags_inspect, 0);
460
600
  rb_define_method(cDNSSDFlags, "to_i", dnssd_flags_to_i, 0);
461
601
  rb_define_method(cDNSSDFlags, "==", dnssd_flags_equal, 1);
602
+
603
+ rb_define_method(cDNSSDFlags, "&", dnssd_flags_and, 1);
604
+ rb_define_method(cDNSSDFlags, "|", dnssd_flags_or, 1);
605
+ rb_define_method(cDNSSDFlags, "~", dnssd_flags_not, 0);
606
+
607
+ rb_define_method(cDNSSDFlags, "set_flag", dnssd_flags_set, 1);
608
+ rb_define_method(cDNSSDFlags, "clear_flag", dnssd_flags_clear, 1);
462
609
 
463
- /* prototype: rb_define_attr(class, name, read, write) */
464
610
  cDNSSDReply = rb_define_class_under(mDNSSD, "Reply", rb_cObject);
465
- /* DNSSD::Reply objects can only be instantiated by DNSSD.browse(), DNSSD.register(), DNSSD.resolve(). */
466
- rb_define_method(cDNSSDReply, "initialize", dnssd_reply_initialize, -1);
467
- /* Flags describing the reply. See DNSSD::Flags for more information. */
468
- rb_define_attr(cDNSSDReply, "flags", 1, 0);
611
+ /* DNSSD::Reply objects can only be instantiated by
612
+ * DNSSD.browse(), DNSSD.register(), DNSSD.resolve(), DNSSD.enumerate_domains(). */
613
+ rb_define_method(cDNSSDReply, "initialize", reply_initialize, -1);
469
614
  /* The service associated with the reply. See DNSSD::Service for more information. */
470
615
  rb_define_attr(cDNSSDReply, "service", 1, 0);
471
- rb_define_method(cDNSSDReply, "fullname", dnssd_reply_fullname, 0);
472
-
473
- cDNSSDBrowseReply = rb_define_class_under(mDNSSD, "BrowseReply", cDNSSDReply);
474
- /* The interface on which the service is advertised.
475
- * The interface should be passed to DNSSD.resolve() when resolving the service. */
476
- rb_define_attr(cDNSSDBrowseReply, "interface", 1, 0);
477
- /* The service name discovered. */
478
- rb_define_attr(cDNSSDBrowseReply, "name", 1, 0);
479
- /* The service type, as passed in to DNSSD.browse(). */
480
- rb_define_attr(cDNSSDBrowseReply, "type", 1, 0);
481
- /* The domain on which the service was discovered.
482
- * (If the application did not specify a domain in DNSSD.browse(),
483
- * this indicates the domain on which the service was discovered.) */
484
- rb_define_attr(cDNSSDBrowseReply, "domain", 1, 0);
485
- rb_define_method(cDNSSDBrowseReply, "inspect", dnssd_browse_inspect, 0);
486
-
487
- cDNSSDResolveReply = rb_define_class_under(mDNSSD, "ResolveReply", cDNSSDReply);
488
- /* The interface on which the service was resolved. */
489
- rb_define_attr(cDNSSDResolveReply, "interface", 1, 0);
616
+ /* Flags describing the reply. See DNSSD::Flags for more information. */
617
+ rb_define_attr(cDNSSDReply, "flags", 1, 0);
618
+ /* The service name. (Not used by DNSSD.enumerate_domains().) */
619
+ rb_define_attr(cDNSSDReply, "name", 1, 0);
620
+ /* The service type. (Not used by DNSSD.enumerate_domains().) */
621
+ rb_define_attr(cDNSSDReply, "type", 1, 0);
622
+ /* The service domain. */
623
+ rb_define_attr(cDNSSDReply, "domain", 1, 0);
624
+ /* The interface on which the service is available. (Used only by DNSSSD.resolve().) */
625
+ rb_define_attr(cDNSSDReply, "interface", 1, 0);
490
626
  /* The full service domain name, in the form "<servicename>.<protocol>.<domain>.".
491
627
  * (Any literal dots (".") are escaped with a backslash ("\."), and literal
492
628
  * backslashes are escaped with a second backslash ("\\"), e.g. a web server
493
629
  * named "Dr. Pepper" would have the fullname "Dr\.\032Pepper._http._tcp.local.".)
494
630
  * See DNSSD::Service.fullname() for more information. */
495
- rb_define_attr(cDNSSDResolveReply, "fullname", 1, 0);
631
+ rb_define_attr(cDNSSDReply, "fullname", 1, 0);
632
+ /* The service's primary text record, see DNSSD::TextRecord for more information. */
633
+ rb_define_attr(cDNSSDReply, "text_record", 1, 0);
496
634
  /* The target hostname of the machine providing the service.
497
635
  * This name can be passed to functions like Socket.gethostbyname()
498
636
  * to identify the host's IP address. */
499
- rb_define_attr(cDNSSDResolveReply, "target", 1, 0);
637
+ rb_define_attr(cDNSSDReply, "target", 1, 0);
500
638
  /* The port on which connections are accepted for this service. */
501
- rb_define_attr(cDNSSDResolveReply, "port", 1, 0);
502
- /* The service's primary text record, see DNSSD::TextRecord for more information. */
503
- rb_define_attr(cDNSSDResolveReply, "text_record", 1, 0);
504
- rb_define_method(cDNSSDResolveReply, "inspect", dnssd_resolve_inspect, 0);
505
-
506
- cDNSSDRegisterReply = rb_define_class_under(mDNSSD, "RegisterReply", cDNSSDReply);
507
- /* The service name registered.
508
- * (If the application did not specify a name in DNSSD.register(),
509
- * this indicates what name was automatically chosen.) */
510
- rb_define_attr(cDNSSDRegisterReply, "name", 1, 0);
511
- /* The type of service registered as it was passed to DNSSD.register(). */
512
- rb_define_attr(cDNSSDRegisterReply, "type", 1, 0);
513
- /* The domain on which the service was registered.
514
- * (If the application did not specify a domain in DNSSD.register(),
515
- * this indicates the default domain on which the service was registered.) */
516
- rb_define_attr(cDNSSDRegisterReply, "domain", 1, 0);
517
- rb_define_method(cDNSSDRegisterReply, "inspect", dnssd_register_inspect, 0);
639
+ rb_define_attr(cDNSSDReply, "port", 1, 0);
640
+
641
+ rb_define_method(cDNSSDReply, "inspect", reply_inspect, 0);
518
642
 
519
643
  /* flag constants */
520
644
  #if DNSSD_MAX_FLAGS != 9
@@ -575,9 +699,7 @@ Init_DNSSD_Replies(void)
575
699
 
576
700
  /* Document-class: DNSSD::Reply
577
701
  *
578
- * DNSSD::Reply is the parent class of DNSSD::BrowseReply, DNSSD::RegisterReply, and DNSSD::ResolveReply.
579
- * It simply contains the behavior that is common to those classes, otherwise it is not
580
- * used by the DNSSD Ruby API.
702
+ * DNSSD::Reply is used to return information
581
703
  *
582
704
  */
583
705