Ready for reading by JAVA.
[timetab.git] / tt-decode.c
blob7d4e6bd570bd4643d6f33fbf3027b33c5018a582
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 time_t
68 tstamp(unsigned x)
70 return (x-70*365-17)*86400 + 5000;
73 static char *
74 ystamp(unsigned x, char *fmt)
76 time_t w = tstamp(x);
77 static char buf[64];
78 struct tm *t = localtime(&w);
79 strftime(buf, sizeof(buf), fmt, t);
80 return buf;
83 static char *
84 xstamp(unsigned x)
86 return ystamp(x, "%Y-%m-%d");
89 static char *
90 xstamp2(unsigned x)
92 return ystamp(x, "y%Y m%m d%Y");
95 static void
96 string(int *i, char *s, int t)
98 if (t < 0 || t >= size(i)/4-1)
99 printf("<invalid:%08x>", t);
100 else
101 fwrite(s+i[t], 1, i[t+1] - i[t], stdout);
104 /* Header */
106 static int langs;
107 static int time_rs, time_r_off;
109 static void
110 dump_hdr(void)
112 char *hdr = load("0000");
113 int *dbni = load("0001");
114 char *dbns = load("0002");
115 int *copi = load("0003");
116 char *cops = load("0004");
118 puts("!version 1.1\n");
119 printf("; ### DATABASE ###\n");
120 ASSERT(hdr[0x3f] == 0x0d && hdr[0x40] == 0x0a && hdr[0x41] == 0x1a);
121 printf("; Database: "); string(dbni, dbns, 0); putchar('\n');
122 printf("; Copyright: "); string(copi, cops, 0); putchar('\n');
123 printf("; Versions: %x %d.%d\n", gl(hdr+0x46), hdr[0x4a], hdr[0x4b]);
124 printf("; File created: %s\n", ustamp(gl(hdr+0x42)));
125 printf("!valid %s .. %s\n", xstamp2(gl(hdr+0x54)), xstamp2(gl(hdr+0x58)));
126 printf("; Time remark range: %s ", xstamp(gl(hdr+0x5c)));
127 strcpy(start_date, xstamp2(gl(hdr+0x54)));
128 start_stamp=tstamp(gl(hdr+0x54));
129 printf("; to %s\n", xstamp(gl(hdr+0x60)));
130 time_r_off = gl(hdr+0x5c);
131 time_rs = gl(hdr+0x60) - time_r_off + 1;
132 printf("; Last update: %s\n", xstamp(gl(hdr+0x50)));
133 langs = size(dbni) / 4;
134 printf("; Language count: %d\n", langs);
137 /* Stations */
139 static int *stanami;
140 static char *stanams;
141 static int nstats;
143 static void
144 dump_stat(void)
146 int i;
147 int *x10 = load("0010");
148 unsigned short *x11 = load("0011");
149 unsigned short *x14 = load("0014");
150 unsigned short *x15 = load("0015");
151 short *ctry = load("0016");
152 int *ctryi = load("0017");
153 char *ctrys = load("0018");
154 short *x19 = load("0019");
155 int *x19i = load("0020");
156 char *x19s = load("0021");
157 int *x23 = load("0023");
159 puts("\n; ### STATIONS ###\n");
160 stanami = load("0008");
161 nstats = size(stanami) / 4 - 1;
162 stanams = load("0009");
163 for (i=0; i<nstats; i++)
165 printf("; %08x ", i);
166 string(stanami, stanams, i);
167 if (size(ctry))
169 printf(" [");
170 if (ctry[i] < 0)
171 printf("?");
172 else
173 string(ctryi, ctrys, ctry[i]);
174 printf("]");
176 if (size(x19))
178 printf(" [");
179 if (x19[i])
180 string(x19i, x19s, x19[i]-1);
181 else
182 printf("?");
183 printf("]");
185 putchar('\n');
186 printf("; \t%08x %04x %04x %04x %08x\n", x10[i], x11[i], x14[i], x15[i], x23[i]);
190 /* Time remarks */
192 static unsigned char **time_r;
194 static void
195 load_time_r(void)
197 int i;
199 time_r = malloc(sizeof(unsigned char *) * time_rs);
200 for (i=0; i<time_rs; i++)
202 char x[8];
203 sprintf(x, "%d", 7000+i);
204 time_r[i] = load(x);
208 static void
209 timerem(int i)
211 int j;
212 unsigned char week = 0, old_week = 0xff;
213 int count = 0;
215 printf("D %d %d ", start_stamp, time_rs);
217 for (j=0; j<time_rs; j++)
219 /* j corresponds to day time_r_off + j */
220 unsigned char *z = time_r[j];
222 week |= (!!(z[i/8] & (1 << (i%8)))) << (j%7);
223 if (!((j+1)%7))
225 if (old_week == week)
226 count++;
227 else
229 if (old_week != 0xff)
230 printf("%d:%x ", count+1, old_week );
231 old_week = week;
232 week = 0;
233 count = 0;
237 printf("%d:%x", count+1, old_week );
240 /* The Timetable */
243 static void
244 dump_tt(void)
246 int *neighi = load("0025");
247 unsigned short *neighx = load("0026");
248 int *neighd = load("0027");
249 int *tti = load("3001");
250 char *tts = load("3002");
251 int *tnum = load("3004");
252 int *tnumi = load("3005");
253 char *tnums = load("3006");
254 int *tname = load("3008");
255 int *tnamei = load("3009");
256 char *tnames = load("3010");
257 unsigned int *tflag = load("3011");
258 int *tabbri = load("4000");
259 char *tabbrs = load("4001");
260 short *rembl = load("5000");
261 int *rembi = load("5001");
262 short *rembx = load("5002");
263 int *remi = load("5003");
264 char *rems = load("5004");
265 short *trem = load("5100");
266 int *metri = load("6001");
267 int *metrx = load("6002");
268 short *line = load("6100");
269 int *linei = load("6101");
270 char *lines = load("6102");
271 short *comp = load("6200");
272 int *compi = load("6201");
273 char *comps = load("6202");
274 int time_plus, conn;
275 int i,j,k,m;
278 puts("; ### TIMETABLE ###\n");
279 for(i=0; i<size(tti)/4-1; i++)
281 j = tflag[i] & 0x7fffff;
282 printf("# ");
283 for (k=0; j & (1 << k); k++)
284 string(tabbri, tabbrs, k);
286 if (tnum[i] >= 0)
287 printf("%d", tnum[i]);
288 else
289 string(tnumi, tnums, ~tnum[i]);
290 printf(" %04x\n;", i);
291 if (size(tname))
293 printf(" \"");
294 if (tname[i] >= 0)
295 printf("%d", tname[i]);
296 else
297 string(tnamei, tnames, ~tname[i]);
298 putchar('"');
300 printf(" flag=%08x\n", tflag[i]);
302 time_plus = 0;
303 conn = i;
305 retry:
307 unsigned short *z;
308 int j,k,w;
309 int last = -1;
310 int cud = 0;
312 for(j=tti[conn], w=0; j<tti[conn+1]; j+=4, w++)
314 if(j > (size(tts))) {
315 fprintf(stderr, "Pointer to real data out of range?\n");
316 printf("; Error: Pointer to real data out of range!\n");
317 break;
319 z = (short *)(tts+j);
320 if ((z[0] & 0x800) && j == tti[conn])
322 printf("; -> %x + %d\n", ((z[0] & 0xf000) << 4) | z[1], z[0] & 0x7ff);
323 conn = ((z[0] & 0xf000) << 4) | z[1];
324 time_plus = z[0] & 0x7ff;
325 goto retry;
327 else
329 k = (z[0] & 0x7ff) + time_plus;
330 if (k > 24*60) {
331 static int warn;
332 if (!warn)
333 fprintf(stderr, "Warning - invalid time:\t%2d:%02d\n", k/60, k%60);
334 warn = 1;
335 // k = k % (24*60);
337 printf("\t%d\t", k);
339 /* if (size(metri) && metri[conn] < metri[conn+1])
341 if (metri[conn] + 4*w < metri[conn+1])
342 printf("%f", (double) metrx[(metri[conn]+w)/4] / 1000);
343 else
344 printf("-");
346 else
348 #if 0
349 if (w && last != z[1])
351 int nei;
352 for (nei=neighi[last]; nei<neighi[last+1]; nei++)
353 if (neighx[nei] == z[1])
354 break;
355 if (nei < neighi[last+1])
357 cud += neighd[nei];
358 // printf("%d:", neighd[nei]);
360 else
361 ASSERT(0);
363 #endif
364 printf("%f", (double) cud/1000);
366 putchar('\t');
367 printf("%d\t", z[1]);
368 // string(stanami, stanams, z[1]);
369 last = z[1];
370 if (z[0] & 0xf800) printf(" %04x", z[0] & 0xf800);
371 putchar('\n');
376 if (size(line))
378 printf("L");
379 string(linei, lines, line[i]);
380 putchar('\n');
382 if (size(comp))
384 printf("G");
385 string(compi, comps, comp[i]);
386 putchar('\n');
389 timerem(trem[i]);
390 putchar('\n');
392 if (size(rembl))
394 k = rembl[i];
395 for (j=rembi[k]; j<rembi[k+1]; j++)
397 m = rembx[j];
398 printf("B%x ", m);
399 string(remi, rems, m);
400 putchar('\n');
406 /* main */
408 int main(void)
410 dump_hdr();
411 dump_stat();
412 load_time_r();
413 dump_tt();
414 return 0;