Added customized decode.c
[timetab.git] / tt-decode.c
blob84219073a31da62bf1084a0566073768214eba57
1 /*
2 * IDOS Data Decoder
4 * (c) 2000--2001 Martin Mares <mj@ucw.cz>
5 * (c) 2001--2002 Pavel Machek <pavel@ucw.cz>
6 * (c) 2013--2013 Tomas Pokorny <jethro@kam.mff.cuni.cz>
8 * This software can be freely distributed and used according
9 * to the terms of the GNU General Public License.
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/stat.h>
16 #include <fcntl.h>
17 #include <unistd.h>
18 #include <time.h>
20 static char start_date[100];
21 static unsigned int start_stamp;
23 /* Loading of blocks */
25 static void *
26 load(char *name)
28 int *p;
29 struct stat st;
30 int fd;
32 fd = open(name, O_RDONLY);
33 if (fd < 0) { fprintf(stderr, "open(%s): %m", name); exit(1); }
34 if (fstat(fd, &st) < 0) { fprintf(stderr, "stat: %m"); exit(1); }
35 p = malloc(st.st_size + sizeof(int));
36 *p++ = st.st_size;
37 if (read(fd, p, st.st_size) != st.st_size) { fprintf(stderr, "read: %m"); exit(1); }
38 close(fd);
39 return p;
42 static int
43 size(void *x)
45 return ((int *)x)[-1];
48 #define ASSERT(x) if (!(x)) { fprintf(stderr, "Assertion failed: " #x "\n"); exit(1); }
50 /* Misc */
52 static unsigned int
53 gl(unsigned char *x)
55 return x[0] | (x[1] << 8) | (x[2] << 16) | (x[3] << 24);
58 static char *
59 ustamp(time_t x)
61 static char buf[64];
62 struct tm *t = localtime(&x);
63 strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", t);
64 return buf;
67 static char *
68 ystamp(unsigned x, char *fmt)
70 time_t w = (x-70*365-17)*86400 + 5000;
71 static char buf[64];
72 struct tm *t = localtime(&w);
73 strftime(buf, sizeof(buf), fmt, t);
74 return buf;
77 static char *
78 xstamp(unsigned x)
80 return ystamp(x, "%Y-%m-%d");
83 static char *
84 xstamp2(unsigned x)
86 return ystamp(x, "y%Y m%m d%Y");
89 static void
90 string(int *i, char *s, int t)
92 if (t < 0 || t >= size(i)/4-1)
93 printf("<invalid:%08x>", t);
94 else
95 fwrite(s+i[t], 1, i[t+1] - i[t], stdout);
98 /* Header */
100 static int langs;
101 static int time_rs, time_r_off;
103 static void
104 dump_hdr(void)
106 char *hdr = load("0000");
107 int *dbni = load("0001");
108 char *dbns = load("0002");
109 int *copi = load("0003");
110 char *cops = load("0004");
112 puts("!version 1.1\n");
113 printf("; ### DATABASE ###\n");
114 ASSERT(hdr[0x3f] == 0x0d && hdr[0x40] == 0x0a && hdr[0x41] == 0x1a);
115 printf("; Database: "); string(dbni, dbns, 0); putchar('\n');
116 printf("; Copyright: "); string(copi, cops, 0); putchar('\n');
117 printf("; Versions: %x %d.%d\n", gl(hdr+0x46), hdr[0x4a], hdr[0x4b]);
118 printf("; File created: %s\n", ustamp(gl(hdr+0x42)));
119 printf("!valid %s .. %s\n", xstamp2(gl(hdr+0x54)), xstamp2(gl(hdr+0x58)));
120 printf("; Time remark range: %s ", xstamp(gl(hdr+0x5c)));
121 strcpy(start_date, xstamp2(gl(hdr+0x54)));
122 start_stamp=gl(hdr+0x54);
123 printf("; to %s\n", xstamp(gl(hdr+0x60)));
124 time_r_off = gl(hdr+0x5c);
125 time_rs = gl(hdr+0x60) - time_r_off + 1;
126 printf("; Last update: %s\n", xstamp(gl(hdr+0x50)));
127 langs = size(dbni) / 4;
128 printf("; Language count: %d\n", langs);
131 /* Stations */
133 static int *stanami;
134 static char *stanams;
135 static int nstats;
137 static void
138 dump_stat(void)
140 int i;
141 int *x10 = load("0010");
142 unsigned short *x11 = load("0011");
143 unsigned short *x14 = load("0014");
144 unsigned short *x15 = load("0015");
145 short *ctry = load("0016");
146 int *ctryi = load("0017");
147 char *ctrys = load("0018");
148 short *x19 = load("0019");
149 int *x19i = load("0020");
150 char *x19s = load("0021");
151 int *x23 = load("0023");
153 puts("\n; ### STATIONS ###\n");
154 stanami = load("0008");
155 nstats = size(stanami) / 4 - 1;
156 stanams = load("0009");
157 for (i=0; i<nstats; i++)
159 printf("; %08x ", i);
160 string(stanami, stanams, i);
161 if (size(ctry))
163 printf(" [");
164 if (ctry[i] < 0)
165 printf("?");
166 else
167 string(ctryi, ctrys, ctry[i]);
168 printf("]");
170 if (size(x19))
172 printf(" [");
173 if (x19[i])
174 string(x19i, x19s, x19[i]-1);
175 else
176 printf("?");
177 printf("]");
179 putchar('\n');
180 printf("; \t%08x %04x %04x %04x %08x\n", x10[i], x11[i], x14[i], x15[i], x23[i]);
184 /* Time remarks */
186 static unsigned char **time_r;
188 static void
189 load_time_r(void)
191 int i;
193 time_r = malloc(sizeof(unsigned char *) * time_rs);
194 for (i=0; i<time_rs; i++)
196 char x[8];
197 sprintf(x, "%d", 7000+i);
198 time_r[i] = load(x);
202 static void
203 timerem(int i)
205 int j;
206 unsigned char week = 0, old_week = 0xff;
207 int count = 0;
209 printf("D%s %d ", start_date, time_rs);
211 for (j=0; j<time_rs; j++)
213 /* j corresponds to day time_r_off + j */
214 unsigned char *z = time_r[j];
216 week |= (!!(z[i/8] & (1 << (i%8)))) << (j%7);
217 if (!((j+1)%7))
219 if (old_week == week)
220 count++;
221 else
223 if (old_week != 0xff)
224 printf("%d:%x ", count+1, old_week );
225 old_week = week;
226 week = 0;
227 count = 0;
231 printf("%d:%x", count+1, old_week );
234 /* The Timetable */
237 static void
238 dump_tt(void)
240 int *neighi = load("0025");
241 unsigned short *neighx = load("0026");
242 int *neighd = load("0027");
243 int *tti = load("3001");
244 char *tts = load("3002");
245 int *tnum = load("3004");
246 int *tnumi = load("3005");
247 char *tnums = load("3006");
248 int *tname = load("3008");
249 int *tnamei = load("3009");
250 char *tnames = load("3010");
251 unsigned int *tflag = load("3011");
252 int *tabbri = load("4000");
253 char *tabbrs = load("4001");
254 short *rembl = load("5000");
255 int *rembi = load("5001");
256 short *rembx = load("5002");
257 int *remi = load("5003");
258 char *rems = load("5004");
259 short *trem = load("5100");
260 int *metri = load("6001");
261 int *metrx = load("6002");
262 short *line = load("6100");
263 int *linei = load("6101");
264 char *lines = load("6102");
265 short *comp = load("6200");
266 int *compi = load("6201");
267 char *comps = load("6202");
268 int time_plus, conn;
269 int i,j,k,m;
272 puts("; ### TIMETABLE ###\n");
273 for(i=0; i<size(tti)/4-1; i++)
275 j = tflag[i] & 0x7fffff;
276 printf("# ");
277 for (k=0; j & (1 << k); k++)
278 string(tabbri, tabbrs, k);
280 if (tnum[i] >= 0)
281 printf("%d", tnum[i]);
282 else
283 string(tnumi, tnums, ~tnum[i]);
284 printf("__%04x\n;", i);
285 if (size(tname))
287 printf(" \"");
288 if (tname[i] >= 0)
289 printf("%d", tname[i]);
290 else
291 string(tnamei, tnames, ~tname[i]);
292 putchar('"');
294 printf(" flag=%08x\n", tflag[i]);
296 time_plus = 0;
297 conn = i;
299 retry:
301 unsigned short *z;
302 int j,k,w;
303 int last = -1;
304 int cud = 0;
306 for(j=tti[conn], w=0; j<tti[conn+1]; j+=4, w++)
308 if(j > (size(tts))) {
309 fprintf(stderr, "Pointer to real data out of range?\n");
310 printf("; Error: Pointer to real data out of range!\n");
311 break;
313 z = (short *)(tts+j);
314 if ((z[0] & 0x800) && j == tti[conn])
316 printf("; -> %x + %d\n", ((z[0] & 0xf000) << 4) | z[1], z[0] & 0x7ff);
317 conn = ((z[0] & 0xf000) << 4) | z[1];
318 time_plus = z[0] & 0x7ff;
319 goto retry;
321 else
323 k = (z[0] & 0x7ff) + time_plus;
324 if (k > 24*60) {
325 static int warn;
326 if (!warn)
327 fprintf(stderr, "Warning - invalid time:\t%2d:%02d\n", k/60, k%60);
328 warn = 1;
329 // k = k % (24*60);
331 printf("\t%d\t", k);
333 if (size(metri) && metri[conn] < metri[conn+1])
335 if (metri[conn] + 4*w < metri[conn+1])
336 printf("%f", (double) metrx[(metri[conn]+w)/4] / 1000);
337 else
338 printf("-");
340 else
342 #if 0
343 if (w && last != z[1])
345 int nei;
346 for (nei=neighi[last]; nei<neighi[last+1]; nei++)
347 if (neighx[nei] == z[1])
348 break;
349 if (nei < neighi[last+1])
351 cud += neighd[nei];
352 // printf("%d:", neighd[nei]);
354 else
355 ASSERT(0);
357 #endif
358 printf("%f", (double) cud/1000);
360 putchar('\t');
361 string(stanami, stanams, z[1]);
362 last = z[1];
363 if (z[0] & 0xf800) printf(" <%04x>", z[0] & 0xf800);
364 putchar('\n');
369 if (size(line))
371 printf("L");
372 string(linei, lines, line[i]);
373 putchar('\n');
375 if (size(comp))
377 printf("G");
378 string(compi, comps, comp[i]);
379 putchar('\n');
382 timerem(trem[i]);
383 putchar('\n');
385 if (size(rembl))
387 k = rembl[i];
388 for (j=rembi[k]; j<rembi[k+1]; j++)
390 m = rembx[j];
391 printf("B%x ", m);
392 string(remi, rems, m);
393 putchar('\n');
399 /* main */
401 int main(void)
403 dump_hdr();
404 dump_stat();
405 load_time_r();
406 dump_tt();
407 return 0;