1/**************************************************************************/
2/* json.h */
3/**************************************************************************/
4/* This file is part of: */
5/* GODOT ENGINE */
6/* https://godotengine.org */
7/**************************************************************************/
8/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10/* */
11/* Permission is hereby granted, free of charge, to any person obtaining */
12/* a copy of this software and associated documentation files (the */
13/* "Software"), to deal in the Software without restriction, including */
14/* without limitation the rights to use, copy, modify, merge, publish, */
15/* distribute, sublicense, and/or sell copies of the Software, and to */
16/* permit persons to whom the Software is furnished to do so, subject to */
17/* the following conditions: */
18/* */
19/* The above copyright notice and this permission notice shall be */
20/* included in all copies or substantial portions of the Software. */
21/* */
22/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29/**************************************************************************/
30
31#ifndef JSON_H
32#define JSON_H
33
34#include "core/io/resource.h"
35#include "core/io/resource_loader.h"
36#include "core/io/resource_saver.h"
37#include "core/variant/variant.h"
38
39class JSON : public Resource {
40 GDCLASS(JSON, Resource);
41
42 enum TokenType {
43 TK_CURLY_BRACKET_OPEN,
44 TK_CURLY_BRACKET_CLOSE,
45 TK_BRACKET_OPEN,
46 TK_BRACKET_CLOSE,
47 TK_IDENTIFIER,
48 TK_STRING,
49 TK_NUMBER,
50 TK_COLON,
51 TK_COMMA,
52 TK_EOF,
53 TK_MAX
54 };
55
56 enum Expecting {
57 EXPECT_OBJECT,
58 EXPECT_OBJECT_KEY,
59 EXPECT_COLON,
60 EXPECT_OBJECT_VALUE,
61 };
62
63 struct Token {
64 TokenType type;
65 Variant value;
66 };
67
68 String text;
69 Variant data;
70 String err_str;
71 int err_line = 0;
72
73 static const char *tk_name[];
74
75 static String _make_indent(const String &p_indent, int p_size);
76 static String _stringify(const Variant &p_var, const String &p_indent, int p_cur_indent, bool p_sort_keys, HashSet<const void *> &p_markers, bool p_full_precision = false);
77 static Error _get_token(const char32_t *p_str, int &index, int p_len, Token &r_token, int &line, String &r_err_str);
78 static Error _parse_value(Variant &value, Token &token, const char32_t *p_str, int &index, int p_len, int &line, int p_depth, String &r_err_str);
79 static Error _parse_array(Array &array, const char32_t *p_str, int &index, int p_len, int &line, int p_depth, String &r_err_str);
80 static Error _parse_object(Dictionary &object, const char32_t *p_str, int &index, int p_len, int &line, int p_depth, String &r_err_str);
81 static Error _parse_string(const String &p_json, Variant &r_ret, String &r_err_str, int &r_err_line);
82
83protected:
84 static void _bind_methods();
85
86public:
87 Error parse(const String &p_json_string, bool p_keep_text = false);
88 String get_parsed_text() const;
89
90 static String stringify(const Variant &p_var, const String &p_indent = "", bool p_sort_keys = true, bool p_full_precision = false);
91 static Variant parse_string(const String &p_json_string);
92
93 inline Variant get_data() const { return data; }
94 void set_data(const Variant &p_data);
95 inline int get_error_line() const { return err_line; }
96 inline String get_error_message() const { return err_str; }
97};
98
99class ResourceFormatLoaderJSON : public ResourceFormatLoader {
100public:
101 virtual Ref<Resource> load(const String &p_path, const String &p_original_path = "", Error *r_error = nullptr, bool p_use_sub_threads = false, float *r_progress = nullptr, CacheMode p_cache_mode = CACHE_MODE_REUSE);
102 virtual void get_recognized_extensions(List<String> *p_extensions) const;
103 virtual bool handles_type(const String &p_type) const;
104 virtual String get_resource_type(const String &p_path) const;
105};
106
107class ResourceFormatSaverJSON : public ResourceFormatSaver {
108public:
109 virtual Error save(const Ref<Resource> &p_resource, const String &p_path, uint32_t p_flags = 0);
110 virtual void get_recognized_extensions(const Ref<Resource> &p_resource, List<String> *p_extensions) const;
111 virtual bool recognize(const Ref<Resource> &p_resource) const;
112};
113
114#endif // JSON_H
115