8#ifndef ADOBE_XSTRING_HPP
9#define ADOBE_XSTRING_HPP
16#include <adobe/implementation/string_pool.hpp>
23#include <boost/noncopyable.hpp>
38namespace implementation {
42inline bool xstring_preorder_predicate(
const token_range_t& range) {
46 return token_range_equal(range, static_token_range(
"xstr")) ||
47 token_range_equal(range, static_token_range(
"marker"));
53 typedef std::output_iterator_tag iterator_category;
54 typedef null_output_t value_type;
55 typedef std::ptrdiff_t difference_type;
56 typedef value_type* pointer;
57 typedef value_type& reference;
59 null_output_t& operator++(
int) {
return *
this; }
60 null_output_t& operator++() {
return *
this; }
61 reference operator*() {
return *
this; }
64 null_output_t& operator=(
const T&) {
71token_range_t xml_xstr_store(
const token_range_t& entire_element_range,
const token_range_t& name,
72 const attribute_set_t& attribute_set,
const token_range_t& value);
74token_range_t xml_xstr_lookup(
const token_range_t& entire_element_range,
const token_range_t& name,
75 const attribute_set_t& attribute_set,
const token_range_t& value);
77token_range_t xml_element_finalize(
const token_range_t& entire_element_range,
78 const token_range_t& name,
const attribute_set_t& attribute_set,
79 const token_range_t& value);
83struct context_frame_t {
85 bool operator()(
const token_range_t& x,
const token_range_t& y)
const {
86 return token_range_less(x, y);
90 typedef std::pair<attribute_set_t, token_range_t> element_t;
91 typedef std::multimap<token_range_t, element_t, comp_t> store_t;
92 typedef store_t::iterator store_iterator;
93 typedef store_t::value_type store_value_type;
94 typedef std::pair<store_iterator, store_iterator> store_range_pair_t;
99 context_frame_t() : parse_info_m(
"xstring context_frame_t"), parsed_m(false) {}
101 context_frame_t(
const context_frame_t& rhs)
102 : parse_info_m(rhs.parse_info_m), parsed_m(rhs.parsed_m),
103 attribute_set_m(rhs.attribute_set_m), glossary_m(rhs.glossary_m),
104 callback_m(rhs.callback_m), predicate_m(rhs.predicate_m)
109 context_frame_t& operator=(
const context_frame_t& rhs) {
110 parse_info_m = rhs.parse_info_m;
111 parsed_m = rhs.parsed_m;
112 attribute_set_m = rhs.attribute_set_m;
113 glossary_m = rhs.glossary_m;
114 callback_m = rhs.callback_m;
115 predicate_m = rhs.predicate_m;
124 delete[] slurp_m.first;
127 inline store_range_pair_t range_for_key(
const store_t::key_type& key) {
128 return glossary_m.equal_range(key);
131 std::pair<bool, store_iterator> exact_match_exists(
const attribute_set_t& attribute_set,
132 const token_range_t& value);
134 store_t::mapped_type* store(
const store_t::key_type& key,
const attribute_set_t& attribute_set,
135 const token_range_t& value,
bool copy =
false);
137 store_iterator closest_match(store_range_pair_t range,
const attribute_set_t& searching);
139 token_range_t element_handler(
const token_range_t& entire_element_range,
140 const token_range_t& name,
const attribute_set_t& attribute_set,
141 const token_range_t& value)
const {
142 if (xstring_preorder_predicate(name))
144 return xml_xstr_lookup(entire_element_range, name, attribute_set, value);
145 else if (predicate_m && predicate_m(name))
146 return callback_m(entire_element_range, name, attribute_set, value);
151 token_range_t clone(
const token_range_t& token);
153 line_position_t parse_info_m;
155 attribute_set_t attribute_set_m;
157 callback_proc_t callback_m;
158 preorder_predicate_t predicate_m;
159 token_range_t slurp_m;
160 unique_string_pool_t pool_m;
165inline bool operator==(
const context_frame_t::element_t& x,
const context_frame_t::element_t& y) {
166 return x.first == y.first && token_range_equal(x.second, y.second);
171implementation::context_frame_t& top_frame();
189 using namespace std::placeholders;
191 const implementation::context_frame_t& context(implementation::top_frame());
195 std::bind(&implementation::context_frame_t::element_handler,
196 std::cref(context), _1, _2, _3, _4),
204 return parse_xml_fragment(
reinterpret_cast<uchar_ptr_t
>(fragment.c_str()), fragment.size(),
210 return parse_xml_fragment(
reinterpret_cast<uchar_ptr_t
>(fragment), std::strlen(fragment),
219inline void xstring(
const char* xstr, std::size_t n, O output) {
224inline void xstring(
const char* xstr, O output) {
225 xstring(xstr, std::strlen(xstr), output);
232inline std::string
xstring(
const char* xstr, std::size_t n) {
235 xstring(xstr, n, std::back_inserter(result));
240inline std::string
xstring(
const std::string& xstr) {
return xstring(xstr.c_str(), xstr.size()); }
249 const std::string* last);
254 const std::string* last);
264 : back_frame_m(implementation::top_frame())
266 implementation::context_frame_t& context(implementation::top_frame());
268 context.slurp_m.first =
reinterpret_cast<uchar_ptr_t
>(parse_first);
269 context.slurp_m.second =
reinterpret_cast<uchar_ptr_t
>(parse_last);
270 context.parse_info_m = parse_info;
271 context.parsed_m =
false;
276 template <
typename I>
278 : back_frame_m(implementation::top_frame())
280 implementation::top_frame().attribute_set_m.insert(first_attribute, last_attribute);
283 template <
typename I>
285 const unsigned char* parse_last,
287 : back_frame_m(implementation::top_frame())
289 implementation::context_frame_t& context(implementation::top_frame());
291 context.attribute_set_m.insert(first_attribute, last_attribute);
292 context.slurp_m.first = parse_first;
293 context.slurp_m.second = parse_last;
294 context.parse_info_m = parse_info;
295 context.parsed_m =
false;
301 implementation::top_frame().predicate_m = proc;
305 implementation::top_frame().callback_m = proc;
311 void glossary_parse() {
312 implementation::context_frame_t& context(implementation::top_frame());
314 if (context.parsed_m || !adobe::token_range_size(context.slurp_m)) {
318 make_xml_parser(context.slurp_m.first, context.slurp_m.second, context.parse_info_m,
319 implementation::xstring_preorder_predicate, &implementation::xml_xstr_store,
320 implementation::null_output_t())
321 .parse_element_sequence();
324 context.parsed_m =
true;
327 implementation::context_frame_t back_frame_m;
335#ifdef __ADOBE_COMPILER_CONCEPTS__
338concept_map OutputIterator<adobe::implementation::null_output_t, char>{};
339concept_map OutputIterator<adobe::implementation::null_output_t, unsigned char>{};
std::function< bool(const token_range_t &)> preorder_predicate_t
xml_element_proc_t callback_proc_t
xml_parser_t< O > make_xml_parser(uchar_ptr_t first, uchar_ptr_t last, const line_position_t &position, typename xml_parser_t< O >::preorder_predicate_t predicate, typename xml_parser_t< O >::callback_proc_t callback, O output)
Create an object that will parse the indicated content range using the preorder and content functions...
std::string xstring_replace(const std::string &xstr, const std::string &marker)
void xstring(const char *xstr, std::size_t n, O output)
void xstring_clear_glossary()
void parse_xml_fragment(uchar_ptr_t fragment, std::size_t n, O output)
OutputIterator copy(const InputRange &range, OutputIterator result)
copy implementation
token_range_t xml_element_strip(const token_range_t &, const token_range_t &, const attribute_set_t &, const token_range_t &value)
A type detailing parser position information.
A character string class for immutable strings.
implementation::context_frame_t::preorder_predicate_t preorder_predicate_t
xstring_context_t(I first_attribute, I last_attribute, const unsigned char *parse_first, const unsigned char *parse_last, const line_position_t &parse_info=line_position_t("xstring_context_t"))
implementation::context_frame_t::callback_proc_t callback_proc_t
xstring_context_t(I first_attribute, I last_attribute)
void set_element_handler(callback_proc_t proc)
void set_preorder_predicate(preorder_predicate_t proc)
xstring_context_t(const char *parse_first, const char *parse_last, const line_position_t &parse_info=line_position_t("xstring_context_t"))