1 /*
2 * ffindex_order
3 * written by Milot Mirdita <milot@mirdita.de>.
4 * Please add your name here if you distribute modified versions.
5 *
6 * FFindex is provided under the Create Commons license "Attribution-ShareAlike
7 * 4.0", which basically captures the spirit of the Gnu Public License (GPL).
8 *
9 * See:
10 * http://creativecommons.org/licenses/by-sa/4.0/
11 *
12 * ffindex_order
13 * Reorders the entries in a FFindex data file by the order given by file
14 * Each line of the order file must contain a key from the FFindex index.
15 * The FFindex data file entries will have the same order as the order file.
16 */
17
18 #define _GNU_SOURCE 1
19 #define _LARGEFILE64_SOURCE 1
20 #define _FILE_OFFSET_BITS 64
21
22 #include <limits.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <sys/types.h>
27
28 #include "ffindex.h"
29 #include "ffutil.h"
30
31
main(int argc,char ** argv)32 int main(int argc, char **argv)
33 {
34 if(argc < 6)
35 {
36 fprintf(stderr, "USAGE: %s ORDER_FILENAME DATA_FILENAME INDEX_FILENAME SORTED_DATA_OUT_FILE SORTED_INDEX_OUT_FILE\n"
37 "\nDesigned and implemented by Milot Mirdita <milot@mirdita.de>.\n",
38 argv[0]);
39 return -1;
40 }
41
42 char *order_filename = argv[1];
43
44 char *data_filename = argv[2];
45 char *index_filename = argv[3];
46
47 char *sorted_data_filename = argv[4];
48 char *sorted_index_filename = argv[5];
49
50 FILE *order_file = fopen(order_filename, "r");
51
52 FILE *data_file = fopen(data_filename, "r");
53 FILE *index_file = fopen(index_filename, "r");
54
55 FILE *sorted_data_file = fopen(sorted_data_filename, "w+");
56 FILE *sorted_index_file = fopen(sorted_index_filename, "w+");
57
58 if(order_file == NULL) { fferror_print(__FILE__, __LINE__, argv[0], order_filename); exit(EXIT_FAILURE); }
59
60 if( data_file == NULL) { fferror_print(__FILE__, __LINE__, argv[0], data_filename); exit(EXIT_FAILURE); }
61 if(index_file == NULL) { fferror_print(__FILE__, __LINE__, argv[0], index_filename); exit(EXIT_FAILURE); }
62
63 if( sorted_data_file == NULL) { fferror_print(__FILE__, __LINE__, argv[0], sorted_data_filename); exit(EXIT_FAILURE); }
64 if(sorted_index_file == NULL) { fferror_print(__FILE__, __LINE__, argv[0], sorted_index_filename); exit(EXIT_FAILURE); }
65
66 size_t data_size;
67 char *data = ffindex_mmap_data(data_file, &data_size);
68
69 size_t entries = ffcount_lines(index_filename);
70 ffindex_index_t* index = ffindex_index_parse(index_file, entries);
71 if(index == NULL) {
72 perror("ffindex_index_parse failed");
73 exit(EXIT_FAILURE);
74 }
75
76
77 char message[LINE_MAX];
78 char line[LINE_MAX];
79 int i = 0;
80 size_t offset = 0;
81 while (fgets(line, sizeof(line), order_file)) {
82 size_t len = strlen(line);
83 if (len && (line[len - 1] != '\n')) {
84 // line is incomplete
85 snprintf(message, LINE_MAX, "Warning: Line %d of order file %s was too long and cut-off.", i, order_filename);
86 fferror_print(__FILE__, __LINE__, argv[0], message);
87 }
88
89 // remove new line
90 char *name = ffnchomp(line, len);
91 ffindex_entry_t* entry = ffindex_get_entry_by_name(index, name);
92
93 if (entry != NULL) {
94 char* filedata = ffindex_get_data_by_entry(data, entry);
95 size_t entryLength = (entry->length == 0 ) ? 0 : entry->length - 1;
96 ffindex_insert_memory(sorted_data_file, sorted_index_file, &offset, filedata, entryLength, name);
97 }
98
99 i++;
100 }
101
102 // cleanup
103 fclose(sorted_data_file);
104 fclose(index_file);
105 fclose(data_file);
106 fclose(order_file);
107
108 // sort FFindex index
109 fclose(sorted_index_file);
110 sorted_index_file = fopen(sorted_index_filename, "r+");
111 entries = ffcount_lines(index_filename);
112 index = ffindex_index_parse(sorted_index_file, entries);
113 if(index == NULL) {
114 perror("ffindex_index_parse failed");
115 exit(EXIT_FAILURE);
116 }
117 fclose(sorted_index_file);
118
119 ffindex_sort_index_file(index);
120 sorted_index_file = fopen(sorted_index_filename, "w");
121 if(sorted_index_file == NULL) {
122 perror(sorted_index_filename);
123 return EXIT_FAILURE;
124 }
125 int err = ffindex_write(index, sorted_index_file);
126 fclose(sorted_index_file);
127
128 return err;
129 }
130
131 /* vim: ts=2 sw=2 et
132 */
133