summary refs log tree commit diff
path: root/mico-dump.c
blob: 982c1b489df1f9d95f30c9675f937c3ff92e6ad6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <zip.h>

zip_t *zip;

struct bitreader {
	zip_file_t *input;

        uint64_t bitbuf;        // value of bits in write buffer
        int bitcount;   // number of bits in write buffer

	int eof;
};

static uint64_t
getbits1_msb(struct bitreader *input, int count)
{
        assert(count >= 1 && count <= 57);

        // Keep reading extra bytes until we have enough bits buffered
        // Big endian; our current bits are at the top of the word,
        // new bits get added at the bottom.
        while (input->bitcount < count) {
		unsigned char buf;
		int ret = zip_fread(input->input, &buf, sizeof buf);
		if (ret < 0) {
			printf("err: %s", zip_strerror(zip));
		}
		if (ret == 0) {
			input->eof = 1;
			return 0;
		}
                input->bitbuf |= (uint64_t)buf << (56 - input->bitcount);
                input->bitcount += 8;
        }

        // We now have enough bits present; the most significant
        // "count" bits in "bitbuf" are our result.
        uint64_t result = input->bitbuf >> (64 - count);

        // Now remove these bits from the buffer
        input->bitbuf <<= count;
        input->bitcount -= count;

        return result;
}

static int32_t
getsigned(struct bitreader *input, int count)
{
        uint64_t bits = getbits1_msb(input, count);
        uint64_t sign = 1 << (count - 1);

        if (bits & sign)
                return -(bits ^ sign) - 1;
        else
                return bits;
}

static int32_t
get1(struct bitreader *input)
{
        if (getbits1_msb(input, 1) == 0)
                return 0;
        if (getbits1_msb(input, 1) == 0)
                return getsigned(input, 7);
        if (getbits1_msb(input, 1) == 0)
                return getsigned(input, 9);
        if (getbits1_msb(input, 1) == 0)
                return getsigned(input, 12);
        return getsigned(input, 32);
}

int
main()
{
	zip = zip_open("out.zip", ZIP_RDONLY, 0);

	int entries = zip_get_num_entries(zip, 0);

	for (int i = 0; i < entries; i += 2) {
		struct bitreader ts = { 0 };
		struct bitreader vs = { 0 };

		/* XXX verify assumptions on zip file order */
		ts.input = zip_fopen_index(zip, i, 0);
		vs.input = zip_fopen_index(zip, i+1, 0);

		char *name = strdup(zip_get_name(zip, i, ZIP_FL_ENC_RAW));
		char *s = strchr(name, '/');
		*s = '{';
		s = strrchr(name, '/');
		*s++ = '}';
		*s = 0;

		int64_t t = 0, td = 0;
		double v = 0.0;

		while (!ts.eof) {
			int32_t tdd = get1(&ts);
			int32_t vd = get1(&vs);

			td += tdd;
			t += td;
			v += vd;

			printf("%s %f %ld\n", name, v/10000.0, t);
		}
	}
}