23 using namespace basis;
29 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s);
42 : _tag_name(tag_name), _attribs(attribs) {}
47 class tag_stack :
public stack<tag_info>
50 tag_stack() :
stack<tag_info>(0) {}
55 xml_generator::xml_generator(
int mods)
56 : _tags(new tag_stack),
58 _human_read(mods & HUMAN_READABLE),
59 _clean_chars(mods & CLEAN_ILLEGAL_CHARS),
72 switch (to_name.
value()) {
74 default:
return common::outcome_name(to_name);
80 if (to_indent <= 0) to_indent = 1;
81 _indentation = to_indent;
86 _accumulator->
reset();
88 while (_tags->pop() == common::OKAY) {}
101 generated =
"<?xml version=\"1.0\"?>";
103 generated += *_accumulator;
115 tag_info new_item(tag_name, attributes);
116 print_open_tag(new_item, HEADER_TAG);
122 tag_info new_item(tag_name, attributes);
123 print_open_tag(new_item);
124 _tags->push(new_item);
130 if (_tags->elements() < 1)
return NOT_FOUND;
132 if (_tags->top()._tag_name != tag_name)
return ERRONEOUS_TAG;
133 print_close_tag(tag_name);
140 while (_tags->elements()) {
149 int num_indents = _tags->elements();
150 for (
int i = 0; i < num_indents; i++)
151 *_accumulator += indentata;
156 *_accumulator += content;
161 void xml_generator::print_open_tag(
const tag_info &to_print,
int type)
163 bool is_header =
false;
164 if (type == HEADER_TAG) is_header =
true;
169 int num_indents = _tags->elements();
170 for (
int i = 0; i < num_indents; i++)
171 *_accumulator += indentata;
175 *_accumulator +=
"<?";
177 *_accumulator +=
"<";
181 *_accumulator += to_print._tag_name;
182 for (
int i = 0; i < to_print._attribs.symbols(); i++) {
184 to_print._attribs.retrieve(i, name, content);
190 *_accumulator +=
" ";
191 *_accumulator += name;
192 *_accumulator +=
"=\"";
193 *_accumulator += content;
194 *_accumulator +=
"\"";
197 *_accumulator +=
"?>";
199 *_accumulator +=
">";
203 void xml_generator::print_close_tag(
const astring &tag_name)
207 int num_indents = _tags->elements() - 1;
208 for (
int i = 0; i < num_indents; i++)
209 *_accumulator += indentata;
211 *_accumulator +=
"</";
215 *_accumulator += tag_name;
216 *_accumulator +=
">";
220 #define PLUGIN_REPLACEMENT(posn, repl_string) { \
221 to_modify.zap(posn, posn); \
222 to_modify.insert(posn, repl_string); \
223 posn += int(strlen(repl_string)) - 1; \
230 const char *quot =
""";
231 const char *amp =
"&";
232 const char *lt =
"<";
233 const char *gt =
">";
234 const char *apos =
"'";
235 const char *space =
"_";
238 for (
int i = 0; i < to_modify.
length(); i++) {
239 switch (to_modify[i]) {
Provides a dynamically resizable ASCII character string.
void reset()
clears out the contents string.
int length() const
Returns the current length of the string.
Outcomes describe the state of completion for an operation.
An abstraction that represents a stack data structure.
Provides a symbol_table that holds strings as the content.
static const char * platform_eol_to_chars()
provides the characters that make up this platform's line ending.
static basis::astring indentation(int spaces)
Returns a string made of white space that is "spaces" long.
basis::outcome add_content(const basis::astring &content)
stores content into the currently opened tag.
static basis::astring clean_reserved(const basis::astring &to_modify, bool replace_spaces=false)
returns a cleaned version of "to_modify" to make it XML appropriate.
static const char * outcome_name(const basis::outcome &to_name)
reports the string version of "to_name".
static void clean_reserved_mod(basis::astring &to_modify, bool replace_spaces=false)
ensures that "to_modify" contains only characters valid for XML.
basis::outcome close_tag(const basis::astring &tag_name)
closes a previously added "tag_name".
basis::outcome open_tag(const basis::astring &tag_name, const structures::string_table &attributes)
adds a tag with "tag_name" and the "attributes", if any.
basis::astring generate()
writes the current state into a string and returns it.
basis::outcome add_header(const basis::astring &tag_name, const structures::string_table &attributes)
adds an xml style header with the "tag_name" and "attributes".
void close_all_tags()
a wide-bore method that closes all outstanding tags.
void reset()
throws out all accumulated information.
void set_indentation(int to_indent)
sets the number of spaces to indent for the human readable form.
The guards collection helps in testing preconditions and reporting errors.
void WHACK(contents *&ptr)
deletion with clearing of the pointer.
A dynamic container class that holds any kind of object via pointers.
#define PLUGIN_REPLACEMENT(posn, repl_string)