Commit | Line | Data |
---|---|---|
3abe9331 | 1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2015 Ericsson Telecom AB | |
3 | // All rights reserved. This program and the accompanying materials | |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | ||
970ed795 EL |
9 | #include "Ttcn2Json.hh" |
10 | ||
11 | #include "compiler.h" | |
12 | ||
13 | #include "../AST.hh" | |
14 | #include "../../common/JSON_Tokenizer.hh" | |
15 | ||
16 | // forward declarations | |
17 | namespace Common { | |
18 | class Type; | |
19 | } | |
20 | ||
21 | namespace Ttcn { | |
22 | ||
23 | Ttcn2Json::Ttcn2Json(Common::Modules* p_modules, const char* p_schema_name) | |
24 | : modules(p_modules) | |
25 | { | |
26 | boolean is_temporary; | |
27 | FILE* file = open_output_file(p_schema_name, &is_temporary); | |
28 | ||
29 | JSON_Tokenizer json(true); | |
30 | ||
31 | create_schema(json); | |
32 | ||
33 | fprintf(file, "%s\n", json.get_buffer()); | |
34 | ||
35 | close_output_file(p_schema_name, file, is_temporary, 0); | |
36 | } | |
37 | ||
38 | void Ttcn2Json::create_schema(JSON_Tokenizer& json) | |
39 | { | |
40 | // top-level object start | |
41 | json.put_next_token(JSON_TOKEN_OBJECT_START, NULL); | |
42 | ||
3abe9331 | 43 | // insert the schema header |
44 | json.put_next_token(JSON_TOKEN_NAME, "$schema"); | |
45 | json.put_next_token(JSON_TOKEN_STRING, "\"http://json-schema.org/draft-04/schema#\""); | |
46 | ||
970ed795 EL |
47 | // start of type definitions |
48 | json.put_next_token(JSON_TOKEN_NAME, "definitions"); | |
49 | json.put_next_token(JSON_TOKEN_OBJECT_START, NULL); | |
50 | ||
af710487 | 51 | // insert module names and schemas for types; gather references to types and |
52 | // JSON encoding/decoding function information | |
53 | map<Common::Type*, JSON_Tokenizer> json_refs; | |
54 | modules->generate_json_schema(json, json_refs); | |
970ed795 EL |
55 | |
56 | // end of type definitions | |
57 | json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); | |
af710487 | 58 | |
59 | if (!json_refs.empty()) { | |
60 | // top-level "anyOf" structure containing references to the types the schema validates | |
61 | // don't insert an empty "anyOf" if there are no references | |
62 | json.put_next_token(JSON_TOKEN_NAME, "anyOf"); | |
63 | json.put_next_token(JSON_TOKEN_ARRAY_START, NULL); | |
64 | ||
65 | // close schema segments and add them to the main schema | |
66 | for (size_t i = 0; i < json_refs.size(); ++i) { | |
67 | JSON_Tokenizer* segment = json_refs.get_nth_elem(i); | |
68 | segment->put_next_token(JSON_TOKEN_OBJECT_END, NULL); | |
69 | insert_schema(json, *segment); | |
70 | delete segment; | |
71 | } | |
72 | json_refs.clear(); | |
73 | ||
74 | // end of the "anyOf" structure | |
75 | json.put_next_token(JSON_TOKEN_ARRAY_END, NULL); | |
970ed795 | 76 | } |
970ed795 EL |
77 | |
78 | // top-level object end | |
79 | json.put_next_token(JSON_TOKEN_OBJECT_END, NULL); | |
80 | } | |
81 | ||
82 | void Ttcn2Json::insert_schema(JSON_Tokenizer& to, JSON_Tokenizer& from) | |
83 | { | |
84 | json_token_t token = JSON_TOKEN_NONE; | |
85 | char* value_str = NULL; | |
86 | size_t value_len = 0; | |
87 | char temp = 0; | |
88 | ||
89 | do { | |
90 | from.get_next_token(&token, &value_str, &value_len); | |
91 | ||
92 | if (token == JSON_TOKEN_ERROR) { | |
93 | FATAL_ERROR("Ttcn2Json::insert_schema"); | |
94 | } | |
95 | ||
96 | if (value_str != NULL) { | |
97 | // put_next_token expects a null terminated string, save the next character | |
98 | // and set it to null | |
99 | temp = value_str[value_len]; | |
100 | value_str[value_len] = 0; | |
101 | } | |
102 | ||
103 | to.put_next_token(token, value_str); | |
104 | ||
105 | if (value_str != NULL) { | |
106 | // put the original character back to its place | |
107 | value_str[value_len] = temp; | |
108 | } | |
109 | } while (token != JSON_TOKEN_NONE); | |
110 | } | |
111 | ||
112 | } // namespace | |
113 |