File: node.h

package info (click to toggle)
mrd6 0.9.5-release-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 1,308 kB
  • ctags: 3,956
  • sloc: cpp: 25,728; perl: 462; makefile: 281; ansic: 142; sh: 67
file content (489 lines) | stat: -rw-r--r-- 12,513 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
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
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
/*
 * Multicast Routing Daemon (MRD)
 *   node.h
 *
 * Copyright (C) 2004, 2005
 *   Universidade de Aveiro, Instituto Telecomunicacoes - Polo Aveiro
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Authors:	Hugo Santos, <hsantos@av.it.pt>
 */

#ifndef _mrd_node_h_
#define _mrd_node_h_

#include <stdint.h>

#include <string>
#include <vector>
#include <map>
#include <deque>
#include <set>

#include <mrd/address.h>
#include <mrd/parser.h>

class base_stream;
class inet6_addr;

class node;

struct method_info {
	const char *name;
	const char *description;
	int id;
	bool informational;
	uint32_t flags;
};

/*!
 * Implements an abstract interface to property values
 */
struct propval {
	virtual ~propval();

	/*!
	 * Returns a pointer to the internal structure holding the value
	 */
	virtual const void *get_value() const = 0;
	/*!
	 * Parses the string representation specified in the param and sets
	 * the value if valid. If the input has a bad format, returns false.
	 */
	virtual bool set_value(const char *) = 0;
	/*!
	 * Outputs the current value into the specified base_stream
	 */
	virtual void output_value(base_stream &) const = 0;
};

/*!
 * Implements an interface to property definitions, including value
 * instantiation, flags and helper methods.
 */
class property_def {
public:
	property_def();
	~property_def();

	enum {
		READ_ONLY	= 0x01,
		REMOVABLE	= 0x02,
		DEFAULT_VALUE	= 0x04,
		PROPERTY	= 0x08,
		METHOD		= 0x10,
		CHILD		= 0x20,
		COMPLETE_M	= 0x40,
		NEGATE		= 0x80,
	};

	/*!
	 * Internal available value types
	 */
	enum valtype {
		VAL_UNKNOWN,
		VAL_BOOL,
		VAL_INTEGER,
		VAL_UNSIGNED,
		VAL_TIME_INTERVAL,
		VAL_STRING,
		VAL_ADDRESS,
	};

	/*!
	 * Instantiates a property to the specified type with the supplied
	 * default value. Also applies supplied flags.
	 */
	bool instantiate(valtype, const void *def, const char *desc,
			 uint32_t flags);
	/*!
	 * Provides instantiation of alien propvals. The moment the propval
	 * is fed into instantiation, the property_def will be it's owner
	 * and is responsible for freeing as required (including if this
	 * method fails).
	 */
	bool instantiate(propval *, const char *desc, uint32_t flags);

	/*! Instantiates a child node property */
	bool instantiate(node *, uint32_t flags);

	bool instantiate(const method_info *);

	bool is_readonly() const { return m_flags & READ_ONLY; }
	bool is_removable() const { return m_flags & REMOVABLE; }
	bool is_default() const { return m_flags & DEFAULT_VALUE; }

	bool is_property() const { return m_flags & PROPERTY; }
	bool is_method() const { return m_flags & METHOD; }
	bool is_child() const { return m_flags & CHILD; }

	uint32_t flags() const { return m_flags; }

	void set_description(const char *);
	const char *description() const;

	void set_readonly();
	void set_removable();

	/*!
	 * Feeds the supplied value into propval::set_value. If rch = true,
	 * removes flag DEFAULT_VALUE. This call will fail if is_property
	 * is not true.
	 */
	bool set_value(const char *, bool rch = true);

	/* helper methods */
	bool get_bool() const;
	int32_t get_integer() const;
	uint32_t get_unsigned() const;
	const char *get_string() const;
	const inet6_addr &get_address() const;
	node *get_node() const;
	const method_info *get_method_info() const;

	/*!
	 * Feeds into propval::output_value, or outputs (null) if
	 * not instantiated
	 */
	void output_value(base_stream &) const;

private:
	bool is_instantiated() const;

