libamxd  6.4.1
Data Model Manager
amxd_object_hierarchy.c File Reference
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ctype.h>
#include "amxd_priv.h"
#include <amxd/amxd_common.h>
#include <amxd/amxd_dm.h>
#include <amxd/amxd_object.h>
#include <amxd/amxd_path.h>
#include "amxd_dm_priv.h"
#include "amxd_object_priv.h"
#include "amxd_assert.h"

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 

Functions

static void amxd_object_hierarchy_up (amxd_object_t *const object, amxd_object_filter_fn_t filter, amxd_object_cb_fn_t cb, int32_t depth, void *priv)
 
static void amxd_object_hierarchy_down (amxd_object_t *const object, const amxd_direction_t direction, amxd_object_filter_fn_t filter, amxd_object_cb_fn_t cb, int32_t depth, void *priv)
 
static void amxd_path_prepend_instance (const amxd_object_t *object, amxc_string_t *path, const char *name, uint32_t length, const uint32_t flags)
 
static char * amxd_object_build_path (const amxd_object_t *object, const amxd_object_t *stop, const uint32_t flags)
 
static amxd_object_tamxd_object_is_supported_impl (amxd_object_t *object, amxd_path_t *path)
 
amxd_object_tamxd_object_get_parent (const amxd_object_t *const object)
 Get the parent object. More...
 
amxd_object_tamxd_object_get_root (const amxd_object_t *const object)
 Get the data model root. More...
 
amxd_dm_tamxd_object_get_dm (const amxd_object_t *const object)
 Get the data model. More...
 
amxd_object_tamxd_object_get_child (const amxd_object_t *object, const char *name)
 Get a child of the object. More...
 
amxd_object_tamxd_object_get_instance (const amxd_object_t *object, const char *name, uint32_t index)
 Get an instance of the template object. More...
 
amxd_object_tamxd_object_get (const amxd_object_t *object, const char *name)
 Get an instance or child of an object. More...
 
amxd_object_tamxd_object_findf (amxd_object_t *const object, const char *rel_path,...)
 
amxd_status_t amxd_object_resolve_pathf (amxd_object_t *object, amxc_llist_t *paths, const char *rel_path,...)
 
amxd_status_t amxd_object_resolve_pathf_ext (amxd_object_t *object, bool *key_path, amxc_llist_t *paths, const char *rel_path,...)
 
char * amxd_object_get_path (const amxd_object_t *object, const uint32_t flags)
 Get the full path of the object. More...
 
char * amxd_object_get_rel_path (const amxd_object_t *child, const amxd_object_t *parent, const uint32_t flags)
 Get the relative path of the object. More...
 
bool amxd_object_is_child_of (const amxd_object_t *const child, const amxd_object_t *const parent)
 Checks if the child object is in the hierarchical tree of the parent object. More...
 
void amxd_object_hierarchy_walk (amxd_object_t *const object, const amxd_direction_t direction, amxd_object_filter_fn_t filter, amxd_object_cb_fn_t cb, int32_t depth, void *priv)
 Iterates over all objects in the data model tree. More...
 
void amxd_object_for_all (amxd_object_t *object, const char *rel_spath, amxd_mobject_cb_t fn, void *priv)
 Executes a task for all matching objects in an object tree. More...
 
bool amxd_object_is_supported (amxd_object_t *object, const char *req_path)
 Checks if a path is in the supported data model. More...
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 56 of file amxd_object_hierarchy.c.

Function Documentation

◆ amxd_object_build_path()

static char* amxd_object_build_path ( const amxd_object_t object,
const amxd_object_t stop,
const uint32_t  flags 
)
static

Definition at line 152 of file amxd_object_hierarchy.c.

