Add load_metadata module.
authorTomas Mlcoch <tmlcoch@redhat.com>
Wed, 18 Jan 2012 15:40:43 +0000 (16:40 +0100)
committerTomas Mlcoch <tmlcoch@redhat.com>
Wed, 18 Jan 2012 15:40:43 +0000 (16:40 +0100)
Makefile
load_metadata.c [new file with mode: 0644]
load_metadata.h [new file with mode: 0644]
load_metadata.i [new file with mode: 0644]
typemaps.i

index 01137f9..f463950 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,13 +1,22 @@
 SWIG=/usr/bin/swig
 CFLAGS=-O -fPIC -DDEBUG -I/usr/include/python2.7/ `pkg-config --cflags glib-2.0` `xml2-config --cflags`
 LINKFLAGS=`pkg-config --libs glib-2.0` `xml2-config --libs` -lrpm -lrpmio
+LC=-lc
 
-all: package.so xml_dump.so parsehdr.so parsepkg.so
+# Profiling
+CFLAGS=-pg -O -fPIC -DDEBUG -I/usr/include/python2.7/ `pkg-config --cflags glib-2.0` `xml2-config --cflags`
+#LINKFLAGS=/lib/gcrt0.o `pkg-config --libs glib-2.0` `xml2-config --libs` -lrpm -lrpmio
+LC=-lc
 
-ctests: parsepkg_test_01 xml_dump_primary_test_01 xml_dump_filelists_test_01 xml_dump_other_test_01
+
+all: package.so xml_dump.so parsehdr.so parsepkg.so load_metadata.so
+
+ctests: parsepkg_test_01 parsehdr_test_01 parsehdr_test_02 xml_dump_primary_test_01 \
+        xml_dump_filelists_test_01 xml_dump_other_test_01 load_metadata_test_01
 
 test: main
 
+
 # Object files + Swit object files
 
 package.o package_wrap.o: package.i package.c package.h
@@ -30,6 +39,11 @@ parsepkg.o parsepkg_wrap.o: parsepkg.c parsepkg.h constants.h
        $(SWIG) -python -Wall parsepkg.i
        gcc $(CFLAGS) -c parsepkg.c parsepkg_wrap.c
 
+load_metadata.o load_metadata_wrap.o: load_metadata.c load_metadata.h constants.h
+       $(SWIG) -python -Wall load_metadata.i
+       gcc $(CFLAGS) -c load_metadata.c load_metadata_wrap.c
+
+
 # Object files
 
 misc.o: misc.c misc.h
@@ -45,22 +59,32 @@ xml_dump_other.o: xml_dump_other.c xml_dump.h
        gcc $(CFLAGS) -c xml_dump_other.c
 
 package.so: package_wrap.o package.o
-       ld $(LINKFLAGS) -shared package.o package_wrap.o -o _package.so -lc
+       ld $(LINKFLAGS) -shared package.o package_wrap.o -o _package.so $(LC)
 
 xml_dump.so: package.o xml_dump_wrap.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o
-       ld $(LINKFLAGS) -shared package.o xml_dump_wrap.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o -o _xml_dump.so -lc
+       ld $(LINKFLAGS) -shared package.o xml_dump_wrap.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o -o _xml_dump.so $(LC)
 
 parsehdr.so: parsehdr_wrap.o parsehdr.o package.o xml_dump.o misc.o
-       ld $(LINKFLAGS) -shared misc.o parsehdr_wrap.o parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o -o _parsehdr.so -lc
+       ld $(LINKFLAGS) -shared misc.o parsehdr_wrap.o parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o -o _parsehdr.so $(LC)
 
 parsepkg.so: parsepkg_wrap.o parsepkg.o parsehdr.o package.o xml_dump.o misc.o
-       ld $(LINKFLAGS) -shared misc.o parsepkg_wrap.o parsepkg.o parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o -o _parsepkg.so -lc
+       ld $(LINKFLAGS) -shared misc.o parsepkg_wrap.o parsepkg.o parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o -o _parsepkg.so $(LC)
+
+load_metadata.so: load_metadata_wrap.o load_metadata.o
+       ld $(LINKFLAGS) -shared load_metadata_wrap.o load_metadata.o -o _load_metadata.so $(LC)
+
 
 # Tests
 
 parsepkg_test_01: parsepkg.o parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o
        gcc $(LINKFLAGS) $(CFLAGS) parsepkg.o parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o ctests/parsepkg_test_01.c -o ctests/parsepkg_test_01
 
