aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2014-06-29 11:21:52 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2014-06-29 17:18:09 -0700
commite92576600bca2d2bfec4000ffde0d4e7cb21b57d (patch)
treec2f42b25c6cd6d4e726901cf7c765f8b2706ac4d
parent5b311abfb51046585ffba9d865b2f759fd8983d0 (diff)
downloadsubsurface-e92576600bca2d2bfec4000ffde0d4e7cb21b57d.tar.gz
Parse git-format picture data
This adds the loading of picture data from git repositories too. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--load-git.c97
1 files changed, 89 insertions, 8 deletions
diff --git a/load-git.c b/load-git.c
index f50b067cf..be0e3539c 100644
--- a/load-git.c
+++ b/load-git.c
@@ -659,6 +659,20 @@ static void parse_settings_divecomputerid(char *line, struct membuffer *str, voi
create_device_node(id.model, id.deviceid, id.serial, id.firmware, id.nickname);
}
+static void parse_picture_filename(char *line, struct membuffer *str, void *_pic)
+{
+ struct picture *pic = _pic;
+ pic->filename = get_utf8(str);
+}
+
+static void parse_picture_gps(char *line, struct membuffer *str, void *_pic)
+{
+ struct picture *pic = _pic;
+
+ pic->latitude = parse_degrees(line, &line);
+ pic->longitude = parse_degrees(line, &line);
+}
+
/* These need to be sorted! */
struct keyword_action dc_action[] = {
#undef D
@@ -715,6 +729,18 @@ static void settings_parser(char *line, struct membuffer *str, void *_unused)
match_action(line, str, NULL, settings_action, ARRAY_SIZE(settings_action));
}
+/* These need to be sorted! */
+static struct keyword_action picture_action[] = {
+#undef D
+#define D(x) { #x, parse_picture_ ## x }
+ D(filename), D(gps)
+};
+
+static void picture_parser(char *line, struct membuffer *str, void *_pic)
+{
+ match_action(line, str, _pic, picture_action, ARRAY_SIZE(picture_action));
+}
+
/*
* We have a very simple line-based interface, with the small
* complication that lines can have strings in the middle, and
@@ -1010,6 +1036,13 @@ static int dive_directory(const char *root, const char *name, int timeoff)
return GIT_WALK_OK;
}
+static int picture_directory(const char *root, const char *name)
+{
+ if (!active_dive)
+ return GIT_WALK_SKIP;
+ return GIT_WALK_OK;
+}
+
/*
* Return the length of the string without the unique part.
*/
@@ -1051,6 +1084,8 @@ static int nonunique_length(const char *str)
* are optional, and may be encoded in the path leading up to
* the dive).
*
+ * - It is a per-dive picture directory ("Pictures")
+ *
* - It's some random non-dive-data directory.
*
* Subsurface doesn't create these yet, but maybe we'll encode
@@ -1064,6 +1099,9 @@ static int walk_tree_directory(const char *root, const git_tree_entry *entry)
int digits = 0, len;
char c;
+ if (!strcmp(name, "Pictures"))
+ return picture_directory(root, name);
+
while (isdigit(c = name[digits]))
digits++;
@@ -1180,20 +1218,63 @@ static int parse_settings_entry(git_repository *repo, const git_tree_entry *entr
return 0;
}
+static int parse_picture_entry(git_repository *repo, const git_tree_entry *entry, const char *name)
+{
+ git_blob *blob;
+ struct picture *pic;
+ int hh, mm, ss, offset;
+ char sign;
+
+ /*
+ * The format of the picture name files is just the offset
+ * within the dive in form [[+-]hh:mm:ss, possibly followed
+ * by a hash to make the filename unique (which we can just
+ * ignore).
+ */
+ if (sscanf(name, "%c%d:%d:%d", &sign, &hh, &mm, &ss) != 4)
+ return report_error("Unknown file name %s", name);
+ offset = ss + 60*(mm + 60*hh);
+ if (sign == '-')
+ offset = -offset;
+
+ blob = git_tree_entry_blob(repo, entry);
+ if (!blob)
+ return report_error("Unable to read trip file");
+
+ pic = alloc_picture();
+ pic->offset.seconds = offset;
+ dive_add_picture(active_dive, pic);
+
+ for_each_line(blob, picture_parser, pic);
+ git_blob_free(blob);
+ return 0;
+}
+
static int walk_tree_file(const char *root, const git_tree_entry *entry, git_repository *repo)
{
struct dive *dive = active_dive;
dive_trip_t *trip = active_trip;
const char *name = git_tree_entry_name(entry);
- if (dive && !strncmp(name, "Divecomputer", 12))
- return parse_divecomputer_entry(repo, entry, name+12);
- if (dive && !strncmp(name, "Dive", 4))
- return parse_dive_entry(repo, entry, name+4);
- if (trip && !strcmp(name, "00-Trip"))
- return parse_trip_entry(repo, entry);
- if (!strcmp(name, "00-Subsurface"))
- return parse_settings_entry(repo, entry);
+ switch (*name) {
+ /* Picture file? They are saved as time offsets in the dive */
+ case '-': case '+':
+ if (dive)
+ return parse_picture_entry(repo, entry, name);
+ break;
+ case 'D':
+ if (dive && !strncmp(name, "Divecomputer", 12))
+ return parse_divecomputer_entry(repo, entry, name+12);
+ if (dive && !strncmp(name, "Dive", 4))
+ return parse_dive_entry(repo, entry, name+4);
+ break;
+ case '0':
+ if (trip && !strcmp(name, "00-Trip"))
+ return parse_trip_entry(repo, entry);
+ if (!strcmp(name, "00-Subsurface"))
+ return parse_settings_entry(repo, entry);
+ break;
+ }
report_error("Unknown file %s%s (%p %p)", root, name, dive, trip);
return GIT_WALK_SKIP;
}