Initial commit
authorTomas Mlcoch <tmlcoch@redhat.com>
Mon, 12 Dec 2011 09:37:45 +0000 (10:37 +0100)
committerTomas Mlcoch <tmlcoch@redhat.com>
Mon, 12 Dec 2011 09:37:45 +0000 (10:37 +0100)
12 files changed:
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
main.c [new file with mode: 0644]
package.c [new file with mode: 0644]
package.h [new file with mode: 0644]
package.i [new file with mode: 0644]
xml_dump.c [new file with mode: 0644]
xml_dump.h [new file with mode: 0644]
xml_dump.i [new file with mode: 0644]
xml_dump_filelists.c [new file with mode: 0644]
xml_dump_other.c [new file with mode: 0644]
xml_dump_primary.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..99145b6
--- /dev/null
@@ -0,0 +1,7 @@
+*.o
+*.so
+*.py
+*.pyc
+*_wrap.c
+snippets/
+notes
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..283f2d2
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,40 @@
+SWIG=/usr/bin/swig
+
+CFLAGS=-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`
+
+all:   package.so xml_dump.so
+
+test: main
+
+package.o package_wrap.o: package.i package.c package.h
+       $(SWIG) -python -Wall package.i
+       gcc $(CFLAGS) -c package.c package_wrap.c 
+
+xml_dump_wrap.o: xml_dump.i xml_dump.c xml_dump.h
+       $(SWIG) -python -Wall xml_dump.i
+       gcc $(CFLAGS) -c xml_dump_wrap.c xml_dump_wrap.c 
+
+xml_dump.o: xml_dump.c xml_dump.h
+       gcc $(CFLAGS) -c xml_dump.c
+
+xml_dump_primary.o: xml_dump_primary.c xml_dump.h
+       gcc $(CFLAGS) -c xml_dump_primary.c
+
+xml_dump_filelists.o: xml_dump_filelists.c xml_dump.h
+       gcc $(CFLAGS) -c xml_dump_filelists.c
+
+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
+
+xml_dump.so: xml_dump_wrap.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o
+       ld $(LINKFLAGS) -shared xml_dump_wrap.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o -o _xml_dump.so
+
+main: package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o
+       gcc $(LINKFLAGS) $(CFLAGS) package.o xml_dump.o xml_dump_primary.o xml_dump_filelists.o xml_dump_other.o main.c -o main
+
+clean:
+       rm -f *.o package_wrap.* _package.so main
diff --git a/main.c b/main.c
new file mode 100644 (file)
index 0000000..fa6b29f
--- /dev/null
+++ b/main.c
@@ -0,0 +1,122 @@
+#include <stdio.h>
+#include "package.h"
+#include "xml_dump.h"
+
+int main() {
+    Package *package = package_new();
+
+    package->name = "ŠŠŠJMÉNÓ";
+    package->pkgKey = 111;
+    package->pkgId = "32543dsafchecksum";
+    package->arch = "i386";
+    package->version = "88";
+    package->epoch = "11";
+    package->release = "08";
+    package->summary = "short summary";
+    package->description = "long description";
+    package->url = "http://foo.bar";
+    package->time_file = 123456;
+    package->time_build = 234567;
+    package->rpm_license = "GPL";
+    package->rpm_vendor = "we";
+    package->rpm_group = "grupa";
+    package->rpm_buildhost = "superman";
+    package->rpm_sourcerpm = "neco.src.rpm";
+    package->rpm_header_start = 1;
+    package->rpm_header_end = 100;
+    package->rpm_packager = "batman";
+    package->size_package = 777;
+    package->size_installed = 888;
+    package->size_archive = 666;
+    package->location_href = "tady";
+    package->location_base = "";
+    package->checksum_type = "sha256";
+
+
+    Dependency *file = dependency_new();
+    file->name = "soubor";
+    file->flags = "A";
+    file->epoch = "1";
+    file->version = "2";
+    file->release = "3";
+    file->pre = 1;
+
+    package->requires = g_slist_append(package->requires, file);
+    package->requires = g_slist_append(package->requires, file);
+    package->requires = g_slist_append(package->requires, file);
+    package->requires = g_slist_append(package->requires, file);
+
+    package->provides = g_slist_append(package->provides, file);
+    package->provides = g_slist_append(package->provides, file);
+    package->provides = g_slist_append(package->provides, file);
+
+    package->conflicts = g_slist_append(package->conflicts, file);
+    package->conflicts = g_slist_append(package->conflicts, file);
+
+    package->obsoletes = g_slist_append(package->obsoletes, file);
+
+
+    PackageFile *pkgfile = package_file_new();
+    pkgfile->name = "/bin/neco";
+    pkgfile->type = "";
+
+    PackageFile *pkgfile2 = package_file_new();
+    pkgfile2->name = "/usr/addresar";
+    pkgfile2->type = "dir";
+
+    PackageFile *pkgfile3 = package_file_new();
+    pkgfile3->name = "/etc/neco.conf";
+    pkgfile3->type = "";
+
+    PackageFile *pkgfile4 = package_file_new();
+    pkgfile4->name = "/usr/lib/sendmail";
+    pkgfile4->type = "";
+
+    PackageFile *pkgfile5 = package_file_new();
+    pkgfile5->name = "/etc/neco.dir";
+    pkgfile5->type = "dir";
+
+    PackageFile *pkgfile6 = package_file_new();
+    pkgfile6->name = "/bin/neco.dir";
+    pkgfile6->type = "dir";
+
+    PackageFile *pkgfile7 = package_file_new();
+    pkgfile7->name = "/usr/lib/sendmail";
+    pkgfile7->type = "dir";
+
+    package->files = g_slist_append(package->files, pkgfile);
+    package->files = g_slist_append(package->files, pkgfile2);
+    package->files = g_slist_append(package->files, pkgfile3);
+    package->files = g_slist_append(package->files, pkgfile4);
+    package->files = g_slist_append(package->files, pkgfile5);
+    package->files = g_slist_append(package->files, pkgfile6);
+    package->files = g_slist_append(package->files, pkgfile7);
+
+
+    ChangelogEntry *chlog = changelog_entry_new();
+    chlog->author = "foobar";
+    chlog->date = 1234567;
+    chlog->changelog = "very long changelog message";
+
+    ChangelogEntry *chlog2 = changelog_entry_new();
+    chlog2->author = "foobar2";
+    chlog2->date = 67890;
+    chlog2->changelog = "short changelog message";
+
+    package->changelogs = g_slist_append(package->changelogs, chlog);
+    package->changelogs = g_slist_append(package->changelogs, chlog2);
+
+
+    //printf("Jde se dumpovat\n");
+    char *ret = xml_dump_primary(package, NULL);
+    printf("%s\n\n", ret);
+
+    ret = xml_dump_filelists(package, NULL);
+    printf("%s\n\n", ret);
+
+    ret = xml_dump_other(package, NULL);
+    printf("%s\n\n", ret);
+
+    return 0;
+}
+
diff --git a/package.c b/package.c
new file mode 100644 (file)
index 0000000..dfd9ed9
--- /dev/null
+++ b/package.c
@@ -0,0 +1,99 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+
+/* This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ * 02111-1307, USA.
+ */
+
+#include "package.h"
+
+#define PACKAGE_CHUNK_SIZE 2048
+
+Dependency *
+dependency_new (void)
+{
+    Dependency *dep;
+
+    dep = g_new0 (Dependency, 1);
+
+    return dep;
+}
+
+PackageFile *
+package_file_new (void)
+{
+    PackageFile *file;
+
+    file = g_new0 (PackageFile, 1);
+
+    return file;
+}
+
+ChangelogEntry *
+changelog_entry_new (void)
+{
+    ChangelogEntry *entry;
+
+    entry = g_new0 (ChangelogEntry, 1);
+
+    return entry;
+}
+
+Package *
+package_new (void)
+{
+    Package *package;
+
+    package = g_new0 (Package, 1);
+    package->chunk = g_string_chunk_new (PACKAGE_CHUNK_SIZE);
+
+    return package;
+}
+
+void
+package_free (Package *package)
+{
+    g_string_chunk_free (package->chunk);
+
+    if (package->requires) {
+        g_slist_foreach (package->requires, (GFunc) g_free, NULL);
+        g_slist_free (package->requires);
+    }
+
+    if (package->provides) {
+        g_slist_foreach (package->provides, (GFunc) g_free, NULL);
+        g_slist_free (package->provides);
+    }
+
+    if (package->conflicts) {
+        g_slist_foreach (package->conflicts, (GFunc) g_free, NULL);
+        g_slist_free (package->conflicts);
+    }
+
+    if (package->obsoletes) {
+        g_slist_foreach (package->obsoletes, (GFunc) g_free, NULL);
+        g_slist_free (package->obsoletes);
+    }
+
+    if (package->files) {
+        g_slist_foreach (package->files, (GFunc) g_free, NULL);
+        g_slist_free (package->files);
+    }
+
+    if (package->changelogs) {
+        g_slist_foreach (package->changelogs, (GFunc) g_free, NULL);
+        g_slist_free (package->changelogs);
+    }
+
+    g_free (package);
+}
diff --git a/package.h b/package.h
new file mode 100644 (file)
index 0000000..93b1b6c
--- /dev/null
+++ b/package.h
@@ -0,0 +1,73 @@
+#ifndef __YUM_PACKAGE_H__
+#define __YUM_PACKAGE_H__
+
+#include <glib.h>
+
+typedef struct {
+    char *name;
+    char *flags;
+    char *epoch;
+    char *version;
+    char *release;
+    gboolean pre;
+} Dependency;
+
+typedef struct {
+    char *type;
+    char *name;
+} PackageFile;
+
+typedef struct {
+    char *author;
+    gint64 date;
+    char *changelog;
+} ChangelogEntry;
+
+typedef struct {
+    gint64 pkgKey;
+    char *pkgId;
+    char *name;
+    char *arch;
+    char *version;
+    char *epoch;
+    char *release;
+    char *summary;
+    char *description;
+    char *url;
+    gint64 time_file;
+    gint64 time_build;
+    char *rpm_license;
+    char *rpm_vendor;
+    char *rpm_group;
+    char *rpm_buildhost;
+    char *rpm_sourcerpm;
+    gint64 rpm_header_start;
+    gint64 rpm_header_end;
+    char *rpm_packager;
+    gint64 size_package;
+    gint64 size_installed;
+    gint64 size_archive;
+    char *location_href;
+    char *location_base;
+    char *checksum_type;
+
+    GSList *requires;
+    GSList *provides;
+    GSList *conflicts;
+    GSList *obsoletes;
+
+    GSList *files;
+    GSList *changelogs;
+
+    GStringChunk *chunk;
+} Package;
+
+typedef void (*PackageFn) (Package *pkg, gpointer data);
+
+Dependency     *dependency_new      (void);
+PackageFile    *package_file_new    (void);
+ChangelogEntry *changelog_entry_new (void);
+Package        *package_new         (void);
+void            package_free        (Package *package);
+
+#endif /* __YUM_PACKAGE_H__ */
diff --git a/package.i b/package.i
new file mode 100644 (file)
index 0000000..ecce25b
--- /dev/null
+++ b/package.i
@@ -0,0 +1,8 @@
+%module package
+
+%{
+#include "package.h"
+%}
+
+%include "package.h"
+
diff --git a/xml_dump.c b/xml_dump.c
new file mode 100644 (file)
index 0000000..b78662d
--- /dev/null
@@ -0,0 +1,143 @@
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#include <string.h>
+#include "xml_dump.h"
+
+//xmlCharEncodingHandlerPtr handler = NULL;
+
+xmlChar *
+ConvertInput(const char *in, xmlCharEncodingHandlerPtr handler)
+{
+    xmlChar *out;
+    int ret;
+    int size;
+    int out_size;
+    int temp;
+
+    if (in == 0) {
+        return NULL;
+    }
+
+    if (!handler) {
+//        printf("Nic neprevadim\n");
+        return (xmlChar*) in;
+    }
+
+
+    size = (int) strlen(in) + 1;
+    out_size = size * 2 - 1;
+    out = (unsigned char *) xmlMalloc((size_t) out_size);
+    printf("%s | size: %d, out_size: %d\n", in, size, out_size);
+
+
+    if (out != NULL) {
+
+        temp = size - 1;
+//        printf("JDU PREVADET\n");
+        ret = handler->input(out, &out_size, (const xmlChar *) in, &temp);
+//        printf("JDU PREVADET\n");
+        if ((ret < 0) || (temp - size + 1)) {
+            if (ret < 0) {
+                printf("ConvertInput: conversion wasn't successful.\n");
+            } else {
+                printf
+                    ("ConvertInput: conversion wasn't successful. converted: %i octets.\n",
+                     temp);
+            }
+
+            xmlFree(out);
+            out = 0;
+        } else {
+            out = (unsigned char *) xmlRealloc(out, out_size + 1);
+            out[out_size] = 0;  /*null terminating out */
+        }
+    } else {
+        printf("ConvertInput: no mem\n");
+    }
+
+    return out;
+}
+
+
+GRegex *pri_re_1 = NULL;
+GRegex *pri_re_2 = NULL;
+GRegex *pri_re_3 = NULL;
+
+void
+dump_files(xmlTextWriterPtr writer, Package *package, int primary, 
+           xmlCharEncodingHandlerPtr handler)
+{
+#ifdef DEBUG
+    printf("CALLED dump_files\n");
+#endif
+
+    // Regex compilation
+    if (!pri_re_1) {
+        GRegexMatchFlags compile_flags = G_REGEX_OPTIMIZE|G_REGEX_MATCH_ANCHORED;
+        pri_re_1 = g_regex_new(".*bin/.*", compile_flags, 0, NULL);
+        pri_re_2 = g_regex_new("/etc/.*", compile_flags, 0, NULL);
+        pri_re_3 = g_regex_new("/usr/lib/sendmail$", compile_flags, 0, NULL);
+    }
+
+    xmlChar *tmp = NULL;
+
+    if (!package->files) {
+        return;
+    }
+
+    GSList *element = NULL;
+    for(element = package->files; element; element=element->next) {
+
+        PackageFile *entry = (PackageFile*) element->data;
+
+        if (primary) {
+            // Only files or dirs could be primary - sorry ghost files :(
+            if (entry->type[0] != '\0' && strcmp(entry->type, "file") && strcmp(entry->type, "dir")) {
+                continue;
+            }
+
+            // Check if file name match pattern for primary files
+            if (!g_regex_match(pri_re_1, entry->name, 0, NULL)
+               && !g_regex_match(pri_re_2, entry->name, 0, NULL)
+               && !g_regex_match(pri_re_3, entry->name, 0, NULL)) {
+                continue;
+            }
+        }
+
+
+        // ***********************************
+        // Element: file
+        // ************************************
+
+        int rc;
+        rc = xmlTextWriterStartElement(writer, BAD_CAST "file");
+        if (rc < 0) {
+            printf("Error at xmlTextWriterWriteElement\n");
+            return;
+        }
+
+        // Write type
+        if (entry->type && strlen(entry->type)) {
+            tmp = ConvertInput(entry->type, handler);
+            rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", tmp);
+            if (rc < 0) {
+                 printf("Error at xmlTextWriterWriteAttribute\n");
+                 return;
+            }
+            if (handler && tmp != NULL) xmlFree(tmp);
+        }
+
+        // Write text (file path)
+        tmp = ConvertInput(entry->name, handler);
+        xmlTextWriterWriteString(writer, BAD_CAST tmp);
+        if (handler && tmp != NULL) xmlFree(tmp);
+
+        // Close file element
+        rc = xmlTextWriterEndElement(writer);
+        if (rc < 0) {
+            printf("Error at xmlTextWriterEndElement\n");
+            return;
+        }
+    }
+}
+
diff --git a/xml_dump.h b/xml_dump.h
new file mode 100644 (file)
index 0000000..ceeab61
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef __XML_DUMP__
+#define __XML_DUMP__
+
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#include "package.h"
+
+/**
+ * ConvertInput:
+ * @in: string in a given encoding
+ * @encoding: the encoding used
+ *
+ * Converts @in into UTF-8 for processing with libxml2 APIs
+ *
+ * Returns the converted UTF-8 string, or NULL in case of error.
+ */
+xmlChar *ConvertInput(const char *, xmlCharEncodingHandlerPtr);
+
+void dump_files(xmlTextWriterPtr, Package *, int, xmlCharEncodingHandlerPtr);
+
+char *xml_dump_primary(Package *, const char *);
+char *xml_dump_filelists(Package *, const char *);
+char *xml_dump_other(Package *, const char *);
+
+#endif /* __XML_DUMP__ */
diff --git a/xml_dump.i b/xml_dump.i
new file mode 100644 (file)
index 0000000..126f37b
--- /dev/null
@@ -0,0 +1,11 @@
+%module xml_dump
+
+%{
+#include "xml_dump.h"
+%}
+
+//%include "xml_dump.h"
+
+char *xml_dump_primary(Package *, const char *);
+char *xml_dump_filelists(Package *, const char *);
+char *xml_dump_other(Package *, const char *);
\ No newline at end of file
diff --git a/xml_dump_filelists.c b/xml_dump_filelists.c
new file mode 100644 (file)
index 0000000..bee7346
--- /dev/null
@@ -0,0 +1,196 @@
+#include <stdio.h>
+#include <string.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#include "package.h"
+#include "xml_dump.h"
+
+#define MY_ENCODING "UTF-8"
+//#define DEBUG
+#undef DEBUG
+//#define DEBUG_REQUIRES
+
+#define PROVIDES    0
+#define CONFLICTS   1
+#define OBSOLETES   2
+#define REQUIRES    3
+
+
+/**
+ * dump_base_items:
+ * @writer:
+ * @package:
+ *
+ * Converts @pkg_dict into xml string
+ *
+ * Returns the converted XML string, or NULL in case of error.
+ */
+void
+dump_filelists_items(xmlTextWriterPtr writer, Package *package, xmlCharEncodingHandlerPtr handler)
+{
+    int rc;
+    xmlChar *tmp  = NULL;
+    gchar   *tmp2 = NULL;
+
+#ifdef DEBUG
+    printf("CALLED dump_filelists_items\n");
+#endif
+
+    rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
+    if (rc < 0) {
+        printf ("Error at xmlTextWriterStartDocument\n");
+        return;
+    }
+
+
+    /***********************************
+    Element: package
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "package");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Add an attribute to package */
+    tmp = ConvertInput(package->pkgId, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    tmp = ConvertInput(package->name, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    tmp = ConvertInput(package->arch, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: version
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "version");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Write version attribute epoch */
+    tmp = ConvertInput(package->epoch, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "epoch", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write version attribute ver */
+    tmp = ConvertInput(package->version, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ver", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write version attribute rel */
+    tmp = ConvertInput(package->release, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "rel", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Close version element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /* Files dump */
+    dump_files(writer, package, 0, handler);
+
+    /* Close package element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /* Close document (and every still opened tags) */
+    rc = xmlTextWriterEndDocument(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndDocument\n");
+        return;
+    }
+}
+
+
+char *
+xml_dump_filelists(Package *package, const char *encoding)
+{
+
+    /*
+    * Global variable initialization
+    */
+
+    // Encoging handler for selected encoding
+    xmlCharEncodingHandlerPtr handler = NULL;
+    if (encoding) {
+        handler = xmlFindCharEncodingHandler(encoding);
+        if (!handler) {
+            printf("ConvertInput: no encoding handler found for 'utf-8'\n");
+            return NULL;
+        }
+    }
+
+    /*
+     * XML Gen
+     */
+
+    xmlBufferPtr buf = xmlBufferCreate();
+    if (buf == NULL) {
+        printf("Error creating the xml buffer\n");
+        return NULL;
+    }
+
+    xmlTextWriterPtr writer = xmlNewTextWriterMemory(buf, 0);
+    if (writer == NULL) {
+        printf("Error creating the xml writer\n");
+        return NULL;
+    }
+
+#ifdef DEBUG
+    printf("Xml buffer and writer created\n");
+#endif
+
+    dump_filelists_items(writer, package, handler);
+
+    xmlFreeTextWriter(writer);
+
+    // Get rid off <?xml ...?> header
+    char *pkg_str = strstr((const char*) buf->content, "<package");
+    if (!pkg_str) {
+        pkg_str = (char*) buf->content;
+    }
+
+    char *result = malloc(sizeof(char) * strlen(pkg_str) + 1);
+    strcpy(result, pkg_str);
+
+    xmlBufferFree(buf);
+    return result;
+}
+
diff --git a/xml_dump_other.c b/xml_dump_other.c
new file mode 100644 (file)
index 0000000..2655a95
--- /dev/null
@@ -0,0 +1,258 @@
+#include <stdio.h>
+#include <string.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#include "package.h"
+#include "xml_dump.h"
+
+#define MY_ENCODING "UTF-8"
+//#define DEBUG
+#undef DEBUG
+//#define DEBUG_REQUIRES
+
+#define PROVIDES    0
+#define CONFLICTS   1
+#define OBSOLETES   2
+#define REQUIRES    3
+
+
+void
+dump_changelog(xmlTextWriterPtr writer, Package *package, xmlCharEncodingHandlerPtr handler)
+{
+#ifdef DEBUG
+    printf("CALLED dump_changelog\n");
+#endif
+
+    xmlChar *tmp = NULL;
+    gchar   *tmp2 = NULL;
+
+    if (!package->changelogs) {
+        return;
+    }
+
+    GSList *element = NULL;
+    for(element = package->changelogs; element; element=element->next) {
+
+        ChangelogEntry *entry = (ChangelogEntry*) element->data;
+        // ***********************************
+        // Element: file
+        // ************************************
+
+        int rc;
+        rc = xmlTextWriterStartElement(writer, BAD_CAST "changelog");
+        if (rc < 0) {
+            printf("Error at xmlTextWriterWriteElement\n");
+            return;
+        }
+
+        // Write param author
+        tmp = ConvertInput(entry->author, handler);
+        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "author", tmp);
+        if (rc < 0) {
+             printf("Error at xmlTextWriterWriteAttribute\n");
+             return;
+        }
+        if (handler && tmp != NULL) xmlFree(tmp);
+
+        // Write param date
+        tmp2 = g_strdup_printf("%d", entry->date);
+        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "date", tmp2);
+        if (rc < 0) {
+             printf("Error at xmlTextWriterWriteAttribute\n");
+             return;
+        }
+        if (tmp2 != NULL) g_free(tmp2);
+
+        // Write text (file path)
+        tmp = ConvertInput(entry->changelog, handler);
+        xmlTextWriterWriteString(writer, BAD_CAST tmp);
+        if (handler && tmp != NULL) xmlFree(tmp);
+
+        // Close file element
+        rc = xmlTextWriterEndElement(writer);
+        if (rc < 0) {
+            printf("Error at xmlTextWriterEndElement\n");
+            return;
+        }
+    }
+}
+
+
+/**
+ * dump_base_items:
+ * @writer:
+ * @package:
+ *
+ * Converts @pkg_dict into xml string
+ *
+ * Returns the converted XML string, or NULL in case of error.
+ */
+void
+dump_other_items(xmlTextWriterPtr writer, Package *package, xmlCharEncodingHandlerPtr handler)
+{
+    int rc;
+    xmlChar *tmp  = NULL;
+    gchar   *tmp2 = NULL;
+
+#ifdef DEBUG
+    printf("CALLED dump_other_items\n");
+#endif
+
+    rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
+    if (rc < 0) {
+        printf ("Error at xmlTextWriterStartDocument\n");
+        return;
+    }
+
+
+    /***********************************
+    Element: package
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "package");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Add an attribute to package */
+    tmp = ConvertInput(package->pkgId, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    tmp = ConvertInput(package->name, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    tmp = ConvertInput(package->arch, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: version
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "version");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Write version attribute epoch */
+    tmp = ConvertInput(package->epoch, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "epoch", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write version attribute ver */
+    tmp = ConvertInput(package->version, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ver", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write version attribute rel */
+    tmp = ConvertInput(package->release, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "rel", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Close version element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /* Files dump */
+    dump_changelog(writer, package, handler);
+
+    /* Close package element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /* Close document (and every still opened tags) */
+    rc = xmlTextWriterEndDocument(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndDocument\n");
+        return;
+    }
+}
+
+
+char *
+xml_dump_other(Package *package, const char *encoding)
+{
+
+    /*
+    * Global variable initialization
+    */
+
+    // Encoging handler for selected encoding
+    xmlCharEncodingHandlerPtr handler = NULL;
+    if (encoding) {
+        handler = xmlFindCharEncodingHandler(encoding);
+        if (!handler) {
+            printf("ConvertInput: no encoding handler found for 'utf-8'\n");
+            return NULL;
+        }
+    }
+
+    /*
+     * XML Gen
+     */
+
+    xmlBufferPtr buf = xmlBufferCreate();
+    if (buf == NULL) {
+        printf("Error creating the xml buffer\n");
+        return NULL;
+    }
+
+    xmlTextWriterPtr writer = xmlNewTextWriterMemory(buf, 0);
+    if (writer == NULL) {
+        printf("Error creating the xml writer\n");
+        return NULL;
+    }
+
+#ifdef DEBUG
+    printf("Xml buffer and writer created\n");
+#endif
+
+    dump_other_items(writer, package, handler);
+
+    xmlFreeTextWriter(writer);
+
+    // Get rid off <?xml ...?> header
+    char *pkg_str = strstr((const char*) buf->content, "<package");
+    if (!pkg_str) {
+        pkg_str = (char*) buf->content;
+    }
+
+    char *result = malloc(sizeof(char) * strlen(pkg_str) + 1);
+    strcpy(result, pkg_str);
+
+    xmlBufferFree(buf);
+    return result;
+}
+
diff --git a/xml_dump_primary.c b/xml_dump_primary.c
new file mode 100644 (file)
index 0000000..655cae9
--- /dev/null
@@ -0,0 +1,660 @@
+#include <stdio.h>
+#include <string.h>
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#include "package.h"
+#include "xml_dump.h"
+
+#define MY_ENCODING "UTF-8"
+//#define DEBUG
+#undef DEBUG
+//#define DEBUG_REQUIRES
+
+#define PROVIDES    0
+#define CONFLICTS   1
+#define OBSOLETES   2
+#define REQUIRES    3
+
+void
+dump_pco(xmlTextWriterPtr writer, Package *package, int pcotype, 
+         xmlCharEncodingHandlerPtr handler)
+{
+#ifdef DEBUG
+    printf("CALLED dump_pco\n");
+#endif
+
+    xmlChar *tmp = NULL;
+    char provides[]  = "rpm:provides";
+    char conflicts[] = "rpm:conflicts";
+    char obsoletes[] = "rpm:obsoletes";
+    char requires[]  = "rpm:requires";
+
+    char *elem_name = NULL;
+    GSList *files = NULL;
+
+    if (pcotype == PROVIDES) {
+        elem_name = provides;
+        files = package->provides;
+    } else if (pcotype == CONFLICTS) {
+        elem_name = conflicts;
+        files = package->conflicts;
+    } else if (pcotype == OBSOLETES) {
+        elem_name = obsoletes;
+        files = package->obsoletes;
+    } else if (pcotype == REQUIRES) {
+        elem_name = requires;
+        files = package->requires;
+    } else {
+        return;
+    }
+
+    if (!files) {
+        return;
+    }
+
+    /***********************************
+    PCP Element: provides, oboletes, conflicts, requires
+    ************************************/
+    int rc;
+    tmp = ConvertInput(elem_name, handler);
+    rc = xmlTextWriterStartElement(writer, BAD_CAST elem_name);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    GSList *element = NULL;
+    for(element = files; element; element=element->next) {
+
+        Dependency *entry = (Dependency*) element->data;
+
+        /***********************************
+        Element: entry
+        ************************************/
+        int rc;
+        rc = xmlTextWriterStartElement(writer, BAD_CAST "rpm:entry");
+        if (rc < 0) {
+            printf("Error at xmlTextWriterWriteElement\n");
+            return;
+        }
+
+        tmp = ConvertInput(entry->name, handler);
+        if (!tmp || ! strlen(tmp)) {
+            if (handler && tmp != NULL) xmlFree(tmp);
+            goto close;
+        }
+        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "name", tmp);
+        if (rc < 0) {
+             printf("Error at xmlTextWriterWriteAttribute\n");
+             return;
+        }
+        if (handler && tmp != NULL) xmlFree(tmp);
+
+        tmp = ConvertInput(entry->flags, handler);
+        if (!tmp || ! strlen(tmp)) {
+            if (handler && tmp != NULL) xmlFree(tmp);
+            goto close;
+        }
+        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "flags", tmp);
+        if (rc < 0) {
+             printf("Error at xmlTextWriterWriteAttribute\n");
+             return;
+        }
+        if (handler && tmp != NULL) xmlFree(tmp);
+
+        tmp = ConvertInput(entry->epoch, handler);
+        if (tmp && strlen(tmp)) {
+            rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "epoch", tmp);
+            if (rc < 0) {
+                 printf("Error at xmlTextWriterWriteAttribute\n");
+                 return;
+            }
+        }
+        if (handler && tmp != NULL) xmlFree(tmp);
+
+        tmp = ConvertInput(entry->version, handler);
+        if (tmp && strlen(tmp)) {
+            rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ver", tmp);
+            if (rc < 0) {
+                 printf("Error at xmlTextWriterWriteAttribute\n");
+                 return;
+            }
+        }
+        if (handler && tmp != NULL) xmlFree(tmp);
+
+        tmp = ConvertInput(entry->release, handler);
+        if (tmp && strlen(tmp)) {
+            rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "rel", tmp);
+            if (rc < 0) {
+                 printf("Error at xmlTextWriterWriteAttribute\n");
+                 return;
+            }
+        }
+        if (handler && tmp != NULL) xmlFree(tmp);
+
+    close:
+
+        if (pcotype == REQUIRES) {
+            /* Add pre attribute */
+            if (entry->pre) {
+                rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pre", "1");
+            } else {
+                rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pre", "0");
+            }
+            if (rc < 0) {
+                 printf("Error at xmlTextWriterWriteAttribute\n");
+                 return;
+            }
+        }
+
+        /* Close entry element */
+        rc = xmlTextWriterEndElement(writer);
+        if (rc < 0) {
+            printf("Error at xmlTextWriterEndElement\n");
+            return;
+        }
+    }
+
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+}
+
+
+
+/**
+ * dump_base_items:
+ * @writer:
+ * @package:
+ *
+ * Converts @pkg_dict into xml string
+ *
+ * Returns the converted XML string, or NULL in case of error.
+ */
+void
+dump_base_items(xmlTextWriterPtr writer, Package *package, xmlCharEncodingHandlerPtr handler)
+{
+    int rc;
+    xmlChar *tmp  = NULL;
+    gchar   *tmp2 = NULL;
+
+#ifdef DEBUG
+    printf("CALLED dump_base_items\n");
+#endif
+
+    rc = xmlTextWriterStartDocument(writer, NULL, MY_ENCODING, NULL);
+    if (rc < 0) {
+        printf ("Error at xmlTextWriterStartDocument\n");
+        return;
+    }
+
+
+    /***********************************
+    Element: package
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "package");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Add an attribute with name type to package */
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", BAD_CAST "rpm");
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+
+    /***********************************
+    Element: name
+    ************************************/
+    tmp = ConvertInput(package->name, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "name", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: arch
+    ************************************/
+    tmp = ConvertInput(package->arch, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "arch", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: version
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "version");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Write version attribute epoch */
+    tmp = ConvertInput(package->epoch, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "epoch", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write version attribute ver */
+    tmp = ConvertInput(package->version, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "ver", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write version attribute rel */
+    tmp = ConvertInput(package->release, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "rel", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Close version element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /***********************************
+    Element: checksum
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "checksum");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Write checksum attribute pkgid */
+    tmp = ConvertInput("YES", handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "pkgid", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write checksum attribute checksum_type */
+    tmp = ConvertInput(package->checksum_type, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "type", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write element string */
+    tmp = ConvertInput(package->pkgId, handler);
+    rc = xmlTextWriterWriteString(writer, BAD_CAST tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteString\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Close checksum element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /***********************************
+    Element: summary
+    ************************************/
+    tmp = ConvertInput(package->summary, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "summary", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: description
+    ************************************/
+    tmp = ConvertInput(package->description, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "description", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: packager
+    ************************************/
+    tmp = ConvertInput(package->rpm_packager, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "packager", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: url
+    ************************************/
+    tmp = ConvertInput(package->url, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "url", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: time
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "time");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Write time attribute file */
+    tmp2 = g_strdup_printf("%d", package->time_file);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "file", tmp2);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (tmp2 != NULL) g_free(tmp2);
+
+    /* Write time attribute build */
+    tmp2 = g_strdup_printf("%d", package->time_build);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "build", tmp2);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (tmp2 != NULL) g_free(tmp2);
+
+    /* Close time element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /***********************************
+    Element: size
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "size");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Write size attribute package */
+    tmp2 = g_strdup_printf("%d", package->size_package);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "package", tmp2);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (tmp2 != NULL) g_free(tmp2);
+
+    /* Write size attribute installed */
+    tmp2 = g_strdup_printf("%d", package->size_installed);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "installed", tmp2);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (tmp2 != NULL) g_free(tmp2);
+
+    /* Write size attribute archive */
+    tmp2 = g_strdup_printf("%d", package->size_archive);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "archive", tmp2);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (tmp2 != NULL) g_free(tmp2);
+
+    /* Close size element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /***********************************
+    Element: location
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "location");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /* Write location attribute href */
+    tmp = ConvertInput(package->location_href, handler);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "href", tmp);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Write location attribute base */
+    tmp = ConvertInput(package->location_base, handler);
+    if (strlen(package->location_base)) {
+        rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "base", tmp);
+        if (rc < 0) {
+             printf("Error at xmlTextWriterWriteAttribute\n");
+             return;
+        }
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /* Close location element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /***********************************
+    Element: format
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "format");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterStartElement\n");
+        return;
+    }
+
+    /***********************************
+    Element: license
+    ************************************/
+    tmp = ConvertInput(package->rpm_license, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:license", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: vendor
+    ************************************/
+    tmp = ConvertInput(package->rpm_vendor, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:vendor", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: group
+    ************************************/
+    tmp = ConvertInput(package->rpm_group, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:group", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: buildhost
+    ************************************/
+    tmp = ConvertInput(package->rpm_buildhost, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:buildhost", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: sourcerpm
+    ************************************/
+    tmp = ConvertInput(package->rpm_sourcerpm, handler);
+    rc = xmlTextWriterWriteElement(writer, BAD_CAST "rpm:sourcerpm", tmp);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+    if (handler && tmp != NULL) xmlFree(tmp);
+
+    /***********************************
+    Element: header-range
+    ************************************/
+    rc = xmlTextWriterStartElement(writer, BAD_CAST "rpm:header-range");
+    if (rc < 0) {
+        printf("Error at xmlTextWriterWriteElement\n");
+        return;
+    }
+
+    /* Write header-range attribute hdrstart */
+    tmp2 = g_strdup_printf("%d", package->rpm_header_start);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "start", tmp2);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (tmp2 != NULL) g_free(tmp2);
+
+    /* Write header-range attribute hdrend */
+    tmp2 = g_strdup_printf("%d", package->rpm_header_end);
+    rc = xmlTextWriterWriteAttribute(writer, BAD_CAST "end", tmp2);
+    if (rc < 0) {
+         printf("Error at xmlTextWriterWriteAttribute\n");
+         return;
+    }
+    if (tmp2 != NULL) g_free(tmp2);
+
+    /* Close header-range element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+
+    /* Files dump */
+    dump_pco(writer,   package, PROVIDES, handler);
+    dump_pco(writer,   package, REQUIRES, handler);
+    dump_pco(writer,   package, CONFLICTS, handler);
+    dump_pco(writer,   package, OBSOLETES, handler);
+    dump_files(writer, package, 1, handler);
+
+
+    /* Close format element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /* Close package element */
+    rc = xmlTextWriterEndElement(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndElement\n");
+        return;
+    }
+
+    /* Close document (and every still opened tags) */
+    rc = xmlTextWriterEndDocument(writer);
+    if (rc < 0) {
+        printf("Error at xmlTextWriterEndDocument\n");
+        return;
+    }
+}
+
+
+char *
+xml_dump_primary(Package *package, const char *encoding)
+{
+
+    /*
+    * Global variable initialization
+    */
+
+    // Encoging handler for selected encoding
+    xmlCharEncodingHandlerPtr handler = NULL;
+    if (encoding) {
+        handler = xmlFindCharEncodingHandler(encoding);
+        if (!handler) {
+            printf("ConvertInput: no encoding handler found for 'utf-8'\n");
+            return NULL;
+        }
+    }
+
+    /*
+     * XML Gen
+     */
+
+    xmlBufferPtr buf = xmlBufferCreate();
+    if (buf == NULL) {
+        printf("Error creating the xml buffer\n");
+        return NULL;
+    }
+
+    xmlTextWriterPtr writer = xmlNewTextWriterMemory(buf, 0);
+    if (writer == NULL) {
+        printf("Error creating the xml writer\n");
+        return NULL;
+    }
+
+#ifdef DEBUG
+    printf("Xml buffer and writer created\n");
+#endif
+
+    dump_base_items(writer, package, handler);
+
+    xmlFreeTextWriter(writer);
+
+    // Get rid off <?xml ...?> header
+    char *pkg_str = strstr((const char*) buf->content, "<package");
+    if (!pkg_str) {
+        pkg_str = (char*) buf->content;
+    }
+
+    char *result = malloc(sizeof(char) * strlen(pkg_str) + 1);
+    strcpy(result, pkg_str);
+
+    xmlBufferFree(buf);
+    return result;
+}
+