incubator-celix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From abroekh...@apache.org
Subject svn commit: r1043903 [3/5] - /incubator/celix/trunk/celix/
Date Thu, 09 Dec 2010 11:49:43 GMT
Added: incubator/celix/trunk/celix/ioapi.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/ioapi.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/ioapi.c (added)
+++ incubator/celix/trunk/celix/ioapi.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,235 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+*/
+
+#if (defined(_WIN32))
+        #define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#include "ioapi.h"
+
+voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
+{
+    if (pfilefunc->zfile_func64.zopen64_file != NULL)
+        return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
+    else
+    {
+        return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
+    }
+}
+
+long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
+{
+    if (pfilefunc->zfile_func64.zseek64_file != NULL)
+        return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
+    else
+    {
+        uLong offsetTruncated = (uLong)offset;
+        if (offsetTruncated != offset)
+            return -1;
+        else
+            return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
+    }
+}
+
+ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
+{
+    if (pfilefunc->zfile_func64.zseek64_file != NULL)
+        return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
+    else
+    {
+        uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
+        if ((tell_uLong) == ((uLong)-1))
+            return (ZPOS64_T)-1;
+        else
+            return tell_uLong;
+    }
+}
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
+{
+    p_filefunc64_32->zfile_func64.zopen64_file = NULL;
+    p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
+    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+    p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
+    p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
+    p_filefunc64_32->zfile_func64.ztell64_file = NULL;
+    p_filefunc64_32->zfile_func64.zseek64_file = NULL;
+    p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
+    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+    p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
+    p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
+    p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
+}
+
+
+
+static voidpf  ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
+static uLong   ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+static uLong   ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
+static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
+static long    ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+static int     ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
+static int     ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
+
+static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
+{
+    FILE* file = NULL;
+    const char* mode_fopen = NULL;
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+        mode_fopen = "rb";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+        mode_fopen = "r+b";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+        mode_fopen = "wb";
+
+    if ((filename!=NULL) && (mode_fopen != NULL))
+        file = fopen(filename, mode_fopen);
+    return file;
+}
+
+static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
+{
+    FILE* file = NULL;
+    const char* mode_fopen = NULL;
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+        mode_fopen = "rb";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+        mode_fopen = "r+b";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+        mode_fopen = "wb";
+
+    if ((filename!=NULL) && (mode_fopen != NULL))
+        file = fopen64((const char*)filename, mode_fopen);
+    return file;
+}
+
+
+static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
+{
+    uLong ret;
+    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
+{
+    uLong ret;
+    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
+{
+    long ret;
+    ret = ftell((FILE *)stream);
+    return ret;
+}
+
+
+static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
+{
+    ZPOS64_T ret;
+    ret = ftello64((FILE *)stream);
+    return ret;
+}
+
+static long ZCALLBACK fseek_file_func (voidpf  opaque, voidpf stream, uLong offset, int origin)
+{
+    int fseek_origin=0;
+    long ret;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        fseek_origin = SEEK_CUR;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        fseek_origin = SEEK_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        fseek_origin = SEEK_SET;
+        break;
+    default: return -1;
+    }
+    ret = 0;
+    if (fseek((FILE *)stream, offset, fseek_origin) != 0)
+        ret = -1;
+    return ret;
+}
+
+static long ZCALLBACK fseek64_file_func (voidpf  opaque, voidpf stream, ZPOS64_T offset, int origin)
+{
+    int fseek_origin=0;
+    long ret;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        fseek_origin = SEEK_CUR;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        fseek_origin = SEEK_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        fseek_origin = SEEK_SET;
+        break;
+    default: return -1;
+    }
+    ret = 0;
+
+    if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
+                        ret = -1;
+
+    return ret;
+}
+
+
+static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
+{
+    int ret;
+    ret = fclose((FILE *)stream);
+    return ret;
+}
+
+static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
+{
+    int ret;
+    ret = ferror((FILE *)stream);
+    return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+  zlib_filefunc_def* pzlib_filefunc_def;
+{
+    pzlib_filefunc_def->zopen_file = fopen_file_func;
+    pzlib_filefunc_def->zread_file = fread_file_func;
+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+    pzlib_filefunc_def->ztell_file = ftell_file_func;
+    pzlib_filefunc_def->zseek_file = fseek_file_func;
+    pzlib_filefunc_def->zclose_file = fclose_file_func;
+    pzlib_filefunc_def->zerror_file = ferror_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_fopen64_filefunc (zlib_filefunc64_def*  pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = fopen64_file_func;
+    pzlib_filefunc_def->zread_file = fread_file_func;
+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+    pzlib_filefunc_def->ztell64_file = ftell64_file_func;
+    pzlib_filefunc_def->zseek64_file = fseek64_file_func;
+    pzlib_filefunc_def->zclose_file = fclose_file_func;
+    pzlib_filefunc_def->zerror_file = ferror_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}

Added: incubator/celix/trunk/celix/ioapi.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/ioapi.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/ioapi.h (added)
+++ incubator/celix/trunk/celix/ioapi.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,200 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         Changes
+
+    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
+    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
+               More if/def section may be needed to support other platforms
+    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
+                          (but you should use iowin32.c for windows instead)
+
+*/
+
+#ifndef _ZLIBIOAPI64_H
+#define _ZLIBIOAPI64_H
+
+#if (!defined(_WIN32)) && (!defined(WIN32))
+
+  // Linux needs this to support file operation on files larger then 4+GB
+  // But might need better if/def to select just the platforms that needs them.
+
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zlib.h"
+
+#if defined(USE_FILE32API)
+#define fopen64 fopen
+#define ftello64 ftell
+#define fseeko64 fseek
+#else
+#ifdef _MSC_VER
+ #define fopen64 fopen
+ #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
+  #define ftello64 _ftelli64
+  #define fseeko64 _fseeki64
+ #else // old MSC
+  #define ftello64 ftell
+  #define fseeko64 fseek
+ #endif
+#endif
+#endif
+
+/*
+#ifndef ZPOS64_T
+  #ifdef _WIN32
+                #define ZPOS64_T fpos_t
+  #else
+    #include <stdint.h>
+    #define ZPOS64_T uint64_t
+  #endif
+#endif
+*/
+
+#ifdef HAVE_MINIZIP64_CONF_H
+#include "mz64conf.h"
+#endif
+
+/* a type choosen by DEFINE */
+#ifdef HAVE_64BIT_INT_CUSTOM
+typedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;
+#else
+#ifdef HAS_STDINT_H
+#include "stdint.h"
+typedef uint64_t ZPOS64_T;
+#else
+
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 ZPOS64_T;
+#else
+typedef unsigned long long int ZPOS64_T;
+#endif
+#endif
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ      (1)
+#define ZLIB_FILEFUNC_MODE_WRITE     (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE   (8)
+
+
+#ifndef ZCALLBACK
+ #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+   #define ZCALLBACK CALLBACK
+ #else
+   #define ZCALLBACK
+ #endif
+#endif
+
+
+
+
+typedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));
+typedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));
+typedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));
+typedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+
+
+/* here is the "old" 32 bits structure structure */
+typedef struct zlib_filefunc_def_s
+{
+    open_file_func      zopen_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell_file_func      ztell_file;
+    seek_file_func      zseek_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc_def;
+
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
+typedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+typedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));
+
+typedef struct zlib_filefunc64_def_s
+{
+    open64_file_func    zopen64_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell64_file_func    ztell64_file;
+    seek64_file_func    zseek64_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc64_def;
+
+void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+/* now internal definition, only for zip.c and unzip.h */
+typedef struct zlib_filefunc64_32_def_s
+{
+    zlib_filefunc64_def zfile_func64;
+    open_file_func      zopen32_file;
+    tell_file_func      ztell32_file;
+    seek_file_func      zseek32_file;
+} zlib_filefunc64_32_def;
+
+
+#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))
+#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))
+//#define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
+//#define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))
+#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))
+
+voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
+long    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
+ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+
+void    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+
+#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))
+#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))
+#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

Added: incubator/celix/trunk/celix/linked_list_iterator.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/linked_list_iterator.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/linked_list_iterator.c (added)
+++ incubator/celix/trunk/celix/linked_list_iterator.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,123 @@
+/*
+ * linked_list_iterator.c
+ *
+ *  Created on: Jul 16, 2010
+ *      Author: alexanderb
+ */
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "linked_list_iterator.h"
+#include "linked_list_private.h"
+
+struct linkedListIterator {
+	LINKED_LIST_ENTRY lastReturned;
+	LINKED_LIST_ENTRY next;
+	int nextIndex;
+	LINKED_LIST list;
+	int expectedModificationCount;
+};
+
+LINKED_LIST_ITERATOR linkedListIterator_create(LINKED_LIST list, int index) {
+	if (index < 0 || index > list->size) {
+		return NULL;
+	}
+	LINKED_LIST_ITERATOR iterator = (LINKED_LIST_ITERATOR) malloc(sizeof(*iterator));
+	iterator->lastReturned = list->header;
+	iterator->list = list;
+	iterator->expectedModificationCount = list->modificationCount;
+	if (index < (list->size >> 1)) {
+		iterator->next = iterator->list->header->next;
+		for (iterator->nextIndex = 0; iterator->nextIndex < index; iterator->nextIndex++) {
+			iterator->next = iterator->next->next;
+		}
+	} else {
+		iterator->next = list->header;
+		for (iterator->nextIndex = list->size; iterator->nextIndex > index; iterator->nextIndex--) {
+			iterator->next = iterator->next->previous;
+		}
+	}
+	return iterator;
+}
+
+bool linkedListIterator_hasNext(LINKED_LIST_ITERATOR iterator) {
+	return iterator->nextIndex != iterator->list->size;
+}
+
+void * linkedListIterator_next(LINKED_LIST_ITERATOR iterator) {
+	if (iterator->list->modificationCount != iterator->expectedModificationCount) {
+		return NULL;
+	}
+	if (iterator->nextIndex == iterator->list->size) {
+		return NULL;
+	}
+	iterator->lastReturned = iterator->next;
+	iterator->next = iterator->next->next;
+	iterator->nextIndex++;
+	return iterator->lastReturned->element;
+}
+
+bool linkedListIterator_hasPrevious(LINKED_LIST_ITERATOR iterator) {
+	return iterator->nextIndex != 0;
+}
+
+void * linkedListIterator_previous(LINKED_LIST_ITERATOR iterator) {
+	if (iterator->nextIndex == 0) {
+		return NULL;
+	}
+
+	iterator->lastReturned = iterator->next = iterator->next->previous;
+	iterator->nextIndex--;
+
+	if (iterator->list->modificationCount != iterator->expectedModificationCount) {
+		return NULL;
+	}
+
+	return iterator->lastReturned->element;
+}
+
+int linkedListIterator_nextIndex(LINKED_LIST_ITERATOR iterator) {
+	return iterator->nextIndex;
+}
+
+int linkedListIterator_previousIndex(LINKED_LIST_ITERATOR iterator) {
+	return iterator->nextIndex-1;
+}
+
+void linkedListIterator_remove(LINKED_LIST_ITERATOR iterator) {
+	if (iterator->list->modificationCount != iterator->expectedModificationCount) {
+		return;
+	}
+	LINKED_LIST_ENTRY lastNext = iterator->lastReturned->next;
+	if (linkedList_removeEntry(iterator->list, iterator->lastReturned) == NULL) {
+		return;
+	}
+	if (iterator->next == iterator->lastReturned) {
+		iterator->next = lastNext;
+	} else {
+		iterator->nextIndex--;
+	}
+	iterator->lastReturned = iterator->list->header;
+	iterator->expectedModificationCount++;
+}
+
+void linkedListIterator_set(LINKED_LIST_ITERATOR iterator, void * element) {
+	if (iterator->lastReturned == iterator->list->header) {
+		return;
+	}
+	if (iterator->list->modificationCount != iterator->expectedModificationCount) {
+		return;
+	}
+	iterator->lastReturned->element = element;
+}
+
+void linkedListIterator_add(LINKED_LIST_ITERATOR iterator, void * element) {
+	if (iterator->list->modificationCount != iterator->expectedModificationCount) {
+		return;
+	}
+	iterator->lastReturned = iterator->list->header;
+	linkedList_addBefore(iterator->list, element, iterator->next);
+	iterator->nextIndex++;
+	iterator->expectedModificationCount++;
+}
+

Added: incubator/celix/trunk/celix/linked_list_iterator.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/linked_list_iterator.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/linked_list_iterator.h (added)
+++ incubator/celix/trunk/celix/linked_list_iterator.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,29 @@
+/*
+ * linked_list_iterator.h
+ *
+ *  Created on: Jul 16, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef LINKED_LIST_ITERATOR_H_
+#define LINKED_LIST_ITERATOR_H_
+
+#include <stdbool.h>
+
+#include "linkedlist.h"
+
+typedef struct linkedListIterator * LINKED_LIST_ITERATOR;
+
+LINKED_LIST_ITERATOR linkedListIterator_create(LINKED_LIST list, int index);
+bool linkedListIterator_hasNext(LINKED_LIST_ITERATOR iterator);
+void * linkedListIterator_next(LINKED_LIST_ITERATOR iterator);
+bool linkedListIterator_hasPrevious(LINKED_LIST_ITERATOR iterator);
+void * linkedListIterator_previous(LINKED_LIST_ITERATOR iterator);
+int linkedListIterator_nextIndex(LINKED_LIST_ITERATOR iterator);
+int linkedListIterator_previousIndex(LINKED_LIST_ITERATOR iterator);
+void linkedListIterator_remove(LINKED_LIST_ITERATOR iterator);
+void linkedListIterator_set(LINKED_LIST_ITERATOR iterator, void * element);
+void linkedListIterator_add(LINKED_LIST_ITERATOR iterator, void * element);
+
+
+#endif /* LINKED_LIST_ITERATOR_H_ */

Added: incubator/celix/trunk/celix/linked_list_private.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/linked_list_private.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/linked_list_private.h (added)
+++ incubator/celix/trunk/celix/linked_list_private.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,25 @@
+/*
+ * linked_list_private.h
+ *
+ *  Created on: Jul 16, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef LINKED_LIST_PRIVATE_H_
+#define LINKED_LIST_PRIVATE_H_
+
+#include "linkedlist.h"
+
+struct linkedListEntry {
+	void * element;
+	struct linkedListEntry * next;
+	struct linkedListEntry * previous;
+};
+
+struct linkedList {
+	LINKED_LIST_ENTRY header;
+	size_t size;
+	int modificationCount;
+};
+
+#endif /* LINKED_LIST_PRIVATE_H_ */

Added: incubator/celix/trunk/celix/linkedlist.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/linkedlist.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/linkedlist.c (added)
+++ incubator/celix/trunk/celix/linkedlist.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,199 @@
+/*
+ * linkedlist.c
+ *
+ *  Created on: Jul 16, 2010
+ *      Author: alexanderb
+ */
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "linkedlist.h"
+#include "linked_list_private.h"
+
+LINKED_LIST linkedList_create(void) {
+	LINKED_LIST list = (LINKED_LIST) malloc(sizeof(*list));
+	list->header = (LINKED_LIST_ENTRY) malloc(sizeof(*(list->header)));
+	list->header->element = NULL;
+	list->header->next = list->header;
+	list->header->previous = list->header;
+	list->size = 0;
+	list->modificationCount = 0;
+}
+
+void * linkedList_getFirst(LINKED_LIST list) {
+	if (list->size == 0) {
+		return NULL;
+	}
+	return list->header->next->element;
+}
+
+void * linkedList_getLast(LINKED_LIST list) {
+	if (list->size == 0) {
+		return NULL;
+	}
+	return list->header->previous->element;
+}
+
+void * linkedList_removeFirst(LINKED_LIST list) {
+	return linkedList_removeEntry(list, list->header->next);
+}
+
+void * linkedList_removeLast(LINKED_LIST list) {
+	return linkedList_removeEntry(list, list->header->previous);
+}
+
+void linkedList_addFirst(LINKED_LIST list, void * element) {
+	linkedList_addBefore(list, element, list->header->next);
+}
+
+void linkedList_addLast(LINKED_LIST list, void * element) {
+	linkedList_addBefore(list, element, list->header);
+}
+
+bool linkedList_contains(LINKED_LIST list, void * element) {
+	return linkedList_indexOf(list, element) != 0;
+}
+
+int linkedList_size(LINKED_LIST list) {
+	return list->size;
+}
+
+bool linkedList_isEmpty(LINKED_LIST list) {
+	return linkedList_size(list) == 0;
+}
+
+bool linkedList_addElement(LINKED_LIST list, void * element) {
+	linkedList_addBefore(list, element, list->header);
+	return true;
+}
+
+bool linkedList_removeElement(LINKED_LIST list, void * element) {
+	if (element == NULL) {
+		LINKED_LIST_ENTRY entry;
+		for (entry = list->header->next; entry != list->header; entry = entry->next) {
+			if (entry->element == NULL) {
+				linkedList_removeEntry(list, entry);
+				return true;
+			}
+		}
+	} else {
+		LINKED_LIST_ENTRY entry;
+		for (entry = list->header->next; entry != list->header; entry = entry->next) {
+			if (element == entry->element) {
+				linkedList_removeEntry(list, entry);
+				return true;
+			}
+		}
+	}
+	return false;
+}
+
+void linkedList_clear(LINKED_LIST list) {
+	LINKED_LIST_ENTRY entry = list->header->next;
+	while (entry != list->header) {
+		LINKED_LIST_ENTRY next = entry->next;
+		entry->next = entry->previous = NULL;
+		free(entry->element);
+		entry->element = NULL;
+		entry = next;
+	}
+	list->header->next = list->header->previous = list->header;
+	list->size = 0;
+	list->modificationCount++;
+}
+
+void * linkedList_get(LINKED_LIST list, int index) {
+	return linkedList_entry(list, index)->element;
+}
+void * linkedList_set(LINKED_LIST list, int index, void * element) {
+	LINKED_LIST_ENTRY entry = linkedList_entry(list, index);
+	void * old = entry->element;
+	entry->element = element;
+	return old;
+}
+
+void linkedList_addIndex(LINKED_LIST list, int index, void * element) {
+	linkedList_addBefore(list, element, (index == list->size ? list->header : linkedList_entry(list, index)));
+}
+
+void * linkedList_removeIndex(LINKED_LIST list, int index) {
+	return linkedList_removeEntry(list, linkedList_entry(list, index));
+}
+
+LINKED_LIST_ENTRY linkedList_entry(LINKED_LIST list, int index) {
+	if (index < 0 || index >= list->size) {
+		return NULL;
+	}
+
+	LINKED_LIST_ENTRY entry = list->header;
+	int i;
+	if (index < (list->size >> 1)) {
+		for (i = 0; i <= index; i++) {
+			entry = entry->next;
+		}
+	} else {
+		for (i = list->size; i > index; i--) {
+			entry = entry->previous;
+		}
+	}
+	return entry;
+}
+
+int linkedList_indexOf(LINKED_LIST list, void * element) {
+	int index = 0;
+	if (element == NULL) {
+		LINKED_LIST_ENTRY entry;
+		for (entry = list->header->next; entry != list->header; entry = entry->next) {
+			if (entry->element == NULL) {
+				return index;
+			}
+			index++;
+		}
+	} else {
+		LINKED_LIST_ENTRY entry;
+		for (entry = list->header->next; entry != list->header; entry = entry->next) {
+			if (element == entry->element) {
+				return index;
+			}
+			index++;
+		}
+	}
+	return -1;
+}
+
+// int linkedList_lastIndexOf(LINKED_LIST list, void * element);
+
+LINKED_LIST_ENTRY linkedList_addBefore(LINKED_LIST list, void * element, LINKED_LIST_ENTRY entry) {
+	LINKED_LIST_ENTRY new = (LINKED_LIST_ENTRY) malloc(sizeof(*new));
+	new->element = element;
+	new->next = entry;
+	new->previous = entry->previous;
+
+	new->previous->next = new;
+	new->next->previous = new;
+
+	list->size++;
+	list->modificationCount++;
+
+	return new;
+}
+
+void * linkedList_removeEntry(LINKED_LIST list, LINKED_LIST_ENTRY entry) {
+	if (entry == list->header) {
+		return NULL;
+	}
+
+	void * result = entry->element;
+
+	entry->previous->next = entry->next;
+	entry->next->previous = entry->previous;
+
+	entry->next = entry->previous = NULL;
+	free(entry);
+
+	list->size--;
+	list->modificationCount++;
+
+	return result;
+}

Added: incubator/celix/trunk/celix/linkedlist.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/linkedlist.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/linkedlist.h (added)
+++ incubator/celix/trunk/celix/linkedlist.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,39 @@
+/*
+ * linkedlist.h
+ *
+ *  Created on: Jul 16, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef LINKEDLIST_H_
+#define LINKEDLIST_H_
+
+#include <stdbool.h>
+
+typedef struct linkedListEntry * LINKED_LIST_ENTRY;
+typedef struct linkedList * LINKED_LIST;
+
+LINKED_LIST linkedList_create(void);
+void * linkedList_getFirst(LINKED_LIST list);
+void * linkedList_getLast(LINKED_LIST list);
+void * linkedList_removeFirst(LINKED_LIST list);
+void * linkedList_removeLast(LINKED_LIST list);
+void linkedList_addFirst(LINKED_LIST list, void * element);
+void linkedList_addLast(LINKED_LIST list, void * element);
+bool linkedList_contains(LINKED_LIST list, void * element);
+int linkedList_size(LINKED_LIST list);
+bool linkedList_isEmpty(LINKED_LIST list);
+bool linkedList_addElement(LINKED_LIST list, void * element);
+bool linkedList_removeElement(LINKED_LIST list, void * element);
+void linkedList_clear(LINKED_LIST list);
+void * linkedList_get(LINKED_LIST list, int index);
+void * linkedList_set(LINKED_LIST list, int index, void * element);
+void linkedList_addIndex(LINKED_LIST list, int index, void * element);
+void * linkedList_removeIndex(LINKED_LIST list, int index);
+LINKED_LIST_ENTRY linkedList_entry(LINKED_LIST list, int index);
+int linkedList_indexOf(LINKED_LIST list, void * element);
+LINKED_LIST_ENTRY linkedList_addBefore(LINKED_LIST list, void * element, LINKED_LIST_ENTRY entry);
+void * linkedList_removeEntry(LINKED_LIST list, LINKED_LIST_ENTRY entry);
+
+
+#endif /* LINKEDLIST_H_ */

Added: incubator/celix/trunk/celix/manifest.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/manifest.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/manifest.c (added)
+++ incubator/celix/trunk/celix/manifest.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,124 @@
+/*
+ * manifest.c
+ *
+ *  Created on: Jul 5, 2010
+ *      Author: alexanderb
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include "manifest.h"
+
+int fpeek(FILE *stream);
+
+void manifest_clear(MANIFEST manifest) {
+
+}
+
+PROPERTIES manifest_getMainAttributes(MANIFEST manifest) {
+	return manifest->mainAttributes;
+}
+
+MANIFEST manifest_read(char * filename) {
+	MANIFEST mf = (MANIFEST) malloc(sizeof(*mf));
+	PROPERTIES mainAttributes = createProperties();
+
+	mf->mainAttributes = mainAttributes;
+
+	FILE *file = fopen ( filename, "r" );
+	if (file != NULL) {
+		char lbuf [ 512 ];
+		char * lastline;
+		char * name = NULL;
+		char * value = NULL;
+
+		while ( fgets ( lbuf, sizeof lbuf, file ) != NULL ) {
+			bool lineContinued = false;
+			int len = strlen(lbuf);
+
+			if (lbuf[--len] != '\n') {
+				return NULL;
+			}
+
+			if (len > 0 && lbuf[len-1] == '\r') {
+				--len;
+			}
+
+			if (len == 0) {
+				break;
+		    }
+
+			int i = 0;
+			if (lbuf[0] == ' ') {
+				// continuation of previous line
+				if (name == NULL) {
+					return NULL;
+				}
+				lineContinued = true;
+				int newlen = strlen(lastline) + len - 1;
+				char buf [newlen];
+				strcpy(buf, lastline);
+				strncat(buf, lbuf+1, len - 1);
+
+				if (fpeek(file) == ' ') {
+					lastline = strcpy(lastline, buf);
+					continue;
+				}
+				value = (char *) malloc(strlen(buf) + 1);
+				value = strcpy(value, buf);
+				value[strlen(buf)] = '\0';
+				lastline = NULL;
+			} else {
+				while (lbuf[i++] != ':') {
+					if (i >= len) {
+//						throw new IOException("invalid header field");
+						return NULL;
+					}
+				}
+				if (lbuf[i++] != ' ') {
+//					throw new IOException("invalid header field");
+					return NULL;
+				}
+				name = (char *) malloc((i + 1) - 2);
+				name = strncpy(name, lbuf, i - 2);
+				name[i - 2] = '\0';
+				if (fpeek(file) == ' ') {
+					int newlen = len - i;
+					lastline = (char *) malloc(newlen + 1);
+					lastline = strncpy(lastline, lbuf+i, len -i);
+					continue;
+				}
+				value = (char *) malloc((len + 1) - i);
+				value = strncpy(value, lbuf+i, len - i);
+				value[len - i] = '\0';
+			}
+
+			if ((setProperty(mainAttributes, name, value) != NULL) && (!lineContinued)) {
+				printf("Duplicate entry: %s", name);
+			}
+		}
+		fclose(file);
+		return mf;
+	}
+
+	return NULL;
+}
+
+void manifest_write(MANIFEST manifest, char * filename) {
+
+}
+
+char * manifest_getValue(MANIFEST manifest, const char * name) {
+	char * val = getProperty(manifest->mainAttributes, (char *) name);
+	return val;
+}
+
+int fpeek(FILE *stream) {
+	int c;
+	c = fgetc(stream);
+	ungetc(c, stream);
+	return c;
+}
+

Added: incubator/celix/trunk/celix/manifest.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/manifest.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/manifest.h (added)
+++ incubator/celix/trunk/celix/manifest.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,27 @@
+/*
+ * manifest.h
+ *
+ *  Created on: Jul 5, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef MANIFEST_H_
+#define MANIFEST_H_
+
+#include "properties.h"
+
+struct manifest {
+	PROPERTIES mainAttributes;
+};
+
+typedef struct manifest * MANIFEST;
+
+void manifest_clear(MANIFEST manifest);
+PROPERTIES manifest_getMainAttributes(MANIFEST manifest);
+
+MANIFEST manifest_read(char * filename);
+void manifest_write(MANIFEST manifest, char * filename);
+
+char * manifest_getValue(MANIFEST manifest, const char * name);
+
+#endif /* MANIFEST_H_ */

Added: incubator/celix/trunk/celix/manifest_parser.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/manifest_parser.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/manifest_parser.c (added)
+++ incubator/celix/trunk/celix/manifest_parser.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,242 @@
+/*
+ * manifest_parser.c
+ *
+ *  Created on: Jul 12, 2010
+ *      Author: alexanderb
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include "utils.h"
+#include "constants.h"
+#include "manifest_parser.h"
+#include "capability.h"
+#include "requirement.h"
+#include "attribute.h"
+#include "hash_map.h"
+
+MANIFEST_PARSER manifestParser_createManifestParser(MODULE owner, MANIFEST manifest) {
+	MANIFEST_PARSER parser = (MANIFEST_PARSER) malloc(sizeof(*parser));
+	parser->manifest = manifest;
+	parser->owner = owner;
+
+	parser->bundleVersion = version_createEmptyVersion();
+	char * bundleVersion = manifest_getValue(manifest, BUNDLE_VERSION);
+	if (bundleVersion != NULL) {
+		parser->bundleVersion = version_createVersionFromString(bundleVersion);
+	}
+	char * bundleSymbolicName = manifest_getValue(manifest, BUNDLE_SYMBOLICNAME);
+	if (bundleSymbolicName != NULL) {
+		parser->bundleSymbolicName = bundleSymbolicName;
+	}
+
+	parser->capabilities = manifestParser_parseExportHeader(owner, manifest_getValue(manifest, EXPORT_PACKAGE));
+	parser->requirements = manifestParser_parseImportHeader(manifest_getValue(manifest, IMPORT_PACKAGE));
+	return parser;
+}
+
+LINKED_LIST manifestParser_parseDelimitedString(char * value, char * delim) {
+	if (value == NULL) {
+		value = "";
+	}
+
+	LINKED_LIST list = linkedList_create();
+	int CHAR = 1;
+	int DELIMITER = 2;
+	int STARTQUOTE = 4;
+	int ENDQUOTE = 8;
+
+	char * buffer = malloc(sizeof(char) * 512);
+	buffer[0] = '\0';
+
+	int expecting = (CHAR | DELIMITER | STARTQUOTE);
+
+	int i;
+	for (i = 0; i < strlen(value); i++) {
+		char c = value[i];
+
+		bool isDelimiter = (strchr(delim, c) != NULL);
+		bool isQuote = (c == '"');
+
+		if (isDelimiter && ((expecting & DELIMITER) > 0)) {
+			linkedList_addElement(list, strdup(buffer));
+			free(buffer);
+			buffer = malloc(sizeof(char) * 512);
+			buffer[0] = '\0';
+			expecting = (CHAR | DELIMITER | STARTQUOTE);
+		} else if (isQuote && ((expecting & STARTQUOTE) > 0)) {
+			char tmp[2];
+			tmp[0] = c;
+			tmp[1] = '\0';
+			strcat(buffer, tmp);
+			expecting = CHAR | ENDQUOTE;
+		} else if (isQuote && ((expecting & ENDQUOTE) > 0)) {
+			char tmp[2];
+			tmp[0] = c;
+			tmp[1] = '\0';
+			strcat(buffer, tmp);
+			expecting = (CHAR | STARTQUOTE | DELIMITER);
+		} else if ((expecting & CHAR) > 0) {
+			char tmp[2];
+			tmp[0] = c;
+			tmp[1] = '\0';
+			strcat(buffer, tmp);
+		} else {
+			return NULL;
+		}
+	}
+
+	if (strlen(buffer) > 0) {
+		linkedList_addElement(list, strdup(buffer));
+	}
+	free(buffer);
+
+	return list;
+}
+
+LINKED_LIST manifestParser_parseStandardHeaderClause(char * clauseString) {
+	LINKED_LIST pieces = manifestParser_parseDelimitedString(clauseString, ";");
+
+	LINKED_LIST paths = linkedList_create();
+	int pathCount = 0;
+	int pieceIdx;
+	for (pieceIdx = 0; pieceIdx < linkedList_size(pieces); pieceIdx++) {
+		char * piece = linkedList_get(pieces, pieceIdx);
+		if (strchr(piece, '=') != NULL) {
+			break;
+		} else {
+			linkedList_addElement(paths, piece);
+			pathCount++;
+		}
+	}
+
+	if (pathCount == 0) {
+		return NULL;
+	}
+
+	HASH_MAP dirsMap = hashMap_create(string_hash, NULL, string_equals, NULL);
+	HASH_MAP attrsMap = hashMap_create(string_hash, NULL, string_equals, NULL);
+
+	char * sepPtr;
+	char * sep;
+	for (pieceIdx = pathCount; pieceIdx < linkedList_size(pieces); pieceIdx++) {
+		char * DIRECTIVE_SEP = ":=";
+		char * ATTRIBUTE_SEP = "=";
+		char * piece = linkedList_get(pieces, pieceIdx);
+		if ((sepPtr = strstr(piece, DIRECTIVE_SEP)) != NULL) {
+			sep = DIRECTIVE_SEP;
+		} else if ((sepPtr = strstr(piece, ATTRIBUTE_SEP)) != NULL) {
+			sep = ATTRIBUTE_SEP;
+		} else {
+			return NULL;
+		}
+
+		char * key = string_ndup(piece, sepPtr - piece);
+		char * value = strdup(sepPtr+strlen(sep));
+
+		if (value[0] == '"' && value[strlen(value) -1] == '"') {
+			char * oldV = strdup(value);
+			free(value);
+			int len = strlen(oldV) - 2;
+			value = (char *) malloc(sizeof(char) * len+1);
+			value[0] = '\0';
+			value = strncpy(value, oldV+1, strlen(oldV) - 2);
+			value[len] = '\0';
+		}
+
+		if (strcmp(sep, DIRECTIVE_SEP) == 0) {
+			// Not implemented
+		} else {
+			if (hashMap_containsKey(attrsMap, key)) {
+				return NULL;
+			}
+			ATTRIBUTE attr = attribute_create(key, value);
+			hashMap_put(attrsMap, key, attr);
+		}
+	}
+
+	LINKED_LIST clause = linkedList_create();
+	linkedList_addElement(clause, paths);
+	linkedList_addElement(clause, dirsMap);
+	linkedList_addElement(clause, attrsMap);
+
+	return clause;
+}
+
+LINKED_LIST manifestParser_parseStandardHeader(char * header) {
+	LINKED_LIST completeList = linkedList_create();
+	if (header != NULL) {
+		if (strlen(header) == 0) {
+			return NULL;
+		}
+
+		LINKED_LIST clauseStrings = manifestParser_parseDelimitedString(header, ",");
+		int i;
+	  	for (i = 0; (clauseStrings != NULL) && (i < linkedList_size(clauseStrings)); i++) {
+	  		char * clauseString = (char *) linkedList_get(clauseStrings, i);
+	  		linkedList_addElement(completeList, manifestParser_parseStandardHeaderClause(clauseString));
+		}
+	  	return completeList;
+	}
+	return completeList;
+}
+
+LINKED_LIST manifestParser_parseImportHeader(char * header) {
+	LINKED_LIST clauses = manifestParser_parseStandardHeader(header);
+	LINKED_LIST requirements = linkedList_create();
+
+	int clauseIdx;
+	for (clauseIdx = 0; clauseIdx < linkedList_size(clauses); clauseIdx++) {
+		LINKED_LIST clause = linkedList_get(clauses, clauseIdx);
+
+		LINKED_LIST paths = linkedList_get(clause, 0);
+		HASH_MAP directives = linkedList_get(clause, 1);
+		HASH_MAP attributes = linkedList_get(clause, 2);
+
+		int pathIdx;
+		for (pathIdx = 0; pathIdx < linkedList_size(paths); pathIdx++) {
+			char * path = (char *) linkedList_get(paths, pathIdx);
+			if (strlen(path) == 0) {
+				return NULL;
+			}
+
+			ATTRIBUTE name = attribute_create(strdup("service"), path);
+			hashMap_put(attributes, name->key, name);
+
+			REQUIREMENT req = requirement_create(directives, attributes);
+			linkedList_addElement(requirements, req);
+		}
+	}
+
+	return requirements;
+}
+
+LINKED_LIST manifestParser_parseExportHeader(MODULE module, char * header) {
+	LINKED_LIST clauses = manifestParser_parseStandardHeader(header);
+	LINKED_LIST capabilities = linkedList_create();
+
+	int clauseIdx;
+	for (clauseIdx = 0; clauseIdx < linkedList_size(clauses); clauseIdx++) {
+		LINKED_LIST clause = linkedList_get(clauses, clauseIdx);
+
+		LINKED_LIST paths = linkedList_get(clause, 0);
+		HASH_MAP directives = linkedList_get(clause, 1);
+		HASH_MAP attributes = linkedList_get(clause, 2);
+
+		int pathIdx;
+		for (pathIdx = 0; pathIdx < linkedList_size(paths); pathIdx++) {
+			char * path = (char *) linkedList_get(paths, pathIdx);
+			if (strlen(path) == 0) {
+				return NULL;
+			}
+
+			ATTRIBUTE name = attribute_create(strdup("service"), path);
+			hashMap_put(attributes, name->key, name);
+
+			CAPABILITY cap = capability_create(module, directives, attributes);
+			linkedList_addElement(capabilities, cap);
+		}
+	}
+
+	return capabilities;
+}

Added: incubator/celix/trunk/celix/manifest_parser.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/manifest_parser.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/manifest_parser.h (added)
+++ incubator/celix/trunk/celix/manifest_parser.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,36 @@
+/*
+ * manifest_parser.h
+ *
+ *  Created on: Jul 13, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef MANIFEST_PARSER_H_
+#define MANIFEST_PARSER_H_
+
+#include "module.h"
+#include "version.h"
+#include "manifest.h"
+#include "linkedlist.h"
+
+struct manifestParser {
+	MODULE owner;
+	MANIFEST manifest;
+
+	VERSION bundleVersion;
+	char * bundleSymbolicName;
+	LINKED_LIST capabilities;
+	LINKED_LIST requirements;
+};
+
+typedef struct manifestParser * MANIFEST_PARSER;
+
+MANIFEST_PARSER manifestParser_createManifestParser(MODULE owner, MANIFEST manifest);
+
+LINKED_LIST manifestParser_parseImportHeader(char * header);
+LINKED_LIST manifestParser_parseExportHeader(MODULE module, char * header);
+LINKED_LIST manifestParser_parseDelimitedString(char * value, char * delim);
+LINKED_LIST manifestParser_parseStandardHeaderClause(char * clauseString);
+LINKED_LIST manifestParser_parseStandardHeader(char * header);
+
+#endif /* MANIFEST_PARSER_H_ */

Added: incubator/celix/trunk/celix/miniunz.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/miniunz.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/miniunz.c (added)
+++ incubator/celix/trunk/celix/miniunz.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,372 @@
+/*
+   miniunz.c
+   Version 1.1, February 14h, 2010
+   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+#ifndef _WIN32
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <unistd.h>
+#include <utime.h>
+
+#include "unzip.h"
+#include "archive.h"
+
+#define CASESENSITIVITY (0)
+#define WRITEBUFFERSIZE (8192)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+#define USEWIN32IOAPI
+#include "iowin32.h"
+#endif
+/*
+  mini unzip, demo of unzip package
+
+  usage :
+  Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
+
+  list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
+    if it exists
+*/
+
+
+/* change_file_date : change the date/time of a file
+    filename : the filename of the file where date/time must be modified
+    dosdate : the new date at the MSDos format (4 bytes)
+    tmu_date : the SAME new date at the tm_unz format */
+void change_file_date(filename,dosdate,tmu_date)
+    const char *filename;
+    uLong dosdate;
+    tm_unz tmu_date;
+{
+#ifdef _WIN32
+  HANDLE hFile;
+  FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
+
+  hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
+                      0,NULL,OPEN_EXISTING,0,NULL);
+  GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
+  DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
+  LocalFileTimeToFileTime(&ftLocal,&ftm);
+  SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
+  CloseHandle(hFile);
+#else
+#ifdef unix || __APPLE__
+  struct utimbuf ut;
+  struct tm newdate;
+  newdate.tm_sec = tmu_date.tm_sec;
+  newdate.tm_min=tmu_date.tm_min;
+  newdate.tm_hour=tmu_date.tm_hour;
+  newdate.tm_mday=tmu_date.tm_mday;
+  newdate.tm_mon=tmu_date.tm_mon;
+  if (tmu_date.tm_year > 1900)
+      newdate.tm_year=tmu_date.tm_year - 1900;
+  else
+      newdate.tm_year=tmu_date.tm_year ;
+  newdate.tm_isdst=-1;
+
+  ut.actime=ut.modtime=mktime(&newdate);
+  utime(filename,&ut);
+#endif
+#endif
+}
+
+
+/* mymkdir and change_file_date are not 100 % portable
+   As I don't know well Unix, I wait feedback for the unix portion */
+
+int mymkdir(dirname)
+    const char* dirname;
+{
+    int ret=0;
+#ifdef _WIN32
+    ret = _mkdir(dirname);
+#else
+#if defined unix || defined __APPLE__
+    ret = mkdir (dirname,0775);
+#endif
+#endif
+    return ret;
+}
+
+int makedir (newdir)
+    char *newdir;
+{
+  char *buffer ;
+  char *p;
+  int  len = (int)strlen(newdir);
+
+  if (len <= 0)
+    return 0;
+
+  buffer = (char*)malloc(len+1);
+        if (buffer==NULL)
+        {
+                printf("Error allocating memory\n");
+                return UNZ_INTERNALERROR;
+        }
+  strcpy(buffer,newdir);
+
+  if (buffer[len-1] == '/') {
+    buffer[len-1] = '\0';
+  }
+  if (mymkdir(buffer) == 0)
+    {
+      free(buffer);
+      return 1;
+    }
+
+  p = buffer+1;
+  while (1)
+    {
+      char hold;
+
+      while(*p && *p != '\\' && *p != '/')
+        p++;
+      hold = *p;
+      *p = 0;
+      if ((mymkdir(buffer) == -1) && (errno == ENOENT))
+        {
+          printf("couldn't create directory %s\n",buffer);
+          free(buffer);
+          return 0;
+        }
+      if (hold == 0)
+        break;
+      *p++ = hold;
+    }
+  free(buffer);
+  return 1;
+}
+
+int do_extract_currentfile(unzFile uf, char * revisionRoot) {
+    char filename_inzip[256];
+    char* filename_withoutpath;
+    char* p;
+    int err=UNZ_OK;
+    FILE *fout=NULL;
+    void* buf;
+    uInt size_buf;
+
+    unz_file_info64 file_info;
+    err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+    if (err!=UNZ_OK)
+    {
+        printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+        return err;
+    }
+
+    size_buf = WRITEBUFFERSIZE;
+    buf = (void*)malloc(size_buf);
+    if (buf==NULL)
+    {
+        printf("Error allocating memory\n");
+        return UNZ_INTERNALERROR;
+    }
+
+    p = filename_withoutpath = filename_inzip;
+    while ((*p) != '\0')
+    {
+        if (((*p)=='/') || ((*p)=='\\'))
+            filename_withoutpath = p+1;
+        p++;
+    }
+
+    if ((*filename_withoutpath)=='\0') {
+		printf("creating directory: %s\n",filename_inzip);
+		char dir[strlen(revisionRoot) + strlen(filename_inzip) + 2];
+		strcpy(dir, revisionRoot);
+		strcat(dir, "/");
+		strcat(dir, filename_inzip);
+		mymkdir(dir);
+    }
+    else
+    {
+        const char* write_filename;
+        int skip=0;
+        write_filename = filename_inzip;
+
+        int length = strlen(write_filename) + strlen(revisionRoot) + 2;
+        char fWFN[length];
+        strcpy(fWFN, revisionRoot);
+        strcat(fWFN, "/");
+        strcat(fWFN, write_filename);
+
+        err = unzOpenCurrentFile(uf);
+        if (err!=UNZ_OK)
+        {
+            printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
+        }
+
+        if ((skip==0) && (err==UNZ_OK))
+        {
+            fout=fopen64(fWFN,"wb");
+
+            /* some zipfile don't contain directory alone before file */
+            if ((fout==NULL) && (filename_withoutpath!=(char*)filename_inzip))
+            {
+                char c=*(filename_withoutpath-1);
+                *(filename_withoutpath-1)='\0';
+                int length = strlen(write_filename) + strlen(revisionRoot) + 2;
+                char dir[length];
+				strcpy(dir, revisionRoot);
+				strcat(dir, "/");
+				strcat(dir, write_filename);
+                makedir(dir);
+                *(filename_withoutpath-1)=c;
+
+                fout=fopen64(fWFN,"wb");
+            }
+
+            if (fout==NULL)
+            {
+                printf("error opening %s\n",write_filename);
+            }
+        }
+
+        if (fout!=NULL)
+        {
+            do
+            {
+                err = unzReadCurrentFile(uf,buf,size_buf);
+                if (err<0)
+                {
+                    printf("error %d with zipfile in unzReadCurrentFile\n",err);
+                    break;
+                }
+                if (err>0)
+                    if (fwrite(buf,err,1,fout)!=1)
+                    {
+                        printf("error in writing extracted file\n");
+                        err=UNZ_ERRNO;
+                        break;
+                    }
+            }
+            while (err>0);
+            if (fout)
+                    fclose(fout);
+
+            if (err==0)
+                change_file_date(fWFN,file_info.dosDate,
+                                 file_info.tmu_date);
+        }
+
+        if (err==UNZ_OK)
+        {
+            err = unzCloseCurrentFile (uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzCloseCurrentFile\n",err);
+            }
+        }
+        else
+            unzCloseCurrentFile(uf); /* don't lose the error */
+    }
+
+    free(buf);
+    return err;
+}
+
+
+int do_extract(unzFile uf, char * revisionRoot) {
+    uLong i;
+    unz_global_info64 gi;
+    int err;
+
+    err = unzGetGlobalInfo64(uf,&gi);
+    if (err!=UNZ_OK)
+        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+
+    for (i=0;i<gi.number_entry;i++)
+    {
+        if (do_extract_currentfile(uf, revisionRoot) != UNZ_OK)
+            break;
+
+        if ((i+1)<gi.number_entry)
+        {
+            err = unzGoToNextFile(uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzGoToNextFile\n",err);
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int extractBundle(char * bundleName, char * revisionRoot) {
+    char filename_try[MAXFILENAME+16] = "";
+    int ret_value=0;
+    unzFile uf=NULL;
+
+    if (bundleName!=NULL)
+    {
+
+#        ifdef USEWIN32IOAPI
+        zlib_filefunc64_def ffunc;
+#        endif
+
+        strncpy(filename_try, bundleName,MAXFILENAME-1);
+        /* strncpy doesnt append the trailing NULL, of the string is too long. */
+        filename_try[ MAXFILENAME ] = '\0';
+
+#        ifdef USEWIN32IOAPI
+        fill_win32_filefunc64A(&ffunc);
+        uf = unzOpen2_64(bundleName,&ffunc);
+#        else
+        uf = unzOpen64(bundleName);
+#        endif
+        if (uf==NULL)
+        {
+            strcat(filename_try,".zip");
+#            ifdef USEWIN32IOAPI
+            uf = unzOpen2_64(filename_try,&ffunc);
+#            else
+            uf = unzOpen64(filename_try);
+#            endif
+        }
+    }
+
+    if (uf==NULL)
+    {
+        printf("Cannot open %s or %s.zip\n",bundleName,bundleName);
+        return 1;
+    }
+    ret_value = do_extract(uf, revisionRoot);
+
+    unzClose(uf);
+
+    return ret_value;
+}

Added: incubator/celix/trunk/celix/module.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/module.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/module.c (added)
+++ incubator/celix/trunk/celix/module.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,110 @@
+/*
+ * module.c
+ *
+ *  Created on: Jul 19, 2010
+ *      Author: alexanderb
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "module.h"
+#include "manifest_parser.h"
+#include "linked_list_iterator.h"
+#include "capability.h"
+#include "wire.h"
+
+struct module {
+	LINKED_LIST capabilities;
+	LINKED_LIST requirements;
+	LINKED_LIST wires;
+
+	VERSION version;
+	char * symbolicName;
+	bool resolved;
+
+	MANIFEST headerMap;
+	char * id;
+
+	struct bundle * bundle;
+};
+
+MODULE module_create(MANIFEST headerMap, char * moduleId, BUNDLE bundle) {
+	MODULE module = (MODULE) malloc(sizeof(*module));
+	module->headerMap = headerMap;
+	module->id = moduleId;
+	module->bundle = bundle;
+
+	MANIFEST_PARSER mp = manifestParser_createManifestParser(module, headerMap);
+	module->symbolicName = mp->bundleSymbolicName;
+	module->version = mp->bundleVersion;
+	module->capabilities = mp->capabilities;
+	module->requirements = mp->requirements;
+
+	module->wires = NULL;
+
+	return module;
+}
+
+MODULE module_createFrameworkModule() {
+	MODULE module = (MODULE) malloc(sizeof(*module));
+	module->id = "0";
+	module->symbolicName = strdup("framework");
+	module->version = version_createVersion(1, 0, 0, "");
+	module->capabilities = linkedList_create();
+	module->requirements = linkedList_create();
+	return module;
+}
+
+WIRE module_getWire(MODULE module, char * serviceName) {
+	if (module->wires != NULL) {
+		LINKED_LIST_ITERATOR iterator = linkedListIterator_create(module->wires, 0);
+		while (linkedListIterator_hasNext(iterator)) {
+			WIRE wire = linkedListIterator_next(iterator);
+			if (strcasecmp(capability_getServiceName(wire_getCapability(wire)), serviceName) == 0) {
+				return wire;
+			}
+		}
+	}
+	return NULL;
+}
+
+VERSION module_getVersion(MODULE module) {
+	return module->version;
+}
+
+char * module_getSymbolicName(MODULE module) {
+	return module->symbolicName;
+}
+
+char * module_getId(MODULE module) {
+	return module->id;
+}
+
+LINKED_LIST module_getWires(MODULE module) {
+	return module->wires;
+}
+
+void module_setWires(MODULE module, LINKED_LIST wires) {
+	module->wires = wires;
+}
+
+bool module_isResolved(MODULE module) {
+	return module->resolved;
+}
+
+void module_setResolved(MODULE module) {
+	module->resolved = true;
+}
+
+BUNDLE module_getBundle(MODULE module) {
+	return module->bundle;
+}
+
+LINKED_LIST module_getRequirements(MODULE module) {
+	return module->requirements;
+}
+
+LINKED_LIST module_getCapabilities(MODULE module) {
+	return module->capabilities;
+}

Added: incubator/celix/trunk/celix/module.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/module.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/module.h (added)
+++ incubator/celix/trunk/celix/module.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,37 @@
+/*
+ * module.h
+ *
+ *  Created on: Jul 12, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef MODULE_H_
+#define MODULE_H_
+
+#include <stdbool.h>
+
+#include "linkedlist.h"
+#include "headers.h"
+#include "manifest.h"
+
+MODULE module_create(MANIFEST headerMap, char * moduleId, BUNDLE bundle);
+MODULE module_createFrameworkModule();
+
+unsigned int module_hash(void * module);
+int module_equals(void * module, void * compare);
+
+WIRE module_getWire(MODULE module, char * serviceName);
+
+VERSION module_getVersion(MODULE module);
+char * module_getSymbolicName(MODULE module);
+char * module_getId(MODULE module);
+LINKED_LIST module_getWires(MODULE module);
+void module_setWires(MODULE module, LINKED_LIST wires);
+bool module_isResolved(MODULE module);
+void module_setResolved(MODULE module);
+BUNDLE module_getBundle(MODULE module);
+
+LINKED_LIST module_getRequirements(MODULE module);
+LINKED_LIST module_getCapabilities(MODULE module);
+
+#endif /* MODULE_H_ */

Added: incubator/celix/trunk/celix/properties.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/properties.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/properties.c (added)
+++ incubator/celix/trunk/celix/properties.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,150 @@
+/*
+ * properties.c
+ *
+ *  Created on: Apr 27, 2010
+ *      Author: dk489
+ */
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include "properties.h"
+#include "hashtable_itr.h"
+#include "utils.h"
+
+DEFINE_HASHTABLE_INSERT(prop_insert, struct key, struct value);
+DEFINE_HASHTABLE_REMOVE(prop_remove, struct key, struct value);
+DEFINE_HASHTABLE_SEARCH(prop_search, struct key, struct value);
+
+static unsigned int hashfromkey(void * ks) {
+	struct key *k = (struct key *) ks;
+	unsigned long hash = 5381;
+	int i;
+	char * ck = strdup(k->key);
+	for (i=0; i<strlen(ck); ++i) hash = 33*hash + ck[i];
+	//int c;
+	//while (c = *ck++) {
+	//	hash = ((hash << 5) + hash) + c;
+	//}
+	free(ck);
+	return hash;
+}
+
+static int equalskey(void * k1, void * k2) {
+	struct key * key1 = (struct key *) k1;
+	struct key * key2 = (struct key *) k2;
+	return (strcmp(key1->key, key2->key) == 0);
+}
+
+char * addEntry(HASHTABLE properties, char * k, char * v);
+char * addEntry(HASHTABLE properties, char * k, char * v) {
+	struct key * search_key = (struct key *) malloc(sizeof(*search_key));
+	struct key * s_key = (struct key *) malloc(sizeof(*s_key));
+	struct value * s_value = (struct value *) malloc(sizeof(*s_value));
+	struct value * oldValue = NULL;
+	s_key->key = k;
+	search_key->key = k;
+	s_value->value = v;
+	oldValue = prop_search(properties, search_key);
+	if (oldValue != NULL) {
+		prop_remove(properties, search_key);
+	}
+	free(search_key);
+	prop_insert(properties, s_key, s_value);
+
+	return oldValue == NULL ? NULL : oldValue->value;
+}
+
+HASHTABLE createProperties(void) {
+	return create_hashtable(1, hashfromkey, equalskey);
+}
+
+HASHTABLE loadProperties(char * filename) {
+	HASHTABLE props = create_hashtable(1, hashfromkey, equalskey);
+	FILE *file = fopen ( filename, "r" );
+
+	char * cont = strdup("\\");
+
+	if (file != NULL) {
+		char line [ 1024 ];
+		char * key = NULL;
+		char * value = NULL;
+		int split = 0;
+
+		while ( fgets ( line, sizeof line, file ) != NULL ) {
+			if (!split) {
+				unsigned int pos = strcspn(line, "=");
+				if (pos != strlen(line)) {
+					key = string_trim(string_ndup((char *)line, pos));
+					value = string_trim(string_ndup(line+pos+1, strlen(line)));
+					if (value != NULL) {
+						if (strcmp(cont, string_ndup(value+strlen(value)-1, 1)) == 0) {
+							split = 1;
+							value = string_ndup(value, strlen(value)-1);
+						} else {
+							char * old = addEntry(props, key, value);
+						}
+					}
+				}
+			} else {
+				if (strcmp(cont, string_ndup(line+strlen(line)-1, 1)) == 0) {
+					split = 1;
+					strcat(value, string_ndup(line, strlen(line)-1));
+				} else {
+					split = 0;
+					strcat(value, string_trim(line));
+					char * old = addEntry(props, key, value);
+				}
+			}
+		}
+		fclose(file);
+		return props;
+	}
+	free(cont);
+	return NULL;
+}
+
+/**
+ * Header is ignored for now, cannot handle comments yet
+ */
+void storeProperties(HASHTABLE properties, char * filename, char * header) {
+	FILE *file = fopen ( filename, "w+" );
+	if (file != NULL) {
+		if (hashtable_count(properties) > 0)
+		{
+			struct hashtable_itr * itr = hashtable_iterator(properties);
+			do {
+				char * line = NULL;
+				struct key * k = hashtable_iterator_key(itr);
+				struct value * v = hashtable_iterator_value(itr);
+
+				line = strdup(k->key);
+				strcat(line, "=");
+				strcat(line, strdup(v->value));
+				strcat(line, "\n");
+				fputs(line, file);
+			} while (hashtable_iterator_advance(itr));
+			free(itr);
+		}
+		fclose(file);
+	} else {
+		perror("File is null");
+	}
+}
+
+char * getProperty(HASHTABLE properties, char * key) {
+	struct key * s_key = (struct key *) malloc(sizeof(struct key));
+	s_key->key = key;
+	struct value * value = prop_search(properties, s_key);
+	free(s_key);
+	return value == NULL ? NULL : value->value;
+}
+
+char * getPropertyWithDefault(HASHTABLE properties, char * key, char * defaultValue) {
+	char * value = getProperty(properties, key);
+	return value == NULL ? defaultValue : value;
+}
+
+char * setProperty(HASHTABLE properties, char * key, char * value) {
+	return addEntry(properties, key, value);
+}

Added: incubator/celix/trunk/celix/properties.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/properties.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/properties.h (added)
+++ incubator/celix/trunk/celix/properties.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,34 @@
+/*
+ * properties.h
+ *
+ *  Created on: Apr 27, 2010
+ *      Author: dk489
+ */
+
+#ifndef PROPERTIES_H_
+#define PROPERTIES_H_
+
+#include "hashtable.h"
+
+struct key {
+	char * key;
+};
+
+struct value {
+	char * value;
+};
+
+typedef struct hashtable * HASHTABLE;
+typedef struct hashtable * PROPERTIES;
+
+typedef struct entry * ENTRY;
+
+HASHTABLE createProperties(void);
+HASHTABLE loadProperties(char * filename);
+void storeProperties(HASHTABLE properties, char * file, char * header);
+
+char * getProperty(HASHTABLE properties, char * key);
+char * getPropertyWithDefault(HASHTABLE properties, char * key, char * defaultValue);
+char * setProperty(HASHTABLE properties, char * key, char * value);
+
+#endif /* PROPERTIES_H_ */

Added: incubator/celix/trunk/celix/requirement.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/requirement.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/requirement.c (added)
+++ incubator/celix/trunk/celix/requirement.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,47 @@
+/*
+ * requirement.c
+ *
+ *  Created on: Jul 12, 2010
+ *      Author: alexanderb
+ */
+#include <stdlib.h>
+
+#include "requirement.h"
+#include "version_range.h"
+#include "attribute.h"
+
+struct requirement {
+	char * targetName;
+	VERSION_RANGE versionRange;
+	HASH_MAP attributes;
+	HASH_MAP directives;
+};
+
+REQUIREMENT requirement_create(HASH_MAP directives, HASH_MAP attributes) {
+	REQUIREMENT requirement = (REQUIREMENT) malloc(sizeof(*requirement));
+
+	requirement->attributes = attributes;
+	requirement->directives = directives;
+
+	requirement->versionRange = versionRange_createInfiniteVersionRange();
+	ATTRIBUTE versionAttribute = (ATTRIBUTE) hashMap_get(attributes, "version");
+	if (versionAttribute != NULL) {
+		requirement->versionRange = versionRange_parse(versionAttribute->value);
+	}
+	ATTRIBUTE serviceAttribute = (ATTRIBUTE) hashMap_get(attributes, "service");
+	requirement->targetName = serviceAttribute->value;
+
+	return requirement;
+}
+
+VERSION_RANGE requirement_getVersionRange(REQUIREMENT requirement) {
+	return requirement->versionRange;
+}
+
+char * requirement_getTargetName(REQUIREMENT requirement) {
+	return requirement->targetName;
+}
+
+bool requirement_isSatisfied(REQUIREMENT requirement, CAPABILITY capability) {
+	versionRange_isInRange(requirement_getVersionRange(requirement), capability_getVersion(capability));
+}

Added: incubator/celix/trunk/celix/requirement.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/requirement.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/requirement.h (added)
+++ incubator/celix/trunk/celix/requirement.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,21 @@
+/*
+ * requirement.h
+ *
+ *  Created on: Jul 12, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef REQUIREMENT_H_
+#define REQUIREMENT_H_
+
+#include "capability.h"
+#include "hash_map.h"
+#include "headers.h"
+
+REQUIREMENT requirement_create(HASH_MAP directives, HASH_MAP attributes);
+VERSION_RANGE requirement_getVersionRange(REQUIREMENT requirement);
+char * requirement_getTargetName(REQUIREMENT requirement);
+
+bool requirement_isSatisfied(REQUIREMENT requirement, CAPABILITY capability);
+
+#endif /* REQUIREMENT_H_ */

Added: incubator/celix/trunk/celix/resolver.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/resolver.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/resolver.c (added)
+++ incubator/celix/trunk/celix/resolver.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,268 @@
+/*
+ * resolver.c
+ *
+ *  Created on: Jul 13, 2010
+ *      Author: alexanderb
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "resolver.h"
+#include "linked_list_iterator.h"
+
+struct capabilityList {
+	char * serviceName;
+	LINKED_LIST capabilities;
+};
+
+typedef struct capabilityList * CAPABILITY_LIST;
+
+struct candidateSet {
+	MODULE module;
+	REQUIREMENT requirement;
+	LINKED_LIST candidates;
+};
+
+typedef struct candidateSet * CANDIDATE_SET;
+
+// List containing MODULEs
+LINKED_LIST m_modules = NULL;
+// List containing CAPABILITY_LISTs
+LINKED_LIST m_unresolvedServices = NULL;
+// List containing CAPABILITY_LISTs
+LINKED_LIST m_resolvedServices = NULL;
+
+int resolver_populateCandidatesMap(HASH_MAP candidatesMap, MODULE targetModule);
+CAPABILITY_LIST resolver_getCapabilityList(LINKED_LIST list, char * name);
+void resolver_removeInvalidCandidate(MODULE module, HASH_MAP candidates, LINKED_LIST invalid);
+HASH_MAP resolver_populateWireMap(HASH_MAP candidates, MODULE importer, HASH_MAP wireMap);
+
+HASH_MAP resolver_resolve(MODULE root) {
+	if (module_isResolved(root)) {
+		return NULL;
+	}
+
+	HASH_MAP candidatesMap = hashMap_create(NULL, NULL, NULL, NULL);
+
+	if (resolver_populateCandidatesMap(candidatesMap, root) != 0) {
+		return NULL;
+	}
+
+	HASH_MAP wireMap = hashMap_create(NULL,NULL,NULL,NULL);
+	return resolver_populateWireMap(candidatesMap, root, wireMap);
+}
+
+int resolver_populateCandidatesMap(HASH_MAP candidatesMap, MODULE targetModule) {
+	if (hashMap_containsKey(candidatesMap, targetModule)) {
+		return 0;
+	}
+
+	hashMap_put(candidatesMap, targetModule, NULL);
+
+	LINKED_LIST candSetList = linkedList_create();
+
+	int i = 0;
+	for (i = 0; i < linkedList_size(module_getRequirements(targetModule)); i++) {
+		REQUIREMENT req = (REQUIREMENT) linkedList_get(module_getRequirements(targetModule), i);
+		CAPABILITY_LIST capList = resolver_getCapabilityList(m_resolvedServices, requirement_getTargetName(req));
+
+		LINKED_LIST candidates = linkedList_create();
+
+		int c;
+		for (c = 0; (capList != NULL) && (c < linkedList_size(capList->capabilities)); c++) {
+			CAPABILITY cap = (CAPABILITY) linkedList_get(capList->capabilities, c);
+			if (requirement_isSatisfied(req, cap)) {
+				linkedList_addElement(candidates, cap);
+			}
+		}
+		capList = resolver_getCapabilityList(m_unresolvedServices, requirement_getTargetName(req));
+		for (c = 0; (capList != NULL) && (c < linkedList_size(capList->capabilities)); c++) {
+			CAPABILITY cap = (CAPABILITY) linkedList_get(capList->capabilities, c);
+			if (requirement_isSatisfied(req, cap)) {
+				linkedList_addElement(candidates, cap);
+			}
+		}
+
+		if (linkedList_size(candidates) > 0) {
+			LINKED_LIST_ITERATOR iterator;
+			for (iterator = linkedListIterator_create(candidates, 0); linkedListIterator_hasNext(iterator); ) {
+				CAPABILITY candidate = (CAPABILITY) linkedListIterator_next(iterator);
+				if (!module_isResolved(capability_getModule(candidate))) {
+					if (resolver_populateCandidatesMap(candidatesMap, capability_getModule(candidate)) != 0) {
+						linkedListIterator_remove(iterator);
+					}
+				}
+			}
+		}
+
+		if (linkedList_size(candidates) == 0) {
+			LINKED_LIST invalid = linkedList_create();
+			resolver_removeInvalidCandidate(targetModule, candidatesMap, invalid);
+			printf("Unable to resolve: %s, %s\n", module_getSymbolicName(targetModule), requirement_getTargetName(req));
+			return -1;
+		} else if (linkedList_size(candidates) > 0) {
+			CANDIDATE_SET cs = (CANDIDATE_SET) malloc(sizeof(*cs));
+			cs->candidates = candidates;
+			cs->module = targetModule;
+			cs->requirement = req;
+			linkedList_addElement(candSetList, cs);
+		}
+
+	}
+	hashMap_put(candidatesMap, targetModule, candSetList);
+	return 0;
+}
+
+void resolver_removeInvalidCandidate(MODULE invalidModule, HASH_MAP candidates, LINKED_LIST invalid) {
+	hashMap_remove(candidates, invalidModule);
+
+	HASH_MAP_ITERATOR iterator;
+	for (iterator = hashMapIterator_create(candidates); hashMapIterator_hasNext(iterator); ) {
+		HASH_MAP_ENTRY entry = hashMapIterator_nextEntry(iterator);
+		MODULE module = (MODULE) hashMapEntry_getKey(entry);
+		LINKED_LIST candSetList = (LINKED_LIST) hashMapEntry_getValue(entry);
+		if (candSetList != NULL) {
+			LINKED_LIST_ITERATOR itCandSetList;
+			for (itCandSetList = linkedListIterator_create(candSetList, 0); linkedListIterator_hasNext(itCandSetList); ) {
+				CANDIDATE_SET set = (CANDIDATE_SET) linkedListIterator_next(itCandSetList);
+				LINKED_LIST_ITERATOR candIter;
+				for (candIter = linkedListIterator_create(set->candidates, 0); linkedListIterator_hasNext(candIter); ) {
+					CAPABILITY candCap = (CAPABILITY) linkedListIterator_next(candIter);
+					if (capability_getModule(candCap) == invalidModule) {
+						linkedListIterator_remove(candIter);
+						if (linkedList_size(set->candidates) == 0) {
+							linkedListIterator_remove(itCandSetList);
+							if (module != invalidModule && linkedList_contains(invalid, module)) {
+								linkedList_addElement(invalid, module);
+							}
+						}
+						break;
+					}
+				}
+			}
+		}
+	}
+	free(iterator);
+
+	if (linkedList_size(invalid) > 0) {
+		while (!linkedList_isEmpty(invalid)) {
+			MODULE m = (MODULE) linkedList_removeIndex(invalid, 0);
+			resolver_removeInvalidCandidate(m, candidates, invalid);
+		}
+	}
+}
+
+void resolver_addModule(MODULE module) {
+	if (m_modules == NULL) {
+		m_modules = linkedList_create();
+		m_unresolvedServices = linkedList_create();
+		m_resolvedServices = linkedList_create();
+	}
+	linkedList_addElement(m_modules, module);
+
+	int i = 0;
+	for (i = 0; i < linkedList_size(module_getCapabilities(module)); i++) {
+		CAPABILITY cap = (CAPABILITY) linkedList_get(module_getCapabilities(module), i);
+		CAPABILITY_LIST list = resolver_getCapabilityList(m_unresolvedServices, capability_getServiceName(cap));
+		if (list == NULL) {
+			list = (CAPABILITY_LIST) malloc(sizeof(*list));
+			list->serviceName = strdup(capability_getServiceName(cap));
+			list->capabilities = linkedList_create();
+
+			linkedList_addElement(m_unresolvedServices, list);
+		}
+		linkedList_addElement(list->capabilities, cap);
+	}
+}
+
+void resolver_moduleResolved(MODULE module) {
+	if (module_isResolved(module)) {
+		int capIdx;
+		LINKED_LIST capsCopy = linkedList_create();
+		for (capIdx = 0; (module_getCapabilities(module) != NULL) && (capIdx < linkedList_size(module_getCapabilities(module))); capIdx++) {
+			CAPABILITY cap = (CAPABILITY) linkedList_get(module_getCapabilities(module), capIdx);
+			CAPABILITY_LIST list = resolver_getCapabilityList(m_unresolvedServices, capability_getServiceName(cap));
+			linkedList_removeElement(list->capabilities, cap);
+
+			linkedList_addElement(capsCopy, cap);
+		}
+
+		LINKED_LIST wires = module_getWires(module);
+		for (capIdx = 0; (capsCopy != NULL) && (capIdx < linkedList_size(capsCopy)); capIdx++) {
+			CAPABILITY cap = linkedList_get(capsCopy, capIdx);
+
+			int wireIdx = 0;
+			for (wireIdx = 0; (wires != NULL) && (wireIdx < linkedList_size(wires)); wireIdx++) {
+				WIRE wire = (WIRE) linkedList_get(wires, wireIdx);
+
+				if (requirement_isSatisfied(wire_getRequirement(wire), cap)) {
+					linkedList_set(capsCopy, capIdx, NULL);
+					break;
+				}
+			}
+		}
+
+		for (capIdx = 0; (capsCopy != NULL) && (capIdx < linkedList_size(capsCopy)); capIdx++) {
+			CAPABILITY cap = linkedList_get(capsCopy, capIdx);
+
+			if (cap != NULL) {
+				CAPABILITY_LIST list = resolver_getCapabilityList(m_resolvedServices, capability_getServiceName(cap));
+				if (list == NULL) {
+					list = (CAPABILITY_LIST) malloc(sizeof(*list));
+					list->serviceName = strdup(capability_getServiceName(cap));
+					list->capabilities = linkedList_create();
+
+					linkedList_addElement(m_resolvedServices, list);
+				}
+				linkedList_addElement(list->capabilities, cap);
+			}
+		}
+	}
+}
+
+CAPABILITY_LIST resolver_getCapabilityList(LINKED_LIST list, char * name) {
+	LINKED_LIST_ITERATOR iterator = linkedListIterator_create(list, 0);
+	while (linkedListIterator_hasNext(iterator)) {
+		CAPABILITY_LIST services = (CAPABILITY_LIST) linkedListIterator_next(iterator);
+		if (strcmp(services->serviceName, name) == 0) {
+			return services;
+		}
+	}
+	return NULL;
+}
+
+HASH_MAP resolver_populateWireMap(HASH_MAP candidates, MODULE importer, HASH_MAP wireMap) {
+	if (module_isResolved(importer) || (hashMap_get(wireMap, importer))) {
+		return wireMap;
+	}
+
+	LINKED_LIST candSetList = (LINKED_LIST) hashMap_get(candidates, importer);
+
+	LINKED_LIST serviceWires = linkedList_create();
+	LINKED_LIST emptyWires = linkedList_create();
+
+	hashMap_put(wireMap, importer, emptyWires);
+
+	int candSetIdx = 0;
+	for (candSetIdx = 0; candSetIdx < linkedList_size(candSetList); candSetIdx++) {
+		CANDIDATE_SET cs = (CANDIDATE_SET) linkedList_get(candSetList, candSetIdx);
+
+
+		if (importer != capability_getModule(((CAPABILITY) linkedList_get(cs->candidates, 0)))) {
+			WIRE wire = wire_create(importer, cs->requirement,
+					capability_getModule(((CAPABILITY) linkedList_get(cs->candidates, 0))),
+					((CAPABILITY) linkedList_get(cs->candidates, 0)));
+			linkedList_addElement(serviceWires, wire);
+		}
+
+		wireMap = resolver_populateWireMap(candidates,
+				capability_getModule(((CAPABILITY) linkedList_get(cs->candidates, 0))),
+				wireMap);
+	}
+
+	//hashMap_remove(wireMap, importer);
+	hashMap_put(wireMap, importer, serviceWires);
+
+	return wireMap;
+}

Added: incubator/celix/trunk/celix/resolver.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/resolver.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/resolver.h (added)
+++ incubator/celix/trunk/celix/resolver.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,19 @@
+/*
+ * resolver.h
+ *
+ *  Created on: Jul 13, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef RESOLVER_H_
+#define RESOLVER_H_
+
+#include "module.h"
+#include "wire.h"
+#include "hash_map.h"
+
+HASH_MAP resolver_resolve(MODULE root);
+void resolver_moduleResolved(MODULE module);
+void resolver_addModule(MODULE module);
+
+#endif /* RESOLVER_H_ */

Added: incubator/celix/trunk/celix/service_reference.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/service_reference.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/service_reference.c (added)
+++ incubator/celix/trunk/celix/service_reference.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,36 @@
+/*
+ * service_reference.c
+ *
+ *  Created on: Jul 20, 2010
+ *      Author: alexanderb
+ */
+#include <stdio.h>
+#include "service_reference.h"
+#include "module.h"
+#include "wire.h"
+#include "bundle.h"
+
+bool serviceReference_isAssignableTo(SERVICE_REFERENCE reference, BUNDLE requester, char * serviceName) {
+	bool allow = true;
+
+	BUNDLE provider = reference->bundle;
+	if (requester == provider) {
+		return allow;
+	}
+
+	WIRE providerWire = module_getWire(bundle_getModule(provider), serviceName);
+	WIRE requesterWire = module_getWire(bundle_getModule(requester), serviceName);
+
+	if (providerWire == NULL && requesterWire != NULL) {
+		allow = (bundle_getModule(provider) == wire_getExporter(requesterWire));
+	} else if (providerWire != NULL && requesterWire != NULL) {
+		allow = (wire_getExporter(providerWire) == wire_getExporter(requesterWire));
+	} else if (providerWire != NULL && requesterWire == NULL) {
+		allow = (wire_getExporter(providerWire) == bundle_getModule(requester));
+	} else {
+		allow = false;
+	}
+
+	return allow;
+}
+

Added: incubator/celix/trunk/celix/service_reference.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/service_reference.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/service_reference.h (added)
+++ incubator/celix/trunk/celix/service_reference.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,17 @@
+/*
+ * service_reference.h
+ *
+ *  Created on: Jul 20, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef SERVICE_REFERENCE_H_
+#define SERVICE_REFERENCE_H_
+
+#include <stdbool.h>
+
+#include "headers.h"
+
+bool serviceReference_isAssignableTo(SERVICE_REFERENCE reference, BUNDLE requester, char * serviceName);
+
+#endif /* SERVICE_REFERENCE_H_ */

Added: incubator/celix/trunk/celix/service_registration.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/service_registration.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/service_registration.c (added)
+++ incubator/celix/trunk/celix/service_registration.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,77 @@
+/*
+ * service_registration.c
+ *
+ *  Created on: Aug 6, 2010
+ *      Author: alexanderb
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "service_registration.h"
+#include "constants.h"
+
+SERVICE_REGISTRATION serviceRegistration_create(SERVICE_REGISTRY registry, BUNDLE bundle, char * serviceName, long serviceId, void * serviceObject, PROPERTIES dictionary) {
+	SERVICE_REGISTRATION registration = (SERVICE_REGISTRATION) malloc(sizeof(*registration));
+
+	registration->registry = registry;
+	registration->className = serviceName;
+
+	if (dictionary == NULL) {
+		dictionary = createProperties();
+	}
+
+	char sId[sizeof(serviceId) + 1];
+	sprintf(sId, "%ld", serviceId);
+	setProperty(dictionary, (char *) SERVICE_ID, strdup(sId));
+	setProperty(dictionary, (char *) OBJECTCLASS, serviceName);
+
+	registration->properties = dictionary;
+
+	registration->serviceId = serviceId;
+	registration->svcObj = serviceObject;
+
+	SERVICE_REFERENCE reference = (SERVICE_REFERENCE) malloc(sizeof(*reference));
+	reference->bundle = bundle;
+	reference->registration = registration;
+
+	registration->reference = reference;
+
+	registration->isUnregistering = false;
+	pthread_mutex_init(&registration->mutex, NULL);
+
+	return registration;
+}
+
+void serviceRegistration_destroy(SERVICE_REGISTRATION registration) {
+	registration->className = NULL;
+	registration->registry = NULL;
+
+	registration->reference->bundle = NULL;
+	registration->reference->registration = NULL;
+	free(registration->reference);
+
+	pthread_mutex_destroy(&registration->mutex);
+
+	free(registration);
+}
+
+bool serviceRegistration_isValid(SERVICE_REGISTRATION registration) {
+	return registration->svcObj != NULL;
+}
+
+void serviceRegistration_unregister(SERVICE_REGISTRATION registration) {
+	pthread_mutex_lock(&registration->mutex);
+	if (!serviceRegistration_isValid(registration) || registration->isUnregistering) {
+		printf("Service is already unregistered\n");
+		return;
+	}
+	registration->isUnregistering = true;
+	pthread_mutex_unlock(&registration->mutex);
+
+	serviceRegistry_unregisterService(registration->registry, registration->reference->bundle, registration);
+
+	pthread_mutex_lock(&registration->mutex);
+	registration->svcObj = NULL;
+	pthread_mutex_unlock(&registration->mutex);
+}

Added: incubator/celix/trunk/celix/service_registration.h
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/service_registration.h?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/service_registration.h (added)
+++ incubator/celix/trunk/celix/service_registration.h Thu Dec  9 11:49:40 2010
@@ -0,0 +1,20 @@
+/*
+ * service_registration.h
+ *
+ *  Created on: Aug 6, 2010
+ *      Author: alexanderb
+ */
+
+#ifndef SERVICE_REGISTRATION_H_
+#define SERVICE_REGISTRATION_H_
+
+#include <stdbool.h>
+
+#include "headers.h"
+#include "service_registry.h"
+
+SERVICE_REGISTRATION serviceRegistration_create(SERVICE_REGISTRY registry, BUNDLE bundle, char * serviceName, long serviceId, void * serviceObject, PROPERTIES dictionary);
+bool serviceRegistration_isValid(SERVICE_REGISTRATION registration);
+void serviceRegistration_unregister(SERVICE_REGISTRATION registration);
+
+#endif /* SERVICE_REGISTRATION_H_ */

Added: incubator/celix/trunk/celix/service_registry.c
URL: http://svn.apache.org/viewvc/incubator/celix/trunk/celix/service_registry.c?rev=1043903&view=auto
==============================================================================
--- incubator/celix/trunk/celix/service_registry.c (added)
+++ incubator/celix/trunk/celix/service_registry.c Thu Dec  9 11:49:40 2010
@@ -0,0 +1,277 @@
+/*
+ * service_registry.c
+ *
+ *  Created on: Aug 6, 2010
+ *      Author: alexanderb
+ */
+#include <stdlib.h>
+
+#include "service_registry.h"
+#include "service_registration.h"
+
+struct usageCount {
+	unsigned int count;
+	SERVICE_REFERENCE reference;
+	void * service;
+};
+
+typedef struct usageCount * USAGE_COUNT;
+
+USAGE_COUNT serviceRegistry_getUsageCount(SERVICE_REGISTRY registry, BUNDLE bundle, SERVICE_REFERENCE reference) {
+	ARRAY_LIST usages = hashMap_get(registry->inUseMap, bundle);
+	int i;
+	for (i = 0; (usages != NULL) && (i < arrayList_size(usages)); i++) {
+		USAGE_COUNT usage = arrayList_get(usages, i);
+		if (usage->reference == reference) {
+			return usage;
+		}
+	}
+	return NULL;
+}
+
+USAGE_COUNT serviceRegistry_addUsageCount(SERVICE_REGISTRY registry, BUNDLE bundle, SERVICE_REFERENCE reference) {
+	ARRAY_LIST usages = hashMap_get(registry->inUseMap, bundle);
+	USAGE_COUNT usage = (USAGE_COUNT) malloc(sizeof(*usage));
+	usage->reference = reference;
+	usage->count = 0;
+	usage->service = NULL;
+
+	if (usages == NULL) {
+		usages = arrayList_create();
+	}
+	arrayList_add(usages, usage);
+	hashMap_put(registry->inUseMap, bundle, usages);
+	return usage;
+}
+
+void serviceRegistry_flushUsageCount(SERVICE_REGISTRY registry, BUNDLE bundle, SERVICE_REFERENCE reference) {
+	ARRAY_LIST usages = hashMap_get(registry->inUseMap, bundle);
+	ARRAY_LIST_ITERATOR iter = arrayListIterator_create(usages);
+	while (arrayListIterator_hasNext(iter)) {
+		USAGE_COUNT usage = arrayListIterator_next(iter);
+		if (usage->reference == reference) {
+			arrayListIterator_remove(iter);
+		}
+	}
+	if (arrayList_size(usages) > 0) {
+		hashMap_put(registry->inUseMap, bundle, usages);
+	} else {
+		hashMap_remove(registry->inUseMap, bundle);
+	}
+}
+
+SERVICE_REGISTRY serviceRegistry_create(void (*serviceChanged)(SERVICE_EVENT, PROPERTIES)) {
+	SERVICE_REGISTRY registry = (SERVICE_REGISTRY) malloc(sizeof(*registry));
+	registry->serviceChanged = serviceChanged;
+	registry->inUseMap = hashMap_create(NULL, NULL, NULL, NULL);
+	registry->serviceRegistrations = hashMap_create(NULL, NULL, NULL, NULL);
+	pthread_mutex_init(&registry->mutex, NULL);
+	registry->currentServiceId = 1l;
+	return registry;
+}
+
+ARRAY_LIST serviceRegistry_getRegisteredServices(SERVICE_REGISTRY registry, BUNDLE bundle) {
+	ARRAY_LIST regs = (ARRAY_LIST) hashMap_get(registry->serviceRegistrations, bundle);
+	if (regs != NULL) {
+		ARRAY_LIST refs = arrayList_create();
+		int i;
+		for (i = 0; i < arrayList_size(regs); i++) {
+			SERVICE_REGISTRATION reg = arrayList_get(regs, i);
+			if (serviceRegistration_isValid(reg)) {
+				arrayList_add(refs, reg->reference);
+			}
+		}
+		return refs;
+	}
+	return NULL;
+}
+
+SERVICE_REGISTRATION serviceRegistry_registerService(SERVICE_REGISTRY registry, BUNDLE bundle, char * serviceName, void * serviceObject, PROPERTIES dictionary) {
+	SERVICE_REGISTRATION reg = NULL;
+
+	pthread_mutex_lock(&registry->mutex);
+
+	reg = serviceRegistration_create(registry, bundle, serviceName, ++registry->currentServiceId, serviceObject, dictionary);
+
+	ARRAY_LIST regs = (ARRAY_LIST) hashMap_get(registry->serviceRegistrations, bundle);
+	if (regs == NULL) {
+		regs = arrayList_create();
+	}
+	arrayList_add(regs, reg);
+	hashMap_put(registry->serviceRegistrations, bundle, regs);
+
+	pthread_mutex_unlock(&registry->mutex);
+
+	if (registry->serviceChanged != NULL) {
+		SERVICE_EVENT event = (SERVICE_EVENT) malloc(sizeof(*event));
+		event->type = REGISTERED;
+		event->reference = reg->reference;
+		registry->serviceChanged(event, NULL);
+		free(event);
+		event = NULL;
+	}
+
+	return reg;
+}
+
+void serviceRegistry_unregisterService(SERVICE_REGISTRY registry, BUNDLE bundle, SERVICE_REGISTRATION registration) {
+	pthread_mutex_lock(&registry->mutex);
+
+	ARRAY_LIST regs = (ARRAY_LIST) hashMap_get(registry->serviceRegistrations, bundle);
+	if (regs != NULL) {
+		arrayList_removeElement(regs, registration);
+	}
+	hashMap_put(registry->serviceRegistrations, bundle, regs);
+
+	pthread_mutex_unlock(&registry->mutex);
+
+	if (registry->serviceChanged != NULL) {
+		SERVICE_EVENT event = (SERVICE_EVENT) malloc(sizeof(*event));
+		event->type = UNREGISTERING;
+		event->reference = registration->reference;
+		registry->serviceChanged(event, NULL);
+	}
+
+//	pthread_mutex_lock(&registry->mutex);
+	// unget service
+//	pthread_mutex_unlock(&registry->mutex);
+
+}
+
+void serviceRegistry_unregisterServices(SERVICE_REGISTRY registry, BUNDLE bundle) {
+	ARRAY_LIST regs = NULL;
+	pthread_mutex_lock(&registry->mutex);
+	regs = (ARRAY_LIST) hashMap_get(registry->serviceRegistrations, bundle);
+	pthread_mutex_unlock(&registry->mutex);
+
+	int i;
+	for (i = 0; (regs != NULL) && i < arrayList_size(regs); i++) {
+		SERVICE_REGISTRATION reg = arrayList_get(regs, i);
+		if (serviceRegistration_isValid(reg)) {
+			serviceRegistration_unregister(reg);
+		}
+	}
+
+	pthread_mutex_lock(&registry->mutex);
+	hashMap_remove(registry->serviceRegistrations, bundle);
+	pthread_mutex_unlock(&registry->mutex);
+}
+
+ARRAY_LIST serviceRegistry_getServiceReferences(SERVICE_REGISTRY registry, char * serviceName, FILTER filter) {
+	ARRAY_LIST references = arrayList_create();
+
+	HASH_MAP_VALUES registrations = hashMapValues_create(registry->serviceRegistrations);
+	HASH_MAP_ITERATOR iterator = hashMapValues_iterator(registrations);
+	while (hashMapIterator_hasNext(iterator)) {
+		ARRAY_LIST regs = (ARRAY_LIST) hashMapIterator_nextValue(iterator);
+		int regIdx;
+		for (regIdx = 0; (regs != NULL) && regIdx < arrayList_size(regs); regIdx++) {
+			SERVICE_REGISTRATION registration = (SERVICE_REGISTRATION) arrayList_get(regs, regIdx);
+
+			bool matched = false;
+			if ((serviceName == NULL) && ((filter == NULL) || filter_match(filter, registration->properties))) {
+				matched = true;
+			} else if (serviceName != NULL) {
+				if ((strcmp(registration->className, serviceName) == 0) && ((filter == NULL) || filter_match(filter, registration->properties))) {
+					matched = true;
+				}
+			}
+			if (matched) {
+				if (serviceRegistration_isValid(registration)) {
+					arrayList_add(references, registration->reference);
+				}
+			}
+		}
+	}
+
+	return references;
+}
+
+ARRAY_LIST serviceRegistry_getServicesInUse(SERVICE_REGISTRY registry, BUNDLE bundle) {
+	ARRAY_LIST usages = hashMap_get(registry->inUseMap, bundle);
+	if (usages != NULL) {
+		ARRAY_LIST references = arrayList_create();
+		int i;
+		for (i = 0; i < arrayList_size(usages); i++) {
+			USAGE_COUNT usage = arrayList_get(usages, i);
+			arrayList_add(references, usage->reference);
+		}
+		return references;
+	}
+	return NULL;
+}
+
+void * serviceRegistry_getService(SERVICE_REGISTRY registry, BUNDLE bundle, SERVICE_REFERENCE reference) {
+	SERVICE_REGISTRATION registration = reference->registration;
+	void * service = NULL;
+	USAGE_COUNT usage = NULL;
+
+	pthread_mutex_lock(&registry->mutex);
+
+	if (registration->svcObj != NULL) {
+		usage = serviceRegistry_getUsageCount(registry, bundle, reference);
+		if (usage == NULL) {
+			usage = serviceRegistry_addUsageCount(registry, bundle, reference);
+		}
+		usage->count++;
+		service = usage->service;
+	}
+	pthread_mutex_unlock(&registry->mutex);
+
+	if ((usage != NULL) && (service == NULL)) {
+		service = registration->svcObj;
+	}
+	pthread_mutex_lock(&registry->mutex);
+	if ((registration->svcObj == NULL) || (service == NULL)) {
+		serviceRegistry_flushUsageCount(registry, bundle, reference);
+	} else {
+		usage->service = service;
+	}
+	pthread_mutex_unlock(&registry->mutex);
+
+	return service;
+}
+
+bool serviceRegistry_ungetService(SERVICE_REGISTRY registry, BUNDLE bundle, SERVICE_REFERENCE reference) {
+	SERVICE_REGISTRATION registration = reference->registration;
+	USAGE_COUNT usage = NULL;
+
+	pthread_mutex_lock(&registry->mutex);
+
+	usage = serviceRegistry_getUsageCount(registry, bundle, reference);
+	if (usage == NULL) {
+		pthread_mutex_unlock(&registry->mutex);
+		return false;
+	}
+
+	usage->count--;
+
+	if ((registration->svcObj == NULL) || (usage->count <= 0)) {
+		usage->service = NULL;
+		serviceRegistry_flushUsageCount(registry, bundle, reference);
+	}
+
+	pthread_mutex_unlock(&registry->mutex);
+
+	return true;
+}
+
+void serviceRegistry_ungetServices(SERVICE_REGISTRY registry, BUNDLE bundle) {
+	pthread_mutex_lock(&registry->mutex);
+	ARRAY_LIST usages = hashMap_get(registry->inUseMap, bundle);
+	pthread_mutex_unlock(&registry->mutex);
+
+	if (usages == NULL || arrayList_isEmpty(usages)) {
+		return;
+	}
+
+	int i;
+	for (i = 0; i < arrayList_size(usages); i++) {
+		USAGE_COUNT usage = arrayList_get(usages, i);
+		while (serviceRegistry_ungetService(registry, bundle, usage->reference)) {
+			//
+		}
+	}
+}
+
+



Mime
View raw message