Ejemplo n.º 1
0
static void test_uleb(void)
{
    uint32_t i, val;
    uint8_t buf[2];
    int encode_ret, decode_ret;

    for (i = 0; i <= 0x3fff; i++) {
        encode_ret = uleb128_encode_small(&buf[0], i);
        decode_ret = uleb128_decode_small(&buf[0], &val);
        g_assert(encode_ret == decode_ret);
        g_assert(i == val);
    }

    /* decode invalid value */
    buf[0] = 0x80;
    buf[1] = 0x80;

    decode_ret = uleb128_decode_small(&buf[0], &val);
    g_assert(decode_ret == -1);
    g_assert(val == 0);
}
Ejemplo n.º 2
0
static void test_encode_decode_1_byte(void)
{
    uint8_t *buffer = g_malloc0(PAGE_SIZE);
    uint8_t *test = g_malloc0(PAGE_SIZE);
    uint8_t *compressed = g_malloc(PAGE_SIZE);
    int dlen = 0, rc = 0;
    uint8_t buf[2];

    test[PAGE_SIZE - 1] = 1;

    dlen = xbzrle_encode_buffer(buffer, test, PAGE_SIZE, compressed,
                       PAGE_SIZE);
    g_assert(dlen == (uleb128_encode_small(&buf[0], 4095) + 2));

    rc = xbzrle_decode_buffer(compressed, dlen, buffer, PAGE_SIZE);
    g_assert(rc == PAGE_SIZE);
    g_assert(memcmp(test, buffer, PAGE_SIZE) == 0);

    g_free(buffer);
    g_free(compressed);
    g_free(test);
}
Ejemplo n.º 3
0
Archivo: xbzrle.c Proyecto: 8tab/qemu
/*
  page = zrun nzrun
       | zrun nzrun page

  zrun = length

  nzrun = length byte...

  length = uleb128 encoded integer
 */
int xbzrle_encode_buffer(uint8_t *old_buf, uint8_t *new_buf, int slen,
                         uint8_t *dst, int dlen)
{
    uint32_t zrun_len = 0, nzrun_len = 0;
    int d = 0, i = 0;
    long res;
    uint8_t *nzrun_start = NULL;

    g_assert(!(((uintptr_t)old_buf | (uintptr_t)new_buf | slen) %
               sizeof(long)));

    while (i < slen) {
        /* overflow */
        if (d + 2 > dlen) {
            return -1;
        }

        /* not aligned to sizeof(long) */
        res = (slen - i) % sizeof(long);
        while (res && old_buf[i] == new_buf[i]) {
            zrun_len++;
            i++;
            res--;
        }

        /* word at a time for speed */
        if (!res) {
            while (i < slen &&
                   (*(long *)(old_buf + i)) == (*(long *)(new_buf + i))) {
                i += sizeof(long);
                zrun_len += sizeof(long);
            }

            /* go over the rest */
            while (i < slen && old_buf[i] == new_buf[i]) {
                zrun_len++;
                i++;
            }
        }

        /* buffer unchanged */
        if (zrun_len == slen) {
            return 0;
        }

        /* skip last zero run */
        if (i == slen) {
            return d;
        }

        d += uleb128_encode_small(dst + d, zrun_len);

        zrun_len = 0;
        nzrun_start = new_buf + i;

        /* overflow */
        if (d + 2 > dlen) {
            return -1;
        }
        /* not aligned to sizeof(long) */
        res = (slen - i) % sizeof(long);
        while (res && old_buf[i] != new_buf[i]) {
            i++;
            nzrun_len++;
            res--;
        }

        /* word at a time for speed, use of 32-bit long okay */
        if (!res) {
            /* truncation to 32-bit long okay */
            unsigned long mask = (unsigned long)0x0101010101010101ULL;
            while (i < slen) {
                unsigned long xor;
                xor = *(unsigned long *)(old_buf + i)
                    ^ *(unsigned long *)(new_buf + i);
                if ((xor - mask) & ~xor & (mask << 7)) {
                    /* found the end of an nzrun within the current long */
                    while (old_buf[i] != new_buf[i]) {
                        nzrun_len++;
                        i++;
                    }
                    break;
                } else {
                    i += sizeof(long);
                    nzrun_len += sizeof(long);
                }
            }
        }

        d += uleb128_encode_small(dst + d, nzrun_len);
        /* overflow */
        if (d + nzrun_len > dlen) {
            return -1;
        }
        memcpy(dst + d, nzrun_start, nzrun_len);
        d += nzrun_len;
        nzrun_len = 0;
    }

    return d;
}