154  {
155  amxc_string_t path;
156  const amxd_object_t* current = object;
157  const char* sep = NULL;
158  char* str_path = NULL;
159  int sep_length = 0;
160 
161  if((flags & AMXD_OBJECT_REGEXP) == AMXD_OBJECT_REGEXP) {
162  sep = "\\.";
163  sep_length = 2;
164  } else {
165  sep = ".";
166  sep_length = 1;
167  }
168 
169  amxc_string_init(&path, 64);
170 
171  while(current != stop &&
172  amxd_object_get_name(current, flags) != NULL) {
173  const char* name = amxd_object_get_name(current, flags);
174  int length = strlen(name);
175 
176  if(!amxc_string_is_empty(&path) &&
177  ( strncmp(path.buffer, sep, sep_length) != 0)) {
178  amxc_string_prepend(&path, sep, sep_length);
179  }
180 
182  amxd_path_prepend_instance(current, &path, name, length, flags);
183  } else {
184  if(((flags & AMXD_OBJECT_SUPPORTED) == AMXD_OBJECT_SUPPORTED) &&
186  amxc_string_prepend(&path, "{i}", 3);
187  amxc_string_prepend(&path, sep, sep_length);
188  }
189  amxc_string_prepend(&path, name, length);
190  }
191  current = amxd_object_get_parent(current);
192  }
193 
195  amxc_string_append(&path, sep, sep_length);
196  }
197 
198  str_path = amxc_string_take_buffer(&path);
199  amxc_string_clean(&path);
200 
201  return str_path;
202 }
static void amxd_path_prepend_instance(const amxd_object_t *object, amxc_string_t *path, const char *name, uint32_t length, const uint32_t flags)
#define AMXD_OBJECT_SUPPORTED
Path format flag - adds {i} as placeholder for an instance object.
Definition: amxd_object.h:226
#define AMXD_OBJECT_REGEXP
Path format flag - create path that can be used as regular expression.
Definition: amxd_object.h:202
#define AMXD_OBJECT_TERMINATE
Path format flag - when set the object path is terminated with a dot.
Definition: amxd_object.h:214
@ amxd_object_template
Definition: amxd_types.h:183
@ amxd_object_instance
Definition: amxd_types.h:186
amxd_object_t * amxd_object_get_parent(const amxd_object_t *const object)
Get the parent object.
static amxd_object_type_t amxd_object_get_type(const amxd_object_t *const object)
Returns the object type.
Definition: amxd_object.h:586
const char * amxd_object_get_name(const amxd_object_t *const object, const uint32_t flags)
Get the name of the object (or index as a string for instance objects)
Definition: amxd_object.c:239

◆ amxd_object_findf()

amxd_object_t* amxd_object_findf ( amxd_object_t *const  object,
const char *  rel_path,
  ... 
)

Definition at line 392 of file amxd_object_hierarchy.c.

394  {
395  amxd_object_t* result = NULL;
396  amxd_dm_t* dm = NULL;
398  amxd_path_t path;
399  va_list args;
400  bool key_path = false;
401 
402  amxd_path_init(&path, NULL);
403 
404  when_null(object, exit);
405  when_str_empty(rel_path, exit);
406 
407  if(!amxd_object_is_base(object)) {
408  dm = amxd_object_get_dm(object);
409  }
410 
411  va_start(args, rel_path);
412  status = amxd_path_vsetf(&path, true, rel_path, args);
413  va_end(args);
414  when_failed(status, exit);
415 
416  result = amxd_object_find_internal(object, &key_path, &path, &status);
417 
418 exit:
419  if(dm != NULL) {
420  dm->status = status;
421  }
422  amxd_path_clean(&path);
423  return result;
424 }
bool PRIVATE amxd_object_is_base(const amxd_object_t *const object)
Definition: amxd_dm_priv.c:504
PRIVATE amxd_object_t * amxd_object_find_internal(amxd_object_t *const object, bool *key_path, amxd_path_t *path, amxd_status_t *status)
enum _amxd_status amxd_status_t
@ amxd_status_ok
Definition: amxd_types.h:78
amxd_dm_t * amxd_object_get_dm(const amxd_object_t *const object)
Get the data model.
amxd_status_t amxd_path_init(amxd_path_t *path, const char *object_path)
Initializes an amxd_path_t structure.
Definition: amxd_path.c:328
void amxd_path_clean(amxd_path_t *path)
Cleans an amxd_path_t structure.
Definition: amxd_path.c:351
amxd_status_t amxd_path_vsetf(amxd_path_t *path, bool add_dot, const char *obj_path, va_list args)
Sets or replaces the path contained in the amxd_path_t structure.
Definition: amxd_path.c:403
amxd_status_t status
Definition: amxd_types.h:263
static amxd_dm_t dm
static amxd_status_t status

