[Yum-devel] [PATCH 5/5] Add xml parsing for other delta files

James Bowes jbowes at redhat.com
Mon Jun 11 12:16:35 UTC 2007


The xml format is similar to that of primary-delta, replacing the
contents of '<additions>' with xml of the format found in other.xml
---
 delta-parser.c |    6 ++-
 xml-parser.c   |  179 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 xml-parser.h   |    7 ++
 3 files changed, 191 insertions(+), 1 deletions(-)

diff --git a/delta-parser.c b/delta-parser.c
index c67ebe8..52e5f37 100644
--- a/delta-parser.c
+++ b/delta-parser.c
@@ -36,7 +36,11 @@ int main(int argc, char* argv[])
         yum_xml_parse_filelists_delta (argv[2], count_callback,
                                        addition_callback, removal_callback,
                                        NULL, &err);
-    } else {
+    } else if (!strcmp ("other", argv[1])) {
+        yum_xml_parse_other_delta (argv[2], count_callback,
+                                   addition_callback, removal_callback,
+                                   NULL, &err);
+	} else {
         printf ("unknown metadata type '%s'\n", argv[1]);
         return -1;
     }
diff --git a/xml-parser.c b/xml-parser.c
index 4e3900f..695b90d 100644
--- a/xml-parser.c
+++ b/xml-parser.c
@@ -1432,3 +1432,182 @@ yum_xml_parse_other (const char *filename,
 
     g_string_free (sctx.text_buffer, TRUE);
 }
