summaryrefslogtreecommitdiffstats
path: root/file.c
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2012-01-26 17:43:33 -0800
committerGravatar Linus Torvalds <torvalds@linux-foundation.org>2012-01-26 17:43:33 -0800
commita65b9b48e0be56bc33ea857d928b83b726b13c34 (patch)
tree6a3114f50853dc967ced467a20e511e7f35e1e43 /file.c
parent4d10bc017ad683ffa3e7e399b9bcb9dcf524d964 (diff)
downloadsubsurface-a65b9b48e0be56bc33ea857d928b83b726b13c34.tar.gz
Add "native" Suunto SDE zip file reading
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>
Diffstat (limited to 'file.c')
-rw-r--r--file.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/file.c b/file.c
index 5db36a849..26b89a623 100644
--- 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) {