Merge pull request #19 from nspaseski/master
[deliverable/titan.core.git] / core / XER.cc
CommitLineData
970ed795 1///////////////////////////////////////////////////////////////////////////////
3abe9331 2// Copyright (c) 2000-2015 Ericsson Telecom AB
970ed795
EL
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
16static 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
36int 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
44const 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
96void 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
108bool 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
120void 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
51fa56b9 132const char* get_ns_uri_from_prefix(const char *prefix, const XERdescriptor_t& p_td)
133{
134 if (p_td.my_module != 0 && prefix != NULL && prefix[0] != 0) {
135 for (size_t i = 0; i < p_td.my_module->get_num_ns(); ++i) {
136 const namespace_t *ns = p_td.my_module->get_ns(i);
137 if (ns->px != NULL && strcmp(ns->px, prefix) == 0) {
138 return ns->ns;
139 }
140 }
141 }
142 return NULL;
143}
144
970ed795
EL
145void check_namespace_restrictions(const XERdescriptor_t& p_td, const char* p_xmlns)
146{
147 // In case of "anyElement from ..." matching namespaces is good
148 // in case of "anyElement except ..." matching namespaces is bad
149 bool ns_match_allowed = (p_td.xer_bits & ANY_FROM) ? true : false;
150
151 bool ns_error = ns_match_allowed;
152 for (unsigned short idx = 0; idx < p_td.nof_ns_uris; ++idx) {
153 if ((p_xmlns == 0 && strlen(p_td.ns_uris[idx]) == 0) ||
154 (p_xmlns != 0 && strcmp(p_td.ns_uris[idx], p_xmlns) == 0))
155 {
156 ns_error = !ns_match_allowed;
157 break;
158 }
159 }
160
161 if (ns_error) {
162 if (p_xmlns) {
163 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
164 "XML namespace \"%s\" is %s namespace list.", p_xmlns, ns_match_allowed ? "not in the allowed" : "in the excluded");
165 }
166 else {
167 TTCN_EncDec_ErrorContext::error(TTCN_EncDec::ET_INVAL_MSG,
168 "The unqualified XML namespace is %s namespace list.", ns_match_allowed ? "not in the allowed" : "in the excluded");
169 }
170 }
171}
This page took 0.030099 seconds and 5 git commands to generate.