+
+typedef struct {
+    OtherSAXContext pctx;
+    DeltaSAXContextState state;
+    PackageFn package_removal_fn;
+} OtherDeltaSAXContext;
+
+static void
+other_delta_parser_toplevel_start (OtherDeltaSAXContext *ctx,
+                                   const char *name,
+                                   const char **attrs)
+{
+    SAXContext *sctx = &(&ctx->pctx)->sctx;
+
+    if (!strcmp (name, "additions")) {
+        ctx->state = DELTA_PARSER_ADDITIONS;
+    }
+    else if (!strcmp (name, "removals")) {
+        ctx->state = DELTA_PARSER_REMOVALS;
+    }
+
+    else if (sctx->count_fn && !strcmp (name, "other")) {
+        int i;
+        const char *attr;
+        const char *value;
+
+        for (i = 0; attrs && attrs[i]; i++) {
+            attr = attrs[i];
+            value = attrs[++i];
+
+            if (!strcmp (attr, "packages")) {
+                sctx->count_fn (string_to_guint32_with_default (value, 0),
+                               sctx->user_data);
+                break;
+            }
+        }
+    }
+}
+
+static void
+other_delta_sax_start_element (void *data, const char *name,
+                               const char **attrs)
+{
+    OtherDeltaSAXContext *ctx = (OtherDeltaSAXContext *) data;
+    SAXContext *sctx = &(&ctx->pctx)->sctx;
+
+    if (sctx->text_buffer->len)
+        g_string_truncate (sctx->text_buffer, 0);
+
+    switch (ctx->state) {
+    case DELTA_PARSER_TOPLEVEL:
+        other_delta_parser_toplevel_start (ctx, name, attrs);
+        break;
+    case DELTA_PARSER_REMOVALS:
+        delta_parser_removals_start (sctx, name, attrs);
+        break;
+    case DELTA_PARSER_ADDITIONS:
+        other_sax_start_element (&ctx->pctx, name, attrs);
+        break;
+    default:
+        break;
+    }
+}
+
+static void
+other_delta_parser_removals_end (OtherDeltaSAXContext *ctx,
+                                 const char *name)
+{
+    if (!strcmp (name, "package")) {
+        SAXContext *sctx = &(&ctx->pctx)->sctx;
+
+        Package *p = sctx->current_package;
+        g_assert (p != NULL);
+
+        if (ctx->package_removal_fn && !*sctx->error)
+            ctx->package_removal_fn (p, sctx->user_data);
+
+        package_free (p);
+        sctx->current_package = NULL;
+
+        sctx->want_text = FALSE;
+    }
+    else if (!strcmp (name, "removals")) {
+        ctx->state = DELTA_PARSER_TOPLEVEL;
+    }
+}
+
+static void
+other_delta_sax_end_element (void *data, const char *name)
+{
+    OtherDeltaSAXContext *ctx = (OtherDeltaSAXContext *) data;
+    SAXContext *sctx = &(&ctx->pctx)->sctx;
+
+    switch (ctx->state) {
+    case DELTA_PARSER_ADDITIONS:
+        if (ctx->pctx.state == OTHER_PARSER_TOPLEVEL) {
+            if (!strcmp (name, "additions"))
+                ctx->state = DELTA_PARSER_TOPLEVEL;
+        }
+        else
+            other_sax_end_element (&ctx->pctx, name);
+        break;
+    case DELTA_PARSER_REMOVALS:
+        other_delta_parser_removals_end (ctx, name);
+        break;
+    default:
+        break;
+    }
+
+    g_string_truncate (sctx->text_buffer, 0);
+}
+
+static xmlSAXHandler other_delta_sax_handler = {
+    NULL,      /* internalSubset */
+    NULL,      /* isStandalone */
+    NULL,      /* hasInternalSubset */
+    NULL,      /* hasExternalSubset */
+    NULL,      /* resolveEntity */
+    NULL,      /* getEntity */
+    NULL,      /* entityDecl */
+    NULL,      /* notationDecl */
+    NULL,      /* attributeDecl */
+    NULL,      /* elementDecl */
+    NULL,      /* unparsedEntityDecl */
+    NULL,      /* setDocumentLocator */
+    NULL,      /* startDocument */
+    NULL,      /* endDocument */
+    (startElementSAXFunc) other_delta_sax_start_element, /* startElement */
+    (endElementSAXFunc) other_delta_sax_end_element,     /* endElement */
+    NULL,      /* reference */
+    (charactersSAXFunc) sax_characters,      /* characters */
+    NULL,      /* ignorableWhitespace */
+    NULL,      /* processingInstruction */
+    NULL,      /* comment */
+    sax_warning,      /* warning */
+    sax_error,      /* error */
+    sax_error,      /* fatalError */
+};
+
+void
+yum_xml_parse_other_delta (const char *filename,
+                           CountFn count_callback,
+                           PackageFn package_addition_callback,
+                           PackageFn package_removal_callback,
+                           gpointer user_data,
+                           GError **err)
+{
+    OtherDeltaSAXContext ctx;
+    OtherSAXContext pctx;
+    SAXContext sctx;
+    int rc;
+
+    sctx.md_type = "other-delta.xml";
+    sctx.error = err;
+    sctx.count_fn = count_callback;
+    sctx.package_fn = package_addition_callback;
+    sctx.user_data = user_data;
+    sctx.current_package = NULL;
+    sctx.want_text = FALSE;
+    sctx.text_buffer = g_string_sized_new (PACKAGE_FIELD_SIZE);
+
+    pctx.current_entry = NULL;
+    pctx.state = OTHER_PARSER_TOPLEVEL;
+    pctx.sctx = sctx;
+
+    ctx.state = DELTA_PARSER_TOPLEVEL;
+    ctx.package_removal_fn = package_removal_callback;
+    ctx.pctx = pctx;
+
+    xmlSubstituteEntitiesDefault (1);
+    rc = xmlSAXUserParseFile (&other_delta_sax_handler, &ctx, filename);
+
+    if (sctx.current_package) {
+        g_warning ("Incomplete package lost");
+        package_free (sctx.current_package);
+    }
+
+    g_string_free (sctx.text_buffer, TRUE);
+}
diff --git a/xml-parser.h b/xml-parser.h
index 29cc423..6e919f4 100644
--- a/xml-parser.h
+++ b/xml-parser.h
@@ -60,4 +60,11 @@ void yum_xml_parse_other (const char *filename,
                           gpointer user_data,
                           GError **err);
 
+void yum_xml_parse_other_delta (const char *filename,
+                                CountFn count_callback,
+                                PackageFn package_addition_callback,
+                                PackageFn package_removal_callback,
+                                gpointer user_data,
+                                GError **err);
+
 #endif /* __YUM_XML_PARSER_H__ */
-- 
1.5.2.1.938.gac3b4




More information about the Yum-devel mailing list