예제 #1
0
int process_frame_insert(avro_value_t *record_val, frame_reader_t reader, uint64_t wal_pos) {
    int err = 0, key_present;
    avro_value_t relid_val, key_val, new_val, branch_val;
    int64_t relid;
    const void *key_bin = NULL, *new_bin = NULL;
    size_t key_len = 0, new_len = 0;

    check(err, avro_value_get_by_index(record_val, 0, &relid_val, NULL));
    check(err, avro_value_get_by_index(record_val, 1, &key_val,   NULL));
    check(err, avro_value_get_by_index(record_val, 2, &new_val,   NULL));
    check(err, avro_value_get_long(&relid_val, &relid));
    check(err, avro_value_get_discriminant(&key_val, &key_present));
    check(err, avro_value_get_bytes(&new_val, &new_bin, &new_len));

    schema_list_entry *entry = schema_list_lookup(reader, relid);
    if (!entry) {
        avro_set_error("Received insert for unknown relid %u", relid);
        return EINVAL;
    }

    if (key_present) {
        check(err, avro_value_get_current_branch(&key_val, &branch_val));
        check(err, avro_value_get_bytes(&branch_val, &key_bin, &key_len));
        check(err, read_entirely(&entry->key_value, entry->avro_reader, key_bin, key_len));
    }

    check(err, read_entirely(&entry->row_value, entry->avro_reader, new_bin, new_len));

    if (reader->on_insert_row) {
        check(err, reader->on_insert_row(reader->cb_context, wal_pos, relid,
                                         key_bin, key_len, key_bin ? &entry->key_value : NULL,
                                         new_bin, new_len, &entry->row_value));
    }
    return err;
}
예제 #2
0
int parse_frame(frame_reader_t reader, uint64_t wal_pos, char *buf, int buflen) {
    int err = 0;
    check(err, read_entirely(&reader->frame_value, reader->avro_reader, buf, buflen));
    check(err, process_frame(&reader->frame_value, reader, wal_pos));
    return err;
}
예제 #3
0
int parse_cursor_file(xcb_cursor_context_t *c, const int fd, xcint_image_t **images, int *nimg) {
    /* Read the header, verify the magic value. */
    xcint_cursor_file_t cf;
    uint32_t nsizes = 0;
    uint32_t best = 0;
    uint32_t skip = 0;
    /* The amount of images stored in 'images', used when cleaning up. */
    int cnt = 0;

    if (!read_entirely(fd, &(cf.header), sizeof(xcint_file_header_t)))
        return -EINVAL;

    cf.header.magic = le32toh(cf.header.magic);
    cf.header.header = le32toh(cf.header.header);
    cf.header.version = le32toh(cf.header.version);
    cf.header.ntoc = le32toh(cf.header.ntoc);

    if (cf.header.magic != XCURSOR_MAGIC)
        return -EINVAL;

    if ((skip = (cf.header.header - sizeof(xcint_file_header_t))) > 0)
        if (lseek(fd, skip, SEEK_CUR) == EOF)
            return -EINVAL;

    if (cf.header.ntoc > 0x10000)
        return -EINVAL;

    /* Read the table of contents */
    cf.tocs = malloc(cf.header.ntoc * sizeof(xcint_file_toc_t));
    if (!read_entirely(fd, cf.tocs, cf.header.ntoc * sizeof(xcint_file_toc_t)))
        goto error;

    for (int n = 0; n < cf.header.ntoc; n++) {
        cf.tocs[n].type = le32toh(cf.tocs[n].type);
        cf.tocs[n].subtype = le32toh(cf.tocs[n].subtype);
        cf.tocs[n].position = le32toh(cf.tocs[n].position);
    }

    /* No images? Invalid file. */
    if ((best = find_best_size(&cf, c->size, &nsizes)) == 0 || nsizes == 0)
        goto error;

    *nimg = nsizes;
    if ((*images = calloc(nsizes, sizeof(xcint_image_t))) == NULL)
        goto error;

    for (int n = 0; n < cf.header.ntoc; n++) {
        xcint_chunk_header_t chunk;
        /* for convenience */
        xcint_image_t *i = &((*images)[cnt]);
        uint32_t numpixels = 0;
        uint32_t *p = NULL;

        if (cf.tocs[n].type != XCURSOR_IMAGE_TYPE ||
                cf.tocs[n].subtype != best)
            continue;

        lseek(fd, cf.tocs[n].position, SEEK_SET);
        if (!read_entirely(fd, &chunk, sizeof(xcint_chunk_header_t)))
            goto error2;
        chunk.header = le32toh(chunk.header);
        chunk.type = le32toh(chunk.type);
        chunk.subtype = le32toh(chunk.subtype);
        chunk.version = le32toh(chunk.version);
        /* Sanity check, as libxcursor does it. */
        if (chunk.type != cf.tocs[n].type ||
                chunk.subtype != cf.tocs[n].subtype)
            goto error2;
        if (!read_entirely(fd, i, sizeof(xcint_image_t) - sizeof(uint32_t*))) // TODO: better type
            goto error2;
        i->width = le32toh(i->width);
        i->height = le32toh(i->height);
        i->xhot = le32toh(i->xhot);
        i->yhot = le32toh(i->yhot);
        i->delay = le32toh(i->delay);

        /* Read the actual image data and convert it to host byte order */
        /* Catch integer overflows */
        if (((uint64_t)i->width) * i->height > UINT32_MAX)
            goto error2;
        numpixels = i->width * i->height;
        i->pixels = malloc(numpixels * sizeof(uint32_t));
        /* With the malloc, one more image is eligible for cleanup later. */
        cnt++;
        if (!read_entirely(fd, i->pixels, numpixels * sizeof(uint32_t)))
            goto error2;
        p = i->pixels;
        for (int j = 0; j < numpixels; j++, p++)
            *p = le32toh(*p);
    }

    free(cf.tocs);
    return 0;

error2:
    /* Free the memory for all images that were read so far. */
    for (int n = 0; n < cnt; n++)
        free((*images)[n].pixels);
    free(*images);
error:
    *images = NULL;
    free(cf.tocs);
    return -EINVAL;
}