⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xerces_parser.cpp

📁 彩信浏览器
💻 CPP
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player is free software; you can redistribute it and/or modify// it under the terms of the GNU Lesser General Public License as published by// the Free Software Foundation; either version 2.1 of the License, or// (at your option) any later version.//// Ambulant Player is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the// GNU Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public License// along with Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA/*  * @$Id: xerces_parser.cpp,v 1.32 2007/02/12 14:15:03 jackjansen Exp $  */#include "ambulant/lib/xerces_parser.h"#include "ambulant/common/preferences.h"#include "ambulant/lib/logger.h"#include "ambulant/net/url.h"#ifdef	WITH_XERCES#include <xercesc/framework/MemBufInputSource.hpp>#include <xercesc/framework/LocalFileInputSource.hpp>#include <fstream>#include <map>//#define AM_DBG#ifndef AM_DBG#define AM_DBG if(0)#endifusing namespace ambulant;using namespace lib;lib::xml_parser*lib::xerces_factory::new_parser(		sax_content_handler* content_handler, 		sax_error_handler* error_handler) {	AM_DBG lib::logger::get_logger()->debug("xerces_factory::new_parser(): xerces parser returned");	return new lib::xerces_sax_parser(content_handler, error_handler);}std::string lib::xerces_factory::get_parser_name(){	AM_DBG lib::logger::get_logger()->debug("xerces_factory::get_parser_name(): xerces parser");	return "xerces";}xerces_sax_parser::xerces_sax_parser(sax_content_handler*content_handler,				     sax_error_handler *error_handler) :	m_saxparser(0),	m_logger(0),	m_content_handler(content_handler),	m_error_handler(error_handler),	m_parsing(false),	m_buf((char*)malloc(1)),	m_size(0),	m_id("AmbulantXercesParser"){	m_logger = lib::logger::get_logger();        AM_DBG m_logger->debug("xerces_sax_parser::xerces_sax_parser()");	XMLPlatformUtils::Initialize();	m_saxparser = new SAXParser();		common::preferences* prefs = common::preferences::get_preferences();	// Don't attempt to load external DTD if validation is off	m_saxparser->setLoadExternalDTD(false);	// Val_Never, Val_Always, Val_Auto	m_saxparser->setValidationScheme(ambulant_val_scheme_2_xerces_ValSchemes(prefs->m_validation_scheme));		// If set to true, namespace processing must also be turned on	m_saxparser->setDoSchema(prefs->m_do_schema);	// True to turn on full schema constraint checking	m_saxparser->setValidationSchemaFullChecking(prefs->m_validation_schema_full_checking);		// true: understand namespaces; false: otherwise	m_saxparser->setDoNamespaces(prefs->m_do_namespaces);		m_saxparser->setDocumentHandler(this);	m_saxparser->setErrorHandler(this);	m_saxparser->setEntityResolver(this);}xerces_sax_parser::~xerces_sax_parser() {	AM_DBG m_logger->debug("xerces_sax_parser::~xerces_sax_parser()");	XMLPlatformUtils::Terminate();	free (m_buf);}boolxerces_sax_parser::parse(const char *buf, size_t len, bool final) {	bool succeeded = false;	size_t old_size = m_size;	m_buf = (char*) realloc(m_buf, m_size += len);	if (m_buf == NULL)		return false;	memcpy(&m_buf[old_size], buf, len);	if (final == false)		return true;	MemBufInputSource membuf((const XMLByte*) m_buf, (unsigned int)m_size, m_id);	try {		m_saxparser->parse(membuf);		succeeded = true;	} catch (const XMLException& e) {		char *exceptionMessage = XMLString::transcode(e.getMessage());		int linenumber = e.getSrcLine();		sax_error err(exceptionMessage, linenumber, -1);		if(m_error_handler != 0)			m_error_handler->error(err);		else			throw;		XMLString::release(&exceptionMessage);	} catch (const SAXParseException& e) {		char *exceptionMessage = XMLString::transcode(e.getMessage());		int linenumber = e.getLineNumber();		int column = e.getColumnNumber();		sax_error err(exceptionMessage, linenumber, column);		if(m_error_handler != 0)			m_error_handler->error(err);		else			throw e;		XMLString::release(&exceptionMessage);	} catch (...) {		m_logger->error(gettext("%s: Unexpected exception during parsing"), m_id);	}		return succeeded;}voidxerces_sax_parser::set_content_handler(sax_content_handler *h) { 	m_content_handler = h;}voidxerces_sax_parser::set_error_handler(sax_error_handler *h) {		m_error_handler = h;}voidxerces_sax_parser::startElement(const XMLCh* const name,				AttributeList& attrs) {	char *cname = XMLString::transcode(name);	AM_DBG m_logger->debug("*** startElement %s", cname);	q_name_pair qname = to_q_name_pair(name);	q_attributes_list qattrs;	to_qattrs(attrs, qattrs);	m_content_handler->start_element(qname, qattrs);	XMLString::release(&cname);}voidxerces_sax_parser::endElement(const XMLCh* const name) {	char *cname = XMLString::transcode(name);	AM_DBG m_logger->debug("*** endElement %s", cname);	q_name_pair qname = to_q_name_pair(name);	m_content_handler->end_element(qname);	XMLString::release(&cname);}void xerces_sax_parser::warning(const SAXParseException& exception) {	throw exception;}void xerces_sax_parser::error(const SAXParseException& exception) {	throw exception;}voidxerces_sax_parser::fatalError(const SAXParseException& exception)  {	throw exception;}	voidxerces_sax_parser::to_qattrs(AttributeList& attrs, 			     q_attributes_list& list) {	if (attrs.getLength() == 0) return;	for (int i = 0; i < (int)attrs.getLength(); i++) {		char* value = XMLString::transcode(attrs.getValue(i));		xml_string xmlvalue(value);		q_attribute_pair qap (to_q_name_pair(attrs.getName(i)),				      xmlvalue);		list.push_back(q_attribute_pair(qap));		XMLString::release(&value);	}}q_name_pair xerces_sax_parser::to_q_name_pair(const XMLCh* name) {	char *cname = XMLString::transcode(name);	const char *p = cname;	const char ns_sep = char(NS_SEP);	while(*p != 0 && *p != ns_sep) p++;	q_name_pair qn;	if(*p == ns_sep) { 		qn.first = std::string(cname, int(p-cname));		qn.second = std::string(p+1);	} else {		qn.first = "";		qn.second = cname;	}	XMLString::release(&cname);	return  qn;}SAXParser::ValSchemesxerces_sax_parser::ambulant_val_scheme_2_xerces_ValSchemes(std::string v) {	SAXParser::ValSchemes rv = SAXParser::Val_Never;	if (v == "never")		rv = SAXParser::Val_Never;	else if (v == "always")		rv = SAXParser::Val_Always;	else if (v == "auto")		rv = SAXParser::Val_Auto;	return rv;}static std::map<std::string, std::string> dtd_cache_mapping;static std::map<std::string, std::string> obsolete_dtd_cache_mapping;static voidinit_dtd_cache_mapping() {		// "DTDCache/mapping.txt" defines the mapping of URLs to local files	// odd lines are requested URLs as used in .smil files	// even lines are relative pathnames of the corresponding cache	// net::url.get_local_datafile() returns the absolute pathname	// the pairs <requested_URL, absolute_pathname> constitute the	// "dtd_cache_mapping"	net::url mapping = net::url::from_url("DTDCache/mapping.txt");	std::pair<bool, net::url> mapping_filename = mapping.get_local_datafile();	if (!mapping_filename.first) return;	std::ifstream mapping_stream(mapping_filename.second.get_path().c_str());	if (! mapping_stream) return;	std::string requested, relative;	while (! mapping_stream.eof()) {		char buf[1024];		// get a line, ignore empty amd comment lines		mapping_stream.getline(buf, 1024);		if (mapping_stream.eof())			break;		std::string line(buf);		if (line == "" || line[0] == '#')			continue;		// set the requested we're looking for 		if (requested == "") {			requested = line;			continue;		}		relative = line;		net::url relative_url = net::url::from_url(relative);		std::pair<bool, net::url> absolute_url = relative_url.get_local_datafile();		if (absolute_url.first) {			std::string abs_path = absolute_url.second.get_path();			std::pair<std::string,std::string> new_map(requested, abs_path);			if (relative_url.get_query() == "obsolete") 				obsolete_dtd_cache_mapping.insert(new_map);			else				dtd_cache_mapping.insert(new_map);			requested = relative = ""; // reset		} else {			lib::logger::get_logger()->trace("DTDCache/mapping.txt contains non-existent file: %s", relative.c_str());		}	}}static const std::stringfind_cached_dtd(std::string url) {	// return the cached absolute path for this url or "" if not found	std::string result;	if (dtd_cache_mapping.empty())		init_dtd_cache_mapping();	std::map<std::string,std::string>::iterator mi;	mi = dtd_cache_mapping.find(url);	if (mi != dtd_cache_mapping.end()) {		result = mi->second;	} else {		mi = obsolete_dtd_cache_mapping.find(url);		if (mi != obsolete_dtd_cache_mapping.end()) {			result = mi->second;			lib::logger::get_logger()->warn("Obsolete DTD: %s", url.c_str());		}	}	return result;}InputSource* xerces_sax_parser::resolveEntity(const XMLCh* const publicId , const XMLCh* const systemId) {	char* publicId_ts = XMLString::transcode(publicId);	char* systemId_ts = XMLString::transcode(systemId);	XMLCh* XMLCh_local_id = NULL;	InputSource* local_input_source = NULL;	AM_DBG m_logger->debug("xerces_sax_parser::resolveEntity(%s,%s)",publicId_ts, systemId_ts);	const std::string dtd = find_cached_dtd(systemId_ts);	if (dtd != "") {		XMLCh_local_id = XMLString::transcode(dtd.c_str());	}	if (XMLCh_local_id != NULL) {		m_logger->trace("Using cached DTD: %s", dtd.c_str());		local_input_source = new LocalFileInputSource(XMLCh_local_id );		//delete XMLCh_local_id;		XMLString::release(&XMLCh_local_id);	}	XMLString::release(&publicId_ts);	XMLString::release(&systemId_ts);	return local_input_source;}#endif/*WITH_XERCES*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -