return len * 2 + 1;
}
+static uint8_t stree_aux(size_t rem)
+{
+ if (rem == 0) return 0;
+ if (rem <= 1) return 1;
+ if (rem <= 2) return 2;
+ if (rem <= 4) return 3;
+ if (rem <= 8) return 4;
+ if (rem <= 16) return 5;
+ if (rem <= 32) return 6;
+ return 7;
+}
+
int stree_encode(size_t len, const uint8_t *in, uint8_t *out, size_t *aux)
{
struct node *nodes;
active_node = root;
for (i = 0; i < len; ++i) {
- aux[i] = (size_t) (active_node - root);
+ aux[i] = stree_aux(rem);
prev = (struct node *) 0;
++rem;
memset(seen, 0, sizeof seen);
active_node = root;
for (i = 0; i < len; ++i) {
- aux[i] = (size_t) (active_node - root);
+ aux[i] = stree_aux(rem);
prev = (struct node *) 0;
++rem;
memset(seen, 0, sizeof seen);
size_t aux[5];
ASSERT_EQ(0, stree_encode(5, in, out, aux));
- /*
- ASSERT_EQ(0, out[0]);
- ASSERT_EQ(1, out[1]);
- ASSERT_EQ(0, out[2]);
+ ASSERT_EQ('a', out[0]);
+ ASSERT_EQ('b', out[1]);
+ ASSERT_EQ(1, out[2]);
ASSERT_EQ(1, out[3]);
- ASSERT_EQ(0, out[4]);
- */
-
- ASSERT_EQ(0, aux[0]);
- ASSERT_EQ(0, aux[1]);
- ASSERT_EQ(0, aux[2]);
- ASSERT_EQ(0, aux[3]);
- ASSERT_EQ(3, aux[4]);
+ ASSERT_EQ(1, out[4]);
return TEST_SUCCESS;
}
size_t aux[10];
ASSERT_EQ(0, stree_encode(10, in, out, aux));
- /*
- ASSERT_EQ(0, out[0]);
- ASSERT_EQ(1, out[1]);
- ASSERT_EQ(2, out[2]);
- ASSERT_EQ(0, out[3]);
+ ASSERT_EQ('a', out[0]);
+ ASSERT_EQ('b', out[1]);
+ ASSERT_EQ('c', out[2]);
+ ASSERT_EQ(2, out[3]);
ASSERT_EQ(0, out[4]);
- ASSERT_EQ(3, out[5]);
- ASSERT_EQ(0, out[6]);
+ ASSERT_EQ('x', out[5]);
+ ASSERT_EQ(3, out[6]);
ASSERT_EQ(0, out[7]);
- ASSERT_EQ(1, out[8]);
- ASSERT_EQ(3, out[9]);
- */
-
- ASSERT_EQ(0, aux[0]);
- ASSERT_EQ(0, aux[1]);
- ASSERT_EQ(0, aux[2]);
- ASSERT_EQ(0, aux[3]);
- ASSERT_EQ(0, aux[4]);
- ASSERT_EQ(0, aux[5]);
- ASSERT_EQ(0, aux[6]);
- ASSERT_EQ(0, aux[7]);
- ASSERT_EQ(4, aux[8]);
- ASSERT_EQ(4, aux[9]);
+ ASSERT_EQ(0, out[8]);
+ ASSERT_EQ('e', out[9]);
return TEST_SUCCESS;
}
size_t aux[7];
ASSERT_EQ(0, stree_encode(7, in, out, aux));
- /*
- ASSERT_EQ(2, out[0]);
- ASSERT_EQ(3, out[1]);
- ASSERT_EQ(1, out[2]);
+ ASSERT_EQ('c', out[0]);
+ ASSERT_EQ('d', out[1]);
+ ASSERT_EQ(0, out[2]);
ASSERT_EQ(0, out[3]);
ASSERT_EQ(1, out[4]);
ASSERT_EQ(0, out[5]);
ASSERT_EQ(1, out[6]);
- */
-
- ASSERT_EQ(0, aux[0]);
- ASSERT_EQ(0, aux[1]);
- ASSERT_EQ(0, aux[2]);
- ASSERT_EQ(0, aux[3]);
- ASSERT_EQ(0, aux[4]);
- ASSERT_EQ(0, aux[5]);
- ASSERT_EQ(0, aux[6]);
return TEST_SUCCESS;
}
ASSERT_EQ('a', out[3]);
ASSERT_EQ('a', out[4]);
- ASSERT_EQ(0, aux[0]);
- ASSERT_EQ(0, aux[1]);
- ASSERT_EQ(0, aux[2]);
- ASSERT_EQ(0, aux[3]);
- ASSERT_EQ(3, aux[4]);
-
return TEST_SUCCESS;
}
return TEST_SUCCESS;
}
+static enum test_result test_stree_roundtrip_iterated(void)
+{
+ const uint8_t *in = (const uint8_t *) "1231313223";
+ uint8_t enc[10];
+ uint8_t dec[10];
+ size_t aux1[10];
+ size_t aux2[10];
+ size_t i;
+
+ ASSERT_EQ(0, stree_encode(10, in, enc, aux1));
+
+ for (i = 0; i < 1024; ++i) {
+ ASSERT_EQ(0, stree_encode(10, enc, dec, aux2));
+ ASSERT_EQ(0, stree_encode(10, dec, enc, aux2));
+ }
+
+ for (i = 0; i < 1024; ++i) {
+ ASSERT_EQ(0, stree_decode(10, enc, dec, aux2));
+ ASSERT_EQ(0, stree_decode(10, dec, enc, aux2));
+ }
+
+ ASSERT_EQ(0, stree_decode(10, enc, dec, aux2));
+
+ ASSERT_EQ(in[0], dec[0]);
+ ASSERT_EQ(in[1], dec[1]);
+ ASSERT_EQ(in[2], dec[2]);
+ ASSERT_EQ(in[3], dec[3]);
+ ASSERT_EQ(in[4], dec[4]);
+ ASSERT_EQ(in[5], dec[5]);
+ ASSERT_EQ(in[6], dec[6]);
+ ASSERT_EQ(in[7], dec[7]);
+ ASSERT_EQ(in[8], dec[8]);
+ ASSERT_EQ(in[9], dec[9]);
+
+ ASSERT_EQ(aux1[0], aux2[0]);
+ ASSERT_EQ(aux1[1], aux2[1]);
+ ASSERT_EQ(aux1[2], aux2[2]);
+ ASSERT_EQ(aux1[3], aux2[3]);
+ ASSERT_EQ(aux1[4], aux2[4]);
+ ASSERT_EQ(aux1[5], aux2[5]);
+ ASSERT_EQ(aux1[6], aux2[6]);
+ ASSERT_EQ(aux1[7], aux2[7]);
+ ASSERT_EQ(aux1[8], aux2[8]);
+ ASSERT_EQ(aux1[9], aux2[9]);
+
+ return TEST_SUCCESS;
+}
+
int main(void)
{
RUN_TEST(test_stree_encode_empty);
RUN_TEST(test_stree_decode_simple);
RUN_TEST(test_stree_decode_nontrivial);
RUN_TEST(test_stree_roundtrip_so_example);
+ RUN_TEST(test_stree_roundtrip_iterated);
}