libamxrt  0.4.2
Ambiorix Run Time Library
amxrt_save_load.c File Reference
#include <stdlib.h>
#include <string.h>
#include <amxrt/amxrt.h>
#include <amxo/amxo_save.h>
#include <amxd/amxd_object.h>
#include <amxp/amxp_dir.h>
#include "amxrt_priv.h"

Go to the source code of this file.

Data Structures

struct  _odl_storage
 

Typedefs

typedef struct _odl_storage odl_storage_t
 

Functions

static int isdot (int c)
 
static amxc_var_t * amxrt_get_save_objects (amxo_parser_t *parser)
 
static char * amxrt_get_directory (amxo_parser_t *parser)
 
static int amxrt_dm_load (amxd_dm_t *dm, amxo_parser_t *parser)
 
static int amxrt_dm_save_object (amxo_parser_t *parser, amxd_object_t *object, const char *dir, const char *name)
 
static int amxrt_dm_save (amxd_dm_t *dm, amxo_parser_t *parser)
 
static bool amxrt_save_check_tree (amxd_object_t *object)
 
static bool amxrt_save_check_persistent_params (amxd_object_t *object, const amxc_var_t *data)
 
static void amxrt_save_add_path (const char *path)
 
static bool amxrt_save_check_paths (amxo_parser_t *parser, amxd_object_t *object)
 
static void amxrt_timed_save (UNUSED amxp_timer_t *const timer, UNUSED void *data)
 
static void amxrt_save_changed (const char *const sig_name, const amxc_var_t *const data, UNUSED void *const priv)
 
static void amxrt_save_subscribe (amxd_dm_t *dm)
 
static bool amxrt_is_odl_storage_enabled (amxo_parser_t *parser)
 
static void amxrt_monitor_changes (UNUSED const char *const sig_name, UNUSED const amxc_var_t *const data, UNUSED void *const priv)
 
static int amxrt_odl_save_load_init (amxd_dm_t *dm, amxo_parser_t *parser)
 
static void amxrt_odl_save_load_cleanup (amxd_dm_t *dm, amxo_parser_t *parser)
 
int amxrt_dm_create_dir (amxo_parser_t *parser, uid_t uid, gid_t gid)
 
int amxrt_dm_save_load_main (int reason, amxd_dm_t *dm, amxo_parser_t *parser)
 The data model auto load and save module. More...
 

Variables

static odl_storage_t storage
 

Typedef Documentation

◆ odl_storage_t

typedef struct _odl_storage odl_storage_t

Function Documentation

◆ amxrt_dm_create_dir()

int amxrt_dm_create_dir ( amxo_parser_t *  parser,
uid_t  uid,
gid_t  gid 
)

Definition at line 436 of file amxrt_save_load.c.

436  {
437  int rv = -1;
438  char* directory = NULL;
439 
440  when_null(parser, exit);
441 
442  if(!amxrt_is_odl_storage_enabled(parser)) {
443  goto exit;
444  }
445 
446  directory = amxrt_get_directory(parser);
447  rv = amxp_dir_owned_make(directory, 0777, uid, gid);
448  if(rv != 0) {
449  amxrt_print_error("Failed to create directory %s", directory);
450  }
451  free(directory);
452 
453 exit:
454  return rv;
455 }
PRIVATE void amxrt_print_error(const char *fmt,...)
static char * amxrt_get_directory(amxo_parser_t *parser)
static bool amxrt_is_odl_storage_enabled(amxo_parser_t *parser)

◆ amxrt_dm_load()

static int amxrt_dm_load ( amxd_dm_t *  dm,
amxo_parser_t *  parser 
)
static

Definition at line 117 of file amxrt_save_load.c.

