/* $Id: makeimagedl-info.cc,v 1.4 2004/02/04 15:34:40 atterer Exp $ -*- C++ -*- __ _ |_) /| Copyright (C) 2003 | richard@ | \/¯| Richard Atterer | atterer.net ¯ '` ¯ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License, version 2. See the file COPYING for details. Download .jigdo/.template and file URLs */ #include #include #include #include //______________________________________________________________________ using namespace Job; DEBUG_UNIT("makeimagedl-info") //______________________________________________________________________ namespace { struct ImageInfoParse { ImageInfoParse(string* o, bool e, const char** s) : output(o), escapedText(e), subst(s), depth(0) { } string* output; bool escapedText; const char** subst; int depth; }; // For ImageInfo - verify that the XML is correct void parseStartElem(GMarkupParseContext* /*context*/, const gchar* elem, const gchar** attrNames, const gchar** /*attrValues*/, gpointer user_data, GError** error) { debug("imageInfo parse: <%1>", elem); ImageInfoParse* x = static_cast(user_data); ++x->depth; if (attrNames != 0 && attrNames[0] != 0) { g_set_error(error, g_markup_error_quark(), G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, " "); return; } if (strcmp("x", elem) == 0 && x->depth == 1) return; // Ignore dummy outer element const char* s; if (strcmp("b", elem) == 0) s = x->subst[MakeImageDl::B]; else if (strcmp("i", elem) == 0) s = x->subst[MakeImageDl::I]; else if (strcmp("tt", elem) == 0) s = x->subst[MakeImageDl::TT]; else if (strcmp("u", elem) == 0) s = x->subst[MakeImageDl::U]; else if (strcmp("big", elem) == 0) s = x->subst[MakeImageDl::BIG]; else if (strcmp("small", elem) == 0) s = x->subst[MakeImageDl::SMALL]; else if (strcmp("br", elem) == 0) s = x->subst[MakeImageDl::BR]; else { g_set_error(error, g_markup_error_quark(), G_MARKUP_ERROR_UNKNOWN_ELEMENT, " "); return; } *x->output += s; } void parseEndElem(GMarkupParseContext* /*context*/, const gchar* elem, gpointer user_data, GError** error) { debug("imageInfo parse: ", elem); ImageInfoParse* x = static_cast(user_data); --x->depth; if (strcmp("x", elem) == 0 && x->depth == 0) return; // Ignore dummy outer element if (strcmp("br", elem) == 0) return; const char* s; if (strcmp("b", elem) == 0) s = x->subst[MakeImageDl::B_]; else if (strcmp("i", elem) == 0) s = x->subst[MakeImageDl::I_]; else if (strcmp("tt", elem) == 0) s = x->subst[MakeImageDl::TT_]; else if (strcmp("u", elem) == 0) s = x->subst[MakeImageDl::U_]; else if (strcmp("big", elem) == 0) s = x->subst[MakeImageDl::BIG_]; else if (strcmp("small", elem) == 0) s = x->subst[MakeImageDl::SMALL_]; else { g_set_error(error, g_markup_error_quark(), G_MARKUP_ERROR_UNKNOWN_ELEMENT, " "); return; } *x->output += s; } void parseText(GMarkupParseContext* context, const gchar* text, gsize textLen, gpointer user_data, GError** error) { ImageInfoParse* x = static_cast(user_data); debug("imageInfo parseText: \"%1\"", string(text, textLen)); if (textLen == 0) return; if (strcmp(g_markup_parse_context_get_element(context), "br") == 0) { //
element must be empty g_set_error(error, g_markup_error_quark(), G_MARKUP_ERROR_INVALID_CONTENT, " "); return; } if (x->escapedText) { x->output->append(text, textLen); // Leave escaped } else { // Unescape. NB UTF-8 const char* p = text; const char* end = text + textLen; while (p < end) { if (*p != '&') { *x->output += *p; ++p; continue; } if (p + 4 <= end && strncmp(p + 1, "lt;", 3) == 0) { *x->output += '<'; p += 4; continue; } if (p + 4 <= end && strncmp(p + 1, "gt;", 3) == 0) { *x->output += '>'; p += 4; continue; } if (p + 5 <= end && strncmp(p + 1, "amp;", 4) == 0) { *x->output += '&'; p += 5; continue; } *x->output += *p; ++p; } } } // Comments, processing instructions and CDATA not allowed void parseComment(GMarkupParseContext* /*context*/, const gchar* /*passthrough_text*/, gsize /*textLen*/, gpointer /*user_data*/, GError** error) { debug("imageInfo parseComment"); g_set_error(error, g_markup_error_quark(), G_MARKUP_ERROR_INVALID_CONTENT, " "); } } // namespace void MakeImageDl::imageInfo(string* output, bool escapedText, const char* subst[13]) const { Paranoid(output != 0 && subst != 0); unsigned outputLen = output->length(); ImageInfoParse myData(output, escapedText, subst); static GMarkupParser p = { &parseStartElem, &parseEndElem, &parseText, &parseComment, 0 }; GMarkupParseContext* context = g_markup_parse_context_new(&p, (GMarkupParseFlags)0, &myData, 0); GError* err = 0; if (g_markup_parse_context_parse(context, "", 3, &err) && g_markup_parse_context_parse(context, imageInfoVal.data(), imageInfoVal.length(), &err) && g_markup_parse_context_parse(context, "", 4, &err) && g_markup_parse_context_end_parse(context, &err)) { } g_markup_parse_context_free(context); if (err != 0) { g_error_free(err); output->resize(outputLen); if (escapedText) { debug("imageInfo: error, escaping whole ImageInfo (%1)", err->code); for (string::const_iterator i = imageInfoVal.begin(), e = imageInfoVal.end(); i != e; ++i) { if (*i == '<') *output += "<"; else if (*i == '>') *output += ">"; else if (*i == '&') *output += "&"; else *output += *i; } } else { *output += imageInfoVal; } } }