◆ amxd_object_hierarchy_down()

static void amxd_object_hierarchy_down ( amxd_object_t *const  object,
const amxd_direction_t  direction,
amxd_object_filter_fn_t  filter,
amxd_object_cb_fn_t  cb,
int32_t  depth,
void *  priv 
)
static

Definition at line 92 of file amxd_object_hierarchy.c.

97  {
98  if(depth < 0) {
99  return;
100  }
101 
102  if((filter != NULL) && !filter(object, depth, priv)) {
103  return;
104  }
105  if(direction == amxd_direction_down) {
106  cb(object, depth, priv);
107  }
108 
109  depth = depth == INT32_MAX ? INT32_MAX : depth - 1;
110  amxd_object_for_each(child, it, object) {
111  amxd_object_t* child = amxc_container_of(it, amxd_object_t, it);
112  amxd_object_hierarchy_down(child, direction, filter, cb, depth, priv);
113  }
114 
115  amxd_object_for_each(instance, it, object) {
116  amxd_object_t* instance = amxc_container_of(it, amxd_object_t, it);
117  amxd_object_hierarchy_down(instance, direction, filter, cb, depth, priv);
118  }
119  if(direction == amxd_direction_down_reverse) {
120  cb(object, depth, priv);
121  }
122 }
static void amxd_object_hierarchy_down(amxd_object_t *const object, const amxd_direction_t direction, amxd_object_filter_fn_t filter, amxd_object_cb_fn_t cb, int32_t depth, void *priv)
@ amxd_direction_down
Definition: amxd_types.h:216
@ amxd_direction_down_reverse
Definition: amxd_types.h:217
#define amxd_object_for_each(type, it, object)
Helper macro for iterating object content.
Definition: amxd_object.h:113

◆ amxd_object_hierarchy_up()

static void amxd_object_hierarchy_up ( amxd_object_t *const  object,
amxd_object_filter_fn_t  filter,
amxd_object_cb_fn_t  cb,
int32_t  depth,
void *  priv 
)
static

Definition at line 76 of file amxd_object_hierarchy.c.

80  {
81  amxd_object_t* current = object;
82  while(current != NULL && depth >= 0) {
83  if((filter != NULL) && !filter(current, depth, priv)) {
84  break;
85  }
86  cb(current, depth, priv);
87  current = amxd_object_get_parent(current);
88  depth = depth == INT32_MAX ? INT32_MAX : depth - 1;
89  }
90 }

◆ amxd_object_is_supported_impl()

static amxd_object_t* amxd_object_is_supported_impl ( amxd_object_t object,
amxd_path_t path 
)
static

Definition at line 204 of file amxd_object_hierarchy.c.

205  {
206  char* part = NULL;
207 
209  part = amxd_path_get_first(path, true);
210  free(part);
211  }
212  part = amxd_path_get_first(path, true);
213  if((part != NULL) && (part[0] == '.')) {
214  free(part);
215  part = amxd_path_get_first(path, true);
216  }
217  when_null(part, exit);
218  object = amxd_object_get(object, part);
219  free(part);
220  when_null(object, exit);
221  object = amxd_object_is_supported_impl(object, path);
222 
223 exit:
224  return object;
225 }
static amxd_object_t * amxd_object_is_supported_impl(amxd_object_t *object, amxd_path_t *path)
amxd_object_t * amxd_object_get(const amxd_object_t *object, const char *name)
Get an instance or child of an object.
char * amxd_path_get_first(amxd_path_t *path, bool remove)
Gets the first part of the path.
Definition: amxd_path.c:501

