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

📄 node.cpp

📁 彩信浏览器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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: node.cpp,v 1.32 2007/02/12 14:15:02 jackjansen Exp $  */#include "ambulant/lib/node.h"#include "ambulant/lib/node_impl.h"// find_if, etc#include <algorithm>#if !defined(AMBULANT_NO_IOSTREAMS) && !defined(AMBULANT_NO_STRINGSTREAM)// ostringstream#include <sstream>#endif// assert#include <cassert>// trim strings#include "ambulant/lib/string_util.h"// tree helper iterators and visitors#include "ambulant/lib/node_navigator.h" // node context#include "ambulant/lib/document.h" #include "ambulant/lib/logger.h" #include <stdio.h> using namespace ambulant;// This module starts with a set of private node visitors// and continues with the implementation of lib::node.// Node visitors are used by lib::node member functions////////////////////////// private output_visitor// Writes a tree to an ostream.#ifndef AMBULANT_NO_IOSTREAMStemplate <class Node>class output_visitor {	std::ostream& os;	std::basic_string<char> writesp, strincr;	size_t ns;  public:	output_visitor(std::ostream& os_) 	:	os(os_), strincr("  ") {ns = strincr.length();}	void operator()(std::pair<bool, const Node*> x);  private:	void write_start_tag_no_children(const Node*& pe);	void write_start_tag_with_children(const Node*& pe);	void write_end_tag_with_children(const Node*& pe);	const output_visitor& operator=(const output_visitor& o);};#endif////////////////////////// private trimmed_output_visitor// Writes a tree to an ostream without white space.#ifndef AMBULANT_NO_IOSTREAMStemplate <class Node>class trimmed_output_visitor {	std::ostream& os;  public:	trimmed_output_visitor(std::ostream& os_) : os(os_) {}	void operator()(std::pair<bool, const Node*> x);	  private:	void write_start_tag_no_children(const Node*& pe);	void write_start_tag_with_children(const Node*& pe);	void write_end_tag_with_children(const Node*& pe);	const trimmed_output_visitor& operator=(const trimmed_output_visitor& o);	};#endif////////////////////////// private attr_collector// Scans the tree and creates a map attr to nodes.// Intented for unique attrs like name and idtemplate <class Node>class attr_collector {  public:	attr_collector(std::map<std::string, Node*>& m, const char *attr = "id") : 		m_attr(attr), m_map(m) {}			void operator()(std::pair<bool, const Node*> x) {		if(x.first) {			const char *value = x.second->get_attribute(m_attr);			if(value != 0) 				m_map[value] = const_cast<Node*>(x.second);		}	}  private:	std::string m_attr;	std::map<std::string, Node*>& m_map;	const attr_collector& operator=(const attr_collector& o);	};///////////////////////////////////////////////// lib::node implementation// static int lib::node_impl::node_counter = 0;//////////////////////// Node constructors// Note: attrs are as per expat parser// e.g. const char* attrs[] = {"attr_name", "attr_value", ..., 0};lib::node_impl::node_impl(const char *local_name, const char **attrs, const node_context *ctx):	m_qname("",(local_name?local_name:"error")),	m_context(ctx),	m_parent(0), m_next(0), m_child(0) {	set_attributes(attrs);	m_numid = ++node_counter;}lib::node_impl::node_impl(const xml_string& local_name, const char **attrs, const node_context *ctx):   m_qname("", local_name),	m_context(ctx),	m_parent(0), m_next(0), m_child(0) {	set_attributes(attrs);	m_numid = ++node_counter;}lib::node_impl::node_impl(const q_name_pair& qn, const q_attributes_list& qattrs, const node_context *ctx):	m_qname(qn), m_qattrs(qattrs), m_context(ctx),	m_parent(0), m_next(0), m_child(0){	m_numid = ++node_counter;}// shallow copy from otherlib::node_impl::node_impl(const node_impl* other):   m_qname(other->get_qname()),	m_qattrs(other->get_attrs()),	m_data(other->get_data()),	m_context(other->get_context()),	m_parent(0), m_next(0), m_child(0) {	m_numid = ++node_counter;}//////////////////////// Node destructorlib::node_impl::~node_impl() { 	node_counter--;	node_navigator<node_impl>::delete_tree(this); }///////////////////////////////// basic navigation// inline//////////////////////// set down/up/next// inline///////////////////////////////// deduced navigationconst lib::node_impl* lib::node_impl::previous() const { 	return node_navigator<const node_impl>::previous(this); }const lib::node_impl* lib::node_impl::get_last_child() const { 	return node_navigator<const node_impl>::last_child(this);}void lib::node_impl::get_children(std::list<const lib::node*>& l) const {	node_navigator<const lib::node>::get_children(this, l);}///////////////////////////////// search operations lib::node_impl* lib::node_impl::get_first_child(const char *name) {	node_impl *e = down();	if(!e) return 0;	if(e->m_qname.second == name) return e;	e = e->next();	while(e != 0) {		if(e->m_qname.second == name) 			return e;		e = e->next();	}	return 0;}const lib::node_impl* lib::node_impl::get_first_child(const char *name) const {	const node_impl *e = down();	if(!e) return 0;	if(e->m_qname.second == name) return e;	e = e->next();	while(e != 0) {		if(e->m_qname.second == name) 			return e;		e = e->next();	}	return 0;}lib::node_impl* lib::node_impl::locate_node(const char *path) {	if(!path || !path[0]) {		return this;	}	tokens_vector v(path, "/");	node_impl *n = 0;	tokens_vector::iterator it = v.begin();	if(path[0] == '/') { // or v.at(0) is empty		// absolute		it++; // skip empty		n = get_root();		if(it == v.end())			return n; 		if(n->get_local_name() != (*it))			return 0;		it++; // skip root	} else n = this;	for(; it != v.end() && n != 0;it++) {		n = n->get_first_child((*it).c_str());	}	return n;}#if 0void lib::node_impl::find_nodes_with_name(const xml_string& name, std::list<node*>& lst) {	iterator last = end(); // call once	for(iterator it = begin(); it != last; it++)		if((*it).first && (*it).second->get_local_name() == name) lst.push_back((*it).second);}#endiflib::node_impl* lib::node_impl::get_root() { 	return node_navigator<node_impl>::get_root(this); }inline std::string get_path_desc_comp(const lib::node_impl *n) {	std::string sbuf;	const char *pid = n->get_attribute("id");	sbuf += n->get_local_name();	if(pid) {sbuf += ":"; sbuf += pid;}	return sbuf;}std::string lib::node_impl::get_path_display_desc() const {	std::string sbuf;	std::list<const node_impl*> path;	node_navigator<const node_impl>::get_path(this, path);	int nc = 0;	std::list<const node_impl*>::reverse_iterator it = path.rbegin();	sbuf += get_path_desc_comp(this);it++;nc++;	for(;it != path.rend() && nc<3;it++) {		std::string ln = (*it)->get_local_name();		if(ln != "priorityClass" && ln != "switch") {			sbuf.insert(0, "/");			sbuf.insert(0, get_path_desc_comp(*it));			nc++;		}	}	return sbuf;}///////////////////////////////// iterators// inline///////////////////////// build tree functions	lib::node_impl* lib::node_impl::append_child(node_impl* child) { 	return node_navigator<node_impl>::append_child(this, child);}		lib::node_impl* lib::node_impl::append_child(const char *name) { 	return append_child(new node_impl(name));}lib::node_impl* lib::node_impl::detach() { 	return node_navigator<node_impl>::detach(this); }	void lib::node_impl::append_data(const char *data, size_t len) { 	if(len>0) m_data.append(data, len);}void lib::node_impl::append_data(const char *c_str) { 	if(c_str == 0 || c_str[0] == 0) return;	m_data.append(c_str, strlen(c_str));}void lib::node_impl::append_data(const xml_string& str)	{ m_data += str;}void lib::node_impl::set_attribute(const char *name, const char *value){ 	if(name && name[0]) {		q_name_pair qn("", name);		q_attribute_pair qattr(qn, (value?value:""));		m_qattrs.push_back(qattr);	}}void lib::node_impl::set_attribute(const char *name, const xml_string& value) {	if(name && name[0]) {		q_name_pair qn("", name);		q_attribute_pair qattr(qn, value);		m_qattrs.push_back(qattr);	}}// Note: attrs are as per expat parser// e.g. const char* attrs[] = {"attr_name", "attr_value", ..., 0};void lib::node_impl::set_attributes(const char **attrs) {	if(attrs == 0) return;	for(int i=0;attrs[i];i+=2)		set_attribute(attrs[i], attrs[i+1]);}	void lib::node_impl::set_namespace(const xml_string& ns) {	m_qname.first = ns;}// create a deep copy of thislib::node_impl* lib::node_impl::clone() const {	node_impl* c = new node_impl(this);	const node_impl *e = down();	if(e != 0) {		c->append_child(e->clone());

⌨️ 快捷键说明

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