QEMUFile *qemu_bufopen(const char *mode, QEMUSizedBuffer *input) { QEMUBuffer *s; if (mode == NULL || (mode[0] != 'r' && mode[0] != 'w') || mode[1] != '\0') { error_report("qemu_bufopen: Argument validity check failed"); return NULL; } s = g_malloc0(sizeof(QEMUBuffer)); s->qsb = input; if (s->qsb == NULL) { s->qsb = qsb_create(NULL, 0); s->qsb_allocated = true; } if (!s->qsb) { g_free(s); error_report("qemu_bufopen: qsb_create failed"); return NULL; } if (mode[0] == 'r') { s->file = qemu_fopen_ops(s, &buf_read_ops); } else { s->file = qemu_fopen_ops(s, &buf_write_ops); } return s->file; }
/* Open a read-only qemu-file from an existing memory block */ static QEMUFile *open_mem_file_read(const void *data, size_t len) { /* The qsb gets freed by qemu_fclose */ QEMUSizedBuffer *qsb = qsb_create(data, len); g_assert(qsb); return qemu_bufopen("r", qsb); }
/** * 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; }