export: Refactor gbox walking code into its own routines
[navymail.git] / gbox-walk.c
blob66ebe57cb65254469d59e15ba6394642c052b167
1 /* walk through gbox
2 * Copyright (C) 2011 Kirill Smelkov <kirr@navytux.spb.ru>
4 * This program is free software: you can Use, Study, Modify and Redistribute it
5 * under the terms of the GNU General Public License version 2. This program is
6 * distributed WITHOUT ANY WARRANTY. See COPYING file for full License terms.
7 */
10 #include "navymail/gbox-walk.h"
13 /* TODO die -> error codes */
14 void prepare_gbox_walk(struct gbox_walk *w)
16 /* TODO convert to argv_array */
17 const char *rev_argv[3];
18 int rev_argc=0;
20 rev_argv[rev_argc++] = NULL;
21 if (w->original_order)
22 rev_argv[rev_argc++] = "--reverse";
23 rev_argv[rev_argc++] = w->gbox;
26 init_revisions(&w->revs, NULL/*prefix - ok?*/);
27 if (setup_revisions(rev_argc, rev_argv, &w->revs, NULL) != 1)
28 die("gbox-walk: setup revision failed");
30 if (prepare_revision_walk(&w->revs))
31 die("gbox-walk: revision walk setup failed");
33 w->tree = NULL;
34 w->tree_entries.sha1 = NULL; /* = SHA1_ARRAY_INIT */
35 w->entry_idx = -1;
39 const unsigned char * /*sha1*/ next_gbox_entry(struct gbox_walk *w)
41 struct name_entry entry;
43 start:
44 /* see, if we need to fetch next commit */
45 if (!w->tree) {
46 struct commit *commit;
48 commit = get_revision(&w->revs);
49 if (!commit)
50 return NULL;
52 /* printf("%s\n", sha1_to_hex(commit->object.sha1)); */
53 w->tree = commit->tree;
54 if (parse_tree(w->tree))
55 die("gbox-walk: parse_tree failed");
57 init_tree_desc(&w->tree_desc, w->tree->buffer, w->tree->size);
60 /* preload the tree for original order */
61 if (w->original_order) {
62 while (tree_entry(&w->tree_desc, &entry))
63 sha1_array_append(&w->tree_entries, entry.sha1);
65 w->entry_idx = w->tree_entries.nr - 1;
70 /* fast case - walking gbox in reverse order */
71 if (!w->original_order) {
72 if (tree_entry(&w->tree_desc, &entry))
73 return entry.sha1;
76 /* slow case - exporting mbox in original order */
77 else {
78 if (w->entry_idx >= 0)
79 return w->tree_entries.sha1[w->entry_idx--];
81 sha1_array_clear(&w->tree_entries);
85 /* restart from next commit */
86 w->tree = NULL;
87 goto start;