[Yum-devel] [PATCH 4/5] Add xml parsing for filelists delta files
James Bowes
jbowes at redhat.com
Mon Jun 11 12:16:34 UTC 2007
The xml format is similar to that of primary-delta, replacing the
contents of '<additions>' with xml of the format found in filelists.xml
---
delta-parser.c | 8 ++-
xml-parser.c | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
xml-parser.h | 8 +++
3 files changed, 192 insertions(+), 2 deletions(-)
diff --git a/delta-parser.c b/delta-parser.c
index 52dafbf..c67ebe8 100644
--- a/delta-parser.c
+++ b/delta-parser.c
@@ -28,11 +28,15 @@ int main(int argc, char* argv[])
return -1;
}
- if (!strcmp ("primary", argv[1]))
+ if (!strcmp ("primary", argv[1])) {
yum_xml_parse_primary_delta (argv[2], count_callback,
addition_callback, removal_callback,
NULL, &err);
- else {
+ } else if (!strcmp ("filelists", argv[1])) {
+ yum_xml_parse_filelists_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 7668c48..4e3900f 100644
--- a/xml-parser.c
+++ b/xml-parser.c
@@ -1027,6 +1027,184 @@ yum_xml_parse_filelists (const char *filename,
g_string_free (sctx.text_buffer, TRUE);
}
+typedef struct {
+ FilelistSAXContext pctx;
+ DeltaSAXContextState state;
+ PackageFn package_removal_fn;
+} FilelistDeltaSAXContext;
+
+static void
+filelist_delta_parser_toplevel_start (FilelistDeltaSAXContext *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, "filelists")) {
+ 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
+filelist_delta_sax_start_element (void *data, const char *name,
+ const char **attrs)
+{
+ FilelistDeltaSAXContext *ctx = (FilelistDeltaSAXContext *) 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:
+ filelist_delta_parser_toplevel_start (ctx, name, attrs);
+ break;
+ case DELTA_PARSER_REMOVALS:
+ delta_parser_removals_start (sctx, name, attrs);
+ break;
+ case DELTA_PARSER_ADDITIONS:
+ filelist_sax_start_element (&ctx->pctx, name, attrs);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+filelist_delta_parser_removals_end (FilelistDeltaSAXContext *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
+filelist_delta_sax_end_element (void *data, const char *name)
+{
+ FilelistDeltaSAXContext *ctx = (FilelistDeltaSAXContext *) data;
+ SAXContext *sctx = &(&ctx->pctx)->sctx;
+
+ switch (ctx->state) {
+ case DELTA_PARSER_ADDITIONS:
+ if (ctx->pctx.state == FILELIST_PARSER_TOPLEVEL) {
+ if (!strcmp (name, "additions"))
+ ctx->state = DELTA_PARSER_TOPLEVEL;
+ }
+ else
+ filelist_sax_end_element (&ctx->pctx, name);
+ break;
+ case DELTA_PARSER_REMOVALS:
+ filelist_delta_parser_removals_end (ctx, name);
+ break;
+ default:
+ break;
+ }
+
+ g_string_truncate (sctx->text_buffer, 0);
+}
+
+static xmlSAXHandler filelist_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) filelist_delta_sax_start_element, /* startElement */
+ (endElementSAXFunc) filelist_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_filelists_delta (const char *filename,
+ CountFn count_callback,
+ PackageFn package_addition_callback,
+ PackageFn package_removal_callback,
+ gpointer user_data,
+ GError **err)
+{
+ FilelistDeltaSAXContext ctx;
+ FilelistSAXContext pctx;
+ SAXContext sctx;
+ int rc;
+
+ sctx.md_type = "filelists-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_file = NULL;
+ pctx.state = FILELIST_PARSER_TOPLEVEL;
+ pctx.sctx = sctx;
+
+ ctx.state = DELTA_PARSER_TOPLEVEL;
+ ctx.package_removal_fn = package_removal_callback;
+ ctx.pctx = pctx;
+
+ xmlSubstituteEntitiesDefault (1);
+ rc = xmlSAXUserParseFile (&filelist_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);
+}
/*****************************************************************************/
typedef enum {
diff --git a/xml-parser.h b/xml-parser.h
index 6461628..29cc423 100644
--- a/xml-parser.h
+++ b/xml-parser.h
@@ -46,6 +46,14 @@ yum_xml_parse_filelists (const char *filename,
gpointer user_data,
GError **err);
+void yum_xml_parse_filelists_delta (const char *filename,
+ CountFn count_callback,
+ PackageFn package_addition_callback,
+ PackageFn package_removal_callback,
+ gpointer user_data,
+ GError **err);
+
+
void yum_xml_parse_other (const char *filename,
CountFn count_callback,
PackageFn package_callback,
--
1.5.2.1.938.gac3b4
More information about the Yum-devel
mailing list