First steps towards a real SourceImpl for the 'helix' based testcases
authorKlaus Kaempf <kkaempf@suse.de>
Sun, 22 Jan 2006 18:56:25 +0000 (18:56 +0000)
committerKlaus Kaempf <kkaempf@suse.de>
Sun, 22 Jan 2006 18:56:25 +0000 (18:56 +0000)
14 files changed:
configure.ac
devel/devel.kkaempf/Buffer.cc [new file with mode: 0644]
devel/devel.kkaempf/Buffer.h [new file with mode: 0644]
devel/devel.kkaempf/HelixExtract.cc [new file with mode: 0644]
devel/devel.kkaempf/HelixExtract.h [new file with mode: 0644]
devel/devel.kkaempf/HelixPackageImpl.cc [new file with mode: 0644]
devel/devel.kkaempf/HelixPackageImpl.h [new file with mode: 0644]
devel/devel.kkaempf/HelixParser.cc [new file with mode: 0644]
devel/devel.kkaempf/HelixParser.h [new file with mode: 0644]
devel/devel.kkaempf/HelixSourceImpl.cc [new file with mode: 0644]
devel/devel.kkaempf/HelixSourceImpl.h [new file with mode: 0644]
devel/devel.kkaempf/Makefile.am [new file with mode: 0644]
devel/devel.kkaempf/dummy-packages.xml [new file with mode: 0644]
devel/devel.kkaempf/rcparse.cc [new file with mode: 0644]

