Merge pull request #63 from BenceJanosSzabo/master
[deliverable/titan.core.git] / core / XER.cc
CommitLineData
d44e3c4f 1/******************************************************************************
2 * Copyright (c) 2000-2016 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 * Contributors:
9 * Balasko, Jeno
10 * Baranyi, Botond
11 * Ormandi, Matyas
12 * Raduly, Csaba
13 *
14 ******************************************************************************/
970ed795
EL
15#define DEFINE_XER_STRUCT
16#include "XER.hh"
17
18//#include <libxml/xmlreader.h>
19#include "XmlReader.hh"
20#include "Module_list.hh"
21
22// FIXME: there ought to be a better way than this
23static const char indent_buffer[] =
24 // --------------------------- 32 ----------------------------- ||
25 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //1
26 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //2
27 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //3
28 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //4
29 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //5
30 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //6
31 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //7
32 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //8
33 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //9
34 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //10
35 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //11
36 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //12
37 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //13
38 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //14
39 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t" //15
40 "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";//16
41
42// FIXME do_indent's level should be size_t, but there were plans of passing negative values
43int do_indent(TTCN_Buffer& buf, int level)
44{
45 if (level > 0 && level < (int)sizeof(indent_buffer)) {
46 buf.put_s((size_t)level, (const unsigned char*)indent_buffer);
47 }
48 return level;
49}
50
51const char* verify_name(XmlReaderWrap& reader, const XERdescriptor_t& p_td, int exer)
52{
53 const char *name = (const char*)reader.LocalName();
54 const char *nsuri= (const char*)reader.NamespaceUri(); // NULL if no ns
55
56 const namespace_t *expected_ns = 0;
57 if (p_td.my_module != 0 && p_td.ns_index != -1) {
58 expected_ns = p_td.my_module->get_ns(p_td.ns_index);
59 }
60
61 if (0 == name) {
62 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
63 "NULL XML name instead of `%.*s'",
64 p_td.namelens[exer]-2, p_td.names[exer]);
65 }
66 if (!check_name(name, p_td, exer)) {
67 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
68 "Bad XML tag `%s' instead of `%.*s'",
69 name, p_td.namelens[exer]-2, p_td.names[exer]);
70 }
71
72 if (exer) { // XML namespaces only apply to EXER
73 const char *prefix = (const char*)reader.Prefix(); // may be NULL
74 if (expected_ns == 0) { // get_ns was not called
75 if (nsuri != 0) {
76 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
77 "Unexpected namespace '%s' (%s)", nsuri, prefix ? prefix : "");
78 }
79 }
80 else { // a namespace was expected
81 if (p_td.xer_bits & FORM_UNQUALIFIED) {
82 if (prefix && *prefix) TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
83 "Unexpected prefix '%s'", prefix);
84 }
85 else {
86 if (nsuri == 0) { // XML node has no namespace
87 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
88 "Missing namespace '%s'", expected_ns->ns);
89 }
90 else { // and there is one, but is it the right one ?
91 if (strcmp(nsuri, expected_ns->ns)) {
92 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
93 "Bad XML namespace `%s' instead of `%s'", nsuri, expected_ns->ns);
94 }
95 }
96 }
97 }
98 } // if exer
99
100 return name;
101}
102
103void verify_end(XmlReaderWrap& reader, const XERdescriptor_t& p_td, const int depth, int exer)
104{
105 TTCN_EncDec_ErrorContext endcontext("While checking end tag: ");
106 verify_name(reader, p_td, exer);
107 const int currdepth = reader.Depth();
108 if (currdepth!=depth) {
109 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_TAG,
110 "Bad depth in XML, %d instead of %d", currdepth, depth);
111 }
112}
113
114// This should be called for EXER only
115bool check_namespace(const char *ns_uri, const XERdescriptor_t& p_td)
116{
117 if (p_td.my_module==0 || p_td.ns_index==-1) {// no namespace in XER descriptor
118 return ns_uri==0 || *ns_uri=='\0'; // there should be no ns
119 }
120 else {
121 const namespace_t *expected_ns = p_td.my_module->get_ns(p_td.ns_index);
122 if (ns_uri!=0) return strcmp(ns_uri, expected_ns->ns)==0;
123 else return true; // if no namespace we presume it's the expected one
124 }
125}
126
127void write_ns_prefix(const XERdescriptor_t& p_td, TTCN_Buffer& p_buf)
128{
129 if (p_td.my_module != 0 && p_td.ns_index != -1
130 && !(p_td.xer_bits & FORM_UNQUALIFIED)) {
131 const namespace_t *my_ns = p_td.my_module->get_ns(p_td.ns_index);
132 if (my_ns->px[0] != 0) { // not an empty prefix
133 p_buf.put_s(strlen(my_ns->px), (cbyte*)my_ns->px);
134 p_buf.put_c(':');
135 }
136 }
137}
138
51fa56b9 139const char* get_ns_uri_from_prefix(const char *prefix, const XERdescriptor_t& p_td)
140{
141 if (p_td.my_module != 0 && prefix != NULL && prefix[0] != 0) {
142 for (size_t i = 0; i < p_td.my_module->get_num_ns(); ++i) {
143 const namespace_t *ns = p_td.my_module->get_ns(i);
144 if (ns->px != NULL && strcmp(ns->px, prefix) == 0) {
145 return ns->ns;
146 }
147 }
148 }
149 return NULL;
150}
151
970ed795
EL
152void check_namespace_restrictions(const XERdescriptor_t& p_td, const char* p_xmlns)
153{
154 // In case of "anyElement from ..." matching namespaces is good
155 // in case of "anyElement except ..." matching namespaces is bad
156 bool ns_match_allowed = (p_td.xer_bits & ANY_FROM) ? true : false;
157
158 bool ns_error = ns_match_allowed;
159 for (unsigned short idx = 0; idx < p_td.nof_ns_uris; ++idx) {
160 if ((p_xmlns == 0 && strlen(p_td.ns_uris[idx]) == 0) ||
161 (p_xmlns != 0 && strcmp(p_td.ns_uris[idx], p_xmlns) == 0))
162 {
163 ns_error = !ns_match_allowed;
164 break;
165 }
166 }
167
168 if (ns_error) {
169 if (p_xmlns) {
170 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
171 "XML namespace \"%s\" is %s namespace list.", p_xmlns, ns_match_allowed ? "not in the allowed" : "in the excluded");
172 }
173 else {
174 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
175 "The unqualified XML namespace is %s namespace list.", ns_match_allowed ? "not in the allowed" : "in the excluded");
176 }
177 }
178}
This page took 0.043844 seconds and 5 git commands to generate.