117  {
118  int status = 0;
119  amxc_string_t include;
120  bool is_empty_dir = false;
121 
122  amxd_object_t* root = amxd_dm_get_root(dm);
123  char* odl_dir = amxrt_get_directory(parser);
124  amxc_var_t* eventing = GET_ARG(&parser->config, AMXRT_COPT_EVENT);
125  bool orig_eventing = GET_BOOL(eventing, NULL);
126  bool dm_eventing_enabled = GETP_BOOL(&parser->config, AMXRT_COPT_EVENTS);
127 
128  amxc_string_init(&include, 0);
129 
130  if((odl_dir == NULL) || (*odl_dir == 0)) {
131  amxrt_print_message("Load - No odl directory specified");
132  goto exit;
133  }
134 
135  amxc_var_set(bool, eventing, dm_eventing_enabled);
136  amxp_sigmngr_enable(&dm->sigmngr, dm_eventing_enabled);
137 
138  amxc_string_setf(&include, "include \"%s\";", odl_dir);
139  status = amxo_parser_parse_string(parser, amxc_string_get(&include, 0), root);
140  if(status == 0) {
141  is_empty_dir = amxp_dir_is_empty(odl_dir);
142  }
143  if((status != 0) || is_empty_dir) {
144  const char* def = GETP_CHAR(&parser->config, AMXRT_COPT_DEFAULTS);
145  amxrt_print_message("Load - Failed to load %s or directory is empty", odl_dir);
146  when_true((def == NULL) || (*def == 0), exit);
147  amxrt_print_message("Load - Try to load default from %s", def);
148  amxc_string_setf(&include, "include \"%s\";", def);
149  status = amxo_parser_parse_string(parser, amxc_string_get(&include, 0), root);
150  if(status != 0) {
151  amxrt_print_message("Load - Failed to load defaults from %s", def);
152  }
153  }
154 
155 exit:
156  amxp_sigmngr_enable(&dm->sigmngr, true);
157  amxc_var_set(bool, eventing, orig_eventing);
158  free(odl_dir);
159  amxc_string_clean(&include);
160  return status;
161 }
#define AMXRT_COPT_EVENTS
Definition: amxrt.h:106
#define AMXRT_COPT_DEFAULTS
Definition: amxrt.h:105
#define AMXRT_COPT_EVENT
Definition: amxrt.h:90
PRIVATE void amxrt_print_message(const char *fmt,...)

◆ amxrt_dm_save()

static int amxrt_dm_save ( amxd_dm_t *  dm,
amxo_parser_t *  parser 
)
static

Definition at line 181 of file amxrt_save_load.c.

181  {
182  int status = 0;
183  amxc_var_t* paths = amxrt_get_save_objects(parser);
184  char* odl_dir = amxrt_get_directory(parser);
185  uint32_t index = 0;
186  amxc_string_t file_name;
187 
188  amxc_string_init(&file_name, 0);
189 
190  when_true_status((odl_dir == NULL) || (*odl_dir == 0), exit,
191  amxrt_print_error("Export - No odl directory specified"));
192 
193  if(paths == NULL) {
194  amxd_object_t* root = amxd_dm_get_root(dm);
195  const char* name = GETP_CHAR(&parser->config, AMXRT_COPT_NAME);
196  when_null_status(name, exit, status = -1);
197  status = amxrt_dm_save_object(parser, root, odl_dir, name);
198  goto exit;
199  }
200 
201  when_true(amxc_var_type_of(paths) != AMXC_VAR_ID_LIST, exit);
202 
203  amxc_var_for_each(path, paths) {
204  const char* op = amxc_var_constcast(cstring_t, path);
205  amxd_object_t* obj = NULL;
206  amxc_string_setf(&file_name, "%2.2d_%s", index, op);
207  amxc_string_trimr(&file_name, isdot);
208  obj = amxd_dm_findf(dm, "%s", op);
209  if(obj == NULL) {
210  amxrt_print_error("Export - Object %s not found", op);
211  continue;
212  }
213  status = amxrt_dm_save_object(parser, obj, odl_dir, amxc_string_get(&file_name, 0));
214  index++;
215  }
216 
217 exit:
218  amxc_string_clean(&file_name);
219  free(odl_dir);
220  return status;
221 }
#define AMXRT_COPT_NAME
Definition: amxrt.h:85
static int amxrt_dm_save_object(amxo_parser_t *parser, amxd_object_t *object, const char *dir, const char *name)
static amxc_var_t * amxrt_get_save_objects(amxo_parser_t *parser)
static int isdot(int c)

