[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