18 constexpr std::size_t BUFFSIZE = 1000;
20 const std::string emptyString;
21 constexpr int errorValue{0};
35 me.do_start (el, attr);
47 me.do_char_data (s, len);
53 me.do_default_handler (s, len);
64 const XML_Char* ,
const XML_Char* systemId,
const XML_Char* ){
65 void* user_data = XML_GetUserData (parser);
67 return (me.do_external_entity (parser, context, systemId));
73 std::cout <<
label()<<
"> name=" << name <<
" file_name=" << file_name <<
"\n";
76 s_entities[name] = file_name;
82 std::cout <<
label()<<
"> name=" << name<<
"\n";
85 s_text_entities[name] = text;
89std::unique_ptr<XMLCoreNode>
91 return std::move(
m_top);
102 XML_SetParamEntityParsing(p, XML_PARAM_ENTITY_PARSING_ALWAYS);
103 XML_SetElementHandler(p,
start,
end);
104 XML_SetCharacterDataHandler(p,
char_data);
106 XML_SetCommentHandler(p,
comment);
107 XML_SetUserData(p,
this);
124 std::cout <<
label()<<
"> el=" << el <<
" top=" <<
m_top.get() <<
" last=" <<
m_last <<
" node=" <<
node <<
"\n";
126 for (
int i = 0; attr[i]; i += 2) {
127 const char* name = attr[i];
128 const char* value = attr[i+1];
129 node->set_attrib (name, value);
137 std::cout <<
label()<<
"> el=" << el <<
"\n";
144 std::string text =
rtrim(s, len);
145 if (text.empty())
return;
147 std::cout <<
label()<<
"> [" << text <<
"]\n";
154 std::string text =
rtrim(s, len);
155 if (text.empty())
return;
157 std::cout <<
label()<<
"> [" << text <<
"]\n";
165 std::cout <<
label()<<
"> s=" << s <<
" top=" <<
m_top.get() <<
" last=" <<
m_last <<
" node=" <<
node <<
"\n";
175 std::cout <<
label() <<
"> starting\n";
177 std::array<char, BUFFSIZE> buff{};
179 is.read(buff.data(), buff.size());
180 const auto nbytes = is.gcount();
181 const bool done = is.eof();
183 std::cout <<
"Read error";
184 if (!source_name.empty()) {
185 std::cout <<
" in " << source_name;
191 if (XML_Parse(p, buff.data(),
static_cast<int>(nbytes), done) == XML_STATUS_ERROR) {
192 std::cout <<
"ExpatCoreParser::Parse error at line "
193 << XML_GetCurrentLineNumber(p);
194 if (!source_name.empty()) {
195 std::cout <<
" of " << source_name;
197 std::cout <<
":\n" << XML_ErrorString(XML_GetErrorCode(p)) <<
"\n";
212 if (path.empty())
return errorValue;
214 std::cout <<
label() <<
"> file_name=" << file_name
217 std::ifstream
fs{path, std::ios::binary};
219 std::cout <<
"Could not open file " << path <<
"\n";
228 std::cout <<
label() <<
">\n";
230 std::istringstream is(text);
236 const std::string context_str = context ? context :
"none";
237 if (context !=
nullptr) {
239 if (!replacement.empty()) {
241 std::cout <<
label() <<
"> context=[" << context_str
242 <<
"] replacement=[" << replacement <<
"]\n";
244 XMLParserPtr p{XML_ExternalEntityParserCreate(parser, context,
nullptr)};
245 if (!p)
return errorValue;
250 if (replacement ==
"NULL") {
253 std::string originalSystemId = systemId ? systemId :
"";
254 std::string effectiveSystemId = originalSystemId;
255 if (!replacement.empty()) {
256 effectiveSystemId = replacement;
259 std::cout <<
label() <<
"> context=[" << context_str
260 <<
"] systemId=[" << originalSystemId
261 <<
"] replacement=[" << replacement <<
"]\n";
263 XMLParserPtr p{XML_ExternalEntityParserCreate(parser, context,
nullptr)};
264 if (!p)
return errorValue;
272 ExternalEntityMap::const_iterator it = mapChoice.find(name);
273 return (it == mapChoice.end()) ? emptyString : it->second;
287std::unique_ptr<XMLCoreNode>
289 const std::filesystem::path path{file_name};
292 int result = me.
generic_parse (p.get(), path.filename().string());
293 if (result == errorValue)
return nullptr;
298std::unique_ptr<XMLCoreNode>
303 if (result == errorValue)
return nullptr;
virtual void lock()=0
Interface to allow an object to lock itself when made const in SG.
Various text/ptr utilities to use in the ExpatCoreParser.
int generic_text_parse(XML_Parser p, const std::string &text)
std::string find_text_entity(const std::string &name)
void do_start(const char *el, const char **attr)
static void register_text_entity(const std::string &name, const std::string &text)
void do_default_handler(const XML_Char *s, int len)
std::string find_external_entity(const std::string &name)
XMLCoreNode * add_node(std::unique_ptr< XMLCoreNode > node)
static void char_data(void *, const XML_Char *s, int len)
static int external_entity(XML_Parser parser, const XML_Char *context, const XML_Char *, const XML_Char *systemId, const XML_Char *)
void configure_parser(XML_Parser p)
std::lock_guard< std::mutex > lock_t
int generic_parse(XML_Parser p, const std::string &file_name)
static void start(void *, const char *el, const char **attr)
std::string find_entity(const std::string &name, const ExternalEntityMap &mapChoice)
void do_end(const char *el)
static void default_handler(void *, const XML_Char *s, int len)
std::unique_ptr< XMLCoreNode > get_document()
void do_comment(const XML_Char *s)
static std::unique_ptr< XMLCoreNode > parse(std::string_view file_name)
void do_char_data(const XML_Char *s, int len)
static std::unique_ptr< XMLCoreNode > parse_string(const std::string &text)
static void register_external_entity(const std::string &name, const std::string &file_name)
int stream_parse(XML_Parser p, std::istream &is, const std::string &source_name={})
std::unique_ptr< XMLCoreNode > m_top
static void comment(void *, const XML_Char *s)
std::map< std::string, std::string > ExternalEntityMap
int do_external_entity(XML_Parser parser, const XML_Char *context, const XML_Char *systemId)
static void end(void *, const char *el)
ExpatCoreParser(const std::string &prefix)
static std::mutex s_mutex
Simple DOM-like node structure to hold the result of XML parsing.
std::string xmlFileName(const std::string &fname, const std::string &prefix)
find the xml file locally or on the datapath, return the full filename
bool debug_enabled()
true if XML debug mode is enabled in the environment
XMLParserPtr make_parser()
Create an RAII XMLParser pointer.
std::unique_ptr< std::remove_pointer_t< XML_Parser >, XMLParserDeleter > XMLParserPtr
RAII XMLParser pointer.
std::string label(const std::source_location loc=std::source_location::current())
report function name in a string, for debugging
std::string rtrim(const XML_Char *s, int len)
Trim newline from end of a XML_Char * , return the trimmed string as std::string.