◆ amxd_object_resolve_pathf()

amxd_status_t amxd_object_resolve_pathf ( amxd_object_t object,
amxc_llist_t *  paths,
const char *  rel_path,
  ... 
)

Definition at line 426 of file amxd_object_hierarchy.c.

429  {
431  amxd_path_t path;
432  va_list args;
433  bool key_path = false;
434 
435  amxd_path_init(&path, NULL);
436 
437  when_null(object, exit);
438  when_true(amxd_object_is_base(object), exit);
439  when_str_empty(rel_path, exit);
440 
441  va_start(args, rel_path);
442  status = amxd_path_vsetf(&path, true, rel_path, args);
443  va_end(args);
444  when_failed(status, exit);
445 
446  status = amxd_object_resolve_internal(object, &key_path, paths, &path);
447 
448 exit:
449  amxd_path_clean(&path);
450  return status;
451 }
PRIVATE amxd_status_t amxd_object_resolve_internal(amxd_object_t *const object, bool *key_path, amxc_llist_t *paths, amxd_path_t *path)
@ amxd_status_unknown_error
Definition: amxd_types.h:79

◆ amxd_object_resolve_pathf_ext()

amxd_status_t amxd_object_resolve_pathf_ext ( amxd_object_t object,
bool *  key_path,
amxc_llist_t *  paths,
const char *  rel_path,
  ... 
)

Definition at line 453 of file amxd_object_hierarchy.c.

457  {
459  amxd_path_t path;
460  va_list args;
461 
462  amxd_path_init(&path, NULL);
463 
464  when_null(key_path, exit);
465  when_null(object, exit);
466  when_true(amxd_object_is_base(object), exit);
467  when_str_empty(rel_path, exit);
468 
469  *key_path = false;
470 
471  va_start(args, rel_path);
472  status = amxd_path_vsetf(&path, true, rel_path, args);
473  va_end(args);
474  when_failed(status, exit);
475 
476  status = amxd_object_resolve_internal(object, key_path, paths, &path);
477 
478 exit:
479  amxd_path_clean(&path);
480  return status;
481 }

◆ amxd_path_prepend_instance()

static void amxd_path_prepend_instance ( const amxd_object_t object,
amxc_string_t *  path,
const char *  name,
uint32_t  length,
const uint32_t  flags 
)
static

Definition at line 124 of file amxd_object_hierarchy.c.

128  {
130  if((flags & AMXD_OBJECT_EXTENDED) == AMXD_OBJECT_EXTENDED) {
131  if((flags & AMXD_OBJECT_REGEXP) == AMXD_OBJECT_REGEXP) {
132  amxc_string_prepend(path, "\\]", 2);
133  } else {
134  amxc_string_prepend(path, "]", 1);
135  }
136  }
137  if((flags & AMXD_OBJECT_INDEXED) == AMXD_OBJECT_INDEXED) {
138  amxc_string_prependf(path, "%" PRId32, object->index);
139  } else {
140  amxc_string_prepend(path, name, length);
141  }
142  if((flags & AMXD_OBJECT_EXTENDED) == AMXD_OBJECT_EXTENDED) {
143  if((flags & AMXD_OBJECT_REGEXP) == AMXD_OBJECT_REGEXP) {
144  amxc_string_prepend(path, "\\[", 2);
145  } else {
146  amxc_string_prepend(path, "[", 1);
147  }
148  }
149  }
150 }
#define AMXD_OBJECT_INDEXED
Name and path format flag - use index for instance objects.
Definition: amxd_object.h:176
#define AMXD_OBJECT_EXTENDED
Path format flag - set name or index of instrance objects between '[' and ']'.
Definition: amxd_object.h:188
uint32_t index
Definition: amxd_types.h:240