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