]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Add "native" Suunto SDE zip file reading
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 Jan 2012 01:43:33 +0000 (17:43 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 Jan 2012 01:43:33 +0000 (17:43 -0800)
You need to have libzip-devel installed, and pkg-config needs to know about it
for the build to pick up on it.

On at least Fedora, a simple "yum install libzip-devel" will make things
work, although you may need to force a rebuild of subsurface too (the
"file.o" file in particular - the Makefile doesn't track system
dependencies).

Then, you can just do

   subsurface my-dives.SDE

to read the data directly from the SDE file.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Makefile
file.c

index 39e1cadb01da02bd6a6da662623ca61c315017d4..265f8fe4e8db691f0b59d04711caddf815c54e6c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -87,6 +87,11 @@ GLIB2CFLAGS = $(shell $(PKGCONFIG) --cflags glib-2.0)
 GTK2CFLAGS = $(shell $(PKGCONFIG) --cflags gtk+-2.0)
 CFLAGS += $(shell $(XSLCONFIG) --cflags)
 
+LIBZIP = $(shell $(PKGCONFIG) --libs libzip 2> /dev/null)
+ifneq ($(strip $(LIBZIP)),)
+       ZIP = -DLIBZIP $(shell $(PKGCONFIG) --cflags libzip)
+endif
+
 ifeq ($(UNAME), linux)
        LIBGCONF2 = $(shell $(PKGCONFIG) --libs gconf-2.0)
        GCONF2CFLAGS =  $(shell $(PKGCONFIG) --cflags gconf-2.0)
@@ -111,7 +116,7 @@ ifneq ($(strip $(LIBXSLT)),)
        endif
 endif
 
-LIBS = $(LIBXML2) $(LIBXSLT) $(LIBGTK) $(LIBGCONF2) $(LIBDIVECOMPUTER) $(EXTRALIBS) -lpthread -lm
+LIBS = $(LIBXML2) $(LIBXSLT) $(LIBGTK) $(LIBGCONF2) $(LIBDIVECOMPUTER) $(EXTRALIBS) $(LIBZIP) -lpthread -lm
 
 OBJS = main.o dive.o profile.o info.o equipment.o divelist.o \
        parse-xml.o save-xml.o libdivecomputer.o print.o uemis.o \
@@ -148,7 +153,7 @@ install-macosx: $(NAME)
        $(INSTALL) $(MACOSXFILES)/Subsurface.icns $(MACOSXINSTALL)/Contents/Resources/
 
 file.o: file.c dive.h
-       $(CC) $(CFLAGS) $(GLIB2CFLAGS) $(XML2CFLAGS) $(XSLT) -c file.c
+       $(CC) $(CFLAGS) $(GLIB2CFLAGS) $(XML2CFLAGS) $(XSLT) $(ZIP) -c file.c
 
 parse-xml.o: parse-xml.c dive.h
        $(CC) $(CFLAGS) $(GLIB2CFLAGS) $(XML2CFLAGS) $(XSLT) -c parse-xml.c
diff --git a/file.c b/file.c
index 5db36a849d10acc39332f3b2465a1380dcec676b..26b89a6233ecf27beed452eff3fe7e2fb51d5e86 100644 (file)
--- a/file.c
+++ b/file.c
@@ -2,6 +2,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <stdlib.h>
+#include <string.h>
 #include <errno.h>
 
 #include "dive.h"
@@ -53,10 +54,64 @@ out:
        return ret;
 }
 
+#ifdef LIBZIP
+#include <zip.h>
+
+static void suunto_read(struct zip_file *file, GError **error)
+{
+       int size = 1024, n, read = 0;
+       char *mem = malloc(size);
+
+       while ((n = zip_fread(file, mem+read, size-read)) > 0) {
+               read += n;
+               size = read * 3 / 2;
+               mem = realloc(mem, size);
+       }
+       parse_xml_buffer("SDE file", mem, read, error);
+       free(mem);
+}
+#endif
+
+static int try_to_open_suundo(const char *filename, GError **error)
+{
+       int success = 0;
+#ifdef LIBZIP
+       struct zip *zip = zip_open(filename, ZIP_CHECKCONS, NULL);
+
+       if (zip) {
+               int index;
+               for (index = 0; ;index++) {
+                       struct zip_file *file = zip_fopen_index(zip, index, 0);
+                       if (!file)
+                               break;
+                       suunto_read(file, error);
+                       zip_fclose(file);
+                       success++;
+               }
+               zip_close(zip);
+       }
+#endif
+       return success;
+}
+
+static int open_by_filename(const char *filename, const char *fmt, GError **error)
+{
+       /* Suunto Dive Manager files: SDE */
+       if (!strcasecmp(fmt, "SDE"))
+               return try_to_open_suundo(filename, error);
+
+       return 0;
+}
+
 void parse_file(const char *filename, GError **error)
 {
+       char *fmt;
        struct memblock mem;
 
+       fmt = strrchr(filename, '.');
+       if (fmt && open_by_filename(filename, fmt+1, error))
+               return;
+
        if (readfile(filename, &mem) < 0) {
                fprintf(stderr, "Failed to read '%s'.\n", filename);
                if (error) {