	uint32_t m_flags;

	union {
		propval *val;
		node *child;
		const method_info *method;
	} u;

	const char *m_prop_description;
};

inline bool property_def::get_bool() const {
	return *(const bool *)u.val->get_value();
}

inline int32_t property_def::get_integer() const {
	return *(const int32_t *)u.val->get_value();
}

inline uint32_t property_def::get_unsigned() const {
	return *(const uint32_t *)u.val->get_value();
}

inline const char *property_def::get_string() const {
	return (const char *)u.val->get_value();
}

inline const inet6_addr &property_def::get_address() const {
	return *(const inet6_addr *)u.val->get_value();
}

inline node *property_def::get_node() const {
	return u.child;
}

inline const method_info *property_def::get_method_info() const {
	return u.method;
}

class event_sink {
public:
	virtual ~event_sink();

	virtual void event(int, void *);
};

/*!
 * Implements base node class, core to the mrd internal hierarchy. nodes
 * come with property handling by default.
 */
class node : public event_sink {
public:
	node(node *, const char *);
	virtual ~node();

	virtual bool check_startup();

	/*!
	 * Returns this node's parent node.
	 */
	node *parent() const { return m_parent; }

	/*!
	 * Returns this node's name.
	 */
	const char *name() const { return m_name.c_str(); }

	/*!
	 * Returns a textual description of this node.
	 */
	virtual const char *description() const { return 0; }

	/*!
	 * Returns the full name of this node, with each parent separated
	 * by a dot (.) e.g. mrd.interfaces.eth0
	 */
	std::string full_name() const;

	/*!
	 * Should return a less specific node related to this node. Used for
	 * get_property when the node doesn't have the requested property.
	 */
	virtual node *next_similiar_node() const;

	enum content_type {
		unknown = 0,
		property = 1,
		child = 2,
		method = 4,
		info_method = 8
	};

	/*!
	 * Sets the property specified by key's value. Returns false if the
	 * specified value is not parsable by propval's requirement or the
	 * property doesn't exist.
	 */
	virtual bool set_property(const char *key, const char *value);
	/*!
	 * Removes a REMOVABLE property. Returns false if the property is not
	 * REMOVABLE or doesn't exist.
	 */
	virtual bool remove_property(const char *key, bool force = false);
	/*!
	 * Increments a property propval with value. Follows same rules
	 * as set_property
	 */
	virtual bool increment_property(const char *key, const char *value);
	/*!
	 * Returns a reference to the specified property. If strict=true,
	 * similiar nodes aren't used in case this node doesn't contain
	 * the specified property.
	 */
	const property_def *get_property(const char *key, bool strict = false) const;
	/*!
	 * Returns a modifiable reference to the specified property.
	 */
	property_def *get_property(const char *key, bool strict = false);

	const property_def *get_any_property(const char *name) const;

	/*!
	 * Same as constant get_property, but returns the property from the
	 * specified child. If the child doesn't exist, returns a null
	 * reference
	 */
	const property_def *get_child_property(const char *,
			const char *, bool strict = false) const;

	/*!
	 * These methods should only be called when you are sure of the
	 * property's content and existance
	 */
	bool get_property_bool(const char *) const;
	int32_t get_property_integer(const char *) const;
	uint32_t get_property_unsigned(const char *) const;
	const char *get_property_string(const char *) const;
	const inet6_addr &get_property_address(const char *) const;

	/*!
	 * Returns true if the node holds a property with the specified name
	 */
	virtual bool has_property(const char *) const;

	bool has_child_property(const char *) const;

	/*!
	 * Returns a reference to the specified child. A null reference will
	 * be returned if the child doesn't exist
	 */
	virtual node *get_child(const char *) const;
	/*!
	 * Returns a reference to an existing specified child, or if it doesn't
	 * exist calls create_child() and returns the new child
	 */
	virtual node *get_or_create_child(const char *);
	virtual node *create_child(const char *);