◆ amxrt_dm_save_object()

static int amxrt_dm_save_object ( amxo_parser_t *  parser,
amxd_object_t *  object,
const char *  dir,
const char *  name 
)
static

Definition at line 163 of file amxrt_save_load.c.

166  {
167  int status = 0;
168  amxc_string_t file;
169  amxc_string_init(&file, 0);
170 
171  amxc_string_setf(&file, "%s/%s.odl", dir, name);
172  status = amxo_parser_save_object(parser, amxc_string_get(&file, 0), object, false);
173  when_failed_status(status, exit,
174  amxrt_print_error("Export - Failed to write %s file", amxc_string_get(&file, 0)));
175 
176 exit:
177  amxc_string_clean(&file);
178  return status;
179 }

◆ amxrt_get_directory()

static char* amxrt_get_directory ( amxo_parser_t *  parser)
static

Definition at line 99 of file amxrt_save_load.c.

99  {
100  amxc_string_t dir;
101  const char* odl_dir = GETP_CHAR(&parser->config, AMXRT_COPT_DIRECTORY);
102  char* resolved_dir = NULL;
103 
104  amxc_string_init(&dir, 0);
105  if(odl_dir == NULL) {
106  odl_dir = GETP_CHAR(&parser->config, AMXRT_COPT_STORAGE_DIR);
107  }
108  if(odl_dir != NULL) {
109  amxc_string_setf(&dir, "%s", odl_dir);
110  amxc_string_resolve(&dir, &parser->config);
111  resolved_dir = amxc_string_take_buffer(&dir);
112  }
113 
114  return resolved_dir;
115 }
#define AMXRT_COPT_STORAGE_DIR
Definition: amxrt.h:95
#define AMXRT_COPT_DIRECTORY
Definition: amxrt.h:104

◆ amxrt_get_save_objects()

static amxc_var_t* amxrt_get_save_objects ( amxo_parser_t *  parser)
static

Definition at line 81 of file amxrt_save_load.c.

81  {
82  amxc_var_t* paths = GETP_ARG(&parser->config, AMXRT_COPT_OBJECTS);
83 
84  when_null(paths, exit);
85 
86  if(amxc_var_type_of(paths) == AMXC_VAR_ID_CSTRING) {
87  amxc_var_cast(paths, AMXC_VAR_ID_CSV_STRING);
88  amxc_var_cast(paths, AMXC_VAR_ID_LIST);
89  } else if(amxc_var_type_of(paths) == AMXC_VAR_ID_CSV_STRING) {
90  amxc_var_cast(paths, AMXC_VAR_ID_LIST);
91  } else if(amxc_var_type_of(paths) != AMXC_VAR_ID_LIST) {
92  amxrt_print_error("Export - Export objects specified in wrong format");
93  }
94 
95 exit:
96  return paths;
97 }
#define AMXRT_COPT_OBJECTS
Definition: amxrt.h:107

◆ amxrt_is_odl_storage_enabled()

static bool amxrt_is_odl_storage_enabled ( amxo_parser_t *  parser)
static

Definition at line 374 of file amxrt_save_load.c.

374  {
375  bool retval = true;
376  const char* storage_type = GETP_CHAR(&parser->config, AMXRT_COPT_STORAGE);
377 
378  when_true((storage_type == NULL) || (*storage_type == 0), exit);
379  when_true(strcmp(storage_type, "odl") == 0, exit);
380  retval = false;
381 
382 exit:
383  return retval;
384 }
#define AMXRT_COPT_STORAGE
Definition: amxrt.h:113

