1 /*
2  * QuickJS: binary JSON module (test only)
3  *
4  * Copyright (c) 2017-2019 Fabrice Bellard
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 #include "../quickjs-libc.h"
25 #include "../cutils.h"
26 
js_bjson_read(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)27 static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val,
28                              int argc, JSValueConst *argv)
29 {
30     uint8_t *buf;
31     uint64_t pos, len;
32     JSValue obj;
33     size_t size;
34     int flags;
35 
36     if (JS_ToIndex(ctx, &pos, argv[1]))
37         return JS_EXCEPTION;
38     if (JS_ToIndex(ctx, &len, argv[2]))
39         return JS_EXCEPTION;
40     buf = JS_GetArrayBuffer(ctx, &size, argv[0]);
41     if (!buf)
42         return JS_EXCEPTION;
43     if (pos + len > size)
44         return JS_ThrowRangeError(ctx, "array buffer overflow");
45     flags = 0;
46     if (JS_ToBool(ctx, argv[3]))
47         flags |= JS_READ_OBJ_REFERENCE;
48     obj = JS_ReadObject(ctx, buf + pos, len, flags);
49     return obj;
50 }
51 
js_bjson_write(JSContext * ctx,JSValueConst this_val,int argc,JSValueConst * argv)52 static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val,
53                               int argc, JSValueConst *argv)
54 {
55     size_t len;
56     uint8_t *buf;
57     JSValue array;
58     int flags;
59 
60     flags = 0;
61     if (JS_ToBool(ctx, argv[1]))
62         flags |= JS_WRITE_OBJ_REFERENCE;
63     buf = JS_WriteObject(ctx, &len, argv[0], flags);
64     if (!buf)
65         return JS_EXCEPTION;
66     array = JS_NewArrayBufferCopy(ctx, buf, len);
67     js_free(ctx, buf);
68     return array;
69 }
70 
71 static const JSCFunctionListEntry js_bjson_funcs[] = {
72     JS_CFUNC_DEF("read", 4, js_bjson_read ),
73     JS_CFUNC_DEF("write", 2, js_bjson_write ),
74 };
75 
js_bjson_init(JSContext * ctx,JSModuleDef * m)76 static int js_bjson_init(JSContext *ctx, JSModuleDef *m)
77 {
78     return JS_SetModuleExportList(ctx, m, js_bjson_funcs,
79                                   countof(js_bjson_funcs));
80 }
81 
82 #ifdef JS_SHARED_LIBRARY
83 #define JS_INIT_MODULE js_init_module
84 #else
85 #define JS_INIT_MODULE js_init_module_bjson
86 #endif
87 
JS_INIT_MODULE(JSContext * ctx,const char * module_name)88 JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
89 {
90     JSModuleDef *m;
91     m = JS_NewCModule(ctx, module_name, js_bjson_init);
92     if (!m)
93         return NULL;
94     JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs));
95     return m;
96 }
97