Fix:Android:Corrected and added keycodes
[navit-package] / navit / maptool / sourcesink.c
1 #include <stdio.h>
2 #include <glib.h>
3 #include <string.h>
4 #include "coord.h"
5 #include "item.h"
6 #include "attr.h"
7 #include "maptool.h"
8
9 struct item_bin_sink *
10 item_bin_sink_new(void)
11 {
12         struct item_bin_sink *ret=g_new0(struct item_bin_sink, 1);
13
14         return ret;
15 }
16
17 struct item_bin_sink_func *
18 item_bin_sink_func_new(int (*func)(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data))
19 {
20         struct item_bin_sink_func *ret=g_new0(struct item_bin_sink_func, 1);
21         ret->func=func;
22         return ret;
23 }
24
25 void
26 item_bin_sink_func_destroy(struct item_bin_sink_func *func)
27 {
28         g_free(func);
29 }
30
31 void
32 item_bin_sink_add_func(struct item_bin_sink *sink, struct item_bin_sink_func *func)
33 {
34         sink->sink_funcs=g_list_append(sink->sink_funcs, func);
35 }
36
37 void
38 item_bin_sink_destroy(struct item_bin_sink *sink)
39 {
40         /* g_list_foreach(sink->sink_funcs, (GFunc)g_free, NULL); */
41         g_list_free(sink->sink_funcs);
42         g_free(sink);
43 }
44
45 int
46 item_bin_write_to_sink(struct item_bin *ib, struct item_bin_sink *sink, struct tile_data *tile_data)
47 {
48         GList *list=sink->sink_funcs;
49         int ret=0;
50         while (list) {
51                 struct item_bin_sink_func *func=list->data;
52                 ret=func->func(func, ib, tile_data);
53                 if (ret)
54                         break;
55                 list=g_list_next(list);
56         }
57         return ret;
58 }
59
60 struct item_bin_sink *
61 file_reader_new(FILE *in, int limit, int offset)
62 {
63         struct item_bin_sink *ret;
64         if (!in)
65                 return NULL;
66         ret=item_bin_sink_new();
67         ret->priv_data[0]=in;
68         ret->priv_data[1]=(void *)(long)limit;
69         ret->priv_data[2]=(void *)(long)offset;
70         fseek(in, 0, SEEK_SET);
71         return ret;
72 }
73
74 int
75 file_reader_finish(struct item_bin_sink *sink)
76 {
77         struct item_bin *ib=(struct item_bin *)buffer;
78         int ret =0;
79         FILE *in=sink->priv_data[0];
80         int limit=(int)(long)sink->priv_data[1];
81         int offset=(int)(long)sink->priv_data[2];
82         for (;;) {
83                 switch (item_bin_read(ib, in)) {
84                 case 0:
85                         item_bin_sink_destroy(sink);
86                         return 0;
87                 case 2:
88                         if (offset > 0) {
89                                 offset--;
90                         } else {
91                                 ret=item_bin_write_to_sink(ib, sink, NULL);
92                                 if (ret || (limit != -1 && !--limit)) {
93                                         item_bin_sink_destroy(sink);
94                                         return ret;
95                                 }
96                         }
97                 default:
98                         continue;
99                 }
100         }
101 }
102
103 int
104 file_writer_process(struct item_bin_sink_func *func, struct item_bin *ib, struct tile_data *tile_data)
105 {
106         FILE *out=func->priv_data[0];
107         item_bin_write(ib, out);
108         return 0;
109 }
110
111 struct item_bin_sink_func *
112 file_writer_new(FILE *out)
113 {
114         struct item_bin_sink_func *file_writer;
115         if (!out)
116                 return NULL;
117         file_writer=item_bin_sink_func_new(file_writer_process);
118         file_writer->priv_data[0]=out;
119         return file_writer;
120 }
121
122 int
123 file_writer_finish(struct item_bin_sink_func *file_writer)
124 {
125         item_bin_sink_func_destroy(file_writer);
126         return 0;
127 }
128
129
130 int
131 tile_collector_process(struct item_bin_sink_func *tile_collector, struct item_bin *ib, struct tile_data *tile_data)
132 {
133         int *buffer,*buffer2;
134         int len=ib->len+1;
135         GHashTable *hash=tile_collector->priv_data[0];
136         buffer=g_hash_table_lookup(hash, tile_data->buffer);
137         buffer2=g_malloc((len+(buffer ? buffer[0] : 1))*4);
138         if (buffer) {
139                 memcpy(buffer2, buffer, buffer[0]*4);
140         } else 
141                 buffer2[0]=1;
142         memcpy(buffer2+buffer2[0], ib, len*4);
143         buffer2[0]+=len;
144         g_hash_table_insert(hash, g_strdup(tile_data->buffer), buffer2);
145         return 0;
146 }
147
148 struct item_bin_sink_func *
149 tile_collector_new(struct item_bin_sink *out)
150 {
151         struct item_bin_sink_func *tile_collector;
152         tile_collector=item_bin_sink_func_new(tile_collector_process);
153         tile_collector->priv_data[0]=g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
154         tile_collector->priv_data[1]=out;
155         return tile_collector;
156 }
157