1 /*
2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2012 - Scilab Enterprises - Calixte DENIZET
4 *
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
6 *
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
13 *
14 */
15
16 #include "XMLObject.hxx"
17 #include "XMLValidation.hxx"
18 #include "XMLValidationDTD.hxx"
19 #include "XMLDocument.hxx"
20 #include "VariableScope.hxx"
21
22 extern "C"
23 {
24 #include "expandPathVariable.h"
25 #include "sci_malloc.h"
26 #include "localization.h"
27 }
28
29 namespace org_modules_xml
30 {
31
XMLValidationDTD(const char * path,std::string * error)32 XMLValidationDTD::XMLValidationDTD(const char *path, std::string * error): XMLValidation()
33 {
34 internalValidate = false;
35 char *expandedPath = expandPathVariable(const_cast<char *>(path));
36 if (expandedPath)
37 {
38 validationFile = (void *)xmlParseDTD(0, (const xmlChar *)expandedPath);
39 FREE(expandedPath);
40 if (!validationFile)
41 {
42 errorBuffer.clear();
43 errorBuffer.append(gettext("Cannot parse the DTD"));
44 *error = errorBuffer;
45 }
46 else
47 {
48 openValidationFiles.push_back(this);
49 }
50 }
51 else
52 {
53 *error = std::string(gettext("Invalid file name: ")) + std::string(path);
54 }
55
56 scope->registerPointers(validationFile, this);
57 id = scope->getVariableId(*this);
58 }
59
XMLValidationDTD()60 XMLValidationDTD::XMLValidationDTD(): XMLValidation()
61 {
62 validationFile = 0;
63 internalValidate = true;
64 id = scope->getVariableId(*this);
65 openValidationFiles.push_back(this);
66 }
67
~XMLValidationDTD()68 XMLValidationDTD::~XMLValidationDTD()
69 {
70 scope->unregisterPointer(validationFile);
71 scope->removeId(id);
72
73 if (validationFile)
74 {
75 xmlFreeDtd(getValidationFile < xmlDtd > ());
76 }
77
78 if (validationFile || internalValidate)
79 {
80 openValidationFiles.remove(this);
81 if (openValidationFiles.size() == 0 && XMLDocument::getOpenDocuments().size() == 0)
82 {
83 resetScope();
84 }
85 }
86
87 errorBuffer.clear();
88 }
89
validate(const XMLDocument & doc,std::string * error) const90 bool XMLValidationDTD::validate(const XMLDocument & doc, std::string * error) const
91 {
92 bool ret;
93 xmlValidCtxt *vctxt = xmlNewValidCtxt();
94
95 errorBuffer.clear();
96
97 if (!vctxt)
98 {
99 errorBuffer.append(gettext("Cannot create a valid context"));
100 *error = errorBuffer;
101 return false;
102 }
103
104 vctxt->error = (xmlValidityErrorFunc) XMLValidation::errorFunction;
105
106 ret = xmlValidateDtd(vctxt, doc.getRealDocument(), getValidationFile < xmlDtd > ()) == 1;
107
108 vctxt->error = 0;
109 xmlFreeValidCtxt(vctxt);
110
111 if (!ret)
112 {
113 *error = errorBuffer;
114 }
115
116 return ret;
117 }
118
validate(xmlTextReader * reader,std::string * error) const119 bool XMLValidationDTD::validate(xmlTextReader * reader, std::string * error) const
120 {
121 int last;
122 int valid;
123
124 errorBuffer.clear();
125
126 if (!internalValidate)
127 {
128 errorBuffer.append(gettext("Due to a libxml2 limitation, it is not possible to validate a document against an external DTD\nPlease see help xmlValidate.\n"));
129 *error = errorBuffer;
130 return false;
131 }
132
133 xmlTextReaderSetParserProp(reader, XML_PARSER_VALIDATE, 1);
134 xmlTextReaderSetErrorHandler(reader, (xmlTextReaderErrorFunc) XMLValidation::errorReaderFunction, 0);
135 while ((last = xmlTextReaderRead(reader)) == 1)
136 {
137 ;
138 }
139 valid = xmlTextReaderIsValid(reader);
140
141 xmlTextReaderSetErrorHandler(reader, 0, 0);
142 xmlFreeTextReader(reader);
143
144 if (last == -1 || valid != 1)
145 {
146 *error = errorBuffer;
147 return false;
148 }
149
150 return true;
151 }
152
toString() const153 const std::string XMLValidationDTD::toString() const
154 {
155 std::ostringstream oss;
156 xmlDtd *dtd = getValidationFile < xmlDtd > ();
157
158 oss << "XML DTD" << std::endl;
159 oss << "name: " << (dtd->name ? (const char *)dtd->name : "") << std::endl;
160 oss << "external ID: " << (dtd->ExternalID ? (const char *)dtd->ExternalID : "") << std::endl;
161 oss << "system ID: " << (dtd->SystemID ? (const char *)dtd->SystemID : "");
162
163 return oss.str();
164 }
165 }
166
167