1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation
2425bb815Sopenharmony_ci *
3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License.
5425bb815Sopenharmony_ci * You may obtain a copy of the License at
6425bb815Sopenharmony_ci *
7425bb815Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8425bb815Sopenharmony_ci *
9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS
11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and
13425bb815Sopenharmony_ci * limitations under the License.
14425bb815Sopenharmony_ci */
15425bb815Sopenharmony_ci
16425bb815Sopenharmony_ci#include <math.h>
17425bb815Sopenharmony_ci
18425bb815Sopenharmony_ci#include "jerryscript-ext/arg.h"
19425bb815Sopenharmony_ci#include "jerryscript.h"
20425bb815Sopenharmony_ci
21425bb815Sopenharmony_ci/**
22425bb815Sopenharmony_ci * The common function to deal with optional arguments.
23425bb815Sopenharmony_ci * The core transform function is provided by argument `func`.
24425bb815Sopenharmony_ci *
25425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
26425bb815Sopenharmony_ci *         jerry error: the transformer fails.
27425bb815Sopenharmony_ci */
28425bb815Sopenharmony_cijerry_value_t
29425bb815Sopenharmony_cijerryx_arg_transform_optional (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
30425bb815Sopenharmony_ci                               const jerryx_arg_t *c_arg_p, /**< native arg */
31425bb815Sopenharmony_ci                               jerryx_arg_transform_func_t func) /**< the core transform function */
32425bb815Sopenharmony_ci{
33425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_peek (js_arg_iter_p);
34425bb815Sopenharmony_ci
35425bb815Sopenharmony_ci  if (jerry_value_is_undefined (js_arg))
36425bb815Sopenharmony_ci  {
37425bb815Sopenharmony_ci    return jerryx_arg_js_iterator_pop (js_arg_iter_p);
38425bb815Sopenharmony_ci  }
39425bb815Sopenharmony_ci
40425bb815Sopenharmony_ci  return func (js_arg_iter_p, c_arg_p);
41425bb815Sopenharmony_ci} /* jerryx_arg_transform_optional */
42425bb815Sopenharmony_ci
43425bb815Sopenharmony_ci/**
44425bb815Sopenharmony_ci * The common part in transforming a JS argument to a number (double or certain int) type.
45425bb815Sopenharmony_ci * Type coercion is not allowed.
46425bb815Sopenharmony_ci *
47425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
48425bb815Sopenharmony_ci *         jerry error: the transformer fails.
49425bb815Sopenharmony_ci */
50425bb815Sopenharmony_cistatic jerry_value_t
51425bb815Sopenharmony_cijerryx_arg_transform_number_strict_common (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
52425bb815Sopenharmony_ci                                           double *number_p) /**< [out] the number in JS arg */
53425bb815Sopenharmony_ci{
54425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
55425bb815Sopenharmony_ci
56425bb815Sopenharmony_ci  if (!jerry_value_is_number (js_arg))
57425bb815Sopenharmony_ci  {
58425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
59425bb815Sopenharmony_ci                               (jerry_char_t *) "It is not a number.");
60425bb815Sopenharmony_ci  }
61425bb815Sopenharmony_ci
62425bb815Sopenharmony_ci  *number_p = jerry_get_number_value (js_arg);
63425bb815Sopenharmony_ci
64425bb815Sopenharmony_ci  return jerry_create_undefined ();
65425bb815Sopenharmony_ci} /* jerryx_arg_transform_number_strict_common */
66425bb815Sopenharmony_ci
67425bb815Sopenharmony_ci/**
68425bb815Sopenharmony_ci * The common part in transforming a JS argument to a number (double or certain int) type.
69425bb815Sopenharmony_ci * Type coercion is allowed.
70425bb815Sopenharmony_ci *
71425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
72425bb815Sopenharmony_ci *         jerry error: the transformer fails.
73425bb815Sopenharmony_ci */
74425bb815Sopenharmony_cistatic jerry_value_t
75425bb815Sopenharmony_cijerryx_arg_transform_number_common (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
76425bb815Sopenharmony_ci                                    double *number_p) /**< [out] the number in JS arg */
77425bb815Sopenharmony_ci{
78425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
79425bb815Sopenharmony_ci
80425bb815Sopenharmony_ci  jerry_value_t to_number = jerry_value_to_number (js_arg);
81425bb815Sopenharmony_ci
82425bb815Sopenharmony_ci  if (jerry_value_is_error (to_number))
83425bb815Sopenharmony_ci  {
84425bb815Sopenharmony_ci    jerry_release_value (to_number);
85425bb815Sopenharmony_ci
86425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
87425bb815Sopenharmony_ci                               (jerry_char_t *) "It can not be converted to a number.");
88425bb815Sopenharmony_ci  }
89425bb815Sopenharmony_ci
90425bb815Sopenharmony_ci  *number_p = jerry_get_number_value (to_number);
91425bb815Sopenharmony_ci  jerry_release_value (to_number);
92425bb815Sopenharmony_ci
93425bb815Sopenharmony_ci  return jerry_create_undefined ();
94425bb815Sopenharmony_ci} /* jerryx_arg_transform_number_common */
95425bb815Sopenharmony_ci
96425bb815Sopenharmony_ci/**
97425bb815Sopenharmony_ci * Transform a JS argument to a double. Type coercion is not allowed.
98425bb815Sopenharmony_ci *
99425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
100425bb815Sopenharmony_ci *         jerry error: the transformer fails.
101425bb815Sopenharmony_ci */
102425bb815Sopenharmony_cijerry_value_t
103425bb815Sopenharmony_cijerryx_arg_transform_number_strict (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
104425bb815Sopenharmony_ci                                    const jerryx_arg_t *c_arg_p) /**< the native arg */
105425bb815Sopenharmony_ci{
106425bb815Sopenharmony_ci  return jerryx_arg_transform_number_strict_common (js_arg_iter_p, c_arg_p->dest);
107425bb815Sopenharmony_ci} /* jerryx_arg_transform_number_strict */
108425bb815Sopenharmony_ci
109425bb815Sopenharmony_ci/**
110425bb815Sopenharmony_ci * Transform a JS argument to a double. Type coercion is allowed.
111425bb815Sopenharmony_ci *
112425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
113425bb815Sopenharmony_ci *         jerry error: the transformer fails.
114425bb815Sopenharmony_ci */
115425bb815Sopenharmony_cijerry_value_t
116425bb815Sopenharmony_cijerryx_arg_transform_number (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
117425bb815Sopenharmony_ci                             const jerryx_arg_t *c_arg_p) /**< the native arg */
118425bb815Sopenharmony_ci{
119425bb815Sopenharmony_ci  return jerryx_arg_transform_number_common (js_arg_iter_p, c_arg_p->dest);
120425bb815Sopenharmony_ci} /* jerryx_arg_transform_number */
121425bb815Sopenharmony_ci
122425bb815Sopenharmony_ci/**
123425bb815Sopenharmony_ci * Helper function to process a double number before converting it
124425bb815Sopenharmony_ci * to an integer.
125425bb815Sopenharmony_ci *
126425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
127425bb815Sopenharmony_ci *         jerry error: the transformer fails.
128425bb815Sopenharmony_ci */
129425bb815Sopenharmony_cistatic jerry_value_t
130425bb815Sopenharmony_cijerryx_arg_helper_process_double (double *d, /**< [in, out] the number to be processed */
131425bb815Sopenharmony_ci                                  double min, /**< the min value for clamping */
132425bb815Sopenharmony_ci                                  double max, /**< the max value for clamping */
133425bb815Sopenharmony_ci                                  jerryx_arg_int_option_t option) /**< the converting policies */
134425bb815Sopenharmony_ci{
135425bb815Sopenharmony_ci  if (isnan (*d))
136425bb815Sopenharmony_ci  {
137425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
138425bb815Sopenharmony_ci                               (jerry_char_t *) "The number is NaN.");
139425bb815Sopenharmony_ci  }
140425bb815Sopenharmony_ci
141425bb815Sopenharmony_ci  if (option.clamp == JERRYX_ARG_NO_CLAMP)
142425bb815Sopenharmony_ci  {
143425bb815Sopenharmony_ci    if (*d > max || *d < min)
144425bb815Sopenharmony_ci    {
145425bb815Sopenharmony_ci      return jerry_create_error (JERRY_ERROR_TYPE,
146425bb815Sopenharmony_ci                                 (jerry_char_t *) "The number is out of range.");
147425bb815Sopenharmony_ci    }
148425bb815Sopenharmony_ci  }
149425bb815Sopenharmony_ci  else
150425bb815Sopenharmony_ci  {
151425bb815Sopenharmony_ci    *d = *d < min ? min : *d;
152425bb815Sopenharmony_ci    *d = *d > max ? max : *d;
153425bb815Sopenharmony_ci  }
154425bb815Sopenharmony_ci
155425bb815Sopenharmony_ci  if (option.round == JERRYX_ARG_ROUND)
156425bb815Sopenharmony_ci  {
157425bb815Sopenharmony_ci    *d = (*d >= 0.0) ? floor (*d + 0.5) : ceil (*d - 0.5);
158425bb815Sopenharmony_ci  }
159425bb815Sopenharmony_ci  else if (option.round == JERRYX_ARG_FLOOR)
160425bb815Sopenharmony_ci  {
161425bb815Sopenharmony_ci    *d = floor (*d);
162425bb815Sopenharmony_ci  }
163425bb815Sopenharmony_ci  else
164425bb815Sopenharmony_ci  {
165425bb815Sopenharmony_ci    *d = ceil (*d);
166425bb815Sopenharmony_ci  }
167425bb815Sopenharmony_ci
168425bb815Sopenharmony_ci  return jerry_create_undefined ();
169425bb815Sopenharmony_ci} /* jerryx_arg_helper_process_double */
170425bb815Sopenharmony_ci
171425bb815Sopenharmony_ci/**
172425bb815Sopenharmony_ci * Use the macro to define thr transform functions for int type.
173425bb815Sopenharmony_ci */
174425bb815Sopenharmony_ci#define JERRYX_ARG_TRANSFORM_FUNC_FOR_INT_TEMPLATE(type, suffix, min, max) \
175425bb815Sopenharmony_ci  jerry_value_t jerryx_arg_transform_ ## type ## suffix (jerryx_arg_js_iterator_t *js_arg_iter_p, \
176425bb815Sopenharmony_ci                                                         const jerryx_arg_t *c_arg_p) \
177425bb815Sopenharmony_ci  { \
178425bb815Sopenharmony_ci    double tmp = 0.0; \
179425bb815Sopenharmony_ci    jerry_value_t rv = jerryx_arg_transform_number ## suffix ## _common (js_arg_iter_p, &tmp); \
180425bb815Sopenharmony_ci    if (jerry_value_is_error (rv)) \
181425bb815Sopenharmony_ci    { \
182425bb815Sopenharmony_ci      return rv; \
183425bb815Sopenharmony_ci    } \
184425bb815Sopenharmony_ci    jerry_release_value (rv); \
185425bb815Sopenharmony_ci    union \
186425bb815Sopenharmony_ci    { \
187425bb815Sopenharmony_ci      jerryx_arg_int_option_t int_option; \
188425bb815Sopenharmony_ci      uintptr_t extra_info; \
189425bb815Sopenharmony_ci    } u = { .extra_info = c_arg_p->extra_info }; \
190425bb815Sopenharmony_ci    rv = jerryx_arg_helper_process_double (&tmp, min, max, u.int_option); \
191425bb815Sopenharmony_ci    if (jerry_value_is_error (rv)) \
192425bb815Sopenharmony_ci    { \
193425bb815Sopenharmony_ci      return rv; \
194425bb815Sopenharmony_ci    } \
195425bb815Sopenharmony_ci    *(type ## _t *) c_arg_p->dest = (type ## _t) tmp; \
196425bb815Sopenharmony_ci    return rv; \
197425bb815Sopenharmony_ci  }
198425bb815Sopenharmony_ci
199425bb815Sopenharmony_ci#define JERRYX_ARG_TRANSFORM_FUNC_FOR_INT(type, min, max) \
200425bb815Sopenharmony_ci  JERRYX_ARG_TRANSFORM_FUNC_FOR_INT_TEMPLATE (type, _strict, min, max) \
201425bb815Sopenharmony_ci  JERRYX_ARG_TRANSFORM_FUNC_FOR_INT_TEMPLATE (type, , min, max)
202425bb815Sopenharmony_ci
203425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_FUNC_FOR_INT (uint8, 0, UINT8_MAX)
204425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_FUNC_FOR_INT (int8, INT8_MIN, INT8_MAX)
205425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_FUNC_FOR_INT (uint16, 0, UINT16_MAX)
206425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_FUNC_FOR_INT (int16, INT16_MIN, INT16_MAX)
207425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_FUNC_FOR_INT (uint32, 0, UINT32_MAX)
208425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_FUNC_FOR_INT (int32, INT32_MIN, INT32_MAX)
209425bb815Sopenharmony_ci
210425bb815Sopenharmony_ci#undef JERRYX_ARG_TRANSFORM_FUNC_FOR_INT_TEMPLATE
211425bb815Sopenharmony_ci#undef JERRYX_ARG_TRANSFORM_FUNC_FOR_INT
212425bb815Sopenharmony_ci/**
213425bb815Sopenharmony_ci * Transform a JS argument to a boolean. Type coercion is not allowed.
214425bb815Sopenharmony_ci *
215425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
216425bb815Sopenharmony_ci *         jerry error: the transformer fails.
217425bb815Sopenharmony_ci */
218425bb815Sopenharmony_cijerry_value_t
219425bb815Sopenharmony_cijerryx_arg_transform_boolean_strict (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
220425bb815Sopenharmony_ci                                     const jerryx_arg_t *c_arg_p) /**< the native arg */
221425bb815Sopenharmony_ci{
222425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
223425bb815Sopenharmony_ci
224425bb815Sopenharmony_ci  if (!jerry_value_is_boolean (js_arg))
225425bb815Sopenharmony_ci  {
226425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
227425bb815Sopenharmony_ci                               (jerry_char_t *) "It is not a boolean.");
228425bb815Sopenharmony_ci  }
229425bb815Sopenharmony_ci
230425bb815Sopenharmony_ci  bool *dest = c_arg_p->dest;
231425bb815Sopenharmony_ci  *dest = jerry_get_boolean_value (js_arg);
232425bb815Sopenharmony_ci
233425bb815Sopenharmony_ci  return jerry_create_undefined ();
234425bb815Sopenharmony_ci} /* jerryx_arg_transform_boolean_strict */
235425bb815Sopenharmony_ci
236425bb815Sopenharmony_ci/**
237425bb815Sopenharmony_ci * Transform a JS argument to a boolean. Type coercion is allowed.
238425bb815Sopenharmony_ci *
239425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
240425bb815Sopenharmony_ci *         jerry error: the transformer fails.
241425bb815Sopenharmony_ci */
242425bb815Sopenharmony_cijerry_value_t
243425bb815Sopenharmony_cijerryx_arg_transform_boolean (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
244425bb815Sopenharmony_ci                              const jerryx_arg_t *c_arg_p) /**< the native arg */
245425bb815Sopenharmony_ci{
246425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
247425bb815Sopenharmony_ci
248425bb815Sopenharmony_ci  bool to_boolean = jerry_value_to_boolean (js_arg);
249425bb815Sopenharmony_ci
250425bb815Sopenharmony_ci  bool *dest = c_arg_p->dest;
251425bb815Sopenharmony_ci  *dest = to_boolean;
252425bb815Sopenharmony_ci
253425bb815Sopenharmony_ci  return jerry_create_undefined ();
254425bb815Sopenharmony_ci} /* jerryx_arg_transform_boolean */
255425bb815Sopenharmony_ci
256425bb815Sopenharmony_ci/**
257425bb815Sopenharmony_ci * The common routine for string transformer.
258425bb815Sopenharmony_ci * It works for both CESU-8 and UTF-8 string.
259425bb815Sopenharmony_ci *
260425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
261425bb815Sopenharmony_ci *         jerry error: the transformer fails.
262425bb815Sopenharmony_ci */
263425bb815Sopenharmony_cistatic jerry_value_t
264425bb815Sopenharmony_cijerryx_arg_string_to_buffer_common_routine (jerry_value_t js_arg, /**< JS arg */
265425bb815Sopenharmony_ci                                            const jerryx_arg_t *c_arg_p, /**< native arg */
266425bb815Sopenharmony_ci                                            bool is_utf8) /**< whether it is UTF-8 string */
267425bb815Sopenharmony_ci{
268425bb815Sopenharmony_ci  jerry_char_t *target_p = (jerry_char_t *) c_arg_p->dest;
269425bb815Sopenharmony_ci  jerry_size_t target_buf_size = (jerry_size_t) c_arg_p->extra_info;
270425bb815Sopenharmony_ci  jerry_size_t size;
271425bb815Sopenharmony_ci  jerry_length_t len;
272425bb815Sopenharmony_ci
273425bb815Sopenharmony_ci  if (!is_utf8)
274425bb815Sopenharmony_ci  {
275425bb815Sopenharmony_ci    size = jerry_string_to_char_buffer (js_arg,
276425bb815Sopenharmony_ci                                        target_p,
277425bb815Sopenharmony_ci                                        target_buf_size);
278425bb815Sopenharmony_ci    len = jerry_get_string_length (js_arg);
279425bb815Sopenharmony_ci  }
280425bb815Sopenharmony_ci  else
281425bb815Sopenharmony_ci  {
282425bb815Sopenharmony_ci    size = jerry_string_to_utf8_char_buffer (js_arg,
283425bb815Sopenharmony_ci                                             target_p,
284425bb815Sopenharmony_ci                                             target_buf_size);
285425bb815Sopenharmony_ci    len = jerry_get_utf8_string_length (js_arg);
286425bb815Sopenharmony_ci  }
287425bb815Sopenharmony_ci
288425bb815Sopenharmony_ci  if ((size == target_buf_size) || (size == 0 && len != 0))
289425bb815Sopenharmony_ci  {
290425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
291425bb815Sopenharmony_ci                               (jerry_char_t *) "Buffer size is not large enough.");
292425bb815Sopenharmony_ci  }
293425bb815Sopenharmony_ci
294425bb815Sopenharmony_ci  target_p[size] = '\0';
295425bb815Sopenharmony_ci
296425bb815Sopenharmony_ci  return jerry_create_undefined ();
297425bb815Sopenharmony_ci} /* jerryx_arg_string_to_buffer_common_routine */
298425bb815Sopenharmony_ci
299425bb815Sopenharmony_ci/**
300425bb815Sopenharmony_ci * Transform a JS argument to a UTF-8/CESU-8 char array. Type coercion is not allowed.
301425bb815Sopenharmony_ci *
302425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
303425bb815Sopenharmony_ci *         jerry error: the transformer fails.
304425bb815Sopenharmony_ci */
305425bb815Sopenharmony_cistatic jerry_value_t
306425bb815Sopenharmony_cijerryx_arg_transform_string_strict_common (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
307425bb815Sopenharmony_ci                                           const jerryx_arg_t *c_arg_p, /**< the native arg */
308425bb815Sopenharmony_ci                                           bool is_utf8) /**< whether it is a UTF-8 string */
309425bb815Sopenharmony_ci{
310425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
311425bb815Sopenharmony_ci
312425bb815Sopenharmony_ci  if (!jerry_value_is_string (js_arg))
313425bb815Sopenharmony_ci  {
314425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
315425bb815Sopenharmony_ci                               (jerry_char_t *) "It is not a string.");
316425bb815Sopenharmony_ci  }
317425bb815Sopenharmony_ci
318425bb815Sopenharmony_ci  return jerryx_arg_string_to_buffer_common_routine (js_arg, c_arg_p, is_utf8);
319425bb815Sopenharmony_ci} /* jerryx_arg_transform_string_strict_common */
320425bb815Sopenharmony_ci
321425bb815Sopenharmony_ci/**
322425bb815Sopenharmony_ci * Transform a JS argument to a UTF-8/CESU-8 char array. Type coercion is allowed.
323425bb815Sopenharmony_ci *
324425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
325425bb815Sopenharmony_ci *         jerry error: the transformer fails.
326425bb815Sopenharmony_ci */
327425bb815Sopenharmony_cistatic jerry_value_t
328425bb815Sopenharmony_cijerryx_arg_transform_string_common (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
329425bb815Sopenharmony_ci                                    const jerryx_arg_t *c_arg_p, /**< the native arg */
330425bb815Sopenharmony_ci                                    bool is_utf8) /**< whether it is a UTF-8 string */
331425bb815Sopenharmony_ci{
332425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
333425bb815Sopenharmony_ci
334425bb815Sopenharmony_ci  jerry_value_t to_string = jerry_value_to_string (js_arg);
335425bb815Sopenharmony_ci
336425bb815Sopenharmony_ci  if (jerry_value_is_error (to_string))
337425bb815Sopenharmony_ci  {
338425bb815Sopenharmony_ci    jerry_release_value (to_string);
339425bb815Sopenharmony_ci
340425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
341425bb815Sopenharmony_ci                               (jerry_char_t *) "It can not be converted to a string.");
342425bb815Sopenharmony_ci  }
343425bb815Sopenharmony_ci
344425bb815Sopenharmony_ci  jerry_value_t ret = jerryx_arg_string_to_buffer_common_routine (to_string, c_arg_p, is_utf8);
345425bb815Sopenharmony_ci  jerry_release_value (to_string);
346425bb815Sopenharmony_ci
347425bb815Sopenharmony_ci  return ret;
348425bb815Sopenharmony_ci} /* jerryx_arg_transform_string_common */
349425bb815Sopenharmony_ci
350425bb815Sopenharmony_ci/**
351425bb815Sopenharmony_ci * Transform a JS argument to a cesu8 char array. Type coercion is not allowed.
352425bb815Sopenharmony_ci *
353425bb815Sopenharmony_ci * Note:
354425bb815Sopenharmony_ci *      returned value must be freed with jerry_release_value, when it is no longer needed.
355425bb815Sopenharmony_ci *
356425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
357425bb815Sopenharmony_ci *         jerry error: the transformer fails.
358425bb815Sopenharmony_ci */
359425bb815Sopenharmony_cijerry_value_t
360425bb815Sopenharmony_cijerryx_arg_transform_string_strict (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
361425bb815Sopenharmony_ci                                    const jerryx_arg_t *c_arg_p) /**< the native arg */
362425bb815Sopenharmony_ci{
363425bb815Sopenharmony_ci  return jerryx_arg_transform_string_strict_common (js_arg_iter_p, c_arg_p, false);
364425bb815Sopenharmony_ci} /* jerryx_arg_transform_string_strict */
365425bb815Sopenharmony_ci
366425bb815Sopenharmony_ci/**
367425bb815Sopenharmony_ci * Transform a JS argument to a utf8 char array. Type coercion is not allowed.
368425bb815Sopenharmony_ci *
369425bb815Sopenharmony_ci * Note:
370425bb815Sopenharmony_ci *      returned value must be freed with jerry_release_value, when it is no longer needed.
371425bb815Sopenharmony_ci *
372425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
373425bb815Sopenharmony_ci *         jerry error: the transformer fails.
374425bb815Sopenharmony_ci */
375425bb815Sopenharmony_cijerry_value_t
376425bb815Sopenharmony_cijerryx_arg_transform_utf8_string_strict (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
377425bb815Sopenharmony_ci                                         const jerryx_arg_t *c_arg_p) /**< the native arg */
378425bb815Sopenharmony_ci{
379425bb815Sopenharmony_ci  return jerryx_arg_transform_string_strict_common (js_arg_iter_p, c_arg_p, true);
380425bb815Sopenharmony_ci} /* jerryx_arg_transform_utf8_string_strict */
381425bb815Sopenharmony_ci
382425bb815Sopenharmony_ci/**
383425bb815Sopenharmony_ci * Transform a JS argument to a cesu8 char array. Type coercion is allowed.
384425bb815Sopenharmony_ci *
385425bb815Sopenharmony_ci * Note:
386425bb815Sopenharmony_ci *      returned value must be freed with jerry_release_value, when it is no longer needed.
387425bb815Sopenharmony_ci *
388425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
389425bb815Sopenharmony_ci *         jerry error: the transformer fails.
390425bb815Sopenharmony_ci */
391425bb815Sopenharmony_cijerry_value_t
392425bb815Sopenharmony_cijerryx_arg_transform_string (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
393425bb815Sopenharmony_ci                             const jerryx_arg_t *c_arg_p) /**< the native arg */
394425bb815Sopenharmony_ci{
395425bb815Sopenharmony_ci  return jerryx_arg_transform_string_common (js_arg_iter_p, c_arg_p, false);
396425bb815Sopenharmony_ci} /* jerryx_arg_transform_string */
397425bb815Sopenharmony_ci
398425bb815Sopenharmony_ci/**
399425bb815Sopenharmony_ci * Transform a JS argument to a utf8 char array. Type coercion is allowed.
400425bb815Sopenharmony_ci *
401425bb815Sopenharmony_ci * Note:
402425bb815Sopenharmony_ci *      returned value must be freed with jerry_release_value, when it is no longer needed.
403425bb815Sopenharmony_ci *
404425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
405425bb815Sopenharmony_ci *         jerry error: the transformer fails.
406425bb815Sopenharmony_ci */
407425bb815Sopenharmony_cijerry_value_t
408425bb815Sopenharmony_cijerryx_arg_transform_utf8_string (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
409425bb815Sopenharmony_ci                                  const jerryx_arg_t *c_arg_p) /**< the native arg */
410425bb815Sopenharmony_ci{
411425bb815Sopenharmony_ci  return jerryx_arg_transform_string_common (js_arg_iter_p, c_arg_p, true);
412425bb815Sopenharmony_ci} /* jerryx_arg_transform_utf8_string */
413425bb815Sopenharmony_ci
414425bb815Sopenharmony_ci/**
415425bb815Sopenharmony_ci * Check whether the JS argument is jerry function, if so, assign to the native argument.
416425bb815Sopenharmony_ci *
417425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
418425bb815Sopenharmony_ci *         jerry error: the transformer fails.
419425bb815Sopenharmony_ci */
420425bb815Sopenharmony_cijerry_value_t
421425bb815Sopenharmony_cijerryx_arg_transform_function (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
422425bb815Sopenharmony_ci                               const jerryx_arg_t *c_arg_p) /**< the native arg */
423425bb815Sopenharmony_ci{
424425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
425425bb815Sopenharmony_ci
426425bb815Sopenharmony_ci  if (!jerry_value_is_function (js_arg))
427425bb815Sopenharmony_ci  {
428425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
429425bb815Sopenharmony_ci                               (jerry_char_t *) "It is not a function.");
430425bb815Sopenharmony_ci  }
431425bb815Sopenharmony_ci
432425bb815Sopenharmony_ci  jerry_value_t *func_p = c_arg_p->dest;
433425bb815Sopenharmony_ci  *func_p = jerry_acquire_value (js_arg);
434425bb815Sopenharmony_ci
435425bb815Sopenharmony_ci  return jerry_create_undefined ();
436425bb815Sopenharmony_ci} /* jerryx_arg_transform_function */
437425bb815Sopenharmony_ci
438425bb815Sopenharmony_ci/**
439425bb815Sopenharmony_ci * Check whether the native pointer has the expected type info.
440425bb815Sopenharmony_ci * If so, assign it to the native argument.
441425bb815Sopenharmony_ci *
442425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
443425bb815Sopenharmony_ci *         jerry error: the transformer fails.
444425bb815Sopenharmony_ci */
445425bb815Sopenharmony_cijerry_value_t
446425bb815Sopenharmony_cijerryx_arg_transform_native_pointer (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
447425bb815Sopenharmony_ci                                     const jerryx_arg_t *c_arg_p) /**< the native arg */
448425bb815Sopenharmony_ci{
449425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
450425bb815Sopenharmony_ci
451425bb815Sopenharmony_ci  if (!jerry_value_is_object (js_arg))
452425bb815Sopenharmony_ci  {
453425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
454425bb815Sopenharmony_ci                               (jerry_char_t *) "It is not an object.");
455425bb815Sopenharmony_ci  }
456425bb815Sopenharmony_ci
457425bb815Sopenharmony_ci  const jerry_object_native_info_t *expected_info_p;
458425bb815Sopenharmony_ci  expected_info_p = (const jerry_object_native_info_t *) c_arg_p->extra_info;
459425bb815Sopenharmony_ci  void **ptr_p = (void **) c_arg_p->dest;
460425bb815Sopenharmony_ci  bool is_ok = jerry_get_object_native_pointer (js_arg, ptr_p, expected_info_p);
461425bb815Sopenharmony_ci
462425bb815Sopenharmony_ci  if (!is_ok)
463425bb815Sopenharmony_ci  {
464425bb815Sopenharmony_ci    return jerry_create_error (JERRY_ERROR_TYPE,
465425bb815Sopenharmony_ci                               (jerry_char_t *) "The object has no native pointer or type does not match.");
466425bb815Sopenharmony_ci  }
467425bb815Sopenharmony_ci
468425bb815Sopenharmony_ci  return jerry_create_undefined ();
469425bb815Sopenharmony_ci} /* jerryx_arg_transform_native_pointer */
470425bb815Sopenharmony_ci
471425bb815Sopenharmony_ci/**
472425bb815Sopenharmony_ci * Check whether the JS object's properties have expected types, and transform them into native args.
473425bb815Sopenharmony_ci *
474425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
475425bb815Sopenharmony_ci *         jerry error: the transformer fails.
476425bb815Sopenharmony_ci */
477425bb815Sopenharmony_cijerry_value_t
478425bb815Sopenharmony_cijerryx_arg_transform_object_props (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
479425bb815Sopenharmony_ci                                   const jerryx_arg_t *c_arg_p) /**< the native arg */
480425bb815Sopenharmony_ci{
481425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
482425bb815Sopenharmony_ci
483425bb815Sopenharmony_ci  const jerryx_arg_object_props_t *object_props = (const jerryx_arg_object_props_t *) c_arg_p->extra_info;
484425bb815Sopenharmony_ci
485425bb815Sopenharmony_ci  return jerryx_arg_transform_object_properties (js_arg,
486425bb815Sopenharmony_ci                                                 object_props->name_p,
487425bb815Sopenharmony_ci                                                 object_props->name_cnt,
488425bb815Sopenharmony_ci                                                 object_props->c_arg_p,
489425bb815Sopenharmony_ci                                                 object_props->c_arg_cnt);
490425bb815Sopenharmony_ci} /* jerryx_arg_transform_object_props */
491425bb815Sopenharmony_ci
492425bb815Sopenharmony_ci/**
493425bb815Sopenharmony_ci * Check whether the JS array's items have expected types, and transform them into native args.
494425bb815Sopenharmony_ci *
495425bb815Sopenharmony_ci * @return jerry undefined: the transformer passes,
496425bb815Sopenharmony_ci *         jerry error: the transformer fails.
497425bb815Sopenharmony_ci */
498425bb815Sopenharmony_cijerry_value_t
499425bb815Sopenharmony_cijerryx_arg_transform_array_items (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
500425bb815Sopenharmony_ci                                  const jerryx_arg_t *c_arg_p) /**< the native arg */
501425bb815Sopenharmony_ci{
502425bb815Sopenharmony_ci  jerry_value_t js_arg = jerryx_arg_js_iterator_pop (js_arg_iter_p);
503425bb815Sopenharmony_ci
504425bb815Sopenharmony_ci  const jerryx_arg_array_items_t *array_items_p = (const jerryx_arg_array_items_t *) c_arg_p->extra_info;
505425bb815Sopenharmony_ci
506425bb815Sopenharmony_ci  return jerryx_arg_transform_array (js_arg,
507425bb815Sopenharmony_ci                                     array_items_p->c_arg_p,
508425bb815Sopenharmony_ci                                     array_items_p->c_arg_cnt);
509425bb815Sopenharmony_ci} /* jerryx_arg_transform_array_items */
510425bb815Sopenharmony_ci
511425bb815Sopenharmony_ci/**
512425bb815Sopenharmony_ci * Define transformer for optional argument.
513425bb815Sopenharmony_ci */
514425bb815Sopenharmony_ci#define JERRYX_ARG_TRANSFORM_OPTIONAL(type) \
515425bb815Sopenharmony_ci  jerry_value_t \
516425bb815Sopenharmony_ci  jerryx_arg_transform_ ## type ## _optional (jerryx_arg_js_iterator_t *js_arg_iter_p, \
517425bb815Sopenharmony_ci                                              const jerryx_arg_t *c_arg_p) \
518425bb815Sopenharmony_ci  { \
519425bb815Sopenharmony_ci    return jerryx_arg_transform_optional (js_arg_iter_p, c_arg_p, jerryx_arg_transform_ ## type); \
520425bb815Sopenharmony_ci  }
521425bb815Sopenharmony_ci
522425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (number)
523425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (number_strict)
524425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (boolean)
525425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (boolean_strict)
526425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (string)
527425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (string_strict)
528425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (utf8_string)
529425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (utf8_string_strict)
530425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (function)
531425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (native_pointer)
532425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (object_props)
533425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (array_items)
534425bb815Sopenharmony_ci
535425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (uint8)
536425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (uint16)
537425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (uint32)
538425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (int8)
539425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (int16)
540425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (int32)
541425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (int8_strict)
542425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (int16_strict)
543425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (int32_strict)
544425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (uint8_strict)
545425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (uint16_strict)
546425bb815Sopenharmony_ciJERRYX_ARG_TRANSFORM_OPTIONAL (uint32_strict)
547425bb815Sopenharmony_ci
548425bb815Sopenharmony_ci#undef JERRYX_ARG_TRANSFORM_OPTIONAL
549425bb815Sopenharmony_ci
550425bb815Sopenharmony_ci/**
551425bb815Sopenharmony_ci * Ignore the JS argument.
552425bb815Sopenharmony_ci *
553425bb815Sopenharmony_ci * @return jerry undefined
554425bb815Sopenharmony_ci */
555425bb815Sopenharmony_cijerry_value_t
556425bb815Sopenharmony_cijerryx_arg_transform_ignore (jerryx_arg_js_iterator_t *js_arg_iter_p, /**< available JS args */
557425bb815Sopenharmony_ci                             const jerryx_arg_t *c_arg_p) /**< the native arg */
558425bb815Sopenharmony_ci{
559425bb815Sopenharmony_ci  (void) js_arg_iter_p; /* unused */
560425bb815Sopenharmony_ci  (void) c_arg_p; /* unused */
561425bb815Sopenharmony_ci
562425bb815Sopenharmony_ci  return jerry_create_undefined ();
563425bb815Sopenharmony_ci} /* jerryx_arg_transform_ignore */
564