1 /* 2 * QString Module 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 LGPL, version 2.1 or later. 10 * See the COPYING.LIB file in the top-level directory. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "qapi/qmp/qstring.h" 15 #include "qemu-common.h" 16 17 /** 18 * qstring_new(): Create a new empty QString 19 * 20 * Return strong reference. 21 */ 22 QString *qstring_new(void) 23 { 24 return qstring_from_str(""); 25 } 26 27 /** 28 * qstring_get_length(): Get the length of a QString 29 */ 30 size_t qstring_get_length(const QString *qstring) 31 { 32 return qstring->length; 33 } 34 35 /** 36 * qstring_from_substr(): Create a new QString from a C string substring 37 * 38 * Return string reference 39 */ 40 QString *qstring_from_substr(const char *str, size_t start, size_t end) 41 { 42 QString *qstring; 43 44 assert(start <= end); 45 46 qstring = g_malloc(sizeof(*qstring)); 47 qobject_init(QOBJECT(qstring), QTYPE_QSTRING); 48 49 qstring->length = end - start; 50 qstring->capacity = qstring->length; 51 52 assert(qstring->capacity < SIZE_MAX); 53 qstring->string = g_malloc(qstring->capacity + 1); 54 memcpy(qstring->string, str + start, qstring->length); 55 qstring->string[qstring->length] = 0; 56 57 return qstring; 58 } 59 60 /** 61 * qstring_from_str(): Create a new QString from a regular C string 62 * 63 * Return strong reference. 64 */ 65 QString *qstring_from_str(const char *str) 66 { 67 return qstring_from_substr(str, 0, strlen(str)); 68 } 69 70 static void capacity_increase(QString *qstring, size_t len) 71 { 72 if (qstring->capacity < (qstring->length + len)) { 73 assert(len <= SIZE_MAX - qstring->capacity); 74 qstring->capacity += len; 75 assert(qstring->capacity <= SIZE_MAX / 2); 76 qstring->capacity *= 2; /* use exponential growth */ 77 78 qstring->string = g_realloc(qstring->string, qstring->capacity + 1); 79 } 80 } 81 82 /* qstring_append(): Append a C string to a QString 83 */ 84 void qstring_append(QString *qstring, const char *str) 85 { 86 size_t len = strlen(str); 87 88 capacity_increase(qstring, len); 89 memcpy(qstring->string + qstring->length, str, len); 90 qstring->length += len; 91 qstring->string[qstring->length] = 0; 92 } 93 94 void qstring_append_int(QString *qstring, int64_t value) 95 { 96 char num[32]; 97 98 snprintf(num, sizeof(num), "%" PRId64, value); 99 qstring_append(qstring, num); 100 } 101 102 /** 103 * qstring_append_chr(): Append a C char to a QString 104 */ 105 void qstring_append_chr(QString *qstring, int c) 106 { 107 capacity_increase(qstring, 1); 108 qstring->string[qstring->length++] = c; 109 qstring->string[qstring->length] = 0; 110 } 111 112 /** 113 * qstring_get_str(): Return a pointer to the stored string 114 * 115 * NOTE: Should be used with caution, if the object is deallocated 116 * this pointer becomes invalid. 117 */ 118 const char *qstring_get_str(const QString *qstring) 119 { 120 return qstring->string; 121 } 122 123 /** 124 * qstring_get_try_str(): Return a pointer to the stored string 125 * 126 * NOTE: will return NULL if qstring is not provided. 127 */ 128 const char *qstring_get_try_str(const QString *qstring) 129 { 130 return qstring ? qstring_get_str(qstring) : NULL; 131 } 132 133 /** 134 * qobject_get_try_str(): Return a pointer to the corresponding string 135 * 136 * NOTE: the string will only be returned if the object is valid, and 137 * its type is QString, otherwise NULL is returned. 138 */ 139 const char *qobject_get_try_str(const QObject *qstring) 140 { 141 return qstring_get_try_str(qobject_to(QString, qstring)); 142 } 143 144 /** 145 * qstring_is_equal(): Test whether the two QStrings are equal 146 */ 147 bool qstring_is_equal(const QObject *x, const QObject *y) 148 { 149 return !strcmp(qobject_to(QString, x)->string, 150 qobject_to(QString, y)->string); 151 } 152 153 /** 154 * qstring_destroy_obj(): Free all memory allocated by a QString 155 * object 156 */ 157 void qstring_destroy_obj(QObject *obj) 158 { 159 QString *qs; 160 161 assert(obj != NULL); 162 qs = qobject_to(QString, obj); 163 g_free(qs->string); 164 g_free(qs); 165 } 166