+parsehdr_test_01: parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o
+       gcc $(LINKFLAGS) $(CFLAGS) parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o ctests/parsehdr_test_01.c -o ctests/parsehdr_test_01
+
+parsehdr_test_02: parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o
+       gcc $(LINKFLAGS) $(CFLAGS) parsehdr.o package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o ctests/parsehdr_test_02.c -o ctests/parsehdr_test_02
+
 xml_dump_primary_test_01: package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o
        gcc $(LINKFLAGS) $(CFLAGS) package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o ctests/xml_dump_primary_test_01.c -o ctests/xml_dump_primary_test_01
 
@@ -70,6 +94,9 @@ xml_dump_filelists_test_01: package.o xml_dump.o xml_dump_primary.o xml_dump_fil
 xml_dump_other_test_01: package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o
        gcc $(LINKFLAGS) $(CFLAGS) package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o misc.o ctests/xml_dump_other_test_01.c -o ctests/xml_dump_other_test_01
 
+load_metadata_test_01: load_metadata.o
+       gcc $(LINKFLAGS) $(CFLAGS) load_metadata.o ctests/load_metadata_test_01.c -o ctests/load_metadata_test_01
+
 
 clean:
        rm -f *.o *.so *_wrap.* main *.pyc
diff --git a/load_metadata.c b/load_metadata.c
new file mode 100644 (file)
index 0000000..fde9337
--- /dev/null
@@ -0,0 +1,125 @@
+#include <glib.h>
+#include <stdio.h>
+#include "load_metadata.h"
+
+
+void free_values(gpointer data)
+{
+    struct package_metadata *md = (struct package_metadata *) data;
+    g_free(md->checksum_type);
+    g_free(md->primary_xml);
+    g_free(md->filelists_xml);
+    g_free(md->other_xml);
+    g_free(md);
+}
+
+
+GHashTable *load_metadata(const char *primary_xml_path, const char *filelists_xml_path, const char *other_xml_path)
+{
+    GFileTest flags = G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR;
+    if (!g_file_test(primary_xml_path, flags) ||
+        !g_file_test(filelists_xml_path, flags) ||
+        !g_file_test(other_xml_path, flags))
+    {
+        return NULL;
+    }
+
+    GHashTable *metadata = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, free_values);
+
+    // Map file into memmory
+    char *pri_cont, *fil_cont, *oth_cont;
+    int pri_len, fil_len, oth_len;
+
+    g_file_get_contents(primary_xml_path, &pri_cont, &pri_len, NULL);
+    g_file_get_contents(filelists_xml_path, &fil_cont, &fil_len, NULL);
+    g_file_get_contents(other_xml_path, &oth_cont, &oth_len, NULL);
+
+    GRegexCompileFlags c_flags = G_REGEX_DOTALL | G_REGEX_OPTIMIZE;
+    GRegexMatchFlags   m_flags = 0;
+
+    GRegex *package_re       = g_regex_new("<package.*?</package>", c_flags, m_flags, NULL);
+    GRegex *filename_re      = g_regex_new("<location href=\"([^\"]*)", c_flags, m_flags, NULL);
+    GRegex *checksum_type_re = g_regex_new("<checksum .*?type=\"([a-zA-Z0-9]+)\"", c_flags, m_flags, NULL);
+    GRegex *filetime_re      = g_regex_new("<time .*?file=\"([0-9]+)\"", c_flags, m_flags, NULL);
+    GRegex *size_re          = g_regex_new("<size .*?package=\"([0-9]+)\"", c_flags, m_flags, NULL);
+
+    GMatchInfo *pri_pkg_match_info = NULL;
+    GMatchInfo *fil_pkg_match_info = NULL;
+    GMatchInfo *oth_pkg_match_info = NULL;
+
+    g_regex_match(package_re, pri_cont, m_flags, &pri_pkg_match_info);
+    g_regex_match(package_re, fil_cont, m_flags, &fil_pkg_match_info);
+    g_regex_match(package_re, oth_cont, m_flags, &oth_pkg_match_info);
+
+    // Iterate over all packages
+    while (g_match_info_matches (pri_pkg_match_info) &&
+           g_match_info_matches (fil_pkg_match_info) &&
+           g_match_info_matches (oth_pkg_match_info))
+    {
+        char *pkg_pri = g_match_info_fetch (pri_pkg_match_info, 0);
+        char *pkg_fil = g_match_info_fetch (fil_pkg_match_info, 0);
+        char *pkg_oth = g_match_info_fetch (oth_pkg_match_info, 0);
+
+        // Get Location
+        GMatchInfo *mi_location;
+        g_regex_match(filename_re, pkg_pri, m_flags, &mi_location);
+        char *location = g_match_info_fetch(mi_location, 1);
+
+        // Get Checksum type
+        GMatchInfo *mi_checksum;
+        g_regex_match(checksum_type_re, pkg_pri, m_flags, &mi_checksum);
+        char *checksum_type = g_match_info_fetch(mi_checksum, 1);
+
+        // Get Filetime
+        GMatchInfo *mi_filetime;
+        g_regex_match(filetime_re, pkg_pri, m_flags, &mi_filetime);
+        char *filetime_str = g_match_info_fetch(mi_filetime, 1);
+        gint64 filetime = g_ascii_strtoll(filetime_str, NULL, 10);
+
+        // Get Size
+        GMatchInfo *mi_size;
+        g_regex_match(size_re, pkg_pri, m_flags, &mi_size);
+        char *size_str = g_match_info_fetch(mi_size, 1);
+        gint64 size = g_ascii_strtoll(size_str, NULL, 10);
+
+        // Insert into metadata hash table
+        struct package_metadata *pkg_md = g_malloc(sizeof(struct package_metadata));
+        pkg_md->time_file = filetime;
+        pkg_md->size_package = size;
+        pkg_md->checksum_type = checksum_type;
+        pkg_md->primary_xml = pkg_pri;
+        pkg_md->filelists_xml = pkg_fil;
+        pkg_md->other_xml = pkg_oth;
+        g_hash_table_insert(metadata, location, pkg_md);
+
+        // Clean up
+        g_free(filetime_str);
+        g_free(size_str);
+
+        g_match_info_free(mi_location);
+        g_match_info_free(mi_checksum);
+        g_match_info_free(mi_filetime);
+        g_match_info_free(mi_size);
+
+        // Get next item
+        g_match_info_next (pri_pkg_match_info, NULL);
+        g_match_info_next (fil_pkg_match_info, NULL);
+        g_match_info_next (oth_pkg_match_info, NULL);
+    }
+
+    g_match_info_free(pri_pkg_match_info);
+    g_match_info_free(fil_pkg_match_info);
+    g_match_info_free(oth_pkg_match_info);
+
+    g_regex_unref(package_re);
+    g_regex_unref(filename_re);
+    g_regex_unref(checksum_type_re);
+    g_regex_unref(filetime_re);
+    g_regex_unref(size_re);
+
+    g_free(pri_cont);
+    g_free(fil_cont);
+    g_free(oth_cont);
+
+    return metadata;
+}
diff --git a/load_metadata.h b/load_metadata.h
new file mode 100644 (file)
index 0000000..2554a50
--- /dev/null
@@ -0,0 +1,20 @@
+#ifndef __LOAD_METADATA__
+#define __LOAD_METADATA__
+
+#include <glib.h>
+#include "constants.h"
+
+struct package_metadata {
+    gint64 time_file;
+    gint64 size_package;
+    char *checksum_type;
+    char *primary_xml;
+    char *filelists_xml;
+    char *other_xml;
+//    GStringChunk *chunk;
+};
+
+
+GHashTable *load_metadata(const char *primary_xml_path, const char *filelists_xml_path, const char *other_xml_path);
+
+#endif /* __LOAD_METADATA__ */
diff --git a/load_metadata.i b/load_metadata.i
new file mode 100644 (file)
index 0000000..c32a594
--- /dev/null
@@ -0,0 +1,9 @@
+%module load_metadata
+
+%include <typemaps.i>
+
+%{
+#include "load_metadata.h"
+%}
+
+%include "load_metadata.h"
index 03a1287..43a24ec 100644 (file)
     }
 }
 
