OSDN Git Service

LinGui: change deblock control to a slider to set deblock strength
[handbrake-jp/handbrake-jp-git.git] / gtk / src / create_resources.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <glib.h>
4 #include <glib/gstdio.h>
5 #include "icon_tools.h"
6 #include "plist.h"
7 #include "values.h"
8
9 enum
10 {
11         R_NONE = 0,
12         R_RESOURCES,
13         R_SECTION,
14         R_ICON,
15         R_PLIST,
16         R_STRING,
17 };
18
19 typedef struct
20 {
21         gchar *tag;
22         gint id;
23 } tag_map_t;
24
25 static tag_map_t tag_map[] =
26 {
27         {"resources", R_RESOURCES},
28         {"section", R_SECTION},
29         {"icon", R_ICON},
30         {"plist", R_PLIST},
31         {"string", R_STRING},
32 };
33 #define TAG_MAP_SZ      (sizeof(tag_map)/sizeof(tag_map_t))
34
35 typedef struct
36 {
37         gchar *key;
38         gchar *value;
39         GValue *plist;
40         GQueue *stack;
41         GQueue *tag_stack;
42         gboolean closed_top;
43 } parse_data_t;
44
45 static const gchar*
46 lookup_attr_value(
47         const gchar *name, 
48         const gchar **attr_names, 
49         const gchar **attr_values)
50 {
51         gint ii;
52
53         if (attr_names == NULL) return NULL;
54         for (ii = 0; attr_names[ii] != NULL; ii++)
55         {
56                 if (strcmp(name, attr_names[ii]) == 0)
57                         return attr_values[ii];
58         }
59         return NULL;
60 }
61  
62 static GValue*
63 read_string_from_file(const gchar *filename)
64 {
65         gchar *buffer;
66         size_t size;
67         GValue *gval;
68         FILE *fd;
69
70         fd = g_fopen(filename, "r");
71         if (fd == NULL)
72                 return NULL;
73         fseek(fd, 0, SEEK_END);
74         size = ftell(fd);
75         fseek(fd, 0, SEEK_SET);
76         buffer = g_malloc(size+1);
77         size = fread(buffer, 1, size, fd);
78         buffer[size] = 0;
79         gval = ghb_value_new(G_TYPE_STRING);
80         g_value_take_string(gval, buffer);
81         fclose(fd);
82         return gval;
83 }
84
85 static void
86 start_element(
87         GMarkupParseContext *ctx, 
88         const gchar *tag, 
89         const gchar **attr_names,
90         const gchar **attr_values,
91         gpointer ud,
92         GError **error)
93 {
94         parse_data_t *pd = (parse_data_t*)ud;
95         union 
96         {
97                 gint id;
98                 gpointer pid;
99         } id;
100         gint ii;
101
102         // Check to see if the first element found has been closed
103         // If so, ignore any junk following it.
104         if (pd->closed_top)
105                 return;
106
107         for (ii = 0; ii < TAG_MAP_SZ; ii++)
108         {
109                 if (strcmp(tag, tag_map[ii].tag) == 0)
110                 {
111                         id.id = tag_map[ii].id;
112                         break;
113                 }
114         }
115         if (ii == TAG_MAP_SZ)
116         {
117                 g_warning("Unrecognized start tag (%s)", tag);
118                 return;
119         }
120         g_queue_push_head(pd->tag_stack, id.pid);
121         GType gtype = 0;
122         GValue *gval = NULL;
123         GValue *current = g_queue_peek_head(pd->stack);
124         switch (id.id)
125         {
126                 case R_SECTION:
127                 {
128                         const gchar *name;
129
130                         name = lookup_attr_value("name", attr_names, attr_values);
131                         if (name && strcmp(name, "icons") == 0)
132                         {
133                                 gval = ghb_dict_value_new();
134                                 if (pd->key) g_free(pd->key);
135                                 pd->key = g_strdup(name);
136                                 g_queue_push_head(pd->stack, gval);
137                         }
138                 } break;
139                 case R_ICON:
140                 {
141                         const gchar *filename, *name;
142
143                         filename = lookup_attr_value("file", attr_names, attr_values);
144                         name = lookup_attr_value("name", attr_names, attr_values);
145                         if (filename && name)
146                         {
147                                 ghb_rawdata_t *rd;
148                                 guint size;
149
150                                 rd = g_malloc(sizeof(ghb_rawdata_t));
151                                 rd->data = icon_file_serialize(filename, &size);
152                                 rd->size = size;
153                                 gval = ghb_rawdata_value_new(rd);
154                                 if (pd->key) g_free(pd->key);
155                                 pd->key = g_strdup(name);
156                         }
157                         else
158                         {
159                                 g_warning("%s:missing a requried attribute", name);
160                         }
161                 } break;
162                 case R_PLIST:
163                 {
164                         const gchar *filename, *name;
165
166                         filename = lookup_attr_value("file", attr_names, attr_values);
167                         name = lookup_attr_value("name", attr_names, attr_values);
168                         if (filename && name)
169                         {
170                                 gval = ghb_plist_parse_file(filename);
171                                 if (pd->key) g_free(pd->key);
172                                 pd->key = g_strdup(name);
173                         }
174                         else
175                         {
176                                 g_warning("%s:missing a requried attribute", name);
177                         }
178                 } break;
179                 case R_STRING:
180                 {
181                         const gchar *filename, *name;
182
183                         filename = lookup_attr_value("file", attr_names, attr_values);
184                         name = lookup_attr_value("name", attr_names, attr_values);
185                         if (filename && name)
186                         {
187                                 gval = read_string_from_file(filename);
188                                 if (pd->key) g_free(pd->key);
189                                 pd->key = g_strdup(name);
190                         }
191                         else
192                         {
193                                 g_warning("%s:missing a requried attribute", name);
194                         }
195                 } break;
196         }
197         // Add the element to the current container
198         if (gval)
199         { // There's an element to add
200                 if (current == NULL)
201                 {
202                         pd->plist = gval;
203                         return;
204                 }
205                 gtype = G_VALUE_TYPE(current);
206                 if (gtype == ghb_array_get_type())
207                 {
208                         ghb_array_append(current, gval);
209                 }
210                 else if (gtype == ghb_dict_get_type())
211                 {
212                         if (pd->key == NULL)
213                         {
214                                 g_warning("No key for dictionary item");
215                                 ghb_value_free(gval);
216                         }
217                         else
218                         {
219                                 ghb_dict_insert(current, g_strdup(pd->key), gval);
220                         }
221                 }
222                 else
223                 {
224                         g_error("Invalid container type. This shouldn't happen");
225                 }
226         }
227 }
228
229 static void
230 end_element(
231         GMarkupParseContext *ctx, 
232         const gchar *name, 
233         gpointer ud,
234         GError **error)
235 {
236         parse_data_t *pd = (parse_data_t*)ud;
237         gint id;
238         union 
239         {
240                 gint id;
241                 gpointer pid;
242         } start_id;
243         gint ii;
244
245         // Check to see if the first element found has been closed
246         // If so, ignore any junk following it.
247         if (pd->closed_top)
248                 return;
249
250         for (ii = 0; ii < TAG_MAP_SZ; ii++)
251         {
252                 if (strcmp(name, tag_map[ii].tag) == 0)
253                 {
254                         id = tag_map[ii].id;
255                         break;
256                 }
257         }
258         if (ii == TAG_MAP_SZ)
259         {
260                 g_warning("Unrecognized start tag (%s)", name);
261                 return;
262         }
263         start_id.pid = g_queue_pop_head(pd->tag_stack);
264         if (start_id.id != id)
265                 g_warning("start tag != end tag: (%s %d) %d", name, id, id);
266
267         GValue *gval = NULL;
268         GValue *current = g_queue_peek_head(pd->stack);
269         GType gtype = 0;
270         switch (id)
271         {
272                 case R_SECTION:
273                 {
274                         g_queue_pop_head(pd->stack);
275                 } break;
276         }
277         if (gval)
278         {
279                 // Get the top of the data structure stack and if it's an array
280                 // or dict, add the current element
281                 if (current == NULL)
282                 {
283                         pd->plist = gval;
284                         pd->closed_top = TRUE;
285                         return;
286                 }
287                 gtype = G_VALUE_TYPE(current);
288                 if (gtype == ghb_array_get_type())
289                 {
290                         ghb_array_append(current, gval);
291                 }
292                 else if (gtype == ghb_dict_get_type())
293                 {
294                         if (pd->key == NULL)
295                         {
296                                 g_warning("No key for dictionary item");
297                                 ghb_value_free(gval);
298                         }
299                         else
300                         {
301                                 ghb_dict_insert(current, g_strdup(pd->key), gval);
302                         }
303                 }
304                 else
305                 {
306                         g_error("Invalid container type. This shouldn't happen");
307                 }
308         }
309         if (g_queue_is_empty(pd->tag_stack))
310                 pd->closed_top = TRUE;
311 }
312
313 static void
314 text_data(
315         GMarkupParseContext *ctx, 
316         const gchar *text, 
317         gsize len,
318         gpointer ud,
319         GError **error)
320 {
321         parse_data_t *pd = (parse_data_t*)ud;
322         if (pd->value) g_free(pd->value);
323         pd->value = g_strdup(text);
324 }
325
326 static void
327 passthrough(
328         GMarkupParseContext *ctx, 
329         const gchar *text, 
330         gsize len,
331         gpointer ud,
332         GError **error)
333 {
334         //parse_data_t *pd = (parse_data_t*)ud;
335
336         //g_debug("passthrough %s", text);
337 }
338
339 static void
340 parse_error(GMarkupParseContext *ctx, GError *error, gpointer ud)
341 {
342         g_warning("Resource parse error: %s", error->message);
343 }
344
345 // This is required or the parser crashes
346 static void 
347 destroy_notify(gpointer data)
348 { // Do nothing
349         //g_debug("destroy parser");
350 }
351
352 GValue*
353 ghb_resource_parse(const gchar *buf, gssize len)
354 {
355         GMarkupParseContext *ctx;
356         GMarkupParser parser;
357         parse_data_t pd;
358         GError *err = NULL;
359
360         pd.stack = g_queue_new();
361         pd.tag_stack = g_queue_new();
362         pd.key = NULL;
363         pd.value = NULL;
364         pd.plist = ghb_dict_value_new();
365         g_queue_push_head(pd.stack, pd.plist);
366         pd.closed_top = FALSE;
367
368         parser.start_element = start_element;
369         parser.end_element = end_element;
370         parser.text = text_data;
371         parser.passthrough = passthrough;
372         parser.error = parse_error;
373         ctx = g_markup_parse_context_new(&parser, 0, &pd, destroy_notify);
374
375         g_markup_parse_context_parse(ctx, buf, len, &err);
376         g_markup_parse_context_end_parse(ctx, &err);
377         g_markup_parse_context_free(ctx);
378         g_queue_free(pd.stack);
379         g_queue_free(pd.tag_stack);
380         return pd.plist;
381 }
382
383 GValue*
384 ghb_resource_parse_file(FILE *fd)
385 {
386         gchar *buffer;
387         size_t size;
388         GValue *gval;
389
390         if (fd == NULL)
391                 return NULL;
392         fseek(fd, 0, SEEK_END);
393         size = ftell(fd);
394         fseek(fd, 0, SEEK_SET);
395         buffer = g_malloc(size+1);
396         size = fread(buffer, 1, size, fd);
397         buffer[size] = 0;
398         gval = ghb_resource_parse(buffer, (gssize)size);
399         g_free(buffer);
400         return gval;
401 }
402
403
404 gint
405 main(gint argc, gchar *argv[])
406 {
407         FILE *file;
408         GValue *gval;
409
410         if (argc < 3)
411         {
412                 fprintf(stderr, "Usage: <in resource list> <out resource plist>\n");
413                 return 1;
414         }
415         g_type_init();
416         file = g_fopen(argv[1], "r");
417         if (file == NULL)
418                 return 1;
419
420         gval = ghb_resource_parse_file(file);
421         ghb_plist_write_file(argv[2], gval);
422         return 0;
423 }
424