summary refs log tree commit diff
path: root/mico-dump.c
diff options
context:
space:
mode:
Diffstat (limited to 'mico-dump.c')
-rw-r--r--mico-dump.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/mico-dump.c b/mico-dump.c
new file mode 100644
index 0000000..8bf12e4
--- /dev/null
+++ b/mico-dump.c
@@ -0,0 +1,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/10.0, t);
+		}
+	}
+}