コード例 #1
0
ファイル: qemu-file-buf.c プロジェクト: AdrianHuang/qemu
static int buf_close(void *opaque)
{
    QEMUBuffer *s = opaque;

    if (s->qsb_allocated) {
        qsb_free(s->qsb);
    }

    g_free(s);

    return 0;
}
コード例 #2
0
ファイル: qemu-file-buf.c プロジェクト: AdrianHuang/qemu
/**
 * Create a QEMUSizedBuffer
 * This type of buffer uses scatter-gather lists internally and
 * can grow to any size. Any data array in the scatter-gather list
 * can hold different amount of bytes.
 *
 * @buffer: Optional buffer to copy into the QSB
 * @len: size of initial buffer; if @buffer is given, buffer must
 *       hold at least len bytes
 *
 * Returns a pointer to a QEMUSizedBuffer or NULL on allocation failure
 */
QEMUSizedBuffer *qsb_create(const uint8_t *buffer, size_t len)
{
    QEMUSizedBuffer *qsb;
    size_t alloc_len, num_chunks, i, to_copy;
    size_t chunk_size = (len > QSB_MAX_CHUNK_SIZE)
                        ? QSB_MAX_CHUNK_SIZE
                        : QSB_CHUNK_SIZE;

    num_chunks = DIV_ROUND_UP(len ? len : QSB_CHUNK_SIZE, chunk_size);
    alloc_len = num_chunks * chunk_size;

    qsb = g_try_new0(QEMUSizedBuffer, 1);
    if (!qsb) {
        return NULL;
    }

    qsb->iov = g_try_new0(struct iovec, num_chunks);
    if (!qsb->iov) {
        g_free(qsb);
        return NULL;
    }

    qsb->n_iov = num_chunks;

    for (i = 0; i < num_chunks; i++) {
        qsb->iov[i].iov_base = g_try_malloc0(chunk_size);
        if (!qsb->iov[i].iov_base) {
            /* qsb_free is safe since g_free can cope with NULL */
            qsb_free(qsb);
            return NULL;
        }

        qsb->iov[i].iov_len = chunk_size;
        if (buffer) {
            to_copy = (len - qsb->used) > chunk_size
                      ? chunk_size : (len - qsb->used);
            memcpy(qsb->iov[i].iov_base, &buffer[qsb->used], to_copy);
            qsb->used += to_copy;
        }
    }

    qsb->size = alloc_len;

    return qsb;
}
コード例 #3
0
/**
 * Create a deep copy of the given QEMUSizedBuffer.
 *
 * @qsb: A QEMUSizedBuffer
 *
 * Returns a clone of @qsb or NULL on allocation failure
 */
QEMUSizedBuffer *qsb_clone(const QEMUSizedBuffer *qsb)
{
    QEMUSizedBuffer *out = qsb_create(NULL, qsb_get_length(qsb));
    size_t i;
    ssize_t res;
    off_t pos = 0;

    if (!out) {
        return NULL;
    }

    for (i = 0; i < qsb->n_iov; i++) {
        res =  qsb_write_at(out, qsb->iov[i].iov_base,
                            pos, qsb->iov[i].iov_len);
        if (res < 0) {
            qsb_free(out);
            return NULL;
        }
        pos += res;
    }

    return out;
}