◆ amxrt_monitor_changes()

static void amxrt_monitor_changes ( UNUSED const char *const  sig_name,
UNUSED const amxc_var_t *const  data,
UNUSED void *const  priv 
)
static

Definition at line 386 of file amxrt_save_load.c.

388  {
389  amxp_slot_disconnect_all(amxrt_monitor_changes);
391 }
static odl_storage_t storage
static void amxrt_save_subscribe(amxd_dm_t *dm)
static void amxrt_monitor_changes(UNUSED const char *const sig_name, UNUSED const amxc_var_t *const data, UNUSED void *const priv)
amxd_dm_t * dm

◆ amxrt_odl_save_load_cleanup()

static void amxrt_odl_save_load_cleanup ( amxd_dm_t *  dm,
amxo_parser_t *  parser 
)
static

Definition at line 424 of file amxrt_save_load.c.

424  {
425  amxp_timer_delete(&storage.save_timer);
426  amxp_slot_disconnect_all(amxrt_save_changed);
427  amxp_slot_disconnect_all(amxrt_monitor_changes);
428  if(GETP_BOOL(&parser->config, AMXRT_COPT_SAVE)) {
429  amxrt_dm_save(dm, parser);
430  }
431  amxc_llist_clean(&storage.save_paths, amxc_string_list_it_free);
432  storage.dm = NULL;
433  storage.parser = NULL;
434 }
#define AMXRT_COPT_SAVE
Definition: amxrt.h:109
static int amxrt_dm_save(amxd_dm_t *dm, amxo_parser_t *parser)
static void amxrt_save_changed(const char *const sig_name, const amxc_var_t *const data, UNUSED void *const priv)
amxp_timer_t * save_timer
amxc_llist_t save_paths
amxo_parser_t * parser

◆ amxrt_odl_save_load_init()

static int amxrt_odl_save_load_init ( amxd_dm_t *  dm,
amxo_parser_t *  parser 
)
static

Definition at line 393 of file amxrt_save_load.c.

393  {
394  char* directory = amxrt_get_directory(parser);
395  int retval = 0;
396 
397  storage.dm = dm;
398  storage.parser = parser;
399  amxc_llist_init(&storage.save_paths);
400 
401  if(amxp_dir_make(directory, 0777) != 0) {
402  amxrt_print_error("Failed to create directory %s", directory);
403  }
404 
405  if(GETP_BOOL(&parser->config, AMXRT_COPT_LOAD)) {
406  retval = amxrt_dm_load(dm, parser);
407  if(retval != 0) {
408  // turn off saving and exit
409  amxc_var_t* save_opt = GETP_ARG(&parser->config, AMXRT_COPT_SAVE);
410  amxc_var_set(bool, save_opt, false);
411  goto exit;
412  }
413  }
414 
415  if(GETP_BOOL(&parser->config, AMXRT_COPT_ON_CHANGED)) {
416  amxp_slot_connect(&dm->sigmngr, "app:start", NULL, amxrt_monitor_changes, NULL);
417  }
418 
419 exit:
420  free(directory);
421  return retval;
422 }
#define AMXRT_COPT_LOAD
Definition: amxrt.h:108
#define AMXRT_COPT_ON_CHANGED
Definition: amxrt.h:110
static int amxrt_dm_load(amxd_dm_t *dm, amxo_parser_t *parser)

◆ amxrt_save_add_path()

static void amxrt_save_add_path ( const char *  path)
static

Definition at line 253 of file amxrt_save_load.c.