index 269b347..23a466d 100644 (file)
@@ -195,6 +195,7 @@ AC_OUTPUT(  \
        devel/devel.jsrain/Makefile     \
        devel/devel.jsrain/yum/Makefile \
        devel/devel.ma/Makefile         \
+       devel/devel.kkaempf/Makefile    \
        doc/Makefile                    \
        doc/autodoc/Makefile            \
        doc/autodoc/Doxyfile            \
diff --git a/devel/devel.kkaempf/Buffer.cc b/devel/devel.kkaempf/Buffer.cc
new file mode 100644 (file)
index 0000000..35095c0
--- /dev/null
@@ -0,0 +1,586 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* Buffer.cc 
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * 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 <sys/mman.h>
+
+#include <cstdio>
+#include <fcntl.h>
+#include <cstdlib>
+#include <unistd.h>
+#include <iostream>
+#include <ctype.h>
+#include <string>
+
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+
+#include "Buffer.h"
+
+#include "zlib.h"
+#ifdef HAVE_BZ2
+/* Older bzlib didn't icnlude stdio.h */
+#  include <bzlib.h>
+#endif
+
+#include "zypp/base/Logger.h"
+
+
+using namespace std;
+
+
+//---------------------------------------------------------------------------
+// compress/uncompress stuff
+
+/*
+ * Magic gunzipping goodness
+ */
+
+/*
+ * Count number of bytes to skip at start of buf
+ */
+static int gz_magic[2] = {0x1f, 0x8b};
+/* gzip flag byte */
+#define GZ_ASCII_FLAG   0x01 /* bit 0 set: file probably ascii text */
+#define GZ_HEAD_CRC     0x02 /* bit 1 set: header CRC present */
+#define GZ_EXTRA_FIELD  0x04 /* bit 2 set: extra field present */
+#define GZ_ORIG_NAME    0x08 /* bit 3 set: original file name present */
+#define GZ_COMMENT      0x10 /* bit 4 set: file comment present */
+#define GZ_RESERVED     0xE0 /* bits 5..7: reserved */
+
+static int
+count_gzip_header (const unsigned char *buf, unsigned int input_length)
+{
+    int method, flags;
+    const unsigned char *s = buf;
+    unsigned int left_len = input_length;
+
+    if (left_len < 4) return -1;
+    if (*s++ != gz_magic[0] || *s++ != gz_magic[1]) {
+       return -2;
+    }
+
+    method = *s++;
+    flags = *s++;
+    left_len -= 4;
+
+    if (method != Z_DEFLATED || (flags & GZ_RESERVED) != 0) {
+       /* If it's not deflated, or the reserved isn't 0 */
+       return -3;
+    }
+
+    /* Skip time, xflags, OS code */
+    if (left_len < 6) return -4;
+    s += 6;
+    left_len -= 6;
+
+    if (flags & GZ_EXTRA_FIELD) {
+       unsigned int len;
+       if (left_len < 2) return -5;
+       len = (unsigned int)(*s++);
+       len += ((unsigned int)(*s++)) << 8;
+       if (left_len < len) return -6;
+       s += len;
+       left_len -= len;
+    }
+
+    /* Skip filename */
+    if (flags & GZ_ORIG_NAME) {
+       while (--left_len != 0 && *s++ != '\0') ;
+       if (left_len == 0) return -7;
+    }
+    /* Skip comment */
+    if (flags & GZ_COMMENT) {
+       while (--left_len != 0 && *s++ != '\0') ;
+       if (left_len == 0) return -7;
+    }
+    /* Skip CRC */
+    if (flags & GZ_HEAD_CRC) {
+       if (left_len < 2) return -7;
+       s += 2;
+       left_len -= 2;
+    }
+
+    return input_length - left_len;
+}
+
+
+int
+gunzip_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+{
+    z_stream zs;
+    char *outbuf = NULL;
+    ByteArray *ba = NULL;
+    int zret;
+
+    int gzip_hdr;
+
+    if (input_buffer == NULL) return -1;
+    if (input_length == 0) return -2;
+    if (out_ba == NULL) return -3;
+
+    ba = (ByteArray *)malloc (sizeof (ByteArray));
+    ba->data = NULL;
+    ba->len = 0;
+
+    gzip_hdr = count_gzip_header (input_buffer, input_length);
+    if (gzip_hdr < 0)
+       return -1;
+
+    zs.next_in = (unsigned char *) input_buffer + gzip_hdr;
+    zs.avail_in = input_length - gzip_hdr;
+    zs.zalloc = NULL;
+    zs.zfree = NULL;
+    zs.opaque = NULL;
+
+#define OUTBUFSIZE 10000
+    outbuf = (char *)malloc (OUTBUFSIZE);
+    zs.next_out = (Bytef *)outbuf;
+    zs.avail_out = OUTBUFSIZE;
+
+    /* Negative inflateinit is magic to tell zlib that there is no
+     * zlib header */
+    inflateInit2 (&zs, -MAX_WBITS);
+
+    while (1) {
+       zret = inflate (&zs, Z_SYNC_FLUSH);
+       if (zret != Z_OK && zret != Z_STREAM_END)
+           break;
+
+       ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
+       memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
+       ba->len += (OUTBUFSIZE - zs.avail_out);
+
+       zs.next_out = (Bytef *)outbuf;
+       zs.avail_out = OUTBUFSIZE;
+
+       if (zret == Z_STREAM_END)
+           break;
+    }
+
+    inflateEnd (&zs);
+    free ((void *)outbuf);
+
+    if (zret != Z_STREAM_END) {
+       ERR << "libz inflate failed! (" << zret << ")" << endl;
+       free (ba->data);
+       free (ba);
+       ba = NULL;
+    } else {
+       zret = 0;
+    }
+
+    *out_ba = ba;
+    return zret;
+}
+
+
+int
+gzip_memory (const char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+{
+    z_stream zs;
+    char *outbuf = NULL;
+    ByteArray *ba = NULL;
+    int zret;
+
+    if (input_buffer == NULL) return -1;
+    if (input_length == 0) return -2;
+    if (out_ba == NULL) return -3;
+
+    ba = (ByteArray *)malloc (sizeof (ByteArray));
+    ba->data = NULL;
+    ba->len = 0;
+
+    zs.next_in = (unsigned char *) input_buffer;
+    zs.avail_in = input_length;
+    zs.zalloc = NULL;
+    zs.zfree = NULL;
+    zs.opaque = NULL;
+
+    outbuf = (char *)malloc (OUTBUFSIZE);
+    zs.next_out = (Bytef *)outbuf;
+    zs.avail_out = OUTBUFSIZE;
+
+    deflateInit (&zs, Z_DEFAULT_COMPRESSION);
+
+    while (1) {
+       if (zs.avail_in)
+           zret = deflate (&zs, Z_SYNC_FLUSH);
+       else
+           zret = deflate (&zs, Z_FINISH);
+           
+       if (zret != Z_OK && zret != Z_STREAM_END)
+           break;
+
+       ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
+       memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
+       ba->len += (OUTBUFSIZE - zs.avail_out);
+
+       zs.next_out = (Bytef *)outbuf;
+       zs.avail_out = OUTBUFSIZE;
+
+       if (zret == Z_STREAM_END)
+           break;
+    }
+
+    deflateEnd (&zs);
+    free ((void *)outbuf);
+
+    if (zret != Z_STREAM_END) {
+       ERR << "libz deflate failed! (" << zret << ")" << endl;
+       free (ba->data);
+       free (ba);
+       ba = NULL;
+    } else {
+       zret = 0;
+    }
+
+    *out_ba = ba;
+    return zret;
+} /* gzip_memory */
+
+
+bool
+memory_looks_gzipped (const unsigned char *buffer)
+{
+    if (buffer == NULL)
+       return false;
+
+    /* This is from RFC 1952 */
+
+    return buffer[0] == gz_magic[0]  /* ID1 */
+       && buffer[1] == gz_magic[1]; /* ID2 */
+}
+
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+static char bz2_magic[3] = { 'B', 'Z', 'h' };
+
+int
+bunzip2_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+{
+#ifndef HAVE_BZ2
+
+    ERR << "bz2 support not compiled in" << endl;
+    *out_ba = NULL;
+
+    return -1;
+
+#else
+
+    bz_stream bzs;
+    ByteArray *ba;
+    char *outbuf;
+    int bzret;
+
+    if (input_buffer == NULL) return -1;
+    if (input_length == 0) return -2;
+    if (out_ba == NULL) return -3;
+
+    ba = (ByteArray *)malloc (sizeof (ByteArray));
+    ba->data = NULL;
+    ba->len = 0;
+
+    bzs.next_in = (unsigned char *) input_buffer;
+    bzs.avail_in = input_length;
+    bzs.bzalloc = NULL;
+    bzs.bzfree = NULL;
+    bzs.opaque = NULL;
+
+    outbuf = (char *)malloc (OUTBUFSIZE);
+    bzs.next_out = (Bytef *)outbuf;
+    bzs.avail_out = OUTBUFSIZE;
+
+    BZ2_bzDecompressInit (&bzs, 1, 0);
+
+    while (1) {
+       bzret = BZ2_bzDecompress (&bzs);
+       if (bzret != BZ_OK && bzret != BZ_STREAM_END)
+           break;
+
+       ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
+       memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
+       ba->len += (OUTBUFSIZE - zs.avail_out);
+
+       bzs.next_out = (Bytef *)outbuf;
+       bzs.avail_out = OUTBUFSIZE;
+
+       if (bzret == BZ_STREAM_END)
+           break;
+
+       if (bzs.avail_in == 0) {
+           /* The data is incomplete */
+           bzret = -1;
+           break;
+       }
+    }
+
+    BZ2_bzDecompressEnd (&bzs);
+    free ((void *)outbuf);
+
+    if (bzret != BZ_STREAM_END) {
+       ERR << "libbzip2 decompress failed (" <<  bzret << ")" << endl;
+       free (ba->data);
+       free (ba);
+       ba = NULL;
+    } else {
+       bzret = 0;
+    }
+
+    *out_ba = ba;
+    return bzret;
+#endif
+}
+
+
+int
+bzip2_memory (const char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+{
+#ifndef HAVE_BZ2
+
+    ERR << "bz2 support not compiled in" << endl;
+    *out_ba = NULL;
+
+    return -1;
+
+#else
+
+    bz_stream bzs;
+    ByteArray *ba;
+    char *outbuf;
+    int bzret;
+
+    if (input_buffer == NULL) return -1;
+    if (input_length == 0) return -2;
+    if (out_ba == NULL) return -3;
+
+    ba = (ByteArray *)malloc (sizeof (ByteArray));
+    ba->data = NULL;
+    ba->len = 0;
+
+    bzs.next_in = (unsigned char *) input_buffer;
+    bzs.avail_in = input_length;
+    bzs.bzalloc = NULL;
+    bzs.bzfree = NULL;
+    bzs.opaque = NULL;
+
+    outbuf = (char *)malloc (OUTBUFSIZE);
+    bzs.next_out = (Bytef *)outbuf;
+    bzs.avail_out = OUTBUFSIZE;
+
+    BZ2_bzCompressInit (&bzs, 5, 1, 0);
+
+    while (1) {
+       if (bzs.avail_in)
+           bzret = BZ2_bzCompress (&bzs, BZ_RUN);
+       else
+           bzret = BZ2_bzCompress (&bzs, BZ_FINISH);
+           
+       if (bzret != BZ_OK && bzret != BZ_STREAM_END)
+           break;
+
+       ba->data = (byte *)realloc (ba->data, ba->len + (OUTBUFSIZE - zs.avail_out));
+       memcpy (ba->data + ba->len, outbuf, OUTBUFSIZE - zs.avail_out);
+       ba->len += (OUTBUFSIZE - zs.avail_out);
+
+       bzs.next_out = (Bytef *)outbuf;
+       bzs.avail_out = OUTBUFSIZE;
+
+       if (bzret == BZ_STREAM_END)
+           break;
+    }
+
+    BZ2_bzCompressEnd (&bzs);
+    free ((void *)outbuf);
+
+    if (bzret != BZ_STREAM_END) {
+       ERR << "bz2 compress failed! (" << bzret << ")" << endl;
+       free (ba->data);
+       free (ba);
+       ba = NULL;
+    } else {
+       bzret = 0;
+    }
+
+    *out_ba = ba;
+    return bzret;
+#endif
+}
+
+
+bool
+memory_looks_bzip2ed (const unsigned char *buffer)
+{
+    if (buffer == NULL)
+       return false;
+
+    return buffer[0] == bz2_magic[0]
+       && buffer[1] == bz2_magic[1]
+       && buffer[2] == bz2_magic[2];
+}
+
+/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
+
+int
+uncompress_memory (const unsigned char *input_buffer, unsigned int input_length, ByteArray **out_ba)
+{
+    if (input_length > 2 && memory_looks_bzip2ed (input_buffer))
+       return bunzip2_memory (input_buffer, input_length, out_ba);
+    else if (input_length > 3 && memory_looks_gzipped (input_buffer))
+       return gunzip_memory (input_buffer, input_length, out_ba);
+    else
+       return -1;
+}
+
+bool
+memory_looks_compressed (const unsigned char *buffer, size_t size)
+{
+#ifdef HAVE_BZ2
+    if (size > 2 && memory_looks_bzip2ed (buffer))
+       return true;
+#endif
+
+    if (size > 4 && memory_looks_gzipped (buffer))
+       return true;
+
+    return false;
+}
+
+//---------------------------------------------------------------------------
+// I/O stuff
+
+/* 
+ * This just allows reading from the buffer for now.  It could be extended to
+ * do writing if necessary.
+ */
+
+Buffer *
+bufferMapFile (const string & filename)
+{
+    struct stat s;
+    int fd;
+    unsigned char *data;
+    Buffer *buf = NULL;
+
+    if (filename.empty())
+       return NULL;
+
+    if (stat(filename.c_str(), &s) < 0)
+       return NULL;
+
+    fd = open(filename.c_str(), O_RDONLY);
+
+    if (fd < 0)
+       return NULL;
+
+    data = (unsigned char *)mmap(NULL, s.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
+
+    close (fd);
+
+    if (data == MAP_FAILED)
+       return NULL;
+
+    /* Transparently uncompress */
+    if (memory_looks_compressed (data, s.st_size)) {
+       ByteArray *byte_array = NULL;
+
+       if (uncompress_memory (data, s.st_size, &byte_array)) {
+           WAR << "Uncompression of '" << filename
+               << "' failed" << endl;
+       } else {
+           buf = (Buffer *)malloc(sizeof (Buffer));
+           buf->data       = byte_array->data;
+           buf->size       = byte_array->len;
+           buf->is_mmapped = false;
+       }
+
+       munmap (data, s.st_size);
+
+       if (byte_array) {
+           free (byte_array);
+       }
+
+    } else {
+       buf = (Buffer *)malloc(sizeof (Buffer));
+       buf->data       = (byte *)data;
+       buf->size       = s.st_size;
+       buf->is_mmapped = true;
+    }
+
+    return buf;
+} /* bufferMapFile */
+
+
+void
+bufferUnmapFile (Buffer *buf)
+{
+    if (buf == NULL) return;
+
+    if (buf->is_mmapped)
+       munmap (buf->data, buf->size);
+    else
+       free (buf->data);
+
+    free (buf);
+}
+
+//---------------------------------------------------------------------------
+// XML stuff
+
+xmlDoc *
+parseXmlFromBuffer (const char *input_buffer, size_t input_length)
+{
+    xmlDoc *doc = NULL;
+
+    if (input_buffer == NULL) return NULL;
+
+    if (input_length > 3 && memory_looks_gzipped ((const unsigned char *)input_buffer)) { 
+        ByteArray *buf;
+
+        if (uncompress_memory ((const unsigned char *)input_buffer, input_length, &buf)) {
+            return NULL;
+        }
+        doc = xmlParseMemory ((const char *)(buf->data), buf->len);
+       free (buf->data);
+        free (buf);
+    } else {
+        doc = xmlParseMemory (input_buffer, input_length);
+    }
+
+    return doc;
+}
+
+
+xmlDoc *
+parseXmlFromFile (const string & filename)
+{
+    Buffer *buf;
+    xmlDoc *doc = NULL;
+
+    if (filename.empty()) return NULL;
+
+    buf = bufferMapFile (filename);
+    if (buf) {
+        doc = xmlParseMemory ((const char *)(buf->data), buf->size);
+        bufferUnmapFile (buf);
+    }
+
+    return doc;
+}
diff --git a/devel/devel.kkaempf/Buffer.h b/devel/devel.kkaempf/Buffer.h
new file mode 100644 (file)
index 0000000..73abcb1
--- /dev/null
@@ -0,0 +1,58 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
+/*
+ * Buffer.h
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ * Copyright (c) 2005 SUSE Linux Products GmbH
+ *
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef BUFFER_H
+#define BUFFER_H
+
+#include <sys/types.h>
+#include <string>
+
+typedef unsigned char byte;
+
+typedef struct {
+    byte *data;
+    size_t len;
+} ByteArray;
+
+// An easy way to map files.  If we map a compressed file,
+//   it will be magically uncompressed for us.
+
+typedef struct {
+    byte *data;
+    size_t size;
+    bool is_mmapped;
+} Buffer;
+
+Buffer *bufferMapFile (const std::string & filename);
+void bufferUnmapFile (Buffer *buffer);
+
+
+xmlDoc *parseXmlFromBuffer (const char *input_buffer, size_t input_length);
+xmlDoc *parseXmlFromFile (const std::string & filename);
+
+
+#endif // BUFFER_H
+
diff --git a/devel/devel.kkaempf/HelixExtract.cc b/devel/devel.kkaempf/HelixExtract.cc
new file mode 100644 (file)
index 0000000..917b935
--- /dev/null
@@ -0,0 +1,72 @@
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * extract.cc
+ *
+ * Copyright (C) 2000-2003 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ */
+
+/*
+ * 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 "HelixExtract.h"
+#include "HelixParser.h"
+#include "Buffer.h"
+
+#include "zypp/base/Logger.h"
+#include "zypp/solver/temporary/Channel.h"
+#include "zypp/solver/temporary/XmlNode.h"
+
+using namespace std;
+using namespace zypp;
+using namespace zypp::solver::detail;
+
+int 
+extractHelixBuffer (const char buf[], size_t len, Channel_Ptr channel, ResolvableStoreCallback callback, ResStore *store)
+{
+//    _DBG("HelixExtract") << "extract_packages_from_helix_buffer(" << buf << "...," << (long)len << ",...)" << endl;
+
+    if (buf == NULL || len == 0)
+       return 1;
+
+    HelixParser parser (channel);
+    parser.parseChunk (buf, len, callback, store);
+    parser.done ();
+
+    return 0;
+}
+
+
+int
+extractHelixFile (const std::string & filename, Channel_Ptr channel, ResolvableStoreCallback callback, ResStore *store)
+{
+    Buffer *buf;
+
+    if (filename.empty())
+       return -1;
+
+    buf = bufferMapFile (filename);
+    if (buf == NULL)
+       return -1;
+
+    extractHelixBuffer ((const char *)(buf->data), buf->size, channel, callback, store);
+
+    bufferUnmapFile (buf);
+
+    return 0;
+}
+
diff --git a/devel/devel.kkaempf/HelixExtract.h b/devel/devel.kkaempf/HelixExtract.h
new file mode 100644 (file)
index 0000000..b5a6406
--- /dev/null
@@ -0,0 +1,41 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
+/*
+ * HelixExtract.h
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ * Copyright (c) 2005 SUSE Linux Products GmbH
+ *
+ */
+
+/*
+ * 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.
+ */
+
+#ifndef HELIXEXTRACT_H
+#define HELIXEXTRACT_H
+
+#include "zypp/Resolvable.h"
+#include "zypp/ResStore.h"
+#include "zypp/solver/temporary/XmlNodePtr.h"
+#include "zypp/solver/temporary/ChannelPtr.h"
+
+typedef bool (*ResolvableStoreCallback) (zypp::Resolvable::Ptr res, zypp::ResStore *store);
+
+int extractHelixBuffer (const char data[], size_t len, zypp::solver::detail::Channel_Ptr channel, ResolvableStoreCallback callback, zypp::ResStore *store);
+int extractHelixFile (const std::string & filename, zypp::solver::detail::Channel_Ptr channel, ResolvableStoreCallback callback, zypp::ResStore *store);
+
+#endif /* HELIXEXTRACT_H */
+
diff --git a/devel/devel.kkaempf/HelixPackageImpl.cc b/devel/devel.kkaempf/HelixPackageImpl.cc
new file mode 100644 (file)
index 0000000..8d9e2fc
--- /dev/null
@@ -0,0 +1,335 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/solver/temporary/HelixPackageImpl.cc
+ *
+*/
+
+#include "HelixPackageImpl.h"
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+using namespace std;
+using namespace zypp::detail;
+using namespace zypp::solver::detail;
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace solver
+  { /////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+      ///////////////////////////////////////////////////////////////////
+      //
+      //        CLASS NAME : HelixPackageImpl
+      //
+      ///////////////////////////////////////////////////////////////////
+
+      /** Default ctor
+      */
+      HelixPackageImpl::HelixPackageImpl(
+       const HelixParser & parsed
+      )
+      : _summary(parsed.summary),
+       _description(parsed.description),
+       _group(parsed.group),
+       _install_only(parsed.installOnly),
+        _size_package(parsed.fileSize),
+       _size_installed(parsed.installedSize)
+      {
+      }
+
+      /** Package summary */
+      Label HelixPackageImpl::summary() const
+      { return _summary; }
+
+      /** Package description */
+      Text HelixPackageImpl::description() const
+      { return _description; }
+
+      Text HelixPackageImpl::insnotify() const
+      // metadata doesn't priovide this attribute
+      { return ResObjectImplIf::insnotify(); }
+
+      Text HelixPackageImpl::delnotify() const
+      // metadata doesn't priovide this attribute
+      { return ResObjectImplIf::delnotify(); }
+
+      ByteCount HelixPackageImpl::size() const
+#warning fixme
+      { return 0; }
+
+      bool HelixPackageImpl::providesSources() const
+      { return ResObjectImplIf::providesSources(); }
+
+      Label HelixPackageImpl::instSrcLabel() const
+      { return ResObjectImplIf::instSrcLabel(); }
+      
+      Vendor HelixPackageImpl::instSrcVendor() const
+      { return ResObjectImplIf::instSrcVendor(); }
+      
+      /** */
+      Date HelixPackageImpl::buildtime() const
+      { return _buildtime; }
+
+      /** */
+      std::string HelixPackageImpl::buildhost() const
+      { return _buildhost; }
+
+      /** */
+      Date HelixPackageImpl::installtime() const
+      { return PackageImplIf::installtime(); }
+
+      /** */
+      std::string HelixPackageImpl::distribution() const
+#warning fixme
+      { return string(); }
+
+      /** */
+      Vendor HelixPackageImpl::vendor() const
+      { return _vendor; }
+
+      /** */
+      Label HelixPackageImpl::license() const
+      { return _license; }
+
+      /** */
+      std::string HelixPackageImpl::packager() const
+      { return _packager; }
+
+      /** */
+      PackageGroup HelixPackageImpl::group() const
+      { return _group; }
+
+      /** */
+      Changelog HelixPackageImpl::changelog() const
+      { return _changelog; }
+
+      /** Don't ship it as class Url, because it might be
+       * in fact anything but a legal Url. */
+      std::string HelixPackageImpl::url() const
+      { return _url; }
+
+      /** */
+      std::string HelixPackageImpl::os() const
+      // metadata doesn't priovide this attribute
+      { return PackageImplIf::os(); }
+
+      /** */
+      Text HelixPackageImpl::prein() const
+      // metadata doesn't priovide this attribute
+      { return PackageImplIf::prein(); }
+
+      /** */
+      Text HelixPackageImpl::postin() const
+      // metadata doesn't priovide this attribute
+      { return PackageImplIf::postin(); }
+
+      /** */
+      Text HelixPackageImpl::preun() const
+      // metadata doesn't priovide this attribute
+      { return PackageImplIf::preun(); }
+
+      /** */
+      Text HelixPackageImpl::postun() const
+      // metadata doesn't priovide this attribute
+      { return PackageImplIf::postun(); }
+
+      /** */
+      ByteCount HelixPackageImpl::sourcesize() const
+#warning fixme
+      { return 0; }
+
+      /** */
+      ByteCount HelixPackageImpl::archivesize() const
+#warning fixme
+      { return 0; }
+
+      /** */
+      Text HelixPackageImpl::authors() const
+      { return _authors; }
+
+      /** */
+      Text HelixPackageImpl::filenames() const
+      { return _filenames; }
+
+      License HelixPackageImpl::licenseToConfirm() const
+      { return _license_to_confirm; }
+
+      /** */
+      std::string HelixPackageImpl::type() const
+      { return _type; }
+
+      /** */
+      std::list<std::string> HelixPackageImpl::keywords() const
+      { return _keywords; }
+
+      bool HelixPackageImpl::installOnly() const
+      { return _install_only; }
+
+      unsigned HelixPackageImpl::mediaId() const
+      { return _mediaid; }
+
+      CheckSum HelixPackageImpl::checksum() const
+      { return _checksum; }
+
+      std::list<DeltaRpm> HelixPackageImpl::deltaRpms() const
+      { return _delta_rpms; }
+
+      std::list<PatchRpm> HelixPackageImpl::patchRpms() const
+      { return _patch_rpms; }
+
+#if 0
+      /** */
+      std::list<std::string> HelixPackageImpl::insnotify() const
+      { return std::list<std::string>(); }
+      /** */
+      std::list<std::string> HelixPackageImpl::delnotify() const
+      { return std::list<std::string>(); }
+      /** */
+      unsigned HelixPackageImpl::packageSize() const
+      { return _size_package; }
+      /** */
+      unsigned HelixPackageImpl::archiveSize() const
+      { return _size_archive; }
+      /** */
+      unsigned HelixPackageImpl::installedSize() const
+      { return _size_installed; }
+// FIXME do not understand items below
+      /** */
+      bool HelixPackageImpl::providesSources() const
+      {
+       return false;
+      }
+      /** */
+      std::string HelixPackageImpl::instSrcLabel() const
+      {
+       return "";
+      }
+      /** */
+      std::string HelixPackageImpl::instSrcVendor() const
+      {
+       return "";
+      }
+      /** */
+      unsigned HelixPackageImpl::instSrcRank() const
+      {
+       return 0;
+      }
+      /** */
+      std::string HelixPackageImpl::buildhost() const
+      {
+       return _buildhost;
+      }
+      /** */
+      std::string HelixPackageImpl::distribution() const
+      {
+       return "";
+      }
+      /** */
+      std::string HelixPackageImpl::vendor() const
+      {
+       return _vendor;
+      }
+      /** */
+      std::string HelixPackageImpl::license() const
+      {
+       return _license;
+      }
+      /** */
+      std::list<std::string> HelixPackageImpl::licenseToConfirm() const
+      {
+       return std::list<std::string>();
+      }
+      /** */
+      std::string HelixPackageImpl::packager() const
+      {
+       return _packager;
+      }
+      /** */
+      std::string HelixPackageImpl::group() const
+      {
+       return _group;
+      }
+      /** */
+      std::list<std::string> HelixPackageImpl::changelog() const
+      {}
+      /** */
+      std::string HelixPackageImpl::url() const
+      {
+       return _url;
+      }
+      /** */
+      std::string HelixPackageImpl::os() const
+      {}
+      /** */
+      std::list<std::string> HelixPackageImpl::prein() const
+      {}
+      /** */
+      std::list<std::string> HelixPackageImpl::postin() const
+      {}
+      /** */
+      std::list<std::string> HelixPackageImpl::preun() const
+      {}
+      /** */
+      std::list<std::string> HelixPackageImpl::postun() const
+      {}
+      /** */
+      std::string HelixPackageImpl::sourcepkg() const
+      { return _sourcepkg; }
+      /** */
+      std::list<std::string> HelixPackageImpl::authors() const
+      { return _authors; }
+      /** */
+      std::list<std::string> HelixPackageImpl::filenames() const
+      {}
+      /** */
+      std::list<std::string> HelixPackageImpl::recommends() const
+      {}
+      /** */
+      std::list<std::string> HelixPackageImpl::suggests() const
+      {}
+      /** */
+      std::string HelixPackageImpl::location() const
+      {}
+      /** */
+      std::string HelixPackageImpl::md5sum() const
+      {}
+      /** */
+      std::string HelixPackageImpl::externalUrl() const
+      {}
+      /** */
+      std::list<Edition> HelixPackageImpl::patchRpmBaseVersions() const
+      {}
+      /** */
+      unsigned HelixPackageImpl::patchRpmSize() const
+      {}
+      /** */
+      bool HelixPackageImpl::forceInstall() const
+      {}
+      /** */
+      std::string HelixPackageImpl::patchRpmMD5() const
+      {}
+      /** */
+      bool HelixPackageImpl::isRemote() const
+      {}
+      /** */
+      bool HelixPackageImpl::prefererCandidate() const
+      {}
+
+#endif
+
+    } // namespace yum
+    /////////////////////////////////////////////////////////////////
+  } // namespace source
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
diff --git a/devel/devel.kkaempf/HelixPackageImpl.h b/devel/devel.kkaempf/HelixPackageImpl.h
new file mode 100644 (file)
index 0000000..e194074
--- /dev/null
@@ -0,0 +1,73 @@
+/*---------------------------------------------------------------------\
+|                          ____ _   __ __ ___                          |
+|                         |__  / \ / / . \ . \                         |
+|                           / / \ V /|  _/  _/                         |
+|                          / /__ | | | | | |                           |
+|                         /_____||_| |_| |_|                           |
+|                                                                      |
+\---------------------------------------------------------------------*/
+/** \file zypp/solver/temporary/HelixPackageImpl.h
+ *
+*/
+#ifndef ZYPP_SOLVER_TEMPORARY_RCPACKAGEIMPL_H
+#define ZYPP_SOLVER_TEMPORARY_RCPACKAGEIMPL_H
+
+#include "zypp/detail/PackageImpl.h"
+#include "HelixParser.h"
+
+///////////////////////////////////////////////////////////////////
+namespace zypp
+{ /////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////
+  namespace solver
+  { /////////////////////////////////////////////////////////////////
+    namespace detail
+    { //////////////////////////////////////////////////////////////
+
+      ///////////////////////////////////////////////////////////////////
+      //
+      //        CLASS NAME : HelixPackageImpl
+      //
+      /** Class representing a package
+      */
+      class HelixPackageImpl : public zypp::detail::PackageImplIf
+      {
+      public:
+
+       class HelixParser;
+       /** Default ctor
+       */
+       HelixPackageImpl(
+         const HelixParser & data
+       );
+#if 0
+       /** Package summary */
+       virtual Label summary() const;
+       /** Package description */
+       virtual Text description() const;
+       virtual ByteCount size() const;
+       /** */
+       virtual PackageGroup group() const;
+       /** */
+       virtual ByteCount archivesize() const;
+       /** */
+
+      protected:
+       Label _summary;
+       Text _description;
+       PackageGroup _group;
+
+       ByteCount _size_installed;
+       ByteCount _size_archive;
+#endif
+
+       };
+      ///////////////////////////////////////////////////////////////////
+    } // namespace detail
+    /////////////////////////////////////////////////////////////////
+  } // namespace solver
+  ///////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////
+} // namespace zypp
+///////////////////////////////////////////////////////////////////
+#endif // ZYPP_SOLVER_TEMPORARY_HELIXPACKAGEIMPL_H
diff --git a/devel/devel.kkaempf/HelixParser.cc b/devel/devel.kkaempf/HelixParser.cc
new file mode 100644 (file)
index 0000000..bca7183
--- /dev/null
@@ -0,0 +1,740 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* HelixParser.cc  wrapper for XML I/O
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <ctype.h>
+#include <assert.h>
+#include "HelixParser.h"
+
+#include "zypp/ResObject.h"
+#include "zypp/CapFactory.h"
+#include "zypp/CapSet.h"
+#include "zypp/Dependencies.h"
+
+#include "zypp/base/String.h"
+#include "zypp/base/Logger.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+    namespace solver
+    { /////////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////
+  namespace detail
+  { ///////////////////////////////////////////////////////////////////
+
+using namespace std;
+
+//---------------------------------------------------------------------------
+
+static Resolvable::Kind
+string2kind (const std::string & str)
+{
+    Resolvable::Kind kind = ResTraits<zypp::Package>::kind;
+    if (!str.empty()) {
+       if (str == "package") {
+           // empty
+       }
+       else if (str == "patch") {
+           kind = ResTraits<zypp::Patch>::kind;
+       }
+       else if (str == "pattern") {
+           kind = ResTraits<zypp::Pattern>::kind;
+       }
+       else if (str == "script") {
+           kind = ResTraits<zypp::Script>::kind;
+       }
+       else if (str == "message") {
+           kind = ResTraits<zypp::Message>::kind;
+       }
+       else if (str == "product") {
+           kind = ResTraits<zypp::Product>::kind;
+       }
+       else {
+           ERR << "get_resItem unknown kind '" << str << "'" << endl;
+       }
+    }
+    return kind;
+}
+
+
+//---------------------------------------------------------------------------
+
+static Capability
+parse_dep_attrs(bool *is_obsolete, const xmlChar **attrs)
+{
+    CapFactory  factory;
+    int i;
+    bool op_present = false;
+    /* Temporary variables dependent upon the presense of an 'op' attribute */
+
+    Resolvable::Kind dkind = ResTraits<zypp::Package>::kind;   // default to package
+    string dname;
+    int depoch = Edition::noepoch;
+    string dversion;
+    string drelease;
+    string darch = "";
+    Rel relation = Rel::ANY;
+
+    *is_obsolete = false;
+
+    for (i = 0; attrs[i]; i++) {
+       const string attr ((const char *)attrs[i++]);
+       const string value ((const char *)attrs[i]);
+
+       if (attr == "name")             dname = value;
+       else if (attr == "kind")        dkind = string2kind (value);
+       else if (attr == "op") {        op_present = true; relation = Rel(value); }
+       else if (attr == "epoch")       depoch = str::strtonum<int>( value );
+       else if (attr == "version")     dversion = value;
+       else if (attr == "release")     drelease = value;
+       else if (attr == "arch")        darch = value;
+       else if (attr == "obsoletes")   *is_obsolete = true;
+       else {
+           _DBG("HelixParser") << "! Unknown attribute: " << attr << " = " << value << endl;
+       }
+
+    }
+
+    return  factory.parse ( dkind, dname, relation, Edition (dversion, drelease, depoch));
+}
+
+
+//---------------------------------------------------------------------------
+// SAX callbacks
+
+static void
+sax_start_document(void *ptr)
+{
+    HelixParser *ctx = (HelixParser *)ptr;
+    if (ctx->processing()) return;
+
+//    _XXX("HelixParser") << "* Start document" << endl;
+
+    ctx->setProcessing (true);
+}
+
+
+static void
+sax_end_document(void *ptr)
+{
+    HelixParser *ctx = (HelixParser *)ptr;
+    if (!ctx->processing()) return;
+
+//    _XXX("HelixParser") << "* End document" << endl;
+
+    ctx->setProcessing (false);
+}
+
+
+static void
+sax_start_element(void *ptr, const xmlChar *xmlchar, const xmlChar **attrs)
+{
+    HelixParser *ctx = (HelixParser *)ptr;
+
+    ctx->releaseBuffer();
+
+#if 0
+    _XXX("HelixParser") <<  "* Start element (" << (const char *)name << ")";
+
+    if (attrs) {
+       for (int i = 0; attrs[i]; i += 2) {
+           _DBG("HelixParser") <<  "   - Attribute (" << (const char *)attrs[i] << "=" << (const char *)attrs[i+1] << ")" << endl;
+       }
+    }
+#endif
+
+    string token ((const char *)xmlchar);
+
+    if (token == "channel"
+       || token == "subchannel") {
+       /* Unneeded container tags.  Ignore */
+       return;
+    }
+
+    return ctx->startElement (token, attrs);
+
+}
+
+
+static void
+sax_end_element(void *ptr, const xmlChar *xmlchar)
+{
+    HelixParser *ctx = (HelixParser *)ptr;
+
+//    _XXX("HelixParser") << "* End element (" << (const char *)name << ")" << endl;
+    string token ((const char *)xmlchar);
+
+    if (token == "channel"
+       || token == "subchannel") {
+       /* Unneeded container tags.  Ignore */
+       token.clear();
+    }
+
+    return ctx->endElement (token);
+}
+
+
+static void
+sax_characters(void *ptr, const xmlChar *ch, int len)
+{
+    HelixParser *ctx = (HelixParser *)ptr;
+
+    ctx->toBuffer (str::trim (string ((const char *)ch)));
+    return;
+}
+
+
+static void
+sax_warning(void *ptr, const char *msg, ...)
+{
+    va_list args;
+    char tmp[2048];
+
+    va_start(args, msg);
+
+    if (vsnprintf(tmp, 2048, msg, args) >= 2048) ERR << "vsnprintf overflow" << endl;
+    WAR << "* SAX Warning: " << tmp << endl;
+
+    va_end(args);
+}
+
+
+static void
+sax_error(void *ptr, const char *msg, ...)
+{
+    va_list args;
+    char tmp[2048];
+
+    va_start(args, msg);
+
+    if (vsnprintf(tmp, 2048, msg, args) >= 2048) ERR << "vsnprintf overflow" << endl;;
+    ERR << "* SAX Error: " <<  tmp <<endl;
+
+    va_end(args);
+}
+
+
+static xmlSAXHandler 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 */
+    sax_start_document,        /* startDocument */
+    sax_end_document,  /* endDocument */
+    sax_start_element, /* startElement */
+    sax_end_element,   /* endElement */
+    NULL,              /* reference */
+    sax_characters,     /* characters */
+    NULL,              /* ignorableWhitespace */
+    NULL,              /* processingInstruction */
+    NULL,              /* comment */
+    sax_warning,       /* warning */
+    sax_error,         /* error */
+    sax_error          /* fatalError */
+};
+
+//---------------------------------------------------------------------------
+
+HelixParser::HelixParser (Channel_constPtr channel)
+    : _channel (channel)
+    , _processing (false)
+    , _xml_context (NULL)
+    , _state (PARSER_TOPLEVEL)
+    , _stored(true)
+    , _toplevel_dep_list (NULL)
+    , _dep_list (NULL)
+{
+//    _XXX("HelixParser") <<  "* Context created (" << this << ")" << endl;
+}
+
+
+HelixParser::~HelixParser()
+{
+    releaseBuffer ();
+}
+
+//---------------------------------------------------------------------------
+
+string
+HelixParser::asString ( void ) const
+{
+    return toString (*this);
+}
+
+
+string
+HelixParser::toString ( const HelixParser & context )
+{
+    return "<HelixParser/>";
+}
+
+
+ostream &
+HelixParser::dumpOn( ostream & str ) const
+{
+    str << asString();
+    return str;
+}
+
+
+ostream&
+operator<<( ostream& os, const HelixParser& context)
+{
+    return os << context.asString();
+}
+
+//---------------------------------------------------------------------------
+
+void
+HelixParser::toBuffer (string data)
+{
+    _text_buffer = data;
+
+//    _XXX("HelixParser") << "HelixParser[" << this << "]::toBuffer(" << data << "...," << (long)size << ")" << endl;
+}
+
+
+void
+HelixParser::releaseBuffer ()
+{
+    _text_buffer.clear();
+
+//    _XXX("HelixParser") <<  "HelixParser[" << this << "]::releaseBuffer()" << endl;
+}
+
+
+// called for extracting
+
+void
+HelixParser::parseChunk(const char *xmlbuf, size_t size, ResolvableStoreCallback callback, ResStore *store)
+{
+//    _DBG("HelixParser") << "HelixParser::parseChunk(" << xmlbuf << "...," << (long)size << ")" << endl;
+
+    xmlSubstituteEntitiesDefault(true);
+
+    if (!_xml_context) {
+       _xml_context = xmlCreatePushParserCtxt(&sax_handler, this, NULL, 0, NULL);
+    }
+
+    _callback = callback;
+    _store = store;
+
+    xmlParseChunk(_xml_context, xmlbuf, size, 0);
+}
+
+
+void
+HelixParser::done()
+{
+//    _XXX("HelixParser") << "HelixParser::done()" << endl;
+
+    if (_processing)
+       xmlParseChunk(_xml_context, NULL, 0, 1);
+
+    if (_xml_context)
+       xmlFreeParserCtxt(_xml_context);
+
+    if (!_stored) {
+       ERR << "Incomplete package lost" << endl;
+    }
+
+    return;
+}
+
+
+//---------------------------------------------------------------------------
+// Parser state callbacks
+
+void
+HelixParser::startElement(const string & token, const xmlChar **attrs)
+{
+//    _XXX("HelixParser") << "HelixParser::startElement(" << token << ")" << endl;
+
+    switch (_state) {
+       case PARSER_TOPLEVEL:
+           toplevelStart (token, attrs);
+           break;
+       case PARSER_RESOLVABLE:
+           resolvableStart (token, attrs);
+           break;
+       case PARSER_HISTORY:
+           historyStart (token, attrs);
+           break;
+       case PARSER_DEP:
+           dependencyStart (token, attrs);
+           break;
+       default:
+           break;
+    }
+
+    return;
+}
+
+
+void
+HelixParser::endElement(const string & token)
+{
+//    _XXX("HelixParser") <<  "HelixParser::endElement(" << token << ")" << endl;
+
+    if (!token.empty()) {                      // sax_end_element might set token to NULL
+       switch (_state) {
+           case PARSER_RESOLVABLE:
+               resolvableEnd (token);
+               break;
+           case PARSER_HISTORY:
+               historyEnd (token);
+               break;
+           case PARSER_UPDATE:
+               updateEnd (token);
+               break;
+           case PARSER_DEP:
+               dependencyEnd (token);
+               break;
+           default:
+               break;
+       }
+    }
+
+    releaseBuffer();
+
+    return;
+}
+
+
+void
+HelixParser::toplevelStart(const std::string & token, const xmlChar **attrs)
+{
+//    _XXX("HelixParser") << "HelixParser::toplevelStart(" << token << ")" << endl;
+
+    if ((token == "package")
+       || (token == "pattern")
+       || (token == "script")
+       || (token == "message")
+       || (token == "patch")
+       || (token == "product")) {
+
+       _state = PARSER_RESOLVABLE;
+
+       _stored = false;
+       name = "";
+       summary = "";
+       description = "";
+       section = "";
+       kind = string2kind (token);     // needed for <update>..</update>, see updateStart
+
+       fileSize = 0;
+       installedSize = 0;
+       installOnly = false;
+
+       requires.clear();
+       provides.clear();
+       conflicts.clear();
+       freshens.clear();
+       enhances.clear();
+       children.clear();
+       recommends.clear();
+       suggests.clear();
+       obsoletes.clear();
+
+    }
+    else {
+       _DBG("HelixParser") << "! Not handling " << token << " at toplevel" << endl;
+    }
+}
+
+
+void
+HelixParser::resolvableStart(const std::string & token, const xmlChar **attrs)
+{
+//    _XXX("HelixParser") << "HelixParser::resolvableStart(" << token << ")" << endl;
+
+    /* Only care about the containers here */
+    if (token == "history") {
+       _state = PARSER_HISTORY;
+    }
+    else if (token == "deps") {
+       /*
+        * We can get a <deps> tag surrounding the actual package
+        * dependency sections (requires, provides, conflicts, etc).
+        * In this case, we'll just ignore this tag quietly.
+        */
+    }
+    else if (token == "requires") {
+       _state = PARSER_DEP;
+       _dep_list = _toplevel_dep_list = &requires;
+    }
+    else if (token == "recommends") {
+       _state = PARSER_DEP;
+       _dep_list = _toplevel_dep_list = &recommends;
+    }
+    else if (token == "suggests") {
+       _state = PARSER_DEP;
+       _dep_list = _toplevel_dep_list = &suggests;
+    }
+    else if (token == "conflicts") {
+       bool is_obsolete = false;
+       int i;
+
+       _state = PARSER_DEP;
+
+       for (i = 0; attrs && attrs[i] && !is_obsolete; i += 2) {
+           string attr ((const char *)(attrs[i]));
+           if (attr == "obsoletes")
+               is_obsolete = true;
+       }
+
+       if (is_obsolete)
+           _dep_list = _toplevel_dep_list = &obsoletes;
+       else {
+           _dep_list = _toplevel_dep_list = &conflicts;
+       }
+    }
+    else if (token == "obsoletes") {
+       _state = PARSER_DEP;
+       _dep_list = _toplevel_dep_list = &obsoletes;
+    }
+    else if (token == "provides") {
+       _state = PARSER_DEP;
+       _dep_list = _toplevel_dep_list = &provides;
+    }
+    else if (token == "children") {
+       _state = PARSER_DEP;
+       _dep_list = _toplevel_dep_list = &children;
+    }
+    else if (token == "freshens") {
+       _state = PARSER_DEP;
+       _dep_list = _toplevel_dep_list = &freshens;
+    }
+    else {
+//     _XXX("HelixParser") << "! Not handling " << token << " in package start" << endl;
+    }
+}
+
+
+void
+HelixParser::historyStart(const std::string & token, const xmlChar **attrs)
+{
+//    _XXX("HelixParser") << "HelixParser::historyStart(" << token << ")" << endl;
+
+    if (token == "update") {
+
+       _state = PARSER_UPDATE;
+    }
+    else {
+       _XXX("HelixParser") << "! Not handling " << token << " in history" << endl;
+    }
+}
+
+
+void
+HelixParser::dependencyStart(const std::string & token, const xmlChar **attrs)
+{
+//    _XXX("HelixParser") << "HelixParser::dependencyStart(" << token << ")" << endl;
+
+    if (token == "dep") {
+       Capability dep;
+       bool is_obsolete;
+
+       dep = parse_dep_attrs(&is_obsolete, attrs);
+
+       if (is_obsolete)
+           obsoletes.insert (dep);
+       else {
+           _dep_list->insert (dep);
+       }
+    }
+    else if (token == "or")
+       _dep_list->clear();
+    else {
+       _DBG("HelixParser") <<  "! Not handling " << token << " in dependency" << endl;
+    }
+}
+
+
+//---------------------------------------------------------------------------
+
+
+void
+HelixParser::resolvableEnd (const std::string & token)
+{
+//    _XXX("HelixParser") << "HelixParser::resolvableEnd(" << token << ")" << endl;
+
+    if ((token == "package")
+       || (token == "pattern")
+       || (token == "script")
+       || (token == "message")
+       || (token == "patch")
+       || (token == "product")) {
+
+       kind = string2kind (token);
+
+       // check if we provide ourselfs properly
+
+       CapFactory  factory;
+       Edition edition (version, release, epoch);
+       Capability selfdep = factory.parse ( kind, name, Rel::EQ, edition);
+       CapSet::const_iterator piter;
+       for (piter = provides.begin(); piter != provides.end(); piter++) {
+           if ((*piter) == selfdep)
+           {
+               break;
+           }
+       }
+
+       if (piter == provides.end()) {                  // no self provide found, construct one
+           _XXX("RC_SPEW") << "Adding self-provide [" << selfdep.asString() << "]" << endl;
+           provides.insert (selfdep);
+       }
+
+       Dependencies deps;
+       deps.requires           = requires;
+       deps.provides           = provides;
+       deps.conflicts          = conflicts;
+       deps.obsoletes          = obsoletes;
+       deps.suggests           = suggests;
+       deps.recommends         = recommends;
+       deps.freshens           = freshens;
+
+#warning Resolvable complete
+#if 0
+       Package_Ptr package = new Package ( channel, kind, name, edition, arch);
+
+       if (_channel->system())                         // simulate system channel by loading xml file
+           package->setInstalled (true);
+#endif
+
+//     _DBG("RC_SPEW") << package->asString(true) << endl;
+//     _DBG("HelixParser") << "HelixParser::resolvableEnd(" << token << ") done: '" << package->asString(true) << "'" << endl;
+//     _XXX("HelixParser") << "HelixParser::resolvableEnd now " << _all_packages.size() << " packages" << endl;
+       _stored = true;
+       _state = PARSER_TOPLEVEL;
+    }
+    else if (token == "name") {                        name = _text_buffer;
+    } else if (token == "pretty_name") {       // ignore
+    } else if (token == "summary") {           summary = _text_buffer;
+    } else if (token == "description") {       description = _text_buffer;
+    } else if (token == "section") {           section = _text_buffer;
+    } else if (token == "arch") {              arch = _text_buffer;
+    } else if (token == "filesize") {          fileSize = str::strtonum<long>(_text_buffer);
+    } else if (token == "installedsize") {     installedSize = str::strtonum<long>(_text_buffer);
+    } else if (token == "install_only") {      installOnly = true;
+    } else {
+       _DBG("HelixParser") << "HelixParser::resolvableEnd(" << token << ") unknown" << endl;
+    }
+
+//    _XXX("HelixParser") << "HelixParser::resolvableEnd(" << token << ") done" << endl;
+
+    releaseBuffer();
+}
+
+
+void
+HelixParser::historyEnd (const std::string & token)
+{
+//    _XXX("HelixParser") << "HelixParser::historyEnd(" << token << ")" << endl;
+
+    if (token == "history") {
+
+       _state = PARSER_RESOLVABLE;
+    }
+}
+
+
+void
+HelixParser::updateEnd (const std::string & token)
+{
+//    _XXX("HelixParser") << "HelixParser::updateEnd(" << token << ")" << endl;
+
+    Channel_constPtr channel;
+
+    if (token == "update") {
+       _state = PARSER_HISTORY;
+    } else if (token == "epoch") {             epoch = str::strtonum<int>(_text_buffer);
+    } else if (token == "version") {           version = _text_buffer;
+    } else if (token == "release") {           release = _text_buffer;
+    } else if (token == "arch") {              arch = _text_buffer;
+    } else if (token == "filename") {          // ignore
+    } else if (token == "filesize") {          fileSize = str::strtonum<long>(_text_buffer);
+    } else if (token == "installedsize") {     installedSize = str::strtonum<long>(_text_buffer);
+    } else if (token == "signaturename") {     // ignore
+    } else if (token == "signaturesize") {     // ignore
+    } else if (token == "md5sum") {            // ignore
+    } else if (token == "importance") {                // ignore
+    } else if (token == "description") {       // ignore
+    } else if (token == "hid") {               // ignore
+    } else if (token == "license") {           // ignore
+    } else {
+       ERR << "HelixParser::updateEnd(" << token << ") unknown" << endl;
+    }
+
+    releaseBuffer();
+}
+
+
+void
+HelixParser::dependencyEnd (const std::string & token)
+{
+//    _XXX("HelixParser") << "HelixParser::dependencyEnd(" << token << ")" << endl;
+
+    if (token == "or") {
+#if 0
+       OrDependency_Ptr or_dep = OrDependency::fromDependencyList (*_dep_list);
+       Dependency_Ptr dep = new Dependency (or_dep);
+
+       (*_dep_list).clear();
+
+       (*_toplevel_dep_list).push_back (dep);
+       _dep_list = _toplevel_dep_list;
+#endif
+    }
+    else if (token == "dep") {
+       /* We handled everything we needed for dep in start */
+    }
+    else {
+       /* All of the dep lists (requires, provides, etc.) */
+       _toplevel_dep_list = NULL;
+       _dep_list = NULL;
+       _state = PARSER_RESOLVABLE;
+    }
+}
+
+
+///////////////////////////////////////////////////////////////////
+  };// namespace detail
+  /////////////////////////////////////////////////////////////////////
+  /////////////////////////////////////////////////////////////////////
+    };// namespace solver
+    ///////////////////////////////////////////////////////////////////////
+    ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
diff --git a/devel/devel.kkaempf/HelixParser.h b/devel/devel.kkaempf/HelixParser.h
new file mode 100644 (file)
index 0000000..5f87a04
--- /dev/null
@@ -0,0 +1,167 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* HelixParser.h: XML routines
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * 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.
+ */
+
+#ifndef ZYPP_SOLVER_TEMPORARY_HELIXPARSER_H
+#define ZYPP_SOLVER_TEMPORARY_HELIXPARSER_H
+
+#include <iosfwd>
+#include <string>
+#include <list>
+
+#include "zypp/CapSet.h"
+
+#include "HelixExtract.h"
+
+#include "zypp/solver/temporary/Channel.h"
+#include "zypp/solver/temporary/XmlNode.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp
+{ ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+  namespace solver
+  { /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+    namespace detail
+    { ///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//
+//      CLASS NAME : HelixParser
+
+class HelixParser
+{
+  public:
+    enum _HelixParserState {
+       PARSER_TOPLEVEL = 0,
+       PARSER_RESOLVABLE,
+       PARSER_HISTORY,
+       PARSER_UPDATE,
+       PARSER_DEP,
+    };
+    typedef enum _HelixParserState HelixParserState;
+
+  private:
+    Channel_constPtr _channel;
+    bool _processing;
+    xmlParserCtxtPtr _xml_context;
+    HelixParserState _state;
+
+    /* Temporary state */
+    bool _stored;
+
+
+  public:
+    Resolvable::Kind kind;
+    std::string name;
+    int epoch;
+    std::string version;
+    std::string release;
+    std::string arch;
+    std::string summary;
+    std::string description;
+    std::string section;
+    int fileSize;
+    int installedSize;
+    bool installOnly;
+
+    CapSet requires;
+    CapSet provides;
+    CapSet conflicts;
+    CapSet children;
+    CapSet recommends;
+    CapSet suggests;
+    CapSet obsoletes;
+    CapSet freshens;
+    CapSet enhances;
+
+  private:
+    // these point to one of the above lists during dependency parsing
+    CapSet *_toplevel_dep_list;
+    CapSet *_dep_list;
+
+    std::string _text_buffer;
+
+    void setState (HelixParserState state) { _state = state; }
+
+  public:
+
+    HelixParser (Channel_constPtr channel);
+    virtual ~HelixParser();
+
+    // ---------------------------------- I/O
+
+    static std::string toString ( const HelixParser & parser);
+    virtual std::ostream & dumpOn( std::ostream & str ) const;
+    friend std::ostream& operator<<( std::ostream & str, const HelixParser & parser);
+    std::string asString ( void ) const;
+
+    // ---------------------------------- accessors
+
+    bool processing (void) const { return _processing; }
+    void setProcessing (bool processing) { _processing = processing; }
+
+  public:
+    // ---------------------------------- accessors
+
+    HelixParserState state (void) const { return _state; }
+
+    // ---------------------------------- methods
+    // callbacks from xml_ parser functions
+
+    void toBuffer (std::string data);
+    void releaseBuffer (void);         // free _text_buffer
+
+    void startElement(const std::string & token, const xmlChar **attrs);
+    void endElement(const std::string & token);
+
+    void parseChunk (const char *xmlbuf, size_t size, ResolvableStoreCallback callback, ResStore *store);
+    void done (void);
+
+  private:
+    ResolvableStoreCallback _callback;
+    ResStore *_store;
+
+    // internal HelixParser functions, c++-style
+    void toplevelStart(const std::string & token, const xmlChar **attrs);
+    void resolvableStart(const std::string & token, const xmlChar **attrs);
+    void historyStart(const std::string & token, const xmlChar **attrs);
+    void dependencyStart(const std::string & token, const xmlChar **attrs);
+
+    void updateEnd(const std::string & token);
+    void resolvableEnd(const std::string & token);
+    void historyEnd(const std::string & token);
+    void dependencyEnd(const std::string & token);
+
+};
+
+///////////////////////////////////////////////////////////////////
+    };// namespace detail
+    /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+  };// namespace solver
+  ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+
+#endif  // ZYPP_SOLVER_TEMPORARY_HELIXPARSER_H
diff --git a/devel/devel.kkaempf/HelixSourceImpl.cc b/devel/devel.kkaempf/HelixSourceImpl.cc
new file mode 100644 (file)
index 0000000..a92da6d
--- /dev/null
@@ -0,0 +1,89 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* HelixSourceImpl.cc
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * 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 "HelixSourceImpl.h"
+#include "zypp/solver/temporary/Channel.h"
+#include "zypp/solver/temporary/extract.h"
+#include "zypp/base/Logger.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp 
+{ ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+  namespace solver
+  { /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+    namespace detail
+    { ///////////////////////////////////////////////////////////////////
+
+using namespace std;
+
+//---------------------------------------------------------------------------
+
+HelixSourceImpl::HelixSourceImpl(media::MediaAccess::Ptr & media_r, const Pathname & path_r)
+{
+    load (path_r.asString());
+}
+
+
+//---------------------------------------------------------------------------
+
+
+static bool
+add_resolvable_cb (Resolvable::Ptr res, ResStore *store)
+{
+#if 0
+    HelixSourceImpl *undump = (HelixSourceImpl *)data;
+
+    undump->addResItem (res);
+#else
+    MIL << "add_resItem_cb()" << endl;
+#endif
+
+    return true;
+}
+
+
+//-----------------------------------------------------------------------------
+
+void
+HelixSourceImpl::load (const string & filename)
+{
+    if (!filename.empty()) {
+       Channel_Ptr channel = new Channel ("test", "test", "test", "test");
+       channel->setType (CHANNEL_TYPE_HELIX);
+//     channel->setSystem (true);
+
+       extractHelixFile (filename, channel, add_resolvable_cb, &_store);
+    }
+}
+
+
+///////////////////////////////////////////////////////////////////
+    };// namespace detail
+    /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+  };// namespace solver
+  ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
diff --git a/devel/devel.kkaempf/HelixSourceImpl.h b/devel/devel.kkaempf/HelixSourceImpl.h
new file mode 100644 (file)
index 0000000..7c54211
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* HelixSourceImpl.h
+ *
+ * Copyright (C) 2000-2002 Ximian, Inc.
+ * Copyright (C) 2005 SUSE Linux Products GmbH
+ *
+ * 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.
+ */
+
+#ifndef ZYPP_SOLVER_TEMPORARY_HELIXSOURCEIMPL_H
+#define ZYPP_SOLVER_TEMPORARY_HELIXSOURCEIMPL_H
+
+#include <iosfwd>
+#include <string>
+
+#include "zypp/source/SourceImpl.h"
+#include "zypp/solver/temporary/Channel.h"
+
+#include "HelixParser.h"
+
+#include "zypp/Package.h"
+#include "zypp/Message.h"
+#include "zypp/Script.h"
+#include "zypp/Patch.h"
+#include "zypp/Product.h"
+#include "zypp/Selection.h"
+#include "zypp/Pattern.h"
+
+/////////////////////////////////////////////////////////////////////////
+namespace zypp 
+{ ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+  namespace solver
+  { /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+    namespace detail
+    { ///////////////////////////////////////////////////////////////////
+        
+///////////////////////////////////////////////////////////////////
+//
+//     CLASS NAME : HelixSourceImpl
+
+class HelixSourceImpl : public zypp::source::SourceImpl {
+
+  private:
+
+    void load (const std::string & filename_r);
+    
+  public:
+
+    /** Ctor, FIXME it is here only because of target storage */
+    HelixSourceImpl()
+    {}
+    /** Default ctor */
+    HelixSourceImpl(media::MediaAccess::Ptr & media_r, const Pathname & path_r = "/");
+
+};
+///////////////////////////////////////////////////////////////////
+    };// namespace detail
+    /////////////////////////////////////////////////////////////////////
+    /////////////////////////////////////////////////////////////////////
+  };// namespace solver
+  ///////////////////////////////////////////////////////////////////////
+  ///////////////////////////////////////////////////////////////////////
+};// namespace zypp
+/////////////////////////////////////////////////////////////////////////
+
+#endif // ZYPP_SOLVER_TEMPORARY_HELIXSOURCEIMPL_H
diff --git a/devel/devel.kkaempf/Makefile.am b/devel/devel.kkaempf/Makefile.am
new file mode 100644 (file)
index 0000000..1a9113b
--- /dev/null
@@ -0,0 +1,34 @@
+#
+# Makefile.am for solver/temporary
+#
+
+SUBDIRS =
+
+INCLUDES =                                     \
+       -I$(top_srcdir) -Wall                   \
+       -I/usr/include/libxml2                  \
+       -DG_LOG_DOMAIN=\"devel.kkaempf\"
+
+LDADD =        $(noinst_LTLIBRARIES) $(top_srcdir)/zypp/lib@PACKAGE@.la
+
+noinst_PROGRAMS = rcparse
+
+rcparse_SOURCES = rcparse.cc
+
+noinst_HEADERS = \
+       Buffer.h                                \
+       HelixExtract.h                          \
+       HelixParser.h                           \
+       HelixSourceImpl.h                       \
+       HelixPackageImpl.h
+
+noinst_LTLIBRARIES =   lib@PACKAGE@_devel_kkaempf.la
+
+lib@PACKAGE@_devel_kkaempf_la_SOURCES =                \
+       Buffer.cc                               \
+       HelixExtract.cc                         \
+       HelixParser.cc                          \
+       HelixSourceImpl.cc
+
+#      HelixPackageImpl.cc
+
diff --git a/devel/devel.kkaempf/dummy-packages.xml b/devel/devel.kkaempf/dummy-packages.xml
new file mode 100644 (file)
index 0000000..566f50c
--- /dev/null
@@ -0,0 +1,155 @@
+<channel><subchannel>
+<package>
+  <name>unfulfilled</name>
+  <summary>A fake package</summary>
+  <description>A fake package</description>
+  <section>misc</section>
+  <history>
+    <update>
+      <hid>12345</hid>
+      <epoch>0</epoch>
+      <version>1.0</version>
+      <release>1</release>
+      <filename>foo.bar</filename>
+      <filesize>123</filesize>
+      <installedsize>234</installedsize>
+      <md5sum>0f55f36a3240858038a281911605024e</md5sum>
+      <importance>suggested</importance>
+      <description>Yggdrasil Linux</description>
+    </update>
+  </history>
+  <provides>
+    <dep name="x" op="(any)" version="1.0"/>
+  </provides>
+  <requires>
+    <dep name="nothere"/>
+  </requires>
+</package>
+<package>
+  <name>A</name>
+  <summary>A fake package</summary>
+  <description>A fake package</description>
+  <section>misc</section>
+  <history>
+    <update>
+      <hid>12345</hid>
+      <epoch>0</epoch>
+      <version>1.0</version>
+      <release>1</release>
+      <filename>foo.bar</filename>
+      <filesize>123</filesize>
+      <installedsize>234</installedsize>
+      <md5sum>0f55f36a3240858038a281911605024e</md5sum>
+      <importance>suggested</importance>
+      <description>Yggdrasil Linux</description>
+    </update>
+  </history>
+  <requires>
+    <dep name="b" op="(any)" version="1.0"/>
+  </requires>
+  <provides>
+    <dep name="a" op="(any)" version="1.0"/>
+  </provides>
+</package>
+<package>
+  <name>B</name>
+  <summary>A fake package</summary>
+  <description>A fake package</description>
+  <section>misc</section>
+  <history>
+    <update>
+      <hid>12345</hid>
+      <epoch>0</epoch>
+      <version>1.0</version>
+      <release>1</release>
+      <filename>foo.bar</filename>
+      <filesize>123</filesize>
+      <installedsize>234</installedsize>
+      <md5sum>0f55f36a3240858038a281911605024e</md5sum>
+      <importance>suggested</importance>
+      <description>Yggdrasil Linux</description>
+    </update>
+  </history>
+  <requires>
+    <dep name="c" op="(any)" version="1.0"/>
+  </requires>
+  <provides>
+    <dep name="b" op="(any)" version="1.0"/>
+  </provides>
+  <conflicts>
+    <dep name="e" op="(any)" version="1.0"/>
+  </conflicts>
+</package>
+<package>
+  <name>C</name>
+  <summary>A fake package</summary>
+  <description>A fake package</description>
+  <section>misc</section>
+  <history>
+    <update>
+      <hid>12345</hid>
+      <epoch>0</epoch>
+      <version>1.0</version>
+      <release>1</release>
+      <filename>foo.bar</filename>
+      <filesize>123</filesize>
+      <installedsize>234</installedsize>
+      <md5sum>0f55f36a3240858038a281911605024e</md5sum>
+      <importance>suggested</importance>
+      <description>Yggdrasil Linux</description>
+    </update>
+  </history>
+  <provides>
+    <dep name="c" op="(any)" version="1.0"/>
+  </provides>
+</package>
+<package>
+  <name>D</name>
+  <summary>A fake package</summary>
+  <description>A fake package</description>
+  <section>misc</section>
+  <history>
+    <update>
+      <hid>12345</hid>
+      <epoch>0</epoch>
+      <version>1.0</version>
+      <release>1</release>
+      <filename>foo.bar</filename>
+      <filesize>123</filesize>
+      <installedsize>234</installedsize>
+      <md5sum>0f55f36a3240858038a281911605024e</md5sum>
+      <importance>suggested</importance>
+      <description>Yggdrasil Linux</description>
+    </update>
+  </history>
+  <provides>
+    <dep name="d" op="(any)" version="1.0"/>
+    <dep name="c" op="(any)" version="1.0"/>
+  </provides>
+</package>
+<package>
+  <name>E</name>
+  <summary>A fake package</summary>
+  <description>A fake package</description>
+  <section>misc</section>
+  <history>
+    <update>
+      <hid>12345</hid>
+      <epoch>0</epoch>
+      <version>1.0</version>
+      <release>1</release>
+      <filename>foo.bar</filename>
+      <filesize>123</filesize>
+      <installedsize>234</installedsize>
+      <md5sum>0f55f36a3240858038a281911605024e</md5sum>
+      <importance>suggested</importance>
+      <description>Yggdrasil Linux</description>
+    </update>
+  </history>
+  <provides>
+    <dep name="c" op="(any)" version="1.0"/>
+    <dep name="e" op="(any)" version="1.0"/>
+    <dep name="x" op="(any)" version="1.0"/>
+  </provides>
+</package>
+</subchannel></channel>
diff --git a/devel/devel.kkaempf/rcparse.cc b/devel/devel.kkaempf/rcparse.cc
new file mode 100644 (file)
index 0000000..bd819dc
--- /dev/null
@@ -0,0 +1,56 @@
+// test for RCUndumpSourceImpl
+//
+
+#include <iostream>
+#include <fstream>
+#include <map>
+#include "zypp/base/Logger.h"
+#include "zypp/SourceFactory.h"
+#include "zypp/Source.h"
+#include "zypp/source/SourceImpl.h"
+#include "zypp/media/MediaAccess.h"
+
+#include "HelixSourceImpl.h"
+
+using namespace std;
+using namespace zypp;
+
+static void
+usage (void)
+{
+    ERR << "Usage: rcparse <filename>" << endl;
+    exit (1);
+}
+
+
+/******************************************************************
+**
+**
+**     FUNCTION NAME : main
+**     FUNCTION TYPE : int
+**
+**     DESCRIPTION :
+*/
+int main( int argc, char * argv[] )
+{
+    if (argc < 2)
+       usage();
+
+    INT << "===[START]==========================================" << endl;
+
+    Pathname p = argv[1];
+
+    media::MediaAccess::Ptr media = new media::MediaAccess();
+    Source::Impl_Ptr impl = new solver::detail::HelixSourceImpl (media, p);
+    SourceFactory _f;
+    Source s = _f.createFrom( impl );
+    ResStore store = s.resolvables();
+    for (ResStore::const_iterator it = store.begin();
+       it != store.end(); it++)
+    {
+       ERR << **it << endl;
+    }
+    ERR << store << endl;
+    INT << "===[END]============================================" << endl;
+    return 0;
+}