	node *add_child(node *chld, bool complete_m = false,
			const char *name = 0,
			const char *description = 0);
	/*!
	 * Removes a child node from the node
	 */
	void remove_child(const char *);

	void clear_childs();

	/*!
	 * Returns true if the node has the specified method
	 */
	virtual bool has_method(const char *name, uint32_t) const;

	/*!
	 * Implements the call handler
	 */
	virtual bool call_method(int id, base_stream &, const std::vector<std::string> &);

	virtual bool negate_method(int, base_stream &, const std::vector<std::string> &);

	/*!
	 * Imports a method table into this node's property list. The
	 * table must be terminated by an entry with name = NULL.
	 */
	void import_methods(const method_info *);

	/*!
	 * Adds a single new method to the node's property list. The
	 * method_info object must live while this node exists.
	 */
	bool add_method(const method_info *info);

	/*!
	 * Removes the specified method from the node's children list
	 */
	void remove_method(const char *name);

	// Info

	virtual bool output_info(base_stream &, const std::vector<std::string> &) const;

	typedef std::map<std::string, property_def> properties;

	const properties &get_properties() const { return m_properties; }

	int match_property(uint32_t, const char *, content_type &, const char * &) const;

	void broadcast_event(int, void *, bool all = false);

protected:
	node *m_parent;

	properties m_properties;

	property_def *instantiate_property(const char *name,
					   property_def::valtype,
					   const char *desc = 0,
					   uint32_t flags = 0);
	property_def *instantiate_property(const char *name,
					   property_def::valtype, const void *,
					   const char *desc = 0,
					   uint32_t flags = 0);
	property_def *instantiate_property(const char *name, propval *,
					   const char *desc = 0,
					   uint32_t flags = 0);

	property_def *instantiate_property_b(const char *name, bool def,
					     const char *desc = 0,
					     uint32_t flags = 0);
	property_def *instantiate_property_i(const char *name, int32_t def,
					     const char *desc = 0,
					     uint32_t flags = 0);
	property_def *instantiate_property_u(const char *name, uint32_t def,
					     const char *desc = 0,
					     uint32_t flags = 0);
	property_def *instantiate_property_t(const char *name, uint32_t def,
					     const char *desc = 0,
					     uint32_t flags = 0);
	property_def *instantiate_property_s(const char *name, const char *def,
					     const char *desc = 0,
					     uint32_t flags = 0);
	property_def *instantiate_property_a(const char *name,
					     const inet6_addr &,
					     const char *desc = 0,
					     uint32_t flags = 0);

	bool set_property_inst(const char *name, property_def::valtype,
			       const char *value);

	bool enable_several(const std::vector<std::string> &, bool);
	bool show(base_stream &, const std::vector<std::string> &);
	bool exec_negate(base_stream &, const std::vector<std::string> &);

	virtual void propagate_property_changed(node *, const char *);
	virtual void property_changed(node *, const char *) {}

	virtual void remove_child_node(node *);

	friend class conf_node;

	std::string m_name;
};

class node_log : public node {
public:
	node_log(node *);

	bool check_startup();

	base_stream &info(int level) const;
	base_stream &warn() const;
	base_stream &fatal() const;

	bool would_log(int level) const;

	void use_nodename(bool);

protected:
	virtual base_stream &log_entry(base_stream &) const;

	property_def *m_mod_level;
	bool m_use_nodename;
};

class conf_node : public node {
public:
	conf_node(node *, const char *);

	void attach_watcher(node *);
	void dettach_watcher(node *);

	void enable(bool);

protected:
	void propagate_property_changed(node *, const char *);
	void property_changed(node *, const char *);

	std::vector<node *> m_watchers;
};

struct propval_integer : propval {
	propval_integer(const int32_t *);
	const void *get_value() const;
	bool set_value(const char *);
	void output_value(base_stream &) const;

	int32_t value;
};

struct propval_enum : propval_integer {
	struct entry {
		const char *name;
		int32_t value;
	};

	propval_enum(entry *);
	bool set_value(const char *);
	void output_value(base_stream &) const;

	entry *entries;
};

#endif