+%typemap(out) GHashTable *load_metadata {
+    PyObject *dict = PyDict_New();
+
+    GHashTable *hash_table = $1;
+    GHashTableIter iter;
+    gpointer key, value;
+
+    g_hash_table_iter_init (&iter, hash_table);
+    while (g_hash_table_iter_next (&iter, &key, &value))
+    {
+        struct package_metadata *md = (struct package_metadata *) value;
+        PyObject *py_value = PyTuple_New(6);
+        PyTuple_SetItem(py_value, 0, PyLong_FromLong(md->time_file));
+        PyTuple_SetItem(py_value, 1, PyLong_FromLong(md->size_package));
+        PyTuple_SetItem(py_value, 2, PyString_FromString(md->checksum_type));
+        PyTuple_SetItem(py_value, 3, PyString_FromString(md->primary_xml));
+        PyTuple_SetItem(py_value, 4, PyString_FromString(md->filelists_xml));
+        PyTuple_SetItem(py_value, 5, PyString_FromString(md->other_xml));
+        PyDict_SetItemString(dict, key, py_value);
+    }
+    g_hash_table_destroy (hash_table);
+
+    $result = dict;
+}
+
+/*
 %typemap(out) GSList *changelogs {
     PyObject *list = PyList_New(0);
     GSList *element = NULL;
     list = g_slist_reverse(list);
     $1 = list;
 }
+*/
 
 %typemap(in) Package * {
     char *str = NULL;