1/* Copyright JS Foundation and other contributors, http://js.foundation
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#ifndef JERRYX_ARG_H
17#define JERRYX_ARG_H
18
19#include <stdbool.h>
20#include <stddef.h>
21#include <stdint.h>
22#include "jerryscript.h"
23
24#ifdef __cplusplus
25extern "C"
26{
27#endif /* __cplusplus */
28
29/**
30 * The forward declaration of jerryx_arg_t.
31 */
32typedef struct jerryx_arg_t jerryx_arg_t;
33
34/**
35 * The forward declaration of jerryx_arg_js_iterator_t
36 */
37typedef struct jerryx_arg_js_iterator_t jerryx_arg_js_iterator_t;
38
39/**
40 * Signature of the transform function.
41 */
42typedef jerry_value_t (*jerryx_arg_transform_func_t) (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
43                                                      const jerryx_arg_t *c_arg_p); /**< native arg */
44
45/**
46 * The structure used in jerryx_arg_object_properties
47 */
48typedef struct
49{
50  const jerry_char_t **name_p; /**< property name list of the JS object */
51  jerry_length_t name_cnt; /**< count of the name list */
52  const jerryx_arg_t *c_arg_p; /**< points to the array of transformation steps */
53  jerry_length_t c_arg_cnt; /**< the count of the `c_arg_p` array */
54} jerryx_arg_object_props_t;
55
56/**
57 * The structure used in jerryx_arg_array
58 */
59typedef struct
60{
61  const jerryx_arg_t *c_arg_p; /**< points to the array of transformation steps */
62  jerry_length_t c_arg_cnt; /**< the count of the `c_arg_p` array */
63} jerryx_arg_array_items_t;
64
65/**
66 * The structure defining a single validation & transformation step.
67 */
68struct jerryx_arg_t
69{
70  jerryx_arg_transform_func_t func; /**< the transform function */
71  void *dest; /**< pointer to destination where func should store the result */
72  uintptr_t extra_info; /**< extra information, specific to func */
73};
74
75jerry_value_t jerryx_arg_transform_this_and_args (const jerry_value_t this_val,
76                                                  const jerry_value_t *js_arg_p,
77                                                  const jerry_length_t js_arg_cnt,
78                                                  const jerryx_arg_t *c_arg_p,
79                                                  jerry_length_t c_arg_cnt);
80
81jerry_value_t jerryx_arg_transform_args (const jerry_value_t *js_arg_p,
82                                         const jerry_length_t js_arg_cnt,
83                                         const jerryx_arg_t *c_arg_p,
84                                         jerry_length_t c_arg_cnt);
85
86jerry_value_t jerryx_arg_transform_object_properties (const jerry_value_t obj_val,
87                                                      const jerry_char_t **name_p,
88                                                      const jerry_length_t name_cnt,
89                                                      const jerryx_arg_t *c_arg_p,
90                                                      jerry_length_t c_arg_cnt);
91jerry_value_t jerryx_arg_transform_array (const jerry_value_t array_val,
92                                          const jerryx_arg_t *c_arg_p,
93                                          jerry_length_t c_arg_cnt);
94
95/**
96 * Indicates whether an argument is allowed to be coerced into the expected JS type.
97 */
98typedef enum
99{
100  JERRYX_ARG_COERCE, /**< the transform inside will invoke toNumber, toBoolean or toString */
101  JERRYX_ARG_NO_COERCE /**< the type coercion is not allowed. */
102} jerryx_arg_coerce_t;
103
104/**
105 * Indicates whether an argument is optional or required.
106 */
107typedef enum
108{
109  /**
110   * The argument is optional. If the argument is `undefined` the transform is
111   * successful and `c_arg_p->dest` remains untouched.
112   */
113  JERRYX_ARG_OPTIONAL,
114  /**
115   * The argument is required. If the argument is `undefined` the transform
116   * will fail and `c_arg_p->dest` remains untouched.
117   */
118  JERRYX_ARG_REQUIRED
119} jerryx_arg_optional_t;
120
121/**
122 * Indicates the rounding policy which will be chosen to transform an integer.
123 */
124typedef enum
125{
126  JERRYX_ARG_ROUND, /**< round */
127  JERRYX_ARG_FLOOR, /**< floor */
128  JERRYX_ARG_CEIL /**< ceil */
129} jerryx_arg_round_t;
130
131/**
132 * Indicates the clamping policy which will be chosen to transform an integer.
133 * If the policy is NO_CLAMP, and the number is out of range,
134 * then the transformer will throw a range error.
135 */
136typedef enum
137{
138  JERRYX_ARG_CLAMP,/**< clamp the number when it is out of range */
139  JERRYX_ARG_NO_CLAMP /**< throw a range error */
140} jerryx_arg_clamp_t;
141
142/* Inline functions for initializing jerryx_arg_t */
143
144#define JERRYX_ARG_INTEGER(type) \
145  static inline jerryx_arg_t \
146  jerryx_arg_ ## type (type ## _t *dest, \
147                       jerryx_arg_round_t round_flag, \
148                       jerryx_arg_clamp_t clamp_flag, \
149                       jerryx_arg_coerce_t coerce_flag, \
150                       jerryx_arg_optional_t opt_flag);
151
152JERRYX_ARG_INTEGER (uint8)
153JERRYX_ARG_INTEGER (int8)
154JERRYX_ARG_INTEGER (uint16)
155JERRYX_ARG_INTEGER (int16)
156JERRYX_ARG_INTEGER (uint32)
157JERRYX_ARG_INTEGER (int32)
158
159#undef JERRYX_ARG_INTEGER
160
161static inline jerryx_arg_t
162jerryx_arg_number (double *dest, jerryx_arg_coerce_t coerce_flag, jerryx_arg_optional_t opt_flag);
163static inline jerryx_arg_t
164jerryx_arg_boolean (bool *dest, jerryx_arg_coerce_t coerce_flag, jerryx_arg_optional_t opt_flag);
165static inline jerryx_arg_t
166jerryx_arg_string (char *dest, uint32_t size, jerryx_arg_coerce_t coerce_flag, jerryx_arg_optional_t opt_flag);
167static inline jerryx_arg_t
168jerryx_arg_utf8_string (char *dest, uint32_t size, jerryx_arg_coerce_t coerce_flag, jerryx_arg_optional_t opt_flag);
169static inline jerryx_arg_t
170jerryx_arg_function (jerry_value_t *dest, jerryx_arg_optional_t opt_flag);
171static inline jerryx_arg_t
172jerryx_arg_native_pointer (void **dest, const jerry_object_native_info_t *info_p, jerryx_arg_optional_t opt_flag);
173static inline jerryx_arg_t
174jerryx_arg_ignore (void);
175static inline jerryx_arg_t
176jerryx_arg_custom (void *dest, uintptr_t extra_info, jerryx_arg_transform_func_t func);
177static inline jerryx_arg_t
178jerryx_arg_object_properties (const jerryx_arg_object_props_t *object_props_p, jerryx_arg_optional_t opt_flag);
179static inline jerryx_arg_t
180jerryx_arg_array (const jerryx_arg_array_items_t *array_items_p, jerryx_arg_optional_t opt_flag);
181
182jerry_value_t
183jerryx_arg_transform_optional (jerryx_arg_js_iterator_t *js_arg_iter_p,
184                               const jerryx_arg_t *c_arg_p,
185                               jerryx_arg_transform_func_t func);
186
187/* Helper functions for transform functions. */
188jerry_value_t jerryx_arg_js_iterator_pop (jerryx_arg_js_iterator_t *js_arg_iter_p);
189jerry_value_t jerryx_arg_js_iterator_restore (jerryx_arg_js_iterator_t *js_arg_iter_p);
190jerry_value_t jerryx_arg_js_iterator_peek (jerryx_arg_js_iterator_t *js_arg_iter_p);
191jerry_length_t jerryx_arg_js_iterator_index (jerryx_arg_js_iterator_t *js_arg_iter_p);
192
193#include "arg.impl.h"
194
195#ifdef __cplusplus
196}
197#endif /* __cplusplus */
198#endif /* !JERRYX_ARG_H */
199