253  {
254  amxc_string_t* save_path = NULL;
255  bool is_set = false;
256 
257  amxc_llist_iterate(it, (&storage.save_paths)) {
258  amxc_string_t* set_path = amxc_string_from_llist_it(it);
259  if(strcmp(path, amxc_string_get(set_path, 0)) == 0) {
260  is_set = true;
261  break;
262  }
263  }
264  if(!is_set) {
265  amxc_string_new(&save_path, 0);
266  amxc_string_setf(save_path, "%s", path);
267  amxc_llist_append(&storage.save_paths, &save_path->it);
268  }
269 }

◆ amxrt_save_changed()

static void amxrt_save_changed ( const char *const  sig_name,
const amxc_var_t *const  data,
UNUSED void *const  priv 
)
static

Definition at line 321 of file amxrt_save_load.c.

323  {
324  amxd_object_t* object = amxd_dm_signal_get_object(storage.dm, data);
325  amxo_parser_t* parser = storage.parser;
326  uint32_t save_delay = amxc_var_dyncast(uint32_t, GETP_ARG(&parser->config, AMXRT_COPT_DELAY));
327  bool save_needed = false;
328 
329  if((strcmp(sig_name, "dm:instance-added") == 0) ||
330  (strcmp(sig_name, "dm:instance-removed") == 0)) {
331  uint32_t index = GET_UINT32(data, "index");
332  amxd_object_t* instance = amxd_object_get_instance(object, NULL, index);
333  object = instance != NULL? instance: object;
334  if(amxd_object_is_attr_set(object, amxd_oattr_persistent)) {
335  save_needed = amxrt_save_check_tree(object);
336  }
337  } else if(strcmp(sig_name, "dm:object-changed") == 0) {
338  if(amxd_object_is_attr_set(object, amxd_oattr_persistent)) {
339  save_needed = amxrt_save_check_tree(object);
340  if(save_needed) {
341  save_needed = amxrt_save_check_persistent_params(object, data);
342  }
343  }
344  } else {
345  if(amxd_object_is_attr_set(object, amxd_oattr_persistent)) {
346  save_needed = amxrt_save_check_tree(object);
347  }
348  }
349 
350  if(save_needed) {
351  save_needed = amxrt_save_check_paths(parser, object);
352 
353  }
354  if(save_needed) {
355  if(storage.save_timer == NULL) {
356  amxp_timer_new(&storage.save_timer, amxrt_timed_save, NULL);
357  save_delay = amxc_var_dyncast(uint32_t, GETP_ARG(&parser->config, AMXRT_COPT_INIT_DELAY));
358  save_delay = save_delay == 0 ? 30000 : save_delay;
359  }
360 
361  if((amxp_timer_remaining_time(storage.save_timer) < save_delay) ||
362  (amxp_timer_get_state(storage.save_timer) != amxp_timer_running)) {
363  amxp_timer_start(storage.save_timer, save_delay == 0 ? 500 : save_delay);
364  }
365  }
366 }
#define AMXRT_COPT_DELAY
Definition: amxrt.h:111
#define AMXRT_COPT_INIT_DELAY
Definition: amxrt.h:112
static bool amxrt_save_check_tree(amxd_object_t *object)
static bool amxrt_save_check_paths(amxo_parser_t *parser, amxd_object_t *object)
static void amxrt_timed_save(UNUSED amxp_timer_t *const timer, UNUSED void *data)
static bool amxrt_save_check_persistent_params(amxd_object_t *object, const amxc_var_t *data)

◆ amxrt_save_check_paths()

static bool amxrt_save_check_paths ( amxo_parser_t *  parser,
amxd_object_t *  object 
)
static

Definition at line 271 of file amxrt_save_load.c.

