diff --git a/src/common/chapter_writer.cpp b/src/common/chapter_writer.cpp index 7efa3f698..78523fe99 100644 --- a/src/common/chapter_writer.cpp +++ b/src/common/chapter_writer.cpp @@ -21,10 +21,10 @@ #include +#include "chapters.h" #include "commonebml.h" #include "mm_io.h" -#include "chapters.h" -#include "xml_element_mapping.h" +#include "xml_element_writer.h" using namespace std; using namespace libmatroska; @@ -203,16 +203,8 @@ write_chapters_simple(int &chapter_num, // {{{ XML chapter output -typedef struct { - int level; - int parent_idx; - int elt_idx; - EbmlElement *e; - mm_io_c *out; -} chapter_writer_cb_t; - static void -pt(chapter_writer_cb_t *cb, +pt(xml_writer_cb_t *cb, const char *tag) { int i; @@ -221,91 +213,6 @@ pt(chapter_writer_cb_t *cb, cb->out->printf("%s", tag); } -static void -write_xml_element_rec(int level, - int parent_idx, - EbmlElement *e, - mm_io_c *out) { - EbmlMaster *m; - int elt_idx, i; - bool found; - string s; - - elt_idx = parent_idx; - found = false; - while ((chapter_elements[elt_idx].name != NULL) && - (chapter_elements[elt_idx].level >= - chapter_elements[parent_idx].level)) { - if (chapter_elements[elt_idx].id == e->Generic().GlobalId) { - found = true; - break; - } - elt_idx++; - } - - for (i = 0; i < level; i++) - out->printf(" "); - - if (!found) { - out->printf("\n", e->Generic().DebugName); - return; - } - - out->printf("<%s>", chapter_elements[elt_idx].name); - switch (chapter_elements[elt_idx].type) { - case EBMLT_MASTER: - out->printf("\n"); - m = dynamic_cast(e); - assert(m != NULL); - for (i = 0; i < m->ListSize(); i++) - write_xml_element_rec(level + 1, elt_idx, (*m)[i], out); - - if (chapter_elements[elt_idx].end_hook != NULL) { - chapter_writer_cb_t cb; - - cb.level = level; - cb.parent_idx = parent_idx; - cb.elt_idx = elt_idx; - cb.e = e; - cb.out = out; - - chapter_elements[elt_idx].end_hook(&cb); - } - - for (i = 0; i < level; i++) - out->printf(" "); - out->printf("\n", chapter_elements[elt_idx].name); - break; - - case EBMLT_UINT: - case EBMLT_BOOL: - out->printf("%llu\n", uint64(*dynamic_cast(e)), - chapter_elements[elt_idx].name); - break; - - case EBMLT_STRING: - s = escape_xml(string(*dynamic_cast(e))); - out->printf("%s\n", s.c_str(), chapter_elements[elt_idx].name); - break; - - case EBMLT_USTRING: - s = UTFstring_to_cstrutf8(UTFstring(*static_cast - (e)).c_str()); - s = escape_xml(s); - out->printf("%s\n", s.c_str(), chapter_elements[elt_idx].name); - break; - - case EBMLT_TIME: - out->printf(FMT_TIMECODEN "\n", - ARG_TIMECODEN(uint64(*dynamic_cast(e))), - chapter_elements[elt_idx].name); - break; - - default: - assert(false); - } -} - static int cet_index(const char *name) { int i; @@ -321,9 +228,9 @@ cet_index(const char *name) { static void end_write_chapter_atom(void *data) { KaxChapterAtom *atom; - chapter_writer_cb_t *cb; + xml_writer_cb_t *cb; - cb = (chapter_writer_cb_t *)data; + cb = (xml_writer_cb_t *)data; atom = dynamic_cast(cb->e); assert(atom != NULL); if (FINDFIRST(atom, KaxChapterTimeStart) == NULL) @@ -333,9 +240,9 @@ end_write_chapter_atom(void *data) { static void end_write_chapter_display(void *data) { KaxChapterDisplay *display; - chapter_writer_cb_t *cb; + xml_writer_cb_t *cb; - cb = (chapter_writer_cb_t *)data; + cb = (xml_writer_cb_t *)data; display = dynamic_cast(cb->e); assert(display != NULL); if (FINDFIRST(display, KaxChapterString) == NULL) @@ -359,7 +266,7 @@ write_chapters_xml(KaxChapters *chapters, end_write_chapter_display; for (i = 0; i < chapters->ListSize(); i++) - write_xml_element_rec(1, 0, (*chapters)[i], out); + write_xml_element_rec(1, 0, (*chapters)[i], out, chapter_elements); } // }}} diff --git a/src/common/tagwriter.cpp b/src/common/tagwriter.cpp index f03798ac4..351263bcb 100644 --- a/src/common/tagwriter.cpp +++ b/src/common/tagwriter.cpp @@ -14,163 +14,13 @@ #include "os.h" -#include -#include -#include - -#include #include -#include + +#include "xml_element_writer.h" using namespace libmatroska; using namespace std; -#include "base64.h" -#include "common.h" -#include "commonebml.h" -#include "matroska.h" -#include "mm_io.h" -#include "xml_element_mapping.h" - -static void -print_binary(int level, - const char *name, - EbmlElement *e, - mm_io_c *out) { - EbmlBinary *b; - string s; - int i, idx, old_idx; - - b = (EbmlBinary *)e; - s = base64_encode((const unsigned char *)b->GetBuffer(), b->GetSize(), true, - 72 - level - 2); - if (s[s.length() - 1] == '\n') - s.erase(s.length() - 1); - - if ((level * 2 + 2 * strlen(name) + 2 + 3 + s.length()) <= 78) { - out->printf("%s\n", s.c_str(), name); - return; - } - - out->printf("\n"); - - for (i = 0; i < (level + 2); i++) - out->printf(" "); - - old_idx = 0; - for (idx = 0; idx < s.length(); idx++) - if (s[idx] == '\n') { - out->printf("%s\n", s.substr(old_idx, idx - old_idx).c_str()); - for (i = 0; i < (level + 2); i++) - out->printf(" "); - old_idx = idx + 1; - } - - if (old_idx < s.length()) - out->printf("%s", s.substr(old_idx).c_str()); - - out->printf("\n"); - - for (i = 0; i < level; i++) - out->printf(" "); - out->printf("\n", name); -} - -typedef struct { - int level; - int parent_idx; - int elt_idx; - EbmlElement *e; -} tag_writer_cb_t; - -static void -write_xml_element_rec(int level, - int parent_idx, - EbmlElement *e, - mm_io_c *out) { - EbmlMaster *m; - int elt_idx, i; - bool found; - string s; - - elt_idx = parent_idx; - found = false; - while ((tag_elements[elt_idx].name != NULL) && - (tag_elements[elt_idx].level >= - tag_elements[parent_idx].level)) { - if (tag_elements[elt_idx].id == e->Generic().GlobalId) { - found = true; - break; - } - elt_idx++; - } - - for (i = 0; i < level; i++) - out->printf(" "); - - if (!found) { - out->printf("\n", e->Generic().DebugName); - return; - } - - out->printf("<%s>", tag_elements[elt_idx].name); - switch (tag_elements[elt_idx].type) { - case EBMLT_MASTER: - out->printf("\n"); - m = dynamic_cast(e); - assert(m != NULL); - for (i = 0; i < m->ListSize(); i++) - write_xml_element_rec(level + 1, elt_idx, (*m)[i], out); - - if (tag_elements[elt_idx].end_hook != NULL) { - tag_writer_cb_t cb; - - cb.level = level; - cb.parent_idx = parent_idx; - cb.elt_idx = elt_idx; - cb.e = e; - - tag_elements[elt_idx].end_hook(&cb); - } - - for (i = 0; i < level; i++) - out->printf(" "); - out->printf("\n", tag_elements[elt_idx].name); - break; - - case EBMLT_UINT: - case EBMLT_BOOL: - out->printf("%llu\n", uint64(*dynamic_cast(e)), - tag_elements[elt_idx].name); - break; - - case EBMLT_STRING: - s = escape_xml(string(*dynamic_cast(e))); - out->printf("%s\n", s.c_str(), tag_elements[elt_idx].name); - break; - - case EBMLT_USTRING: - s = UTFstring_to_cstrutf8(UTFstring(*static_cast - (e)).c_str()); - s = escape_xml(s); - out->printf("%s\n", s.c_str(), tag_elements[elt_idx].name); - break; - - case EBMLT_TIME: - out->printf(FMT_TIMECODEN "\n", - ARG_TIMECODEN(uint64(*dynamic_cast(e))), - tag_elements[elt_idx].name); - break; - - case EBMLT_BINARY: - print_binary(level, tag_elements[elt_idx].name, e, out); - break; - - default: - assert(false); - } -} - void write_tags_xml(KaxTags &tags, mm_io_c *out) { @@ -182,5 +32,5 @@ write_tags_xml(KaxTags &tags, } for (i = 0; i < tags.ListSize(); i++) - write_xml_element_rec(1, 0, tags[i], out); + write_xml_element_rec(1, 0, tags[i], out, tag_elements); } diff --git a/src/common/tagwriter.h b/src/common/tagwriter.h index 8c61f1c65..a9a2ea671 100644 --- a/src/common/tagwriter.h +++ b/src/common/tagwriter.h @@ -15,8 +15,6 @@ #ifndef __TAGWRITER_H #define __TAGWRITER_H -#include - #include #include diff --git a/src/common/xml_element_writer.cpp b/src/common/xml_element_writer.cpp new file mode 100644 index 000000000..ce3022223 --- /dev/null +++ b/src/common/xml_element_writer.cpp @@ -0,0 +1,153 @@ +/* + mkvmerge -- utility for splicing together matroska files + from component media subtypes + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + $Id$ + + XML chapter writer functions + + Written by Moritz Bunkus . +*/ + +#include +#include +#include +#include +#include +#include +#include + +#include "base64.h" +#include "common.h" +#include "commonebml.h" +#include "mm_io.h" +#include "xml_element_writer.h" + +using namespace libebml; + +static void +print_binary(int level, + const char *name, + EbmlElement *e, + mm_io_c *out) { + EbmlBinary *b; + const unsigned char *p; + string s; + int i, size; + + b = (EbmlBinary *)e; + p = (const unsigned char *)b->GetBuffer(); + size = b->GetSize(); + + for (i = 0; i < size; i++) { + if ((i % 16) != 0) + s += " "; + s += mxsprintf("%02x", *p); + ++p; + if ((((i + 1) % 16) == 0) && ((i + 1) < size)) + s += mxsprintf("\n%*s", (level + 1) * 2, ""); + } + + if ((level * 2 + 2 * strlen(name) + 2 + 3 + s.length()) <= 78) + out->printf("%s\n", s.c_str(), name); + else + out->printf("\n%*s%s\n%*s\n", (level + 1) * 2, "", s.c_str(), + level * 2, "", name); +} + +void +write_xml_element_rec(int level, + int parent_idx, + EbmlElement *e, + mm_io_c *out, + const parser_element_t *element_map) { + EbmlMaster *m; + int elt_idx, i; + bool found; + string s; + + elt_idx = parent_idx; + found = false; + while ((element_map[elt_idx].name != NULL) && + (element_map[elt_idx].level >= + element_map[parent_idx].level)) { + if (element_map[elt_idx].id == e->Generic().GlobalId) { + found = true; + break; + } + elt_idx++; + } + + for (i = 0; i < level; i++) + out->printf(" "); + + if (!found) { + out->printf("\n", e->Generic().DebugName); + return; + } + + out->printf("<%s%s>", element_map[elt_idx].name, + element_map[elt_idx].type == EBMLT_BINARY ? + " format=\"hex\"" : ""); + switch (element_map[elt_idx].type) { + case EBMLT_MASTER: + out->printf("\n"); + m = dynamic_cast(e); + assert(m != NULL); + for (i = 0; i < m->ListSize(); i++) + write_xml_element_rec(level + 1, elt_idx, (*m)[i], out, element_map); + + if (element_map[elt_idx].end_hook != NULL) { + xml_writer_cb_t cb; + + cb.level = level; + cb.parent_idx = parent_idx; + cb.elt_idx = elt_idx; + cb.e = e; + cb.out = out; + + element_map[elt_idx].end_hook(&cb); + } + + for (i = 0; i < level; i++) + out->printf(" "); + out->printf("\n", element_map[elt_idx].name); + break; + + case EBMLT_UINT: + case EBMLT_BOOL: + out->printf("%llu\n", uint64(*dynamic_cast(e)), + element_map[elt_idx].name); + break; + + case EBMLT_STRING: + s = escape_xml(string(*dynamic_cast(e))); + out->printf("%s\n", s.c_str(), element_map[elt_idx].name); + break; + + case EBMLT_USTRING: + s = UTFstring_to_cstrutf8(UTFstring(*static_cast + (e)).c_str()); + s = escape_xml(s); + out->printf("%s\n", s.c_str(), element_map[elt_idx].name); + break; + + case EBMLT_TIME: + out->printf(FMT_TIMECODEN "\n", + ARG_TIMECODEN(uint64(*dynamic_cast(e))), + element_map[elt_idx].name); + break; + + case EBMLT_BINARY: + print_binary(level, element_map[elt_idx].name, e, out); + break; + + default: + assert(false); + } +} + diff --git a/src/common/xml_element_writer.h b/src/common/xml_element_writer.h new file mode 100644 index 000000000..8cc504067 --- /dev/null +++ b/src/common/xml_element_writer.h @@ -0,0 +1,42 @@ +/* + mkvmerge -- utility for splicing together matroska files + from component media subtypes + + Distributed under the GPL + see the file COPYING for details + or visit http://www.gnu.org/copyleft/gpl.html + + $Id$ + + XML chapter writer functions + + Written by Moritz Bunkus . +*/ + +#ifndef __XML_ELEMENT_WRITER_H +#define __XML_ELEMENT_WRITER_H + +#include "xml_element_parser.h" + +namespace libebml { + class EbmlElement; +}; + +using namespace libebml; + +class mm_io_c; + +struct xml_writer_cb_t { + int level; + int parent_idx; + int elt_idx; + EbmlElement *e; + mm_io_c *out; +}; + +void MTX_DLL_API +write_xml_element_rec(int level, int parent_idx, + EbmlElement *e, mm_io_c *out, + const parser_element_t *element_map); + +#endif // __XML_ELEMENT_WRITER_H