16 unsigned long long * offset_ptr;
20 struct file_info files[MAX_FILES];
23 int parse_config_input(ezxml_t cfg_input);
24 int write_output(char * filename, ezxml_t cfg_output);
27 printf("Usage: builder <infile> [-o outfile]\n");
30 int main(int argc, char ** argv) {
32 char * outfile = NULL;
35 memset((char *)files, 0, sizeof(files));
39 while ((c = getopt(argc, argv, "ho:")) != -1) {
57 infile = argv[optind];
60 printf("Reading Input file: %s\n", infile);
62 ezxml_t cfg_input = ezxml_parse_file(infile);
64 if (cfg_input == NULL) {
65 printf("Could not open configuration input file: %s\n", infile);
73 if (parse_config_input(cfg_input) == -1) {
74 printf("Error parsing configuration input\n");
78 printf("xml : %s\n", ezxml_toxml(cfg_input));
84 if (outfile == NULL) {
85 char * endptr = rindex(infile, '.');
87 outfile = malloc(strlen(infile) + strlen(".dat") + 1);
93 sprintf(outfile, "%s.dat", infile);
97 write_output(outfile, cfg_input);
103 char * get_val(ezxml_t cfg, char * tag) {
104 char * attrib = (char *)ezxml_attr(cfg, tag);
105 ezxml_t txt = ezxml_child(cfg, tag);
107 if ((txt != NULL) && (attrib != NULL)) {
108 printf("Invalid Cfg file: Duplicate value for %s (attr=%s, txt=%s)\n",
109 tag, attrib, ezxml_txt(txt));
113 return (attrib == NULL) ? ezxml_txt(txt) : attrib;
117 int write_output(char * filename, ezxml_t cfg_output) {
118 FILE * data_file = fopen(filename, "w+");
119 char * new_cfg_str = ezxml_toxml(cfg_output);
120 unsigned int cfg_len = strlen(new_cfg_str);
121 unsigned long long zero = 0;
123 unsigned long long offset = 0;
124 unsigned long long file_cnt = num_files;
126 fwrite("v3vee\0\0\0", 8, 1, data_file);
129 // printf("New config: \n%s\n", new_cfg_str);
131 fwrite(&cfg_len, sizeof(unsigned int), 1, data_file);
132 offset += sizeof(unsigned int);
134 fwrite(new_cfg_str, cfg_len, 1, data_file);
137 fwrite(&zero, 1, 8, data_file);
140 printf("setting number of files to %llu\n", file_cnt);
141 printf("sizeof(file_cnt)=%d \n", sizeof(file_cnt));
143 fwrite(&file_cnt, 8, 1, data_file);
146 // each index entry is 16 bytes long plus end padding
147 offset += (16 * num_files) + 8;
149 for (i = 0; i < num_files; i++) {
150 fwrite(&i, 4, 1, data_file);
151 fwrite(&(files[i].size), 4, 1, data_file);
152 fwrite(&offset, 8, 1, data_file);
154 offset += files[i].size;
157 fwrite(&zero, 1, 8, data_file);
159 for (i = 0; i < num_files; i++) {
160 if (fwrite(files[i].data, 1, files[i].size, data_file) != files[i].size) {
161 printf("Error writing data file contents");
175 int parse_config_input(ezxml_t cfg_input) {
176 ezxml_t file_tags = NULL;
177 ezxml_t tmp_file_tag = NULL;
179 // files are transformed into blobs that are slapped to the end of the file
181 file_tags = ezxml_child(cfg_input, "files");
183 tmp_file_tag = ezxml_child(file_tags, "file");
185 while (tmp_file_tag) {
186 char * filename = get_val(tmp_file_tag, "filename");
187 struct stat file_stats;
188 FILE * data_file = NULL;
189 char * id = get_val(tmp_file_tag, "id");
192 snprintf(index_buf, 256, "%d", num_files);
195 strncpy(files[num_files].id, ezxml_attr(tmp_file_tag, "id"), 256);
197 printf("file id=%s, name=%s\n",
202 if (stat(filename, &file_stats) != 0) {
207 files[num_files].size = (unsigned int)file_stats.st_size;
208 printf("file size = %d\n", files[num_files].size);
210 files[num_files].data = malloc(files[num_files].size);
212 data_file = fopen(filename, "r");
214 if (fread(files[num_files].data, files[num_files].size, 1, data_file) == 0) {
215 printf("Error reading data file %s\n", filename);
222 ezxml_set_attr_d(tmp_file_tag, "index", index_buf);
225 tmp_file_tag = ezxml_next(tmp_file_tag);