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 | ||
af710487 | 39 | // insert module names and schemas for types; gather references to types and |
40 | // JSON encoding/decoding function information | |
41 | map<Common::Type*, JSON_Tokenizer> json_refs; | |
42 | modules->generate_json_schema(json, json_refs); | |
970ed795 EL |
43 | |
44 | // end of type definitions | |
45 | json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); | |
af710487 | 46 | |
47 | if (!json_refs.empty()) { | |
48 | // top-level "anyOf" structure containing references to the types the schema validates | |
49 | // don't insert an empty "anyOf" if there are no references | |
50 | json.put_next_token(JSON_TOKEN_NAME, "anyOf"); | |
51 | json.put_next_token(JSON_TOKEN_ARRAY_START, NULL); | |
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); | |
970ed795 | 64 | } |
970ed795 EL |
65 | |
66 | // top-level object end | |
67 | json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); | |
68 | } | |
69 | ||
70 | void Ttcn2Json::insert_schema(JSON_Tokenizer& to, JSON_Tokenizer& from) | |
71 | { | |
72 | json_token_t token = JSON_TOKEN_NONE; | |
73 | char* value_str = NULL; | |
74 | size_t value_len = 0; | |
75 | char temp = 0; | |
76 | ||
77 | do { | |
78 | from.get_next_token(&token, &value_str, &value_len); | |
79 | ||
80 | if (token == JSON_TOKEN_ERROR) { | |
81 | FATAL_ERROR("Ttcn2Json::insert_schema"); | |
82 | } | |
83 | ||
84 | if (value_str != NULL) { | |
85 | // put_next_token expects a null terminated string, save the next character | |
86 | // and set it to null | |
87 | temp = value_str[value_len]; | |
88 | value_str[value_len] = 0; | |
89 | } | |
90 | ||
91 | to.put_next_token(token, value_str); | |
92 | ||
93 | if (value_str != NULL) { | |
94 | // put the original character back to its place | |
95 | value_str[value_len] = temp; | |
96 | } | |
97 | } while (token != JSON_TOKEN_NONE); | |
98 | } | |
99 | ||
100 | } // namespace | |
101 |