Removed last of the std::string-isms.

This commit is contained in:
Jez Higgins 2012-11-21 06:59:40 +00:00
parent bdc7db5da8
commit 51f1912534
28 changed files with 1182 additions and 1126 deletions

View file

@ -1,18 +1,14 @@
#ifdef _MSC_VER #ifdef _MSC_VER
#pragma warning(disable : 4250) #pragma warning(disable : 4250 4244)
#endif #endif
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <SAX/InputSource.hpp>
#include <DOM/SAX2DOM/SAX2DOM.hpp>
#include <DOM/io/Stream.hpp>
#include <XSLT/XSLT.hpp> #include <XSLT/XSLT.hpp>
Arabica::DOM::Document<std::wstring> buildDOM(const std::wstring& xml); Arabica::DOM::Document<std::string> buildDOM(const std::string & xml);
typedef Arabica::default_string_adaptor<std::wstring> adaptor;
int main(int argc, const char* argv[]) int main(int argc, const char* argv[])
{ {
@ -24,12 +20,12 @@ int main(int argc, const char* argv[])
return 0; return 0;
} // if ... } // if ...
Arabica::XSLT::StylesheetCompiler<std::wstring> compiler; Arabica::XSLT::StylesheetCompiler<std::string> compiler;
std::wostringstream errors; std::ostringstream errors;
try try
{ {
Arabica::SAX::InputSource<std::wstring> source(adaptor::construct_from_utf8(argv[2])); Arabica::SAX::InputSource<std::string> source(argv[2]);
std::auto_ptr<Arabica::XSLT::Stylesheet<std::wstring> > stylesheet = compiler.compile(source); std::auto_ptr<Arabica::XSLT::Stylesheet<std::string> > stylesheet = compiler.compile(source);
if(stylesheet.get() == 0) if(stylesheet.get() == 0)
{ {
std::cerr << "Couldn't compile stylesheet: " << compiler.error() << std::endl; std::cerr << "Couldn't compile stylesheet: " << compiler.error() << std::endl;
@ -38,41 +34,28 @@ int main(int argc, const char* argv[])
stylesheet->set_error_output(errors); stylesheet->set_error_output(errors);
Arabica::DOM::Document<std::wstring> document = buildDOM(adaptor::construct_from_utf8(argv[1])); Arabica::DOM::Document<std::string> document = buildDOM(argv[1]);
if(document == 0) if(document == 0)
{ {
std::cerr << "Could not parse XML source" << std::endl; std::cerr << "Could not parse XML source" << std::endl;
return 0; return 0;
} // if ... } // if ...
//document.normalize();
stylesheet->execute(document); stylesheet->execute(document);
/*
std::cout << "\n==============" << std::endl;
Arabica::XSLT::DOMSink output;
stylesheet->set_output(output);
stylesheet->execute(document);
Arabica::DOM::Node<std::wstring> node = output.node();
std::cout << node << std::endl;
*/
} }
catch(const std::runtime_error& ex) catch(const std::runtime_error& ex)
{ {
std::cerr << ex.what() << std::endl; std::cerr << ex.what() << std::endl;
} // catch } // catch
std::wcerr << "\n\n" << errors.str() << std::endl; std::cerr << "\n\n" << errors.str() << std::endl;
return 0; return 0;
} // main } // main
Arabica::DOM::Document<std::wstring> buildDOM(const std::wstring& filename) Arabica::DOM::Document<std::string> buildDOM(const std::string & filename)
{ {
Arabica::SAX::InputSource<std::wstring> is(filename); Arabica::SAX::InputSource<std::string> is(filename);
Arabica::SAX2DOM::Parser<std::wstring> parser; Arabica::SAX2DOM::Parser<std::string> parser;
parser.parse(is); parser.parse(is);
return parser.getDocument(); return parser.getDocument();

View file

@ -1,217 +1,226 @@
#ifndef ARABICA_UTILS_STRING_ADAPTOR_H #ifndef ARABICA_UTILS_STRING_ADAPTOR_H
#define ARABICA_UTILS_STRING_ADAPTOR_H #define ARABICA_UTILS_STRING_ADAPTOR_H
#include <SAX/ArabicaConfig.hpp> #include <SAX/ArabicaConfig.hpp>
#include <string> #include <string>
#include <io/convertstream.hpp> #include <io/convertstream.hpp>
#include <convert/utf8ucs2codecvt.hpp> #include <convert/utf8ucs2codecvt.hpp>
#include <Arabica/stringadaptortag.hpp> #include <Arabica/stringadaptortag.hpp>
namespace Arabica namespace Arabica
{ {
template<class stringT> class default_string_adaptor; template<class stringT> class default_string_adaptor;
template<class stringT> template<class stringT>
class default_string_adaptor_base class default_string_adaptor_base
{ {
public: public:
typedef stringT string_type; typedef stringT string_type;
typedef typename string_type::const_iterator const_iterator; typedef typename string_type::const_iterator const_iterator;
typedef typename string_type::iterator mutable_iterator; typedef typename string_type::iterator mutable_iterator;
typedef typename string_type::iterator iterator; typedef typename string_type::const_reverse_iterator const_reverse_iterator;
typedef typename string_type::value_type value_type; typedef typename string_type::iterator iterator;
typedef typename string_type::size_type size_type; typedef typename string_type::value_type value_type;
typedef typename string_type::size_type size_type;
virtual ~default_string_adaptor_base() {}
virtual ~default_string_adaptor_base() {}
static size_type npos()
{ static size_type npos()
return static_cast<size_type>(-1); {
} return static_cast<size_type>(-1);
}
//todo: is this safe?
template<class InputIterator> //todo: is this safe?
static inline string_type construct(InputIterator from, InputIterator to) template<class InputIterator>
{ static inline string_type construct(InputIterator from, InputIterator to)
return string_type(from, to); {
} return string_type(from, to);
}
static inline string_type construct(const_iterator from, const_iterator to)
{ static inline string_type construct(const_iterator from, const_iterator to)
return string_type(from, to); {
} return string_type(from, to);
}
static string_type construct(const value_type* str) static inline string_type construct(const std::basic_string<value_type>& str)
{ {
return str ? string_type(str) : string_type(); return construct(str.begin(), str.end());
} } // construct
static const string_type& empty_string() { static string_type es; return es; } static string_type construct(const value_type* str)
{
//todo: fix for utf8 return str ? string_type(str) : string_type();
static size_type length(const string_type& str) { return str.length(); } }
// all these functions should operate as std::string member functions do static const string_type& empty_string() { static string_type es; return es; }
static bool empty(const string_type& str) { return str.empty(); }
static size_type find(const string_type& str, value_type what) { return str.find(what); } //todo: fix for utf8
static size_type find(const string_type& str, const string_type& what) { return str.find(what); } static size_type length(const string_type& str) { return str.length(); }
static size_type find(const string_type& str, value_type what, size_type from) { return str.find(what, from); }
static size_type find(const string_type& str, const string_type& what, size_type from) { return str.find(what, from); } // all these functions should operate as std::string member functions do
static string_type substr(const string_type& str, const size_type& offset) { return str.substr(offset); } static bool empty(const string_type& str) { return str.empty(); }
static string_type substr(const string_type& str, const size_type& offset, const size_type& count) { return str.substr(offset, count); } static size_type find(const string_type& str, value_type what) { return str.find(what); }
static void append(string_type& str, const string_type& a) { str.append(a); } static size_type find(const string_type& str, const string_type& what) { return str.find(what); }
static void insert(string_type& str, size_type offset, const string_type& a) { str.insert(offset, a); } static size_type find(const string_type& str, value_type what, size_type from) { return str.find(what, from); }
static void replace(string_type& str, size_type offset, size_type count, const string_type& a) { str.replace(offset, count, a); } static size_type find(const string_type& str, const string_type& what, size_type from) { return str.find(what, from); }
static string_type substr(const string_type& str, const size_type& offset) { return str.substr(offset); }
static const_iterator begin(const string_type& str) { return str.begin(); } static string_type substr(const string_type& str, const size_type& offset, const size_type& count) { return str.substr(offset, count); }
static const_iterator end(const string_type& str) { return str.end(); } static void append(string_type& str, const string_type& a) { str.append(a); }
static void append(string_type& str, const value_type& a) { str += a; }
static iterator begin(string_type& str) { return str.begin(); } static string_type concat(const string_type& str, const string_type& a) { return str + a; }
static iterator end(string_type& str) { return str.end(); } static string_type concat(const string_type& str, const value_type& a) { return str + a; }
static void insert(string_type& str, size_type offset, const string_type& a) { str.insert(offset, a); }
static void replace(string_type& str, size_type offset, size_type count, const string_type& a) { str.replace(offset, count, a); }
// only used to constuct error strings - don't have to be highly efficient!
static std::string asStdString(const string_type& str); static const_iterator begin(const string_type& str) { return str.begin(); }
static const_iterator end(const string_type& str) { return str.end(); }
#ifndef ARABICA_NO_WCHAR_T
static string_type construct_from_utf16(const wchar_t* str); static iterator begin(string_type& str) { return str.begin(); }
static string_type construct_from_utf16(const wchar_t* str, int length); static iterator end(string_type& str) { return str.end(); }
static std::wstring asStdWString(const string_type& str);
static const_reverse_iterator rbegin(const string_type& str) { return str.rbegin(); }
typedef Arabica::io::basic_iconvertstream<wchar_t, std::char_traits<wchar_t>,
char, std::char_traits<char> > widener_t; // only used to constuct error strings - don't have to be highly efficient!
typedef Arabica::io::basic_oconvertstream<wchar_t, std::char_traits<wchar_t>, static std::string asStdString(const string_type& str);
char, std::char_traits<char> > narrower_t;
#ifndef ARABICA_NO_WCHAR_T
static string_type construct_from_utf16(const wchar_t* str);
static const std::locale& utf8ucs2_locale() static string_type construct_from_utf16(const wchar_t* str, int length);
{ static std::wstring asStdWString(const string_type& str);
static const std::locale loc = std::locale(std::locale(), new Arabica::convert::utf8ucs2codecvt);
return loc; typedef Arabica::io::basic_iconvertstream<wchar_t, std::char_traits<wchar_t>,
} char, std::char_traits<char> > widener_t;
#endif //ARABICA_NO_WCHAR_T typedef Arabica::io::basic_oconvertstream<wchar_t, std::char_traits<wchar_t>,
char, std::char_traits<char> > narrower_t;
}; // class default_string_adaptor_base
static const std::locale& utf8ucs2_locale()
// specialize for std::string and std::wstring {
template<> static const std::locale loc = std::locale(std::locale(), new Arabica::convert::utf8ucs2codecvt);
class default_string_adaptor<std::string> : return loc;
public string_adaptor_tag, }
public default_string_adaptor_base<std::string> #endif //ARABICA_NO_WCHAR_T
{
public: }; // class default_string_adaptor_base
static char convert_from_utf8(char c) { return c; }
// specialize for std::string and std::wstring
static std::string construct_from_utf8(const char* str) template<>
{ class default_string_adaptor<std::string> :
return str ? std::string(str) : std::string(); public string_adaptor_tag,
} // construct_from_utf8 public default_string_adaptor_base<std::string>
{
static std::string construct_from_utf8(const char* str, int length) public:
{
return std::string(str, length); static char convert_from_utf8(char c) { return c; }
} // construct_from_utf8
static std::string construct_from_utf8(const char* str)
static const std::string& asStdString(const std::string& str) {
{ return str ? std::string(str) : std::string();
return str; } // construct_from_utf8
} // asStdString
static std::string construct_from_utf8(const char* str, int length)
#ifndef ARABICA_NO_WCHAR_T {
static std::string construct_from_utf16(const wchar_t* str) return std::string(str, length);
{ } // construct_from_utf8
narrower_t n;
n.imbue(utf8ucs2_locale()); static const std::string& asStdString(const std::string& str)
n.str(str ? str : L""); {
//n << str; return str;
return n.str(); } // asStdString
}
#ifndef ARABICA_NO_WCHAR_T
static std::string construct_from_utf16(const wchar_t* str, int length) static std::string construct_from_utf16(const wchar_t* str)
{ {
narrower_t n; narrower_t n;
n.imbue(utf8ucs2_locale()); n.imbue(utf8ucs2_locale());
n.str(std::wstring(str, length)); n.str(str ? str : L"");
//for(int i = 0; i < length; ++i) //n << str;
// n << str[i]; return n.str();
return n.str(); }
} // construct_from_utf16
static std::string construct_from_utf16(const wchar_t* str, int length)
static std::wstring asStdWString(const std::string& str) {
{ narrower_t n;
widener_t w; n.imbue(utf8ucs2_locale());
w.imbue(utf8ucs2_locale()); n.str(std::wstring(str, length));
w.str(str); //for(int i = 0; i < length; ++i)
return w.str(); // n << str[i];
} // toStdWString return n.str();
#endif //ARABICA_NO_WCHAR_T } // construct_from_utf16
}; // class default_string_adaptor<std::string> static std::wstring asStdWString(const std::string& str)
{
widener_t w;
#ifndef ARABICA_NO_WCHAR_T w.imbue(utf8ucs2_locale());
w.str(str);
template<> return w.str();
class default_string_adaptor<std::wstring> : } // toStdWString
public string_adaptor_tag, #endif //ARABICA_NO_WCHAR_T
public default_string_adaptor_base<std::wstring>
{ }; // class default_string_adaptor<std::string>
public:
static wchar_t makeValueT(char c) #ifndef ARABICA_NO_WCHAR_T
{
return static_cast<wchar_t>(c); template<>
} // makeValueT class default_string_adaptor<std::wstring> :
public string_adaptor_tag,
static std::wstring construct_from_utf8(const char* str) public default_string_adaptor_base<std::wstring>
{ {
widener_t w; public:
w.imbue(utf8ucs2_locale());
w.str(str ? str : ""); static wchar_t makeValueT(char c)
return w.str(); {
} return static_cast<wchar_t>(c);
} // makeValueT
static std::wstring construct_from_utf8(const char* str, int length)
{ static std::wstring construct_from_utf8(const char* str)
widener_t w; {
w.imbue(utf8ucs2_locale()); widener_t w;
w.str(std::string(str, length)); w.imbue(utf8ucs2_locale());
return w.str(); w.str(str ? str : "");
} return w.str();
}
static std::wstring construct_from_utf16(const wchar_t* str)
{ static std::wstring construct_from_utf8(const char* str, int length)
return str ? std::wstring(str) : std::wstring(); {
} widener_t w;
w.imbue(utf8ucs2_locale());
static std::wstring construct_from_utf16(const wchar_t* str, int length) w.str(std::string(str, length));
{ return w.str();
return std::wstring(str, length); }
}
static std::wstring construct_from_utf16(const wchar_t* str)
static std::string asStdString(const std::wstring& str) {
{ return str ? std::wstring(str) : std::wstring();
narrower_t n; }
n.imbue(utf8ucs2_locale());
n.str(str); static std::wstring construct_from_utf16(const wchar_t* str, int length)
return n.str(); {
} // toStdString return std::wstring(str, length);
}
static const std::wstring& asStdWString(const std::wstring& str)
{ static std::string asStdString(const std::wstring& str)
return str; {
} // toStdWString narrower_t n;
n.imbue(utf8ucs2_locale());
}; // class default_string_adaptor<std::wstring> n.str(str);
return n.str();
} // toStdString
#endif // ARABICA_NO_WCHAR_T
static const std::wstring& asStdWString(const std::wstring& str)
} // namespace Arabica {
return str;
#endif } // toStdWString
// end of file
}; // class default_string_adaptor<std::wstring>
#endif // ARABICA_NO_WCHAR_T
} // namespace Arabica
#endif
// end of file

View file

@ -1,390 +1,390 @@
#ifndef ARABICA_NAMESPACE_SUPPORT_H #ifndef ARABICA_NAMESPACE_SUPPORT_H
#define ARABICA_NAMESPACE_SUPPORT_H #define ARABICA_NAMESPACE_SUPPORT_H
#include <SAX/ArabicaConfig.hpp> #include <SAX/ArabicaConfig.hpp>
#include <map> #include <map>
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <XML/QName.hpp> #include <XML/QName.hpp>
#include <SAX/SAXException.hpp> #include <SAX/SAXException.hpp>
namespace Arabica namespace Arabica
{ {
namespace SAX namespace SAX
{ {
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
struct NamespaceConstants struct NamespaceConstants
{ {
const string_type xml; const string_type xml;
const string_type xmlns; const string_type xmlns;
const string_type xml_uri; const string_type xml_uri;
const string_type xmlns_uri; const string_type xmlns_uri;
const string_type xmlns11_uri; const string_type xmlns11_uri;
const string_type colon; const string_type colon;
NamespaceConstants() : NamespaceConstants() :
xml(string_adaptor::construct_from_utf8("xml")), xml(string_adaptor::construct_from_utf8("xml")),
xmlns(string_adaptor::construct_from_utf8("xmlns")), xmlns(string_adaptor::construct_from_utf8("xmlns")),
xml_uri(string_adaptor::construct_from_utf8("http://www.w3.org/XML/1998/namespace")), xml_uri(string_adaptor::construct_from_utf8("http://www.w3.org/XML/1998/namespace")),
xmlns_uri(), xmlns_uri(),
xmlns11_uri(string_adaptor::construct_from_utf8("http://www.w3.org/2000/xmlns/")), xmlns11_uri(string_adaptor::construct_from_utf8("http://www.w3.org/2000/xmlns/")),
colon(string_adaptor::construct_from_utf8(":")) colon(string_adaptor::construct_from_utf8(":"))
{ {
} // NamespaceConstants } // NamespaceConstants
}; // struct NamespaceContants }; // struct NamespaceContants
/** /**
* Encapsulate Namespace logic for use by SAX drivers. * Encapsulate Namespace logic for use by SAX drivers.
* *
* <p>This class encapsulates the logic of Namespace processing: * <p>This class encapsulates the logic of Namespace processing:
* it tracks the declarations currently in force for each context * it tracks the declarations currently in force for each context
* and automatically processes qualified XML 1.0 names into their * and automatically processes qualified XML 1.0 names into their
* Namespace parts; it can also be used in reverse for generating * Namespace parts; it can also be used in reverse for generating
* XML 1.0 from Namespaces.</p> * XML 1.0 from Namespaces.</p>
* *
* <p>Namespace support objects are reusable, but the reset method * <p>Namespace support objects are reusable, but the reset method
* must be invoked between each session.</p> * must be invoked between each session.</p>
* *
* <p>Here is a simple session:</p> * <p>Here is a simple session:</p>
* *
* <pre> * <pre>
* NamespaceSupport support; * NamespaceSupport support;
* *
* support.pushContext(); * support.pushContext();
* support.declarePrefix("", "http://www.w3.org/1999/xhtml"); * support.declarePrefix("", "http://www.w3.org/1999/xhtml");
* support.declarePrefix("dc", "http://www.purl.org/dc#"); * support.declarePrefix("dc", "http://www.purl.org/dc#");
* *
* NamespaceSupport parts = support.processName("p", parts, false); * NamespaceSupport parts = support.processName("p", parts, false);
* std::cout << "Namespace URI: " << parts.URI << std::endl; * std::cout << "Namespace URI: " << parts.URI << std::endl;
* std::cout << "Local name: " << parts.localName << std::endl; * std::cout << "Local name: " << parts.localName << std::endl;
* std::cout << "Raw name: " << parts.rawName << std::endl; * std::cout << "Raw name: " << parts.rawName << std::endl;
* parts = support.processName("dc:title", parts, false); * parts = support.processName("dc:title", parts, false);
* std::cout << "Namespace URI: " << parts.URI << std::endl; * std::cout << "Namespace URI: " << parts.URI << std::endl;
* std::cout << "Local name: " << parts.localName << std::endl; * std::cout << "Local name: " << parts.localName << std::endl;
* std::cout << "Raw name: " << parts.rawName << std::endl; * std::cout << "Raw name: " << parts.rawName << std::endl;
* support.popContext(); * support.popContext();
* </pre> * </pre>
* *
* <p>Note that this class is optimized for the use case where most * <p>Note that this class is optimized for the use case where most
* elements do not contain Namespace declarations: if the same * elements do not contain Namespace declarations: if the same
* prefix/URI mapping is repeated for each context (for example), this * prefix/URI mapping is repeated for each context (for example), this
* class will be somewhat less efficient.</p> * class will be somewhat less efficient.</p>
* *
* @since SAX 2.0 * @since SAX 2.0
* @author Jez Higgins, * @author Jez Higgins,
* <a href="mailto:jez@jezuk.co.uk">jez@jezuk.co.uk</a> * <a href="mailto:jez@jezuk.co.uk">jez@jezuk.co.uk</a>
* @version 2.0 * @version 2.0
*/ */
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
class NamespaceSupport class NamespaceSupport
{ {
public: public:
typedef std::vector<string_type> stringListT; typedef std::vector<string_type> stringListT;
// functions // functions
NamespaceSupport() NamespaceSupport()
{ {
reset(); reset();
} // NamespaceSupport } // NamespaceSupport
/** /**
* Reset this Namespace support object for reuse. * Reset this Namespace support object for reuse.
* *
* <p>It is necessary to invoke this method before reusing the * <p>It is necessary to invoke this method before reusing the
* Namespace support object for a new session.</p> * Namespace support object for a new session.</p>
*/ */
void reset() void reset()
{ {
contexts_.clear(); contexts_.clear();
contexts_.push_back(Context()); contexts_.push_back(Context());
contexts_.back().insert(std::make_pair(nsc_.xml, nsc_.xml_uri)); contexts_.back().insert(std::make_pair(nsc_.xml, nsc_.xml_uri));
} // reset } // reset
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Context management. // Context management.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
/** /**
* Start a new Namespace context. * Start a new Namespace context.
* *
* <p>Normally, you should push a new context at the beginning * <p>Normally, you should push a new context at the beginning
* of each XML element: the new context will automatically inherit * of each XML element: the new context will automatically inherit
* the declarations of its parent context, but it will also keep * the declarations of its parent context, but it will also keep
* track of which declarations were made within this context.</p> * track of which declarations were made within this context.</p>
* *
* <p>The Namespace support object always starts with a base context * <p>The Namespace support object always starts with a base context
* already in force: in this context, only the "xml" prefix is * already in force: in this context, only the "xml" prefix is
* declared.</p> * declared.</p>
* *
* @see #popContext * @see #popContext
*/ */
void pushContext() void pushContext()
{ {
contexts_.push_back(Context()); contexts_.push_back(Context());
} // pushContext } // pushContext
/** /**
* Revert to the previous Namespace context. * Revert to the previous Namespace context.
* *
* <p>Normally, you should pop the context at the end of each * <p>Normally, you should pop the context at the end of each
* XML element. After popping the context, all Namespace prefix * XML element. After popping the context, all Namespace prefix
* mappings that were previously in force are restored.</p> * mappings that were previously in force are restored.</p>
* *
* <p>You must not attempt to declare additional Namespace * <p>You must not attempt to declare additional Namespace
* prefixes after popping a context, unless you push another * prefixes after popping a context, unless you push another
* context first.</p> * context first.</p>
* *
* @see #pushContext * @see #pushContext
*/ */
void popContext() void popContext()
{ {
contexts_.pop_back(); contexts_.pop_back();
} // popContext } // popContext
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// Operations within a context. // Operations within a context.
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
/** /**
* Declare a Namespace prefix. * Declare a Namespace prefix.
* *
* <p>This method declares a prefix in the current Namespace * <p>This method declares a prefix in the current Namespace
* context; the prefix will remain in force until this context * context; the prefix will remain in force until this context
* is popped, unless it is shadowed in a descendant context.</p> * is popped, unless it is shadowed in a descendant context.</p>
* *
* <p>To declare a default Namespace, use the empty string. The * <p>To declare a default Namespace, use the empty string. The
* prefix must not be "xml" or "xmlns".</p> * prefix must not be "xml" or "xmlns".</p>
* *
* <p>Note that you must <em>not</em> declare a prefix after * <p>Note that you must <em>not</em> declare a prefix after
* you've pushed and popped another Namespace.</p> * you've pushed and popped another Namespace.</p>
* *
* <p>Note that there is an asymmetry in this library: while {@link * <p>Note that there is an asymmetry in this library: while {@link
* #getPrefix getPrefix} will not return the default "" prefix, * #getPrefix getPrefix} will not return the default "" prefix,
* even if you have declared one; to check for a default prefix, * even if you have declared one; to check for a default prefix,
* you have to look it up explicitly using {@link #getURI getURI}. * you have to look it up explicitly using {@link #getURI getURI}.
* This asymmetry exists to make it easier to look up prefixes * This asymmetry exists to make it easier to look up prefixes
* for attribute names, where the default prefix is not allowed.</p> * for attribute names, where the default prefix is not allowed.</p>
* *
* @param prefix The prefix to declare, or the empty string. * @param prefix The prefix to declare, or the empty string.
* @param uri The Namespace URI to associate with the prefix. * @param uri The Namespace URI to associate with the prefix.
* @return true if the prefix was legal, false otherwise * @return true if the prefix was legal, false otherwise
* @see #processName * @see #processName
* @see #getURI * @see #getURI
* @see #getPrefix * @see #getPrefix
*/ */
bool declarePrefix(const string_type& prefix, const string_type& uri) bool declarePrefix(const string_type& prefix, const string_type& uri)
{ {
if((prefix == nsc_.xml) || (prefix == nsc_.xmlns)) if((prefix == nsc_.xml) || (prefix == nsc_.xmlns))
return false; return false;
contexts_.back().insert(std::make_pair(prefix, uri)); contexts_.back().insert(std::make_pair(prefix, uri));
return true; return true;
} // declarePrefix } // declarePrefix
/** /**
* Process a raw XML 1.0 name. * Process a raw XML 1.0 name.
* *
* <p>This method processes a raw XML 1.0 name in the current * <p>This method processes a raw XML 1.0 name in the current
* context by removing the prefix and looking it up among the * context by removing the prefix and looking it up among the
* prefixes currently declared. * prefixes currently declared.
* *
* <p>If * <p>If
* the raw name has a prefix that has not been declared, then * the raw name has a prefix that has not been declared, then
* the return value will be empty.</p> * the return value will be empty.</p>
* *
* <p>Note that attribute names are processed differently than * <p>Note that attribute names are processed differently than
* element names: an unprefixed element name will received the * element names: an unprefixed element name will received the
* default Namespace (if any), while an unprefixed attribute name * default Namespace (if any), while an unprefixed attribute name
* will not.</p> * will not.</p>
* *
* @param qName The raw XML 1.0 name to be processed. * @param qName The raw XML 1.0 name to be processed.
* @param isAttribute A flag indicating whether this is an * @param isAttribute A flag indicating whether this is an
* attribute name (true) or an element name (false). * attribute name (true) or an element name (false).
* @return A <code>Parts</code> holding three strings representing the * @return A <code>Parts</code> holding three strings representing the
* Namespace URI (or empty string), the local name, and the raw XML * Namespace URI (or empty string), the local name, and the raw XML
* 1.0 name. * 1.0 name.
* @see #declarePrefix * @see #declarePrefix
*/ */
private: private:
class URIMapper class URIMapper
{ {
public: public:
URIMapper(const NamespaceSupport* ns) : ns_(ns) { } URIMapper(const NamespaceSupport* ns) : ns_(ns) { }
string_type operator()(const string_type& prefix) const { return ns_->getURI(prefix); } string_type operator()(const string_type& prefix) const { return ns_->getURI(prefix); }
private: private:
const NamespaceSupport* const ns_; const NamespaceSupport* const ns_;
}; // class URIMapper }; // class URIMapper
public: public:
XML::QualifiedName<string_type, string_adaptor> processName(const string_type& rawName, bool isAttribute) const XML::QualifiedName<string_type, string_adaptor> processName(const string_type& rawName, bool isAttribute) const
{ {
try try
{ {
return XML::QualifiedName<string_type, string_adaptor>::parseQName(rawName, isAttribute, URIMapper(this)); return XML::QualifiedName<string_type, string_adaptor>::parseQName(rawName, isAttribute, URIMapper(this));
} // try } // try
catch(const std::runtime_error& ex) catch(const std::runtime_error& ex)
{ {
throw SAX::SAXException(ex.what()); throw SAX::SAXException(ex.what());
} // catch } // catch
} // processName } // processName
/** /**
* Look up a prefix and get the currently-mapped Namespace URI. * Look up a prefix and get the currently-mapped Namespace URI.
* *
* <p>This method looks up the prefix in the current context. * <p>This method looks up the prefix in the current context.
* Use the empty string ("") for the default Namespace.</p> * Use the empty string ("") for the default Namespace.</p>
* *
* @param prefix The prefix to look up. * @param prefix The prefix to look up.
* @return The associated Namespace URI, or empty string if the prefix * @return The associated Namespace URI, or empty string if the prefix
* is undeclared in this context. * is undeclared in this context.
* @see #getPrefix * @see #getPrefix
* @see #getPrefixes * @see #getPrefixes
*/ */
string_type getURI(const string_type& prefix) const string_type getURI(const string_type& prefix) const
{ {
for(typename contextListT::const_reverse_iterator i = contexts_.rbegin(); i != contexts_.rend(); ++i) for(typename contextListT::const_reverse_iterator i = contexts_.rbegin(); i != contexts_.rend(); ++i)
{ {
typename stringMapT::const_iterator u = i->find(prefix); typename stringMapT::const_iterator u = i->find(prefix);
if(u != i->end()) if(u != i->end())
return u->second; return u->second;
} // for ... } // for ...
return string_type(); return string_type();
} // getURI } // getURI
/** /**
* Return one of the prefixes mapped to a Namespace URI. * Return one of the prefixes mapped to a Namespace URI.
* *
* <p>If more than one prefix is currently mapped to the same * <p>If more than one prefix is currently mapped to the same
* URI, this method will make an arbitrary selection; if you * URI, this method will make an arbitrary selection; if you
* want all of the prefixes, use the {@link #getPrefixes} * want all of the prefixes, use the {@link #getPrefixes}
* method instead.</p> * method instead.</p>
* *
* <p><strong>Note:</strong> this will never return the empty (default) prefix; * <p><strong>Note:</strong> this will never return the empty (default) prefix;
* to check for a default prefix, use the {@link #getURI getURI} * to check for a default prefix, use the {@link #getURI getURI}
* method with an argument of "".</p> * method with an argument of "".</p>
* *
* @param uri The Namespace URI. * @param uri The Namespace URI.
* @return One of the prefixes currently mapped to the URI supplied, * @return One of the prefixes currently mapped to the URI supplied,
* or an empty string if none is mapped or if the URI is assigned to * or an empty string if none is mapped or if the URI is assigned to
* the default Namespace. * the default Namespace.
* @see #getPrefixes(const string_type&) * @see #getPrefixes(const string_type&)
* @see #getURI * @see #getURI
*/ */
string_type getPrefix(const string_type& uri) const string_type getPrefix(const string_type& uri) const
{ {
for(typename contextListT::const_reverse_iterator i = contexts_.rbegin(); i != contexts_.rend(); ++i) for(typename contextListT::const_reverse_iterator i = contexts_.rbegin(); i != contexts_.rend(); ++i)
{ {
for(typename stringMapT::const_iterator u = i->begin(); u != i->end(); ++u) for(typename stringMapT::const_iterator u = i->begin(); u != i->end(); ++u)
if(u->second == uri) if(u->second == uri)
return u->first; return u->first;
} // for ... } // for ...
return string_type(); return string_type();
} // getPrefix } // getPrefix
/** /**
* Returns all prefixes currently declared. * Returns all prefixes currently declared.
* *
* <p><strong>Note:</strong> if there is a default prefix, it will not be * <p><strong>Note:</strong> if there is a default prefix, it will not be
* returned in this enumeration; check for the default prefix * returned in this enumeration; check for the default prefix
* using the {@link #getURI getURI} with an argument of "".</p> * using the {@link #getURI getURI} with an argument of "".</p>
* *
* @return A list of all prefixes declared in the * @return A list of all prefixes declared in the
* current context except for the empty (default) * current context except for the empty (default)
* prefix. * prefix.
* @see #getDeclaredPrefixes * @see #getDeclaredPrefixes
* @see #getURI * @see #getURI
*/ */
stringListT getPrefixes() const stringListT getPrefixes() const
{ {
stringListT prefixes; stringListT prefixes;
for(typename contextListT::const_reverse_iterator i = contexts_.rbegin(); i != contexts_.rend(); ++i) for(typename contextListT::const_reverse_iterator i = contexts_.rbegin(); i != contexts_.rend(); ++i)
{ {
for(typename stringMapT::const_iterator u = i->begin(); u != i->end(); ++u) for(typename stringMapT::const_iterator u = i->begin(); u != i->end(); ++u)
if(!u->first.empty()) if(!string_adaptor::empty(u->first))
prefixes.push_back(u->first); prefixes.push_back(u->first);
} // for ... } // for ...
return prefixes; return prefixes;
} // getPrefixes } // getPrefixes
/** /**
* Returns a list of all prefixes currently declared for a URI. * Returns a list of all prefixes currently declared for a URI.
* *
* <p>This method returns prefixes mapped to a specific Namespace * <p>This method returns prefixes mapped to a specific Namespace
* URI. The xml: prefix will be included. If you want only one * URI. The xml: prefix will be included. If you want only one
* prefix that's mapped to the Namespace URI, and you don't care * prefix that's mapped to the Namespace URI, and you don't care
* which one you get, use the {@link #getPrefix getPrefix} * which one you get, use the {@link #getPrefix getPrefix}
* method instead.</p> * method instead.</p>
* *
* <p><strong>Note:</strong> the empty (default) prefix is <em>never</em> included * <p><strong>Note:</strong> the empty (default) prefix is <em>never</em> included
* in this enumeration; to check for the presence of a default * in this enumeration; to check for the presence of a default
* Namespace, use the {@link #getURI getURI} method with an * Namespace, use the {@link #getURI getURI} method with an
* argument of "".</p> * argument of "".</p>
* *
* @param uri The Namespace URI. * @param uri The Namespace URI.
* @return A list of all prefixes declared in the * @return A list of all prefixes declared in the
* current context. * current context.
* @see #getPrefix * @see #getPrefix
* @see #getDeclaredPrefixes * @see #getDeclaredPrefixes
* @see #getURI * @see #getURI
*/ */
stringListT getPrefixes(const string_type& uri) const stringListT getPrefixes(const string_type& uri) const
{ {
stringListT prefixes; stringListT prefixes;
for(typename contextListT::const_reverse_iterator i = contexts_.rbegin(); i != contexts_.rend(); ++i) for(typename contextListT::const_reverse_iterator i = contexts_.rbegin(); i != contexts_.rend(); ++i)
{ {
for(typename stringMapT::const_iterator u = i->begin(); u != i->end(); ++u) for(typename stringMapT::const_iterator u = i->begin(); u != i->end(); ++u)
if(u->second == uri) if(u->second == uri)
prefixes.push_back(u->first); prefixes.push_back(u->first);
} // for ... } // for ...
return prefixes; return prefixes;
} // getPrefixes } // getPrefixes
/** /**
* Return an enumeration of all prefixes declared in this context. * Return an enumeration of all prefixes declared in this context.
* *
* <p>The empty (default) prefix will be included in this * <p>The empty (default) prefix will be included in this
* enumeration; note that this behaviour differs from that of * enumeration; note that this behaviour differs from that of
* {@link #getPrefix} and {@link #getPrefixes}.</p> * {@link #getPrefix} and {@link #getPrefixes}.</p>
* *
* @return An enumeration of all prefixes declared in this * @return An enumeration of all prefixes declared in this
* context. * context.
* @see #getPrefixes * @see #getPrefixes
* @see #getURI * @see #getURI
*/ */
stringListT getDeclaredPrefixes() const stringListT getDeclaredPrefixes() const
{ {
stringListT prefixes; stringListT prefixes;
for(typename stringMapT::const_iterator u = contexts_.back().begin(); u != contexts_.back().end(); ++u) for(typename stringMapT::const_iterator u = contexts_.back().begin(); u != contexts_.back().end(); ++u)
prefixes.push_back(u->first); prefixes.push_back(u->first);
return prefixes; return prefixes;
} // getDeclaredPrefixes } // getDeclaredPrefixes
private: private:
typedef typename std::multimap<string_type, string_type> stringMapT; typedef typename std::multimap<string_type, string_type> stringMapT;
typedef stringMapT Context; typedef stringMapT Context;
typedef typename std::vector<Context> contextListT; typedef typename std::vector<Context> contextListT;
// member variables // member variables
contextListT contexts_; contextListT contexts_;
const NamespaceConstants<string_type, string_adaptor> nsc_; const NamespaceConstants<string_type, string_adaptor> nsc_;
// no impl // no impl
NamespaceSupport(const NamespaceSupport&); NamespaceSupport(const NamespaceSupport&);
NamespaceSupport& operator=(const NamespaceSupport&); NamespaceSupport& operator=(const NamespaceSupport&);
bool operator==(const NamespaceSupport&) const; bool operator==(const NamespaceSupport&) const;
}; // class NamespaceSupport }; // class NamespaceSupport
} // namespace SAX } // namespace SAX
} // namespace Arabica } // namespace Arabica
#endif // NamespaceSupportH #endif // NamespaceSupportH

View file

@ -1,126 +1,126 @@
#ifndef ARABICA_XMLBASE_SUPPORT_H #ifndef ARABICA_XMLBASE_SUPPORT_H
#define ARABICA_XMLBASE_SUPPORT_H #define ARABICA_XMLBASE_SUPPORT_H
/* /*
* $Id$ * $Id$
* *
* XMLBaseSupport is a helper class for tracking xml:base attributes. * XMLBaseSupport is a helper class for tracking xml:base attributes.
* Usage: * Usage:
* set location of the containing document by calling setDocumentLocation * set location of the containing document by calling setDocumentLocation
* this is usually done when during the setDocumentLocator SAX event * this is usually done when during the setDocumentLocator SAX event
* forward each startElement and endElement event * forward each startElement and endElement event
* to resolve a relative URL against the current base, call makeAbsolute * to resolve a relative URL against the current base, call makeAbsolute
* *
* Derived from org.apache.cocoon.xml.XMLBaseSupport. * Derived from org.apache.cocoon.xml.XMLBaseSupport.
* *
* XML Base is described at http://www.w3.org/TR/xmlbase/ * XML Base is described at http://www.w3.org/TR/xmlbase/
*/ */
#include <stack> #include <stack>
#include <utility> #include <utility>
#include <sstream> #include <sstream>
#include <text/UnicodeCharacters.hpp> #include <text/UnicodeCharacters.hpp>
#include <io/uri.hpp> #include <io/uri.hpp>
namespace Arabica namespace Arabica
{ {
namespace SAX namespace SAX
{ {
template<class string_type, class string_adaptor> template<class string_type, class string_adaptor>
struct XMLBaseConstants struct XMLBaseConstants
{ {
const string_type xml; const string_type xml;
const string_type xml_uri; const string_type xml_uri;
const string_type colon; const string_type colon;
const string_type base; const string_type base;
XMLBaseConstants() : XMLBaseConstants() :
xml(string_adaptor::construct_from_utf8("xml")), xml(string_adaptor::construct_from_utf8("xml")),
xml_uri(string_adaptor::construct_from_utf8("http://www.w3.org/XML/1998/namespace")), xml_uri(string_adaptor::construct_from_utf8("http://www.w3.org/XML/1998/namespace")),
colon(string_adaptor::construct_from_utf8(":")), colon(string_adaptor::construct_from_utf8(":")),
base(string_adaptor::construct_from_utf8("base")) base(string_adaptor::construct_from_utf8("base"))
{ {
} // XMLBaseConstants } // XMLBaseConstants
}; // struct XMLBaseConstants }; // struct XMLBaseConstants
template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> > template<class string_type, class string_adaptor = Arabica::default_string_adaptor<string_type> >
class XMLBaseSupport class XMLBaseSupport
{ {
public: public:
typedef typename string_adaptor::value_type valueT; typedef typename string_adaptor::value_type valueT;
typedef Attributes<string_type, string_adaptor> AttributesT; typedef Attributes<string_type, string_adaptor> AttributesT;
XMLBaseSupport() : XMLBaseSupport() :
depth_(0) { } depth_(0) { }
void setDocumentLocation(const string_type& loc) void setDocumentLocation(const string_type& loc)
{ {
bases_.push(std::make_pair(-1, loc)); bases_.push(std::make_pair(-1, loc));
} // setDocumentLocation } // setDocumentLocation
void startElement(const AttributesT& atts) void startElement(const AttributesT& atts)
{ {
++depth_; ++depth_;
string_type base = atts.getValue(xbc_.xml_uri, xbc_.base); string_type base = atts.getValue(xbc_.xml_uri, xbc_.base);
if(base.empty()) if(string_adaptor::empty(base))
return; return;
string_type baseURI = absolutise(currentBase(), base); string_type baseURI = absolutise(currentBase(), base);
bases_.push(std::make_pair(depth_, baseURI)); bases_.push(std::make_pair(depth_, baseURI));
} // startElement } // startElement
void endElement() void endElement()
{ {
if(currentDepth() == depth_) if(currentDepth() == depth_)
bases_.pop(); bases_.pop();
--depth_; --depth_;
} // endElement } // endElement
string_type currentBase() const string_type currentBase() const
{ {
if(!bases_.size()) if(!bases_.size())
return string_type(); return string_type();
return bases_.top().second; return bases_.top().second;
} // currentBase() } // currentBase()
string_type makeAbsolute(const string_type& spec) const string_type makeAbsolute(const string_type& spec) const
{ {
return absolutise(currentBase(), spec); return absolutise(currentBase(), spec);
} // makeAbsolute } // makeAbsolute
private: private:
string_type absolutise(const string_type& baseURI, const string_type& location) const string_type absolutise(const string_type& baseURI, const string_type& location) const
{ {
Arabica::io::URI base(string_adaptor::asStdString(baseURI)); Arabica::io::URI base(string_adaptor::asStdString(baseURI));
Arabica::io::URI absolute(base, string_adaptor::asStdString(location)); Arabica::io::URI absolute(base, string_adaptor::asStdString(location));
return string_adaptor::construct_from_utf8(absolute.as_string().c_str()); return string_adaptor::construct_from_utf8(absolute.as_string().c_str());
} // absolutise } // absolutise
int currentDepth() const int currentDepth() const
{ {
if(!bases_.size()) if(!bases_.size())
return -1; return -1;
return bases_.top().first; return bases_.top().first;
} // currentDepths } // currentDepths
private: private:
typedef std::pair<int, string_type> baseInfoT; typedef std::pair<int, string_type> baseInfoT;
typedef std::stack<baseInfoT> baseStackT; typedef std::stack<baseInfoT> baseStackT;
baseStackT bases_; baseStackT bases_;
int depth_; int depth_;
const XMLBaseConstants<string_type, string_adaptor> xbc_; const XMLBaseConstants<string_type, string_adaptor> xbc_;
// no impl // no impl
XMLBaseSupport(const XMLBaseSupport&); XMLBaseSupport(const XMLBaseSupport&);
XMLBaseSupport& operator=(const XMLBaseSupport&); XMLBaseSupport& operator=(const XMLBaseSupport&);
bool operator==(const XMLBaseSupport&); bool operator==(const XMLBaseSupport&);
}; // class XMLBaseSupport }; // class XMLBaseSupport
} // namespace SAX } // namespace SAX
} // namespace Arabica } // namespace Arabica
#endif #endif

View file

@ -107,7 +107,7 @@ public:
virtual void characters(const string_type& ch) virtual void characters(const string_type& ch)
{ {
if(no_content_) if(no_content_)
verifyNoCharacterData<string_type, string_adaptor>(ch, SC::include + SC::import); verifyNoCharacterData<string_type, string_adaptor>(ch, SC::include); // + SC::import
context_->parentHandler().characters(ch); context_->parentHandler().characters(ch);
} // characters } // characters

View file

@ -31,7 +31,7 @@ protected:
std::vector<InlineAttribute<string_type, string_adaptor> > inlineAtts; std::vector<InlineAttribute<string_type, string_adaptor> > inlineAtts;
for(int i = 0; i != atts.getLength(); ++i) for(int i = 0; i != atts.getLength(); ++i)
{ {
if(atts.getQName(i).find(SC::xmlns_colon) == 0) if(string_adaptor::find(atts.getQName(i), SC::xmlns_colon) == 0)
continue; continue;
if(atts.getURI(i) == StylesheetConstant<string_type, string_adaptor>::NamespaceURI) if(atts.getURI(i) == StylesheetConstant<string_type, string_adaptor>::NamespaceURI)
continue; continue;
@ -42,9 +42,9 @@ protected:
else else
{ {
std::pair<string_type, string_type> remap = baseT::context().remappedNamespace(atts.getURI(i)); std::pair<string_type, string_type> remap = baseT::context().remappedNamespace(atts.getURI(i));
if(remap.first.empty() && !remap.second.empty()) if(string_adaptor::empty(remap.first) && !string_adaptor::empty(remap.second))
remap.first = baseT::context().autoNamespacePrefix(); remap.first = baseT::context().autoNamespacePrefix();
string_type name = remap.first + SC::COLON + atts.getLocalName(i); string_type name = makeName(remap.first, atts.getLocalName(i));
inlineAtts.push_back(InlineAttribute<string_type, string_adaptor>(name, inlineAtts.push_back(InlineAttribute<string_type, string_adaptor>(name,
remap.second, remap.second,
baseT::context().xpath_attribute_value_template(atts.getValue(i)))); baseT::context().xpath_attribute_value_template(atts.getValue(i))));
@ -55,9 +55,18 @@ protected:
return new InlineElement<string_type, string_adaptor>(qName, namespaceURI, inlineAtts); return new InlineElement<string_type, string_adaptor>(qName, namespaceURI, inlineAtts);
const std::pair<string_type, string_type>& remap = baseT::context().remappedNamespace(namespaceURI); const std::pair<string_type, string_type>& remap = baseT::context().remappedNamespace(namespaceURI);
string_type name = remap.first + SC::COLON + localName; string_type name = makeName(remap.first, localName);
return new InlineElement<string_type, string_adaptor>(name, remap.second, inlineAtts); return new InlineElement<string_type, string_adaptor>(name, remap.second, inlineAtts);
} // createContainer } // createContainer
private:
string_type makeName(const string_type prefix, const string_type localName) const
{
string_type n = prefix;
string_adaptor::append(n, SC::COLON);
string_adaptor::append(n, localName);
return n;
} // makeName
}; // class InlineElementHandler }; // class InlineElementHandler

View file

@ -71,7 +71,7 @@ public:
virtual void characters(const string_type& ch) virtual void characters(const string_type& ch)
{ {
for(typename string_type::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i) for(typename string_adaptor::const_iterator i = string_adaptor::begin(ch), e = string_adaptor::end(ch); i != e; ++i)
if(!Arabica::XML::is_space(*i)) if(!Arabica::XML::is_space(*i))
{ {
container_->add_item(new Text<string_type, string_adaptor>(ch)); container_->add_item(new Text<string_type, string_adaptor>(ch));

View file

@ -44,10 +44,10 @@ public:
std::map<string_type, string_type> namespaces = context_.inScopeNamespaces(); std::map<string_type, string_type> namespaces = context_.inScopeNamespaces();
if((namespaces.find(stylesheet_prefix) == namespaces.end()) && if((namespaces.find(stylesheet_prefix) == namespaces.end()) &&
(!stylesheet_prefix.empty())) (!string_adaptor::empty(stylesheet_prefix)))
throw SAX::SAXException(string_adaptor::asStdString(SC::namespace_alias) + " " + string_adaptor::asStdString(stylesheet_prefix) + " is not a declared namespace prefix"); throw SAX::SAXException(string_adaptor::asStdString(SC::namespace_alias) + " " + string_adaptor::asStdString(stylesheet_prefix) + " is not a declared namespace prefix");
if((namespaces.find(result_prefix) == namespaces.end()) && if((namespaces.find(result_prefix) == namespaces.end()) &&
(!result_prefix.empty())) (!string_adaptor::empty(result_prefix)))
throw SAX::SAXException(string_adaptor::asStdString(SC::namespace_alias) + " " + string_adaptor::asStdString(result_prefix) + " is not a declared namespace prefix"); throw SAX::SAXException(string_adaptor::asStdString(SC::namespace_alias) + " " + string_adaptor::asStdString(result_prefix) + " is not a declared namespace prefix");
context_.addNamespaceAlias(namespaces[stylesheet_prefix], result_prefix, namespaces[result_prefix]); context_.addNamespaceAlias(namespaces[stylesheet_prefix], result_prefix, namespaces[result_prefix]);

View file

@ -66,17 +66,17 @@ private:
{ {
CDATAElements elements; CDATAElements elements;
if(cdata_section_elements.empty()) if(string_adaptor::empty(cdata_section_elements))
return elements; return elements;
std::basic_istringstream<typename string_adaptor::value_type> string_type norm_cdata_sec_elements = text::normalize_whitespace<string_type, string_adaptor>(cdata_section_elements);
is(text::normalize_whitespace<string_type, string_adaptor>(cdata_section_elements)); std::basic_istringstream<typename string_adaptor::value_type> is(string_adaptor::asStdString(norm_cdata_sec_elements));
while(!is.eof()) while(!is.eof())
{ {
string_type e; std::basic_string<typename string_adaptor::value_type> e;
is >> e; is >> e;
XML::QualifiedName<string_type, string_adaptor> qualifiedName = context_.processElementQName(e); XML::QualifiedName<string_type, string_adaptor> qualifiedName = context_.processElementQName(string_adaptor::construct(e));
elements.insert(QName<string_type, string_adaptor>::create(qualifiedName)); elements.insert(QName<string_type, string_adaptor>::create(qualifiedName));
} // while } // while

View file

@ -43,7 +43,7 @@ public:
order = context_.xpath_attribute_value_template(attr[SC::order]); order = context_.xpath_attribute_value_template(attr[SC::order]);
caseorder = context_.xpath_attribute_value_template(attr[SC::case_order]); caseorder = context_.xpath_attribute_value_template(attr[SC::case_order]);
if(attr[SC::lang].length() != 0) if(string_adaptor::length(attr[SC::lang]) != 0)
std::cerr << "Sorry! Don't support xsl:sort lang attribute yet" << std::endl; std::cerr << "Sorry! Don't support xsl:sort lang attribute yet" << std::endl;
sort_ = new Sort<string_type, string_adaptor>(select, sort_ = new Sort<string_type, string_adaptor>(select,

View file

@ -26,7 +26,7 @@ public:
{ {
if(!done_params_) if(!done_params_)
{ {
for(typename string_type::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i) for(typename string_adaptor::const_iterator i = string_adaptor::begin(ch), e = string_adaptor::end(ch); i != e; ++i)
if(!Arabica::XML::is_space(*i)) if(!Arabica::XML::is_space(*i))
{ {
done_params_ = true; done_params_ = true;

View file

@ -46,7 +46,7 @@ public:
virtual void characters(const string_type& ch) virtual void characters(const string_type& ch)
{ {
buffer_ += ch; string_adaptor::append(buffer_, ch);
} // characters } // characters
private: private:

View file

@ -144,7 +144,7 @@ public:
{ {
const string_type& name = r->first; const string_type& name = r->first;
const AttributeValidator<string_type, string_adaptor>& av = r->second; const AttributeValidator<string_type, string_adaptor>& av = r->second;
if((av.mandatory()) && (atts.getValue(name).empty())) if((av.mandatory()) && (string_adaptor::empty(atts.getValue(name))))
throw SAX::SAXException(string_adaptor::asStdString(parentElement) + ": Attribute " + string_adaptor::asStdString(name) + " must be specified"); throw SAX::SAXException(string_adaptor::asStdString(parentElement) + ": Attribute " + string_adaptor::asStdString(name) + " must be specified");
if(av.has_default()) if(av.has_default())
results[name] = av.default_value(); results[name] = av.default_value();
@ -300,7 +300,7 @@ template<class string_type, class string_adaptor>
void verifyNoCharacterData(const string_type& ch, void verifyNoCharacterData(const string_type& ch,
const string_type& name) const string_type& name)
{ {
for(typename string_type::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i) for(typename string_adaptor::const_iterator i = string_adaptor::begin(ch), e = string_adaptor::end(ch); i != e; ++i)
if(!Arabica::XML::is_space(*i)) if(!Arabica::XML::is_space(*i))
throw SAX::SAXException(string_adaptor::asStdString(name) + " element can not contain character data."); throw SAX::SAXException(string_adaptor::asStdString(name) + " element can not contain character data.");
} // verifyNoCharacterContent } // verifyNoCharacterContent

View file

@ -63,9 +63,9 @@ protected:
{ {
if(has_select_) if(has_select_)
{ {
for(typename string_type::const_iterator i = ch.begin(), e = ch.end(); i != e; ++i) for(typename string_adaptor::const_iterator i = string_adaptor::begin(ch), e = string_adaptor::end(ch); i != e; ++i)
if(!Arabica::XML::is_space(*i)) if(!Arabica::XML::is_space(*i))
throw SAX::SAXException("A variable or param can not have both a select attribute and text context"); throw SAX::SAXException("A variable or param can not have both a select attribute and text context");
} }
ItemContainerHandler<VType>::characters(ch); ItemContainerHandler<VType>::characters(ch);
} // characters } // characters

View file

@ -35,7 +35,7 @@ public:
ExecutionContext<string_type, string_adaptor>& context) const ExecutionContext<string_type, string_adaptor>& context) const
{ {
string_type name = name_->evaluateAsString(node, context.xpathContext()); string_type name = name_->evaluateAsString(node, context.xpathContext());
if(name.empty()) if(string_adaptor::empty(name))
throw SAX::SAXException("xsl:attribute name attribute must evaluate to a valid element name"); throw SAX::SAXException("xsl:attribute name attribute must evaluate to a valid element name");
string_type namesp; string_type namesp;
@ -45,7 +45,7 @@ public:
else else
{ {
QName<string_type, string_adaptor> qn = QName<string_type, string_adaptor>::create(name); QName<string_type, string_adaptor> qn = QName<string_type, string_adaptor>::create(name);
if(!qn.prefix.empty()) if(!string_adaptor::empty(qn.prefix))
{ {
typename std::map<string_type, string_type>::const_iterator ns = namespaces_.find(qn.prefix); typename std::map<string_type, string_type>::const_iterator ns = namespaces_.find(qn.prefix);
if(ns == namespaces_.end()) if(ns == namespaces_.end())

View file

@ -171,7 +171,7 @@ public:
{ {
std::basic_ostringstream<typename string_adaptor::value_type> ss; std::basic_ostringstream<typename string_adaptor::value_type> ss;
ss << SC::auto_ns << autoNs_++; ss << SC::auto_ns << autoNs_++;
return ss.str(); return string_adaptor::construct(ss.str());
} // autoNamespacePrefix } // autoNamespacePrefix
void set_precedence(const Precedence& prec) void set_precedence(const Precedence& prec)
@ -204,7 +204,7 @@ private:
const string_type& name, const string_type& name,
const std::vector<Arabica::XPath::XPathExpression<string_type> >& argExprs) const const std::vector<Arabica::XPath::XPathExpression<string_type> >& argExprs) const
{ {
if(!namespace_uri.empty()) if(!string_adaptor::empty(namespace_uri))
return new UndefinedFunction<string_type, string_adaptor>(namespace_uri, name, argExprs); return new UndefinedFunction<string_type, string_adaptor>(namespace_uri, name, argExprs);
// document // document

View file

@ -236,7 +236,7 @@ protected:
std::basic_ostringstream<typename string_adaptor::value_type> os; std::basic_ostringstream<typename string_adaptor::value_type> os;
os << node.underlying_impl(); os << node.underlying_impl();
return os.str(); return string_adaptor::construct(os.str());
} // doEvaluate } // doEvaluate
}; // class GenerateIdFunction }; // class GenerateIdFunction
@ -315,7 +315,7 @@ protected:
const QualifiedName expandedName = QualifiedName::parseQName(functionName, true, namespaces_); const QualifiedName expandedName = QualifiedName::parseQName(functionName, true, namespaces_);
if((expandedName.namespaceUri() != StylesheetConstant<string_type, string_adaptor>::NamespaceURI) && if((expandedName.namespaceUri() != StylesheetConstant<string_type, string_adaptor>::NamespaceURI) &&
(!expandedName.namespaceUri().empty())) (!string_adaptor::empty(expandedName.namespaceUri())))
return false; return false;
static string_type XSLTNames[] = { SC::apply_imports, static string_type XSLTNames[] = { SC::apply_imports,
@ -414,14 +414,14 @@ public:
{ {
typedef Arabica::text::Unicode<typename string_adaptor::value_type> UnicodeT; typedef Arabica::text::Unicode<typename string_adaptor::value_type> UnicodeT;
if(!namespace_uri.empty()) if(!string_adaptor::empty(namespace_uri))
{ {
error_ += UnicodeT::LEFT_SQUARE_BRACKET; string_adaptor::append(error_, UnicodeT::LEFT_SQUARE_BRACKET);
error_ += namespace_uri; string_adaptor::append(error_, namespace_uri);
error_ += UnicodeT::RIGHT_SQUARE_BRACKET; string_adaptor::append(error_, UnicodeT::RIGHT_SQUARE_BRACKET);
} // if .. } // if ..
error_ += name; string_adaptor::append(error_, name);
} // UndefinedFunction } // UndefinedFunction
protected: protected:

View file

@ -42,7 +42,7 @@ public:
if(findPrefix(namespaceURI) != EMPTY_STRING) if(findPrefix(namespaceURI) != EMPTY_STRING)
return; return;
bool remap = (attr && given_prefix.empty()) || (given_prefix == SC::xmlns); bool remap = (attr && string_adaptor::empty(given_prefix)) || (given_prefix == SC::xmlns);
string_type prefix = !remap ? given_prefix : autoNamespacePrefix(); string_type prefix = !remap ? given_prefix : autoNamespacePrefix();
@ -81,7 +81,7 @@ private:
{ {
std::basic_ostringstream<typename string_adaptor::value_type> ss; std::basic_ostringstream<typename string_adaptor::value_type> ss;
ss << SC::auto_ns << autoNs_++; ss << SC::auto_ns << autoNs_++;
return ss.str(); return string_adaptor::construct(ss.str());
} // autoNamespacePrefix } // autoNamespacePrefix
ScopeStack prefixStack_; ScopeStack prefixStack_;

View file

@ -65,7 +65,7 @@ public:
flush_current(); flush_current();
namespaceStack_.pushScope(); namespaceStack_.pushScope();
if(!namespaceURI.empty()) if(!string_adaptor::empty(namespaceURI))
namespaceStack_.declareNamespace(prefix, namespaceURI); namespaceStack_.declareNamespace(prefix, namespaceURI);
string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI); string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
@ -95,13 +95,21 @@ public:
if(!text_mode_) if(!text_mode_)
{ {
string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI); string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
do_end_element((!mapped_prefix.empty()) ? mapped_prefix + SC::COLON + localName : localName, namespaceURI); do_end_element((!string_adaptor::empty(mapped_prefix)) ? makeName(mapped_prefix, localName) : localName, namespaceURI);
element_stack_.pop(); element_stack_.pop();
} // end_element } // end_element
namespaceStack_.popScope(); namespaceStack_.popScope();
} // end_element } // end_element
string_type makeName(const string_type& prefix, const string_type& localName) const
{
string_type n = prefix;
string_adaptor::append(n, SC::COLON);
string_adaptor::append(n, localName);
return n;
} // makeName
void start_attribute(const string_type& qName, const string_type& namespaceURI) void start_attribute(const string_type& qName, const string_type& namespaceURI)
{ {
QName<string_type, string_adaptor> qn = QName<string_type, string_adaptor>::create(qName, namespaceURI); QName<string_type, string_adaptor> qn = QName<string_type, string_adaptor>::create(qName, namespaceURI);
@ -119,11 +127,11 @@ public:
return; return;
} // if ... } // if ...
if(!namespaceURI.empty()) if(!string_adaptor::empty(namespaceURI))
namespaceStack_.declareNamespace(prefix, namespaceURI, true); namespaceStack_.declareNamespace(prefix, namespaceURI, true);
string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI); string_type mapped_prefix = namespaceStack_.findPrefix(namespaceURI);
string_type qName = (!mapped_prefix.empty()) ? mapped_prefix + SC::COLON + localName : localName; string_type qName = (!string_adaptor::empty(mapped_prefix)) ? makeName(mapped_prefix, localName) : localName;
atts_.addOrReplaceAttribute(namespaceURI, atts_.addOrReplaceAttribute(namespaceURI,
localName, localName,
@ -141,7 +149,6 @@ public:
if(pending_attribute_ == -1) if(pending_attribute_ == -1)
return; return;
atts_.setValue(pending_attribute_, buffer_.str());
pending_attribute_ = -1; pending_attribute_ = -1;
} // end_attribute } // end_attribute
@ -173,7 +180,7 @@ public:
if(pending_attribute_ != -1) if(pending_attribute_ != -1)
{ {
atts_.setValue(pending_attribute_, atts_.getValue(pending_attribute_) + ch); atts_.setValue(pending_attribute_, string_adaptor::concat(atts_.getValue(pending_attribute_), ch));
return; return;
} // if ... } // if ...
@ -204,9 +211,9 @@ public:
if(!text_mode_) if(!text_mode_)
{ {
string_type comment = escape(buffer_.str(), SC::double_hyphen, SC::escaped_double_hyphen); string_type comment = escape(string_adaptor::construct(buffer_.str()), SC::double_hyphen, SC::escaped_double_hyphen);
if(comment.length() && *(comment.rbegin()) == SC::HYPHEN_MINUS) if(string_adaptor::length(comment) && *(string_adaptor::rbegin(comment)) == SC::HYPHEN_MINUS)
comment += SC::SPACE; string_adaptor::append(comment, SC::SPACE);
do_comment(comment); do_comment(comment);
} // if ... } // if ...
} // end_comment } // end_comment
@ -228,7 +235,7 @@ public:
if(!text_mode_) if(!text_mode_)
{ {
string_type data = escape(buffer_.str(), SC::PIEnd, SC::escaped_pi_end); string_type data = escape(string_adaptor::construct(buffer_.str()), SC::PIEnd, SC::escaped_pi_end);
do_processing_instruction(target_, data); do_processing_instruction(target_, data);
} // if ... } // if ...
} // end_processing_instruction } // end_processing_instruction
@ -260,11 +267,14 @@ protected:
private: private:
string_type escape(string_type str, const string_type& t, const string_type& r) const string_type escape(string_type str, const string_type& t, const string_type& r) const
{ {
typename string_type::size_type naughty = str.find(t); typename string_adaptor::size_type naughty = string_adaptor::find(str, t);
while(naughty != string_type::npos) while(naughty != string_adaptor::npos())
{ {
str.replace(naughty, t.length(), r, 0, r.length()); string_type newstr = string_adaptor::substr(str, 0, naughty);
naughty = str.find(t, naughty); string_adaptor::append(newstr, r);
string_adaptor::append(newstr, string_adaptor::substr(str, naughty + string_adaptor::length(t)));
str = newstr;
naughty = string_adaptor::find(str, t, naughty);
} // while } // while
return str; return str;
} // escape } // escape
@ -277,7 +287,7 @@ private:
if(is_buf) if(is_buf)
return true; return true;
buffer_.str(string_adaptor::empty_string()); buffer_.str(std::basic_string<typename string_adaptor::value_type>());
return false; return false;
} // push_buffering } // push_buffering
@ -349,7 +359,7 @@ private:
if(n->first == SC::xml) if(n->first == SC::xml)
continue; continue;
string_type qName = (n->first.empty()) ? SC::xmlns : SC::xmlns_colon + n->first; string_type qName = (string_adaptor::empty(n->first)) ? SC::xmlns : string_adaptor::concat(SC::xmlns_colon, n->first);
atts_.addAttribute(SC::xmlns_uri, atts_.addAttribute(SC::xmlns_uri,
n->first, n->first,
qName, qName,

View file

@ -37,25 +37,29 @@ public:
private: private:
void validate_name(const string_type& name) const void validate_name(const string_type& name) const
{ {
if(name.empty()) if(string_adaptor::empty(name))
throw SAX::SAXException("xsl:processing-instruction : name attribute must evaluate to a valid name"); throw SAX::SAXException("xsl:processing-instruction : name attribute must evaluate to a valid name");
if(!Arabica::XML::is_ncname<string_adaptor>(name)) if(!Arabica::XML::is_ncname<string_adaptor>(name))
throw SAX::SAXException("xsl:processing-instruction : '" + string_adaptor::asStdString(name) + "' is not valid as the name"); throw SAX::SAXException("xsl:processing-instruction : '" + string_adaptor::asStdString(name) + "' is not valid as the name");
if(name.length() != 3) if(string_adaptor::length(name) != 3)
return; return;
typedef Arabica::text::Unicode<char> UnicodeT; typedef Arabica::text::Unicode<char> UnicodeT;
if((name[0] != UnicodeT::CAPITAL_X) && typename string_adaptor::const_iterator i = string_adaptor::begin(name);
(name[0] != UnicodeT::LOWERCASE_X))
if((*i != UnicodeT::CAPITAL_X) &&
(*i != UnicodeT::LOWERCASE_X))
return; return;
if((name[1] != UnicodeT::CAPITAL_M) && ++i;
(name[1] != UnicodeT::LOWERCASE_M)) if((*i != UnicodeT::CAPITAL_M) &&
(*i != UnicodeT::LOWERCASE_M))
return; return;
if((name[2] != UnicodeT::CAPITAL_L) && ++i;
(name[2] != UnicodeT::LOWERCASE_L)) if((*i != UnicodeT::CAPITAL_L) &&
(*i != UnicodeT::LOWERCASE_L))
return; return;
throw SAX::SAXException("xsl:processing-instruction name can not be 'xml'"); throw SAX::SAXException("xsl:processing-instruction name can not be 'xml'");

View file

@ -20,18 +20,24 @@ struct QName
string_type qname; string_type qname;
QName(const string_type& p, QName(const string_type& p,
const string_type& lN, const string_type& lN,
const string_type& uri) : const string_type& uri) :
prefix(p), prefix(p),
localName(lN), localName(lN),
namespaceURI(uri), namespaceURI(uri),
qname(p.empty() ? lN : (p + SC::COLON + lN)) qname()
{ {
if(!string_adaptor::empty(p))
{
string_adaptor::append(qname, p);
string_adaptor::append(qname, SC::COLON);
} // if ...
string_adaptor::append(qname, lN);
} // QName } // QName
static QName create(const XML::QualifiedName<string_type>& qName) static QName create(const XML::QualifiedName<string_type>& qName)
{ {
if(qName.prefix().length() && qName.namespaceUri().empty()) if(string_adaptor::length(qName.prefix()) && string_adaptor::empty(qName.namespaceUri()))
throw SAX::SAXException("Prefix " + string_adaptor::asStdString(qName.prefix()) + " is not declared."); throw SAX::SAXException("Prefix " + string_adaptor::asStdString(qName.prefix()) + " is not declared.");
return QName(qName.prefix(), qName.localName(), qName.namespaceUri()); return QName(qName.prefix(), qName.localName(), qName.namespaceUri());
} // create } // create
@ -49,14 +55,14 @@ struct QName
string_type prefix; string_type prefix;
string_type localName; string_type localName;
size_t colon = qName.find(SC::COLON); size_t colon = string_adaptor::find(qName, SC::COLON);
if(colon == string_type::npos) if(colon == string_adaptor::npos())
localName = qName; localName = qName;
else else
{ {
prefix = qName.substr(0, colon); prefix = string_adaptor::substr(qName, 0, colon);
localName = qName.substr(colon+1); localName = string_adaptor::substr(qName, colon+1);
} }
return QName(prefix, localName, namespaceURI); return QName(prefix, localName, namespaceURI);
} // create } // create

View file

@ -146,7 +146,7 @@ protected:
{ {
stream_ << ' ' << atts.getQName(a) << '=' << '\"'; stream_ << ' ' << atts.getQName(a) << '=' << '\"';
string_type ch = atts.getValue(a); string_type ch = atts.getValue(a);
std::for_each(ch.begin(), ch.end(), Arabica::XML::attribute_escaper<typename string_adaptor::value_type>(stream_)); std::for_each(string_adaptor::begin(ch), string_adaptor::end(ch), Arabica::XML::attribute_escaper<typename string_adaptor::value_type>(stream_));
stream_ << '\"'; stream_ << '\"';
} }
empty_ = true; empty_ = true;
@ -175,11 +175,11 @@ protected:
close_element_if_empty(); close_element_if_empty();
if(!disable_output_escaping_ && !in_cdata_) if(!disable_output_escaping_ && !in_cdata_)
std::for_each(ch.begin(), ch.end(), Arabica::XML::text_escaper<typename string_adaptor::value_type>(stream_)); std::for_each(string_adaptor::begin(ch), string_adaptor::end(ch), Arabica::XML::text_escaper<typename string_adaptor::value_type>(stream_));
else if(in_cdata_) else if(in_cdata_)
{ {
size_t breakAt = ch.find(SC::CDATAEnd); size_t breakAt = string_adaptor::find(ch, SC::CDATAEnd);
if(breakAt == string_type::npos) if(breakAt == string_adaptor::npos())
{ {
stream_ << ch; stream_ << ch;
return; return;
@ -188,14 +188,14 @@ protected:
do do
{ {
breakAt += 2; breakAt += 2;
stream_ << ch.substr(start, breakAt); stream_ << string_adaptor::substr(ch, start, breakAt);
do_end_CDATA(); do_end_CDATA();
start = breakAt; start = breakAt;
do_start_CDATA(); do_start_CDATA();
breakAt = ch.find(SC::CDATAEnd, breakAt); breakAt = string_adaptor::find(ch, SC::CDATAEnd, breakAt);
} }
while(breakAt != string_type::npos); while(breakAt != string_adaptor::npos());
stream_ << ch.substr(start); stream_ << string_adaptor::substr(ch, start);
} }
else else
stream_ << ch; stream_ << ch;
@ -294,26 +294,26 @@ private:
{ {
string_type version = setting(SC::version); string_type version = setting(SC::version);
if(version.empty()) if(string_adaptor::empty(version))
version = SC::Version; version = SC::Version;
stream_ << "<?xml version=\"" << version << "\""; stream_ << "<?xml version=\"" << version << "\"";
} }
{ {
string_type s = setting(SC::standalone); string_type s = setting(SC::standalone);
if(!s.empty()) if(!string_adaptor::empty(s))
stream_ << " standalone=\"" << s << "\""; stream_ << " standalone=\"" << s << "\"";
} }
stream_ << "?>\n"; stream_ << "?>\n";
if(!qName.empty()) if(!string_adaptor::empty(qName))
{ {
string_type pub = setting(SC::doctype_public); string_type pub = setting(SC::doctype_public);
string_type sys = setting(SC::doctype_system); string_type sys = setting(SC::doctype_system);
if(!sys.empty()) if(!string_adaptor::empty(sys))
{ {
stream_ << "<!DOCTYPE " << qName << "\n"; stream_ << "<!DOCTYPE " << qName << "\n";
if(!pub.empty()) if(!string_adaptor::empty(pub))
stream_ << " PUBLIC \"" << pub << "\" \"" << sys << "\">\n"; stream_ << " PUBLIC \"" << pub << "\" \"" << sys << "\">\n";
else else
stream_ << " SYSTEM \"" << sys << "\">\n"; stream_ << " SYSTEM \"" << sys << "\">\n";
@ -382,7 +382,7 @@ protected:
if(lc == 0 || lc.getNodeType() != DOM::Node_base::TEXT_NODE) if(lc == 0 || lc.getNodeType() != DOM::Node_base::TEXT_NODE)
current().appendChild(document().createTextNode(ch)); current().appendChild(document().createTextNode(ch));
else else
lc.setNodeValue(lc.getNodeValue() + ch); lc.setNodeValue(string_adaptor::concat(lc.getNodeValue(), ch));
} // do_characters } // do_characters
void do_start_CDATA() void do_start_CDATA()
@ -462,9 +462,10 @@ private:
string_type sps; string_type sps;
if(indent_ != 0) if(indent_ != 0)
{ {
sps += '\n'; std::basic_string<typename string_adaptor::value_type> sps;
std::fill_n(std::back_inserter<string_type>(sps), indent_, ' '); sps += SC::CARRIAGE_RETURN;
do_characters(sps); std::fill_n(std::back_inserter<std::basic_string<typename string_adaptor::value_type> >(sps), indent_, SC::SPACE);
do_characters(string_adaptor::construct(sps));
} // if ... } // if ...
indent_ += 2; indent_ += 2;

View file

@ -63,7 +63,7 @@ public:
if(namespaceURI == SC::NamespaceURI) if(namespaceURI == SC::NamespaceURI)
startXSLTElement(namespaceURI, localName, qName, atts); startXSLTElement(namespaceURI, localName, qName, atts);
else if(!namespaceURI.empty()) else if(!string_adaptor::empty(namespaceURI))
startForeignElement(namespaceURI, localName, qName, atts); startForeignElement(namespaceURI, localName, qName, atts);
else else
oops(qName); oops(qName);
@ -103,7 +103,7 @@ private:
std::map<string_type, string_type> attributes = rules.gather(qName, atts); std::map<string_type, string_type> attributes = rules.gather(qName, atts);
if(attributes[SC::version] != SC::Version) if(attributes[SC::version] != SC::Version)
throw SAX::SAXException("I'm only a poor version 1.0 XSLT Transformer."); throw SAX::SAXException("I'm only a poor version 1.0 XSLT Transformer.");
if(!attributes[SC::extension_element_prefixes].empty()) if(!string_adaptor::empty(attributes[SC::extension_element_prefixes]))
throw SAX::SAXException("Haven't implemented extension-element-prefixes yet"); throw SAX::SAXException("Haven't implemented extension-element-prefixes yet");
} // startStylesheet } // startStylesheet
@ -121,7 +121,7 @@ private:
break; break;
} }
if(version.empty()) if(string_adaptor::empty(version))
throw SAX::SAXException("The source file does not look like a stylesheet."); throw SAX::SAXException("The source file does not look like a stylesheet.");
if(version != SC::Version) if(version != SC::Version)
throw SAX::SAXException("I'm only a poor version 1.0 XSLT Transformer."); throw SAX::SAXException("I'm only a poor version 1.0 XSLT Transformer.");

View file

@ -40,7 +40,7 @@ public:
mode_(mode), mode_(mode),
precedence_(precedence) precedence_(precedence)
{ {
if(!priority.empty()) if(!string_adaptor::empty(priority))
{ {
double p = boost::lexical_cast<double>(Arabica::text::normalize_whitespace<string_type, string_adaptor>(priority)); double p = boost::lexical_cast<double>(Arabica::text::normalize_whitespace<string_type, string_adaptor>(priority));
for(typename MatchExprList::iterator m = matches_.begin(), me = matches_.end(); m != me; ++m) for(typename MatchExprList::iterator m = matches_.begin(), me = matches_.end(); m != me; ++m)
@ -58,7 +58,7 @@ public:
} // execute } // execute
const MatchExprList& compiled_matches() const { return matches_; } const MatchExprList& compiled_matches() const { return matches_; }
bool has_name() const { return !name_.empty(); } bool has_name() const { return !string_adaptor::empty(name_); }
const string_type& name() const { return name_; } const string_type& name() const { return name_; }
const string_type& mode() const { return mode_; } const string_type& mode() const { return mode_; }
const Precedence& precedence() const { return precedence_; } const Precedence& precedence() const { return precedence_; }

View file

@ -159,7 +159,7 @@ public:
{ {
typedef Arabica::text::Unicode<typename string_adaptor::value_type> UnicodeT; typedef Arabica::text::Unicode<typename string_adaptor::value_type> UnicodeT;
string_type clarkName = namespace_uri.empty() ? name : make_clark_name(namespace_uri, name); string_type clarkName = string_adaptor::empty(namespace_uri) ? name : make_clark_name(namespace_uri, name);
if(std::find(resolutionStack_.begin(), resolutionStack_.end(), clarkName) != resolutionStack_.end()) if(std::find(resolutionStack_.begin(), resolutionStack_.end(), clarkName) != resolutionStack_.end())
throw std::runtime_error("Circular dependency: " + string_adaptor::asStdString(clarkName) + " refers to itself directly or indirectly."); throw std::runtime_error("Circular dependency: " + string_adaptor::asStdString(clarkName) + " refers to itself directly or indirectly.");

View file

@ -1,156 +1,177 @@
#include "silly_string.hpp" #include "silly_string.hpp"
#include <io/convertstream.hpp> #include <io/convertstream.hpp>
#include <convert/utf8ucs2codecvt.hpp> #include <convert/utf8ucs2codecvt.hpp>
#include <convert/ucs2utf8codecvt.hpp> #include <convert/ucs2utf8codecvt.hpp>
silly_string::silly_string() silly_string::silly_string()
{ {
} // silly_string } // silly_string
silly_string::silly_string(const silly_string& rhs) silly_string::silly_string(const silly_string& rhs)
{ {
s_ = rhs.s_; s_ = rhs.s_;
} // silly_string } // silly_string
silly_string::~silly_string() silly_string::~silly_string()
{ {
} // ~silly_string } // ~silly_string
bool silly_string::operator==(const silly_string& rhs) const bool silly_string::operator==(const silly_string& rhs) const
{ {
return s_ == rhs.s_; return s_ == rhs.s_;
} // operator== } // operator==
silly_string& silly_string::operator=(const silly_string& rhs) silly_string& silly_string::operator=(const silly_string& rhs)
{ {
s_ = rhs.s_; s_ = rhs.s_;
return *this; return *this;
} // operator= } // operator=
bool operator<(const silly_string& lhs, const silly_string& rhs) bool operator<(const silly_string& lhs, const silly_string& rhs)
{ {
return lhs.s_ < rhs.s_; return lhs.s_ < rhs.s_;
} // operator< } // operator<
//////////////////////////////////////// bool operator>(const silly_string& lhs, const silly_string& rhs)
//////////////////////////////////////// {
char silly_string_adaptor::convert_from_utf8(char c) return lhs.s_ > rhs.s_;
{ } // operator<
return c;
} // convert_from_utf8 ////////////////////////////////////////
////////////////////////////////////////
silly_string silly_string_adaptor::construct_from_utf8(const char* str) char silly_string_adaptor::convert_from_utf8(char c)
{ {
silly_string s; return c;
if(str) } // convert_from_utf8
s.s_ = str;
return s; silly_string silly_string_adaptor::construct_from_utf8(const char* str)
} // construct_from_utf8 {
silly_string s;
silly_string silly_string_adaptor::construct_from_utf8(const char* str, int length) if(str)
{ s.s_ = str;
silly_string s; return s;
if(str) } // construct_from_utf8
s.s_ = std::string(str, length);
return s; silly_string silly_string_adaptor::construct_from_utf8(const char* str, int length)
} // construct_from_utf8 {
silly_string s;
#ifndef ARABICA_NO_WCHAR_T if(str)
silly_string silly_string_adaptor::construct_from_utf16(const wchar_t* str) s.s_ = std::string(str, length);
{ return s;
Arabica::io::basic_oconvertstream<wchar_t, std::char_traits<wchar_t>, } // construct_from_utf8
char, std::char_traits<char> > narrower;
narrower.imbue(std::locale(narrower.getloc(), new Arabica::convert::utf8ucs2codecvt())); #ifndef ARABICA_NO_WCHAR_T
narrower.str(str ? str : L""); silly_string silly_string_adaptor::construct_from_utf16(const wchar_t* str)
silly_string s; {
s.s_ = narrower.str(); Arabica::io::basic_oconvertstream<wchar_t, std::char_traits<wchar_t>,
return s; char, std::char_traits<char> > narrower;
} // construct_from_utf16 narrower.imbue(std::locale(narrower.getloc(), new Arabica::convert::utf8ucs2codecvt()));
narrower.str(str ? str : L"");
silly_string silly_string_adaptor::construct_from_utf16(const wchar_t* str, int length) silly_string s;
{ s.s_ = narrower.str();
Arabica::io::basic_oconvertstream<wchar_t, std::char_traits<wchar_t>, return s;
char, std::char_traits<char> > narrower; } // construct_from_utf16
narrower.imbue(std::locale(narrower.getloc(), new Arabica::convert::utf8ucs2codecvt()));
narrower.str(std::wstring(str, length)); silly_string silly_string_adaptor::construct_from_utf16(const wchar_t* str, int length)
silly_string s; {
s.s_ = narrower.str(); Arabica::io::basic_oconvertstream<wchar_t, std::char_traits<wchar_t>,
return s; char, std::char_traits<char> > narrower;
} // construct_from_utf16 narrower.imbue(std::locale(narrower.getloc(), new Arabica::convert::utf8ucs2codecvt()));
#endif narrower.str(std::wstring(str, length));
silly_string s;
bool silly_string_adaptor::empty(const silly_string& s) s.s_ = narrower.str();
{ return s;
return s.s_.empty(); } // construct_from_utf16
} // empty #endif
silly_string_adaptor::size_type silly_string_adaptor::find(const silly_string& str, const silly_string& what) bool silly_string_adaptor::empty(const silly_string& s)
{ {
return str.s_.find(what.s_); return s.s_.empty();
} // find } // empty
silly_string_adaptor::size_type silly_string_adaptor::find(const silly_string& str, value_type c) silly_string_adaptor::size_type silly_string_adaptor::find(const silly_string& str, const silly_string& what)
{ {
return str.s_.find(c); return str.s_.find(what.s_);
} // find } // find
silly_string_adaptor::size_type silly_string_adaptor::find(const silly_string& str, const silly_string& what, silly_string_adaptor::size_type from) silly_string_adaptor::size_type silly_string_adaptor::find(const silly_string& str, value_type c)
{ {
return str.s_.find(what.s_, from); return str.s_.find(c);
} // find } // find
silly_string_adaptor::size_type silly_string_adaptor::find(const silly_string& str, value_type c, silly_string_adaptor::size_type from) silly_string_adaptor::size_type silly_string_adaptor::find(const silly_string& str, const silly_string& what, silly_string_adaptor::size_type from)
{ {
return str.s_.find(c, from); return str.s_.find(what.s_, from);
} // find } // find
silly_string silly_string_adaptor::substr(const silly_string& str, const size_type& offset) silly_string_adaptor::size_type silly_string_adaptor::find(const silly_string& str, value_type c, silly_string_adaptor::size_type from)
{ {
return silly_string_adaptor::construct_from_utf8(str.s_.substr(offset).c_str()); return str.s_.find(c, from);
} // substr } // find
silly_string silly_string_adaptor::substr(const silly_string& str, const size_type& offset, const size_type& count) silly_string silly_string_adaptor::substr(const silly_string& str, const size_type& offset)
{ {
return silly_string_adaptor::construct_from_utf8(str.s_.substr(offset, count).c_str()); return silly_string_adaptor::construct_from_utf8(str.s_.substr(offset).c_str());
} // substr } // substr
silly_string_adaptor::size_type silly_string_adaptor::length(const silly_string& str) silly_string silly_string_adaptor::substr(const silly_string& str, const size_type& offset, const size_type& count)
{ {
return str.s_.length(); return silly_string_adaptor::construct_from_utf8(str.s_.substr(offset, count).c_str());
} // length } // substr
void silly_string_adaptor::append(silly_string& str, const silly_string& a) silly_string_adaptor::size_type silly_string_adaptor::length(const silly_string& str)
{ {
str.s_.append(a.s_); return str.s_.length();
} // append } // length
void silly_string_adaptor::insert(silly_string& str, size_type offset, const silly_string& a) void silly_string_adaptor::append(silly_string& str, const silly_string& a)
{ {
str.s_.insert(offset, a.s_); str.s_.append(a.s_);
} // insert } // append
void silly_string_adaptor::replace(silly_string& str, size_type offset, size_type count, const silly_string& a) void silly_string_adaptor::append(silly_string& str, const char& a)
{ {
str.s_.replace(offset, count, a.s_); str.s_ += a;
} // replace } // append
silly_string silly_string_adaptor::concat(const silly_string& str, const silly_string& a)
// only used to constuct error strings - don't have to be highly efficient! {
std::string silly_string_adaptor::asStdString(const silly_string& str) return construct(str.s_ + a.s_);
{ }
return str.s_;
} // asStdString silly_string silly_string_adaptor::concat(const silly_string& str, const char& a)
{
#ifndef ARABICA_NO_WCHAR_T return construct(str.s_ + a);
std::wstring silly_string_adaptor::asStdWString(const silly_string& str) }
{
Arabica::io::basic_oconvertstream<char, std::char_traits<char>,
wchar_t, std::char_traits<wchar_t> > widener; void silly_string_adaptor::insert(silly_string& str, size_type offset, const silly_string& a)
std::codecvt<char, wchar_t, std::mbstate_t>* cc = new Arabica::convert::ucs2utf8codecvt(); {
widener.imbue(std::locale(widener.getloc(), cc)); str.s_.insert(offset, a.s_);
widener.str(str.s_); } // insert
return widener.str();
} // asStdWString void silly_string_adaptor::replace(silly_string& str, size_type offset, size_type count, const silly_string& a)
#endif {
str.s_.replace(offset, count, a.s_);
} // replace
// only used to constuct error strings - don't have to be highly efficient!
std::string silly_string_adaptor::asStdString(const silly_string& str)
{
return str.s_;
} // asStdString
#ifndef ARABICA_NO_WCHAR_T
std::wstring silly_string_adaptor::asStdWString(const silly_string& str)
{
Arabica::io::basic_oconvertstream<char, std::char_traits<char>,
wchar_t, std::char_traits<wchar_t> > widener;
std::codecvt<char, wchar_t, std::mbstate_t>* cc = new Arabica::convert::ucs2utf8codecvt();
widener.imbue(std::locale(widener.getloc(), cc));
widener.str(str.s_);
return widener.str();
} // asStdWString
#endif

View file

@ -1,117 +1,130 @@
#ifndef ARABICA_TEST_SILLY_STRING_HPP #ifndef ARABICA_TEST_SILLY_STRING_HPP
#define ARABICA_TEST_SILLY_STRING_HPP #define ARABICA_TEST_SILLY_STRING_HPP
#include <string> #include <string>
#include <functional> #include <functional>
#include <Arabica/stringadaptortag.hpp> #include <Arabica/stringadaptortag.hpp>
#include <SAX/ArabicaConfig.hpp> #include <SAX/ArabicaConfig.hpp>
// testing purposes only // testing purposes only
// a string with as minimal interface as possible // a string with as minimal interface as possible
class silly_string class silly_string
{ {
public: public:
silly_string(); silly_string();
silly_string(const silly_string& rhs); silly_string(const silly_string& rhs);
~silly_string(); ~silly_string();
bool operator==(const silly_string& rhs) const; bool operator==(const silly_string& rhs) const;
bool operator!=(const silly_string& rhs) const { return !(this->operator==(rhs)); } bool operator!=(const silly_string& rhs) const { return !(this->operator==(rhs)); }
silly_string& operator=(const silly_string& rhs); silly_string& operator=(const silly_string& rhs);
private: private:
// use a std::string to the actual work // use a std::string to the actual work
std::string s_; std::string s_;
friend class silly_string_adaptor; friend class silly_string_adaptor;
friend bool operator<(const silly_string& lhs, friend bool operator<(const silly_string& lhs,
const silly_string& rhs); const silly_string& rhs);
}; // class silly_string friend bool operator>(const silly_string& lhs,
const silly_string& rhs);
bool operator<(const silly_string& lhs, const silly_string& rhs); }; // class silly_string
class silly_string_adaptor : public Arabica::string_adaptor_tag bool operator<(const silly_string& lhs, const silly_string& rhs);
{ bool operator>(const silly_string& lhs, const silly_string& rhs);
public:
typedef silly_string string_type; class silly_string_adaptor : public Arabica::string_adaptor_tag
typedef std::string::const_iterator const_iterator; {
typedef std::string::iterator mutable_iterator; public:
typedef char value_type; typedef silly_string string_type;
typedef std::string::size_type size_type; typedef std::string::const_iterator const_iterator;
static size_type npos() typedef std::string::iterator mutable_iterator;
{ typedef std::string::const_reverse_iterator const_reverse_iterator;
return std::string::npos; typedef char value_type;
} typedef std::string::size_type size_type;
static size_type npos()
static const silly_string& empty_string() { static silly_string es; return es; } {
return std::string::npos;
template<class InputIterator> }
static silly_string construct(InputIterator from, InputIterator to)
{ static const silly_string& empty_string() { static silly_string es; return es; }
silly_string ss;
ss.s_ = std::string(from, to); template<class InputIterator>
return ss; static silly_string construct(InputIterator from, InputIterator to)
} // construct {
silly_string ss;
static string_type construct(const value_type* s) ss.s_ = std::string(from, to);
{ return ss;
silly_string ss; } // construct
ss.s_ = std::string(s);
return ss; static string_type construct(const value_type* s)
} // construct {
silly_string ss;
static char convert_from_utf8(char c); ss.s_ = std::string(s);
static silly_string construct_from_utf8(const char* str); return ss;
static silly_string construct_from_utf8(const char* str, int length); } // construct
#ifndef ARABICA_NO_WCHAR_T
static silly_string construct_from_utf16(const wchar_t* str); static silly_string construct(const std::basic_string<value_type>& str)
static silly_string construct_from_utf16(const wchar_t* str, int length); {
#endif return construct(str.c_str());
} // construct
// here we go
static bool empty(const silly_string& s); static char convert_from_utf8(char c);
static size_type find(const silly_string& str, const silly_string& what); static silly_string construct_from_utf8(const char* str);
static size_type find(const silly_string& str, value_type c); static silly_string construct_from_utf8(const char* str, int length);
static size_type find(const silly_string& str, const silly_string& what, size_type from); #ifndef ARABICA_NO_WCHAR_T
static size_type find(const silly_string& str, value_type c, size_type from); static silly_string construct_from_utf16(const wchar_t* str);
static silly_string substr(const silly_string& str, const size_type& offset); static silly_string construct_from_utf16(const wchar_t* str, int length);
static silly_string substr(const silly_string& str, const size_type& offset, const size_type& count); #endif
static size_type length(const silly_string& str);
static void append(silly_string& str, const silly_string& a); // here we go
static void insert(silly_string& str, size_type offset, const silly_string& a); static bool empty(const silly_string& s);
static void replace(silly_string& str, size_type offset, size_type count, const silly_string& a); static size_type find(const silly_string& str, const silly_string& what);
static const_iterator begin(const silly_string& str) { return str.s_.begin(); } static size_type find(const silly_string& str, value_type c);
static mutable_iterator begin(silly_string& str) { return str.s_.begin(); } static size_type find(const silly_string& str, const silly_string& what, size_type from);
static const_iterator end(const silly_string& str) { return str.s_.end(); } static size_type find(const silly_string& str, value_type c, size_type from);
static mutable_iterator end(silly_string& str) { return str.s_.end(); } static silly_string substr(const silly_string& str, const size_type& offset);
static silly_string substr(const silly_string& str, const size_type& offset, const size_type& count);
// mainly used to constuct error strings - don't have to be highly efficient! static size_type length(const silly_string& str);
static std::string asStdString(const silly_string& str); static void append(silly_string& str, const silly_string& a);
#ifndef ARABICA_NO_WCHAR_T static void append(silly_string& str, const char& a);
static std::wstring asStdWString(const silly_string& str); static silly_string concat(const silly_string& str, const silly_string& a);
#endif static silly_string concat(const silly_string& str, const char& a);
}; // class silly_string_adaptor static void insert(silly_string& str, size_type offset, const silly_string& a);
static void replace(silly_string& str, size_type offset, size_type count, const silly_string& a);
template<class CharType, class Traits> static const_iterator begin(const silly_string& str) { return str.s_.begin(); }
std::basic_ostream<CharType, Traits>& operator<<(std::basic_ostream<CharType, Traits>& os, const silly_string& s) static mutable_iterator begin(silly_string& str) { return str.s_.begin(); }
{ static const_iterator end(const silly_string& str) { return str.s_.end(); }
os << silly_string_adaptor::asStdString(s); static mutable_iterator end(silly_string& str) { return str.s_.end(); }
return os; static const_reverse_iterator rbegin(const silly_string& str) { return str.s_.rbegin(); }
} // operator<<
// mainly used to constuct error strings - don't have to be highly efficient!
namespace std { static std::string asStdString(const silly_string& str);
#ifndef ARABICA_NO_WCHAR_T
template<> static std::wstring asStdWString(const silly_string& str);
struct less<silly_string> : public binary_function<silly_string, silly_string, bool> #endif
{ }; // class silly_string_adaptor
// functor for operator<
bool operator()(const silly_string& lhs, const silly_string& rhs) const template<class CharType, class Traits>
{ std::basic_ostream<CharType, Traits>& operator<<(std::basic_ostream<CharType, Traits>& os, const silly_string& s)
// apply operator< to operands {
return (silly_string_adaptor::asStdString(lhs) < silly_string_adaptor::asStdString(rhs)); os << silly_string_adaptor::asStdString(s);
} // operator() return os;
}; } // operator<<
} // namespace std namespace std {
#endif template<>
struct less<silly_string> : public binary_function<silly_string, silly_string, bool>
{
// functor for operator<
bool operator()(const silly_string& lhs, const silly_string& rhs) const
{
// apply operator< to operands
return (silly_string_adaptor::asStdString(lhs) < silly_string_adaptor::asStdString(rhs));
} // operator()
};
} // namespace std
#endif

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32"> <ProjectConfiguration Include="Debug|Win32">
@ -40,10 +40,10 @@
<PropertyGroup> <PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion> <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\..\bin\</OutDir> <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\..\bin\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug_test_xslt\</IntDir> <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug_test_xslt_wide\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\..\bin\</OutDir> <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\..\bin\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release_test_xslt\</IntDir> <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release_test_xslt_wide\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental> <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">xslt_test_wide</TargetName> <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">xslt_test_wide</TargetName>
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">xslt_test_wide</TargetName> <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">xslt_test_wide</TargetName>