summary refs log tree commit diff
path: root/mico-dump.c
blob: 37ed025e7d0a5471d23119b9ab872aee7f60a8ea (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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.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 int64_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);

	int64_t v = getsigned(input, 32);
	v <<= 32;
	v |= getbits1_msb(input, 32);

	return v;
}

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;

		int64_t len = get1(&ts);
		int64_t lenv = get1(&vs);

		if (len != lenv) {
			fprintf(stderr, "time and value length don't agree");
			exit(-1);
		}

		for (int64_t j = 0; j < len; j++) {
			int64_t tdd = get1(&ts);
			int64_t vd = get1(&vs);

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

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