xref: /qemu/qobject/qstring.c (revision 88e25b1e6d8a0e3672ba8d5bae5c1df768c35bc8)
166f70487SLuiz Capitulino /*
241836a9fSLuiz Capitulino  * QString Module
366f70487SLuiz Capitulino  *
466f70487SLuiz Capitulino  * Copyright (C) 2009 Red Hat Inc.
566f70487SLuiz Capitulino  *
666f70487SLuiz Capitulino  * Authors:
766f70487SLuiz Capitulino  *  Luiz Capitulino <lcapitulino@redhat.com>
866f70487SLuiz Capitulino  *
941836a9fSLuiz Capitulino  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
1041836a9fSLuiz Capitulino  * See the COPYING.LIB file in the top-level directory.
1166f70487SLuiz Capitulino  */
1241836a9fSLuiz Capitulino 
13f2ad72b3SPeter Maydell #include "qemu/osdep.h"
147b1b5d19SPaolo Bonzini #include "qapi/qmp/qstring.h"
1566f70487SLuiz Capitulino 
1666f70487SLuiz Capitulino /**
17d30ec846SAnthony Liguori  * qstring_new(): Create a new empty QString
18d30ec846SAnthony Liguori  *
19d30ec846SAnthony Liguori  * Return strong reference.
20d30ec846SAnthony Liguori  */
21d30ec846SAnthony Liguori QString *qstring_new(void)
22d30ec846SAnthony Liguori {
23d30ec846SAnthony Liguori     return qstring_from_str("");
24d30ec846SAnthony Liguori }
25d30ec846SAnthony Liguori 
26d30ec846SAnthony Liguori /**
2754d49ac9SLuiz Capitulino  * qstring_get_length(): Get the length of a QString
2854d49ac9SLuiz Capitulino  */
2954d49ac9SLuiz Capitulino size_t qstring_get_length(const QString *qstring)
3054d49ac9SLuiz Capitulino {
3154d49ac9SLuiz Capitulino     return qstring->length;
3254d49ac9SLuiz Capitulino }
3354d49ac9SLuiz Capitulino 
3454d49ac9SLuiz Capitulino /**
354b5c5766SLuiz Capitulino  * qstring_from_substr(): Create a new QString from a C string substring
364b5c5766SLuiz Capitulino  *
374b5c5766SLuiz Capitulino  * Return string reference
384b5c5766SLuiz Capitulino  */
39ad63c549Sliujunjie QString *qstring_from_substr(const char *str, size_t start, size_t end)
404b5c5766SLuiz Capitulino {
414b5c5766SLuiz Capitulino     QString *qstring;
424b5c5766SLuiz Capitulino 
43ba891d68SMarkus Armbruster     assert(start <= end);
44b65ab77bSMarkus Armbruster 
457267c094SAnthony Liguori     qstring = g_malloc(sizeof(*qstring));
4655e1819cSEric Blake     qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
474b5c5766SLuiz Capitulino 
48ba891d68SMarkus Armbruster     qstring->length = end - start;
494b5c5766SLuiz Capitulino     qstring->capacity = qstring->length;
504b5c5766SLuiz Capitulino 
51b65ab77bSMarkus Armbruster     assert(qstring->capacity < SIZE_MAX);
527267c094SAnthony Liguori     qstring->string = g_malloc(qstring->capacity + 1);
534b5c5766SLuiz Capitulino     memcpy(qstring->string, str + start, qstring->length);
544b5c5766SLuiz Capitulino     qstring->string[qstring->length] = 0;
554b5c5766SLuiz Capitulino 
564b5c5766SLuiz Capitulino     return qstring;
574b5c5766SLuiz Capitulino }
584b5c5766SLuiz Capitulino 
594b5c5766SLuiz Capitulino /**
6066f70487SLuiz Capitulino  * qstring_from_str(): Create a new QString from a regular C string
6166f70487SLuiz Capitulino  *
6266f70487SLuiz Capitulino  * Return strong reference.
6366f70487SLuiz Capitulino  */
6466f70487SLuiz Capitulino QString *qstring_from_str(const char *str)
6566f70487SLuiz Capitulino {
66ba891d68SMarkus Armbruster     return qstring_from_substr(str, 0, strlen(str));
6766f70487SLuiz Capitulino }
6866f70487SLuiz Capitulino 
69f1cc129dSMarkus Armbruster /**
70f1cc129dSMarkus Armbruster  * qstring_from_gstring(): Convert a GString to a QString
71f1cc129dSMarkus Armbruster  *
72f1cc129dSMarkus Armbruster  * Return strong reference.
73f1cc129dSMarkus Armbruster  */
74f1cc129dSMarkus Armbruster 
75f1cc129dSMarkus Armbruster QString *qstring_from_gstring(GString *gstr)
76f1cc129dSMarkus Armbruster {
77f1cc129dSMarkus Armbruster     QString *qstring;
78f1cc129dSMarkus Armbruster 
79f1cc129dSMarkus Armbruster     qstring = g_malloc(sizeof(*qstring));
80f1cc129dSMarkus Armbruster     qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
81f1cc129dSMarkus Armbruster     qstring->length = gstr->len;
82f1cc129dSMarkus Armbruster     qstring->capacity = gstr->allocated_len;
83f1cc129dSMarkus Armbruster     qstring->string = g_string_free(gstr, false);
84f1cc129dSMarkus Armbruster     return qstring;
85f1cc129dSMarkus Armbruster }
86f1cc129dSMarkus Armbruster 
87f1cc129dSMarkus Armbruster 
886fe9565cSLuiz Capitulino static void capacity_increase(QString *qstring, size_t len)
89d30ec846SAnthony Liguori {
90d30ec846SAnthony Liguori     if (qstring->capacity < (qstring->length + len)) {
91b65ab77bSMarkus Armbruster         assert(len <= SIZE_MAX - qstring->capacity);
92d30ec846SAnthony Liguori         qstring->capacity += len;
93b65ab77bSMarkus Armbruster         assert(qstring->capacity <= SIZE_MAX / 2);
94d30ec846SAnthony Liguori         qstring->capacity *= 2; /* use exponential growth */
95d30ec846SAnthony Liguori 
967267c094SAnthony Liguori         qstring->string = g_realloc(qstring->string, qstring->capacity + 1);
97d30ec846SAnthony Liguori     }
986fe9565cSLuiz Capitulino }
99d30ec846SAnthony Liguori 
1006fe9565cSLuiz Capitulino /* qstring_append(): Append a C string to a QString
1016fe9565cSLuiz Capitulino  */
1026fe9565cSLuiz Capitulino void qstring_append(QString *qstring, const char *str)
1036fe9565cSLuiz Capitulino {
1046fe9565cSLuiz Capitulino     size_t len = strlen(str);
1056fe9565cSLuiz Capitulino 
1066fe9565cSLuiz Capitulino     capacity_increase(qstring, len);
107d30ec846SAnthony Liguori     memcpy(qstring->string + qstring->length, str, len);
108d30ec846SAnthony Liguori     qstring->length += len;
109d30ec846SAnthony Liguori     qstring->string[qstring->length] = 0;
110d30ec846SAnthony Liguori }
111d30ec846SAnthony Liguori 
112764c1caeSLuiz Capitulino void qstring_append_int(QString *qstring, int64_t value)
113764c1caeSLuiz Capitulino {
114764c1caeSLuiz Capitulino     char num[32];
115764c1caeSLuiz Capitulino 
116764c1caeSLuiz Capitulino     snprintf(num, sizeof(num), "%" PRId64, value);
117764c1caeSLuiz Capitulino     qstring_append(qstring, num);
118764c1caeSLuiz Capitulino }
119764c1caeSLuiz Capitulino 
12066f70487SLuiz Capitulino /**
1216fe9565cSLuiz Capitulino  * qstring_append_chr(): Append a C char to a QString
1226fe9565cSLuiz Capitulino  */
1236fe9565cSLuiz Capitulino void qstring_append_chr(QString *qstring, int c)
1246fe9565cSLuiz Capitulino {
1256fe9565cSLuiz Capitulino     capacity_increase(qstring, 1);
1266fe9565cSLuiz Capitulino     qstring->string[qstring->length++] = c;
1276fe9565cSLuiz Capitulino     qstring->string[qstring->length] = 0;
1286fe9565cSLuiz Capitulino }
1296fe9565cSLuiz Capitulino 
1306fe9565cSLuiz Capitulino /**
13166f70487SLuiz Capitulino  * qstring_get_str(): Return a pointer to the stored string
13266f70487SLuiz Capitulino  *
13366f70487SLuiz Capitulino  * NOTE: Should be used with caution, if the object is deallocated
13466f70487SLuiz Capitulino  * this pointer becomes invalid.
13566f70487SLuiz Capitulino  */
13666f70487SLuiz Capitulino const char *qstring_get_str(const QString *qstring)
13766f70487SLuiz Capitulino {
13866f70487SLuiz Capitulino     return qstring->string;
13966f70487SLuiz Capitulino }
14066f70487SLuiz Capitulino 
14166f70487SLuiz Capitulino /**
14277593202SPeter Xu  * qstring_get_try_str(): Return a pointer to the stored string
14377593202SPeter Xu  *
14477593202SPeter Xu  * NOTE: will return NULL if qstring is not provided.
14577593202SPeter Xu  */
14677593202SPeter Xu const char *qstring_get_try_str(const QString *qstring)
14777593202SPeter Xu {
14877593202SPeter Xu     return qstring ? qstring_get_str(qstring) : NULL;
14977593202SPeter Xu }
15077593202SPeter Xu 
15177593202SPeter Xu /**
152b26ae1cbSPeter Xu  * qobject_get_try_str(): Return a pointer to the corresponding string
153b26ae1cbSPeter Xu  *
154b26ae1cbSPeter Xu  * NOTE: the string will only be returned if the object is valid, and
155b26ae1cbSPeter Xu  * its type is QString, otherwise NULL is returned.
156b26ae1cbSPeter Xu  */
157b26ae1cbSPeter Xu const char *qobject_get_try_str(const QObject *qstring)
158b26ae1cbSPeter Xu {
159b26ae1cbSPeter Xu     return qstring_get_try_str(qobject_to(QString, qstring));
160b26ae1cbSPeter Xu }
161b26ae1cbSPeter Xu 
162b26ae1cbSPeter Xu /**
163b38dd678SMax Reitz  * qstring_is_equal(): Test whether the two QStrings are equal
164b38dd678SMax Reitz  */
165b38dd678SMax Reitz bool qstring_is_equal(const QObject *x, const QObject *y)
166b38dd678SMax Reitz {
1677dc847ebSMax Reitz     return !strcmp(qobject_to(QString, x)->string,
1687dc847ebSMax Reitz                    qobject_to(QString, y)->string);
169b38dd678SMax Reitz }
170b38dd678SMax Reitz 
171b38dd678SMax Reitz /**
17266f70487SLuiz Capitulino  * qstring_destroy_obj(): Free all memory allocated by a QString
17366f70487SLuiz Capitulino  * object
17466f70487SLuiz Capitulino  */
17555e1819cSEric Blake void qstring_destroy_obj(QObject *obj)
17666f70487SLuiz Capitulino {
177*88e25b1eSMarkus Armbruster     QString *qs;
178*88e25b1eSMarkus Armbruster 
17966f70487SLuiz Capitulino     assert(obj != NULL);
180*88e25b1eSMarkus Armbruster     qs = qobject_to(QString, obj);
181*88e25b1eSMarkus Armbruster     g_free(qs->string);
182*88e25b1eSMarkus Armbruster     g_free(qs);
18366f70487SLuiz Capitulino }
184