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