|  | /* | 
|  | * QString Module | 
|  | * | 
|  | * Copyright (C) 2009 Red Hat Inc. | 
|  | * | 
|  | * Authors: | 
|  | *  Luiz Capitulino <lcapitulino@redhat.com> | 
|  | * | 
|  | * This work is licensed under the terms of the GNU LGPL, version 2.1 or later. | 
|  | * See the COPYING.LIB file in the top-level directory. | 
|  | */ | 
|  |  | 
|  | #include "qapi/qmp/qobject.h" | 
|  | #include "qapi/qmp/qstring.h" | 
|  | #include "qemu-common.h" | 
|  |  | 
|  | static void qstring_destroy_obj(QObject *obj); | 
|  |  | 
|  | static const QType qstring_type = { | 
|  | .code = QTYPE_QSTRING, | 
|  | .destroy = qstring_destroy_obj, | 
|  | }; | 
|  |  | 
|  | /** | 
|  | * qstring_new(): Create a new empty QString | 
|  | * | 
|  | * Return strong reference. | 
|  | */ | 
|  | QString *qstring_new(void) | 
|  | { | 
|  | return qstring_from_str(""); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * qstring_get_length(): Get the length of a QString | 
|  | */ | 
|  | size_t qstring_get_length(const QString *qstring) | 
|  | { | 
|  | return qstring->length; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * qstring_from_substr(): Create a new QString from a C string substring | 
|  | * | 
|  | * Return string reference | 
|  | */ | 
|  | QString *qstring_from_substr(const char *str, int start, int end) | 
|  | { | 
|  | QString *qstring; | 
|  |  | 
|  | qstring = g_malloc(sizeof(*qstring)); | 
|  |  | 
|  | qstring->length = end - start + 1; | 
|  | qstring->capacity = qstring->length; | 
|  |  | 
|  | qstring->string = g_malloc(qstring->capacity + 1); | 
|  | memcpy(qstring->string, str + start, qstring->length); | 
|  | qstring->string[qstring->length] = 0; | 
|  |  | 
|  | QOBJECT_INIT(qstring, &qstring_type); | 
|  |  | 
|  | return qstring; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * qstring_from_str(): Create a new QString from a regular C string | 
|  | * | 
|  | * Return strong reference. | 
|  | */ | 
|  | QString *qstring_from_str(const char *str) | 
|  | { | 
|  | return qstring_from_substr(str, 0, strlen(str) - 1); | 
|  | } | 
|  |  | 
|  | static void capacity_increase(QString *qstring, size_t len) | 
|  | { | 
|  | if (qstring->capacity < (qstring->length + len)) { | 
|  | qstring->capacity += len; | 
|  | qstring->capacity *= 2; /* use exponential growth */ | 
|  |  | 
|  | qstring->string = g_realloc(qstring->string, qstring->capacity + 1); | 
|  | } | 
|  | } | 
|  |  | 
|  | /* qstring_append(): Append a C string to a QString | 
|  | */ | 
|  | void qstring_append(QString *qstring, const char *str) | 
|  | { | 
|  | size_t len = strlen(str); | 
|  |  | 
|  | capacity_increase(qstring, len); | 
|  | memcpy(qstring->string + qstring->length, str, len); | 
|  | qstring->length += len; | 
|  | qstring->string[qstring->length] = 0; | 
|  | } | 
|  |  | 
|  | void qstring_append_int(QString *qstring, int64_t value) | 
|  | { | 
|  | char num[32]; | 
|  |  | 
|  | snprintf(num, sizeof(num), "%" PRId64, value); | 
|  | qstring_append(qstring, num); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * qstring_append_chr(): Append a C char to a QString | 
|  | */ | 
|  | void qstring_append_chr(QString *qstring, int c) | 
|  | { | 
|  | capacity_increase(qstring, 1); | 
|  | qstring->string[qstring->length++] = c; | 
|  | qstring->string[qstring->length] = 0; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * qobject_to_qstring(): Convert a QObject to a QString | 
|  | */ | 
|  | QString *qobject_to_qstring(const QObject *obj) | 
|  | { | 
|  | if (!obj || qobject_type(obj) != QTYPE_QSTRING) { | 
|  | return NULL; | 
|  | } | 
|  | return container_of(obj, QString, base); | 
|  | } | 
|  |  | 
|  | /** | 
|  | * qstring_get_str(): Return a pointer to the stored string | 
|  | * | 
|  | * NOTE: Should be used with caution, if the object is deallocated | 
|  | * this pointer becomes invalid. | 
|  | */ | 
|  | const char *qstring_get_str(const QString *qstring) | 
|  | { | 
|  | return qstring->string; | 
|  | } | 
|  |  | 
|  | /** | 
|  | * qstring_destroy_obj(): Free all memory allocated by a QString | 
|  | * object | 
|  | */ | 
|  | static void qstring_destroy_obj(QObject *obj) | 
|  | { | 
|  | QString *qs; | 
|  |  | 
|  | assert(obj != NULL); | 
|  | qs = qobject_to_qstring(obj); | 
|  | g_free(qs->string); | 
|  | g_free(qs); | 
|  | } |