libamxd  6.4.1
Data Model Manager
amxd_action_param_validate.c
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** SPDX-License-Identifier: BSD-2-Clause-Patent
4 **
5 ** SPDX-FileCopyrightText: Copyright (c) 2023 SoftAtHome
6 **
7 ** Redistribution and use in source and binary forms, with or without modification,
8 ** are permitted provided that the following conditions are met:
9 **
10 ** 1. Redistributions of source code must retain the above copyright notice,
11 ** this list of conditions and the following disclaimer.
12 **
13 ** 2. Redistributions in binary form must reproduce the above copyright notice,
14 ** this list of conditions and the following disclaimer in the documentation
15 ** and/or other materials provided with the distribution.
16 **
17 ** Subject to the terms and conditions of this license, each copyright holder
18 ** and contributor hereby grants to those receiving rights under this license
19 ** a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable
20 ** (except for failure to satisfy the conditions of this license) patent license
21 ** to make, have made, use, offer to sell, sell, import, and otherwise transfer
22 ** this software, where such license applies only to those patent claims, already
23 ** acquired or hereafter acquired, licensable by such copyright holder or contributor
24 ** that are necessarily infringed by:
25 **
26 ** (a) their Contribution(s) (the licensed copyrights of copyright holders and
27 ** non-copyrightable additions of contributors, in source or binary form) alone;
28 ** or
29 **
30 ** (b) combination of their Contribution(s) with the work of authorship to which
31 ** such Contribution(s) was added by such copyright holder or contributor, if,
32 ** at the time the Contribution is added, such addition causes such combination
33 ** to be necessarily infringed. The patent license shall not apply to any other
34 ** combinations which include the Contribution.
35 **
36 ** Except as expressly stated above, no rights or licenses from any copyright
37 ** holder or contributor is granted under this license, whether expressly, by
38 ** implication, estoppel or otherwise.
39 **
40 ** DISCLAIMER
41 **
42 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
43 ** AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
44 ** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
45 ** ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
46 ** LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
47 ** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
48 ** SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
49 ** CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
50 ** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
51 ** USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
52 **
53 ****************************************************************************/
54 
55 #include <stdlib.h>
56 #include <string.h>
57 
58 #include "amxd_priv.h"
59 
60 #include <amxd/amxd_dm.h>
61 #include <amxd/amxd_path.h>
62 #include <amxd/amxd_action.h>
63 #include <amxd/amxd_object.h>
64 #include <amxd/amxd_parameter.h>
67 
68 #include "amxd_assert.h"
69 
71  amxc_var_t* data,
72  const amxc_var_t* value) {
74  amxc_var_t def_val;
75  amxc_var_init(&def_val);
76  amxc_var_copy(&def_val, data);
77  if(amxc_var_cast(&def_val, amxd_param_get_type(param)) != 0) {
78  amxc_var_set_type(&def_val, amxd_param_get_type(param));
79  }
80 
81  if(amxc_var_type_of(data) == AMXC_VAR_ID_CSTRING) {
82  amxd_object_t* object = amxd_param_get_owner(param);
83  amxc_var_t* ref_value = amxd_resolve_param_ref(object, data);
84  data = ref_value == NULL ? &def_val : ref_value;
85  }
86 
87  if((amxd_param_get_type(param) == AMXC_VAR_ID_CSTRING) ||
88  ( amxd_param_get_type(param) == AMXC_VAR_ID_CSV_STRING) ||
89  ( amxd_param_get_type(param) == AMXC_VAR_ID_SSV_STRING)) {
90  int64_t min = amxc_var_dyncast(int64_t, data);
91  char* text = amxc_var_dyncast(cstring_t, value);
92  int64_t length = text == NULL ? 0 : strlen(text);
93  if(length < min) {
95  }
96  free(text);
97  } else {
98  int result = 0;
99  amxc_var_compare(data, value, &result);
100  if(result > 0) {
102  }
103  }
104 
105  amxc_var_clean(&def_val);
106  return status;
107 }
108 
110  amxc_var_t* data,
111  const amxc_var_t* value) {
113  amxc_var_t def_val;
114  amxc_var_init(&def_val);
115  amxc_var_copy(&def_val, data);
116  if(amxc_var_cast(&def_val, amxd_param_get_type(param)) != 0) {
117  amxc_var_set_type(&def_val, amxd_param_get_type(param));
118  }
119 
120  if(amxc_var_type_of(data) == AMXC_VAR_ID_CSTRING) {
121  amxd_object_t* object = amxd_param_get_owner(param);
122  amxc_var_t* ref_value = amxd_resolve_param_ref(object, data);
123  data = ref_value == NULL ? data : ref_value;
124  }
125 
126  if((amxd_param_get_type(param) == AMXC_VAR_ID_CSTRING) ||
127  ( amxd_param_get_type(param) == AMXC_VAR_ID_CSV_STRING) ||
128  ( amxd_param_get_type(param) == AMXC_VAR_ID_SSV_STRING)) {
129  int64_t max = amxc_var_dyncast(int64_t, data);
130  char* text = amxc_var_dyncast(cstring_t, value);
131  int64_t length = text == NULL ? 0 : strlen(text);
132  if(length > max) {
134  }
135  free(text);
136  } else {
137  int result = 0;
138  amxc_var_compare(data, value, &result);
139  if(result < 0) {
141  }
142  }
143 
144  amxc_var_clean(&def_val);
145  return status;
146 }
147 
148 static bool is_value_in(amxc_var_t* value, const amxc_llist_t* values) {
149  bool is_in = false;
150  int result = 0;
151 
152  if((amxc_var_type_of(value) == AMXC_VAR_ID_SSV_STRING) ||
153  (amxc_var_type_of(value) == AMXC_VAR_ID_CSV_STRING)) {
154  amxc_var_cast(value, AMXC_VAR_ID_LIST);
155  is_in = true;
156  amxc_var_for_each(v, value) {
157  is_in &= is_value_in(v, values);
158  if(!is_in) {
159  break;
160  }
161  }
162  } else {
163  amxc_llist_for_each(it, values) {
164  amxc_var_t* check = amxc_var_from_llist_it(it);
165  amxc_var_compare(value, check, &result);
166  if(result == 0) {
167  is_in = true;
168  break;
169  }
170  }
171  }
172 
173  return is_in;
174 }
175 
176 static bool is_string_empty(const amxc_var_t* value) {
177  char* v = amxc_var_dyncast(cstring_t, value);
178  bool retval = (v == NULL || *v == 0);
179  free(v);
180  return retval;
181 }
182 
183 static bool is_key_in_template(const amxd_object_t* object,
184  const amxd_param_t* param) {
185  return (amxd_param_is_attr_set(param, amxd_pattr_key) &&
187 }
188 
190  amxc_var_t* ref) {
191  amxd_object_t* ref_object = NULL;
192  amxd_param_t* ref_param = NULL;
193  amxc_var_t* ref_value = NULL;
195  char* full_ref = amxc_var_dyncast(cstring_t, ref);
196  int ref_len = strlen(full_ref);
197  char* object = full_ref;
198  char* param = NULL;
199 
200  for(int i = ref_len; i >= 0; i--) {
201  if(full_ref[i] == '.') {
202  full_ref[i] = 0;
203  param = full_ref + i + 1;
204  break;
205  }
206  }
207 
208  when_str_empty(param, exit);
209 
210  if(object[0] == 0) {
211  ref_object = obj;
212  } else {
213  if(object[0] == '.') {
214  ref_object = amxd_object_findf(obj, "%s", object);
215  } else {
216  ref_object = amxd_dm_findf(dm, "%s", object);
217  }
218  }
219  ref_param = amxd_object_get_param_def(ref_object, param);
220  when_null(ref_param, exit);
221  ref_value = &ref_param->value;
222 
223 exit:
224  free(full_ref);
225  return ref_value;
226 }
227 
229  amxd_param_t* param,
230  amxd_action_t reason,
231  const amxc_var_t* const args,
232  UNUSED amxc_var_t* const retval,
233  UNUSED void* priv) {
235  amxc_var_t temp;
236 
237  amxc_var_init(&temp);
238  when_null(param, exit);
239  when_true_status(reason != action_param_validate,
240  exit,
242 
243  when_true_status((args == NULL ||
244  amxc_var_type_of(args) == AMXC_VAR_ID_NULL),
245  exit,
247 
248  // TODO: Change in amxc_var_can_covert when the function is available
249  when_failed_status(amxc_var_convert(&temp,
250  args,
251  amxc_var_type_of(&param->value)),
252  exit,
254 
256 
257 exit:
258  amxc_var_clean(&temp);
259  return status;
260 }
261 
263  amxd_param_t* param,
264  amxd_action_t reason,
265  const amxc_var_t* const args,
266  amxc_var_t* const retval,
267  void* priv) {
269  amxc_var_t* data = (amxc_var_t*) priv;
270  amxc_var_t* min_var = NULL;
271  amxc_var_t* max_var = NULL;
272 
273  if(amxc_var_type_of(data) == AMXC_VAR_ID_HTABLE) {
274  min_var = amxc_var_get_key(data, "min", AMXC_VAR_FLAG_DEFAULT);
275  max_var = amxc_var_get_key(data, "max", AMXC_VAR_FLAG_DEFAULT);
276  } else if(amxc_var_type_of(data) == AMXC_VAR_ID_LIST) {
277  min_var = amxc_var_get_path(data, "0", AMXC_VAR_FLAG_DEFAULT);
278  max_var = amxc_var_get_path(data, "1", AMXC_VAR_FLAG_DEFAULT);
279  } else {
281  goto exit;
282  }
283 
284  status = amxd_action_describe_action(reason, retval, "check_range", priv);
285  when_true(status == amxd_status_ok, exit);
286 
287  status = amxd_action_param_validate(object, param, reason, args, retval, priv);
288  when_failed(status, exit);
289 
290  when_true_status(is_key_in_template(object, param), exit, status = amxd_status_ok);
291 
292  status = amxd_param_check_minimum(param, min_var, args);
293  when_failed(status, exit);
294 
295  status = amxd_param_check_maximum(param, max_var, args);
296  when_failed(status, exit);
297 
298 exit:
299  return status;
300 }
301 
303  amxd_param_t* param,
304  amxd_action_t reason,
305  const amxc_var_t* const args,
306  amxc_var_t* const retval,
307  void* priv) {
309  amxc_var_t* data = (amxc_var_t*) priv;
310  const char* name = "check_minimum";
311 
312  when_null_status(param, exit, status = amxd_status_parameter_not_found);
313  when_null_status(data, exit, status = amxd_status_invalid_value);
314 
315  if((amxc_var_type_of(&param->value) == AMXC_VAR_ID_CSTRING) ||
316  (amxc_var_type_of(&param->value) == AMXC_VAR_ID_CSV_STRING) ||
317  (amxc_var_type_of(&param->value) == AMXC_VAR_ID_SSV_STRING)) {
318  name = "check_minimum_length";
319  }
320  status = amxd_action_describe_action(reason, retval, name, priv);
321  when_true(status == amxd_status_ok, exit);
322 
323  status = amxd_action_param_validate(object, param, reason, args, retval, priv);
324  when_failed(status, exit);
325 
326  when_true_status(is_key_in_template(object, param), exit, status = amxd_status_ok);
327 
328  status = amxd_param_check_minimum(param, data, args);
329  when_failed(status, exit);
330 
331 exit:
332  return status;
333 }
334 
336  amxd_param_t* param,
337  amxd_action_t reason,
338  const amxc_var_t* const args,
339  amxc_var_t* const retval,
340  void* priv) {
342  amxc_var_t* data = (amxc_var_t*) priv;
343  const char* name = "check_maximum";
344 
345  when_null_status(param, exit, status = amxd_status_parameter_not_found);
346  when_null_status(data, exit, status = amxd_status_invalid_value);
347 
348  if((amxc_var_type_of(&param->value) == AMXC_VAR_ID_CSTRING) ||
349  (amxc_var_type_of(&param->value) == AMXC_VAR_ID_CSV_STRING) ||
350  (amxc_var_type_of(&param->value) == AMXC_VAR_ID_SSV_STRING)) {
351  name = "check_maximum_length";
352  }
353 
354  status = amxd_action_describe_action(reason, retval, name, priv);
355  when_true(status == amxd_status_ok, exit);
356 
357  status = amxd_action_param_validate(object, param, reason, args, retval, priv);
358  when_failed(status, exit);
359 
360  when_true_status(is_key_in_template(object, param), exit, status = amxd_status_ok);
361 
362  status = amxd_param_check_maximum(param, data, args);
363  when_failed(status, exit);
364 
365 exit:
366  return status;
367 }
368 
370  amxd_param_t* param,
371  amxd_action_t reason,
372  const amxc_var_t* const args,
373  amxc_var_t* const retval,
374  void* priv) {
376  amxc_var_t* data = (amxc_var_t*) priv;
377  const amxc_llist_t* values = NULL;
378  amxc_var_t check_value;
379 
380  amxc_var_init(&check_value);
381  when_true_status(amxc_var_type_of(data) != AMXC_VAR_ID_LIST,
382  exit,
384 
385  status = amxd_action_describe_action(reason, retval, "check_enum", priv);
386  when_true(status == amxd_status_ok, exit);
387 
388  status = amxd_action_param_validate(object, param, reason, args, retval, priv);
389  when_failed(status, exit);
390 
391  when_true_status(is_key_in_template(object, param), exit, status = amxd_status_ok);
392 
393  amxc_var_convert(&check_value, args, amxd_param_get_type(param));
394  values = amxc_var_constcast(amxc_llist_t, data);
395  when_false_status(is_value_in(&check_value, values),
396  exit,
398 
399 exit:
400  amxc_var_clean(&check_value);
401  return status;
402 }
403 
405  amxd_param_t* param,
406  amxd_action_t reason,
407  const amxc_var_t* const args,
408  amxc_var_t* const retval,
409  void* priv) {
411  amxc_var_t* data = (amxc_var_t*) priv;
412  amxc_var_t* ref_value = NULL;
413  amxc_llist_t* values = NULL;
414  amxc_var_t check_value;
415 
416  amxc_var_init(&check_value);
417  when_true_status(amxc_var_type_of(data) != AMXC_VAR_ID_CSTRING,
418  exit,
420 
421  status = amxd_action_describe_action(reason, retval, "check_is_in", priv);
422  when_true(status == amxd_status_ok, exit);
423 
424  status = amxd_action_param_validate(object, param, reason, args, retval, priv);
425  when_failed(status, exit);
426 
427  when_true_status(is_key_in_template(object, param), exit, status = amxd_status_ok);
428 
429  ref_value = amxd_resolve_param_ref(object, data);
430  when_true_status(ref_value == NULL &&
432  exit, status = amxd_status_ok);
433  when_null_status(ref_value, exit, status = amxd_status_invalid_value);
434  when_true_status(is_string_empty(ref_value), exit, status = amxd_status_ok);
435 
436  amxc_var_convert(&check_value, args, amxd_param_get_type(param));
437  values = amxc_var_dyncast(amxc_llist_t, ref_value);
438  when_false_status(is_value_in(&check_value, values),
439  exit,
441 
442 exit:
443  amxc_var_clean(&check_value);
444  amxc_llist_delete(&values, variant_list_it_free);
445  return status;
446 }
447 
449  const amxc_var_t* const value) {
451  amxd_object_t* object = NULL;
452  when_null(param, exit);
453 
454  object = amxd_param_get_owner(param);
455  retval = amxd_dm_invoke_action(object,
456  param,
458  value,
459  NULL);
460 
461 exit:
462  return retval;
463 }
Ambiorix Data Model Default actions header file.
static bool is_string_empty(const amxc_var_t *value)
static bool is_value_in(amxc_var_t *value, const amxc_llist_t *values)
amxd_status_t amxd_param_validate(amxd_param_t *const param, const amxc_var_t *const value)
static bool is_key_in_template(const amxd_object_t *object, const amxd_param_t *param)
amxd_status_t amxd_action_param_validate(UNUSED amxd_object_t *object, amxd_param_t *param, amxd_action_t reason, const amxc_var_t *const args, UNUSED amxc_var_t *const retval, UNUSED void *priv)
static amxd_status_t amxd_param_check_minimum(amxd_param_t *param, amxc_var_t *data, const amxc_var_t *value)
amxc_var_t * amxd_resolve_param_ref(amxd_object_t *obj, amxc_var_t *ref)
static amxd_status_t amxd_param_check_maximum(amxd_param_t *param, amxc_var_t *data, const amxc_var_t *value)
#define when_failed_status(x, l, c)
Definition: amxd_assert.h:65
amxd_status_t amxd_action_describe_action(amxd_action_t reason, amxc_var_t *const retval, const char *description, void *priv)
Definition: amxd_common.c:142
Ambiorix Data Model API header file.
amxd_object_t * amxd_dm_findf(amxd_dm_t *const dm, const char *abs_path,...) __attribute__((format(printf
amxd_status_t amxd_dm_invoke_action(amxd_object_t *object, amxd_param_t *param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval)
Definition: amxd_dm.c:591
Ambiorix Data Model API header file.
bool amxd_param_is_attr_set(const amxd_param_t *const param, const amxd_pattr_id_t attr)
static uint32_t amxd_param_get_type(const amxd_param_t *const param)
amxd_object_t * amxd_param_get_owner(const amxd_param_t *const param)
Ambiorix path API header file.
@ amxd_pattr_key
Definition: amxd_types.h:362
@ action_param_validate
Definition: amxd_types.h:114
enum _amxd_action amxd_action_t
enum _amxd_status amxd_status_t
@ amxd_status_parameter_not_found
Definition: amxd_types.h:82
@ amxd_status_function_not_implemented
Definition: amxd_types.h:83
@ amxd_status_invalid_type
Definition: amxd_types.h:90
@ amxd_status_ok
Definition: amxd_types.h:78
@ amxd_status_unknown_error
Definition: amxd_types.h:79
@ amxd_status_invalid_value
Definition: amxd_types.h:88
@ amxd_object_template
Definition: amxd_types.h:183
amxd_object_t * amxd_object_findf(amxd_object_t *object, const char *rel_path,...) __attribute__((format(printf
Find an object in the data model tree, starting from an object.
amxd_dm_t * amxd_object_get_dm(const amxd_object_t *const object)
Get the data model.
amxd_param_t * amxd_object_get_param_def(const amxd_object_t *const object, const char *name)
Gets a parameter definition from an 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
amxd_status_t amxd_action_param_check_range(amxd_object_t *object, amxd_param_t *param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
Default check range parameter validate action implementation.
amxd_status_t amxd_action_param_check_is_in(amxd_object_t *object, amxd_param_t *param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
Default check is in parameter validate action implementation.
amxd_status_t amxd_action_param_check_enum(amxd_object_t *object, amxd_param_t *param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
Default check enum parameter validate action implementation.
amxd_status_t amxd_action_param_check_maximum(amxd_object_t *object, amxd_param_t *param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
Default check maximum parameter validate action implementation.
amxd_status_t amxd_action_param_check_minimum(amxd_object_t *object, amxd_param_t *param, amxd_action_t reason, const amxc_var_t *const args, amxc_var_t *const retval, void *priv)
Default check minimum parameter validate action implementation.
amxc_var_t value
Definition: amxd_types.h:390
static amxd_dm_t dm
static amxd_status_t status