271  {
272  bool save_needed = false;
273  char* obj_path = amxd_object_get_path(object, AMXD_OBJECT_INDEXED);
274 
275  amxc_var_t* paths = amxrt_get_save_objects(parser);
276  when_null_status(paths, exit, save_needed = true);
277 
278  when_true(amxc_var_type_of(paths) != AMXC_VAR_ID_LIST, exit);
279 
280  amxc_var_for_each(path, paths) {
281  const char* str_path = amxc_var_constcast(cstring_t, path);
282  int len = strlen(str_path);
283  if(strncmp(str_path, obj_path, len) == 0) {
284  amxrt_save_add_path(str_path);
285  save_needed = true;
286  break;
287  }
288  }
289 
290 exit:
291  free(obj_path);
292  return save_needed;
293 }
static void amxrt_save_add_path(const char *path)

◆ amxrt_save_check_persistent_params()

static bool amxrt_save_check_persistent_params ( amxd_object_t *  object,
const amxc_var_t *  data 
)
static

Definition at line 236 of file amxrt_save_load.c.

237  {
238  bool persistent = false;
239  amxc_var_t* params = GET_ARG(data, "parameters");
240 
241  amxc_var_for_each(param, params) {
242  const char* name = amxc_var_key(param);
243  amxd_param_t* param_def = amxd_object_get_param_def(object, name);
244  persistent |= amxd_param_is_attr_set(param_def, amxd_pattr_persistent);
245  if(persistent) {
246  break;
247  }
248  }
249 
250  return persistent;
251 }

◆ amxrt_save_check_tree()

static bool amxrt_save_check_tree ( amxd_object_t *  object)
static

Definition at line 223 of file amxrt_save_load.c.

223  {
224  bool persistent = true;
225  amxd_object_t* parent = amxd_object_get_parent(object);
226 
227  while(amxd_object_get_type(parent) != amxd_object_root &&
228  persistent) {
229  persistent &= amxd_object_is_attr_set(object, amxd_oattr_persistent);
230  parent = amxd_object_get_parent(parent);
231  }
232 
233  return persistent;
234 }

◆ amxrt_save_subscribe()

static void amxrt_save_subscribe ( amxd_dm_t *  dm)
static

Definition at line 368 of file amxrt_save_load.c.

368  {
369  amxp_slot_connect(&dm->sigmngr, "dm:object-changed", NULL, amxrt_save_changed, NULL);
370  amxp_slot_connect(&dm->sigmngr, "dm:instance-added", NULL, amxrt_save_changed, NULL);
371  amxp_slot_connect(&dm->sigmngr, "dm:instance-removed", NULL, amxrt_save_changed, NULL);
372 }

◆ amxrt_timed_save()

static void amxrt_timed_save ( UNUSED amxp_timer_t *const  timer,
UNUSED void *  data 
)
static

Definition at line 295 of file amxrt_save_load.c.

296  {
297  if(amxc_llist_is_empty(&storage.save_paths)) {
299  } else {
300  amxd_object_t* object = NULL;
301  char* dir = amxrt_get_directory(storage.parser);
302  uint32_t index = 0;
303  amxc_string_t file_name;
304  amxc_string_init(&file_name, 0);
305 
306  amxc_llist_for_each(it, (&storage.save_paths)) {
307  amxc_string_t* path = amxc_string_from_llist_it(it);
308  amxc_string_setf(&file_name, "%2.2d_%s", index, amxc_string_get(path, 0));
309  amxc_string_trimr(&file_name, isdot);
310 
311  object = amxd_dm_findf(storage.dm, "%s", amxc_string_get(path, 0));
312  amxrt_dm_save_object(storage.parser, object, dir, amxc_string_get(&file_name, 0));
313  amxc_string_delete(&path);
314  }
315 
316  amxc_string_clean(&file_name);
317  free(dir);
318  }
319 }

◆ isdot()

static int isdot ( int  c)
static

Definition at line 73 of file amxrt_save_load.c.

73  {
74  if(c == '.') {
75  return 1;
76  }
77 
78  return 0;
79 }
#define c(x)
Definition: amxrt_priv.h:97

Variable Documentation

◆ storage

odl_storage_t storage
static

Definition at line 71 of file amxrt_save_load.c.