1/* 2 * QString data type. 3 * 4 * Copyright (C) 2009 Red Hat Inc. 5 * 6 * Authors: 7 * Luiz Capitulino <lcapitulino@redhat.com> 8 * 9 * This work is licensed under the terms of the GNU GPL, version 2. See 10 * the COPYING file in the top-level directory. 11 */ 12#include "qobject.h" 13#include "qstring.h" 14#include "qemu-common.h" 15 16static void qstring_destroy_obj(QObject *obj); 17 18static const QType qstring_type = { 19 .code = QTYPE_QSTRING, 20 .destroy = qstring_destroy_obj, 21}; 22 23/** 24 * qstring_new(): Create a new empty QString 25 * 26 * Return strong reference. 27 */ 28QString *qstring_new(void) 29{ 30 return qstring_from_str(""); 31} 32 33/** 34 * qstring_from_substr(): Create a new QString from a C string substring 35 * 36 * Return string reference 37 */ 38QString *qstring_from_substr(const char *str, int start, int end) 39{ 40 QString *qstring; 41 42 qstring = qemu_malloc(sizeof(*qstring)); 43 44 qstring->length = end - start + 1; 45 qstring->capacity = qstring->length; 46 47 qstring->string = qemu_malloc(qstring->capacity + 1); 48 memcpy(qstring->string, str + start, qstring->length); 49 qstring->string[qstring->length] = 0; 50 51 QOBJECT_INIT(qstring, &qstring_type); 52 53 return qstring; 54} 55 56/** 57 * qstring_from_str(): Create a new QString from a regular C string 58 * 59 * Return strong reference. 60 */ 61QString *qstring_from_str(const char *str) 62{ 63 return qstring_from_substr(str, 0, strlen(str) - 1); 64} 65 66static void capacity_increase(QString *qstring, size_t len) 67{ 68 if (qstring->capacity < (qstring->length + len)) { 69 qstring->capacity += len; 70 qstring->capacity *= 2; /* use exponential growth */ 71 72 qstring->string = qemu_realloc(qstring->string, qstring->capacity + 1); 73 } 74} 75 76/* qstring_append(): Append a C string to a QString 77 */ 78void qstring_append(QString *qstring, const char *str) 79{ 80 size_t len = strlen(str); 81 82 capacity_increase(qstring, len); 83 memcpy(qstring->string + qstring->length, str, len); 84 qstring->length += len; 85 qstring->string[qstring->length] = 0; 86} 87 88void qstring_append_int(QString *qstring, int64_t value) 89{ 90 char num[32]; 91 92 snprintf(num, sizeof(num), "%" PRId64, value); 93 qstring_append(qstring, num); 94} 95 96/** 97 * qstring_append_chr(): Append a C char to a QString 98 */ 99void qstring_append_chr(QString *qstring, int c) 100{ 101 capacity_increase(qstring, 1); 102 qstring->string[qstring->length++] = c; 103 qstring->string[qstring->length] = 0; 104} 105 106/** 107 * qobject_to_qstring(): Convert a QObject to a QString 108 */ 109QString *qobject_to_qstring(const QObject *obj) 110{ 111 if (qobject_type(obj) != QTYPE_QSTRING) 112 return NULL; 113 114 return container_of(obj, QString, base); 115} 116 117/** 118 * qstring_get_str(): Return a pointer to the stored string 119 * 120 * NOTE: Should be used with caution, if the object is deallocated 121 * this pointer becomes invalid. 122 */ 123const char *qstring_get_str(const QString *qstring) 124{ 125 return qstring->string; 126} 127 128/** 129 * qstring_destroy_obj(): Free all memory allocated by a QString 130 * object 131 */ 132static void qstring_destroy_obj(QObject *obj) 133{ 134 QString *qs; 135 136 assert(obj != NULL); 137 qs = qobject_to_qstring(obj); 138 qemu_free(qs->string); 139 qemu_free(qs); 140} 141