Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | #include "Ttcn2Json.hh" |
2 | ||
3 | #include "compiler.h" | |
4 | ||
5 | #include "../AST.hh" | |
6 | #include "../../common/JSON_Tokenizer.hh" | |
7 | ||
8 | // forward declarations | |
9 | namespace Common { | |
10 | class Type; | |
11 | } | |
12 | ||
13 | namespace Ttcn { | |
14 | ||
15 | Ttcn2Json::Ttcn2Json(Common::Modules* p_modules, const char* p_schema_name) | |
16 | : modules(p_modules) | |
17 | { | |
18 | boolean is_temporary; | |
19 | FILE* file = open_output_file(p_schema_name, &is_temporary); | |
20 | ||
21 | JSON_Tokenizer json(true); | |
22 | ||
23 | create_schema(json); | |
24 | ||
25 | fprintf(file, "%s\n", json.get_buffer()); | |
26 | ||
27 | close_output_file(p_schema_name, file, is_temporary, 0); | |
28 | } | |
29 | ||
30 | void Ttcn2Json::create_schema(JSON_Tokenizer& json) | |
31 | { | |
32 | // top-level object start | |
33 | json.put_next_token(JSON_TOKEN_OBJECT_START, NULL); | |
34 | ||
35 | // start of type definitions | |
36 | json.put_next_token(JSON_TOKEN_NAME, "definitions"); | |
37 | json.put_next_token(JSON_TOKEN_OBJECT_START, NULL); | |
38 | ||
39 | // insert module names and schemas for types | |
40 | modules->add_types_to_json_schema(json); | |
41 | ||
42 | // end of type definitions | |
43 | json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); | |
44 | ||
45 | // top-level "anyOf" structure containing references to the types the schema validates | |
46 | json.put_next_token(JSON_TOKEN_NAME, "anyOf"); | |
47 | json.put_next_token(JSON_TOKEN_ARRAY_START, NULL); | |
48 | ||
49 | // gather type references and JSON encoding/decoding function data | |
50 | map<Common::Type*, JSON_Tokenizer> json_refs; | |
51 | modules->add_func_to_json_schema(json_refs); | |
52 | ||
53 | // close schema segments and add them to the main schema | |
54 | for (size_t i = 0; i < json_refs.size(); ++i) { | |
55 | JSON_Tokenizer* segment = json_refs.get_nth_elem(i); | |
56 | segment->put_next_token(JSON_TOKEN_OBJECT_END, NULL); | |
57 | insert_schema(json, *segment); | |
58 | delete segment; | |
59 | } | |
60 | json_refs.clear(); | |
61 | ||
62 | // end of the "anyOf" structure | |
63 | json.put_next_token(JSON_TOKEN_ARRAY_END, NULL); | |
64 | ||
65 | // top-level object end | |
66 | json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); | |
67 | } | |
68 | ||
69 | void Ttcn2Json::insert_schema(JSON_Tokenizer& to, JSON_Tokenizer& from) | |
70 | { | |
71 | json_token_t token = JSON_TOKEN_NONE; | |
72 | char* value_str = NULL; | |
73 | size_t value_len = 0; | |
74 | char temp = 0; | |
75 | ||
76 | do { | |
77 | from.get_next_token(&token, &value_str, &value_len); | |
78 | ||
79 | if (token == JSON_TOKEN_ERROR) { | |
80 | FATAL_ERROR("Ttcn2Json::insert_schema"); | |
81 | } | |
82 | ||
83 | if (value_str != NULL) { | |
84 | // put_next_token expects a null terminated string, save the next character | |
85 | // and set it to null | |
86 | temp = value_str[value_len]; | |
87 | value_str[value_len] = 0; | |
88 | } | |
89 | ||
90 | to.put_next_token(token, value_str); | |
91 | ||
92 | if (value_str != NULL) { | |
93 | // put the original character back to its place | |
94 | value_str[value_len] = temp; | |
95 | } | |
96 | } while (token != JSON_TOKEN_NONE); | |
97 | } | |
98 | ||
99 | } // namespace | |
100 |