xref: /openbmc/qemu/qobject/qstring.c (revision f1cc129df8341ebb6176363d24b57035bb5dabe4)
1a372823aSPaolo Bonzini /*
2a372823aSPaolo Bonzini  * QString Module
3a372823aSPaolo Bonzini  *
4a372823aSPaolo Bonzini  * Copyright (C) 2009 Red Hat Inc.
5a372823aSPaolo Bonzini  *
6a372823aSPaolo Bonzini  * Authors:
7a372823aSPaolo Bonzini  *  Luiz Capitulino <lcapitulino@redhat.com>
8a372823aSPaolo Bonzini  *
9a372823aSPaolo Bonzini  * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10a372823aSPaolo Bonzini  * See the COPYING.LIB file in the top-level directory.
11a372823aSPaolo Bonzini  */
12a372823aSPaolo Bonzini 
13f2ad72b3SPeter Maydell #include "qemu/osdep.h"
14a372823aSPaolo Bonzini #include "qapi/qmp/qstring.h"
15a372823aSPaolo Bonzini 
16a372823aSPaolo Bonzini /**
17a372823aSPaolo Bonzini  * qstring_new(): Create a new empty QString
18a372823aSPaolo Bonzini  *
19a372823aSPaolo Bonzini  * Return strong reference.
20a372823aSPaolo Bonzini  */
21a372823aSPaolo Bonzini QString *qstring_new(void)
22a372823aSPaolo Bonzini {
23a372823aSPaolo Bonzini     return qstring_from_str("");
24a372823aSPaolo Bonzini }
25a372823aSPaolo Bonzini 
26a372823aSPaolo Bonzini /**
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 /**
35a372823aSPaolo Bonzini  * qstring_from_substr(): Create a new QString from a C string substring
36a372823aSPaolo Bonzini  *
37a372823aSPaolo Bonzini  * Return string reference
38a372823aSPaolo Bonzini  */
39ad63c549Sliujunjie QString *qstring_from_substr(const char *str, size_t start, size_t end)
40a372823aSPaolo Bonzini {
41a372823aSPaolo Bonzini     QString *qstring;
42a372823aSPaolo Bonzini 
43ba891d68SMarkus Armbruster     assert(start <= end);
44b65ab77bSMarkus Armbruster 
45a372823aSPaolo Bonzini     qstring = g_malloc(sizeof(*qstring));
4655e1819cSEric Blake     qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
47a372823aSPaolo Bonzini 
48ba891d68SMarkus Armbruster     qstring->length = end - start;
49a372823aSPaolo Bonzini     qstring->capacity = qstring->length;
50a372823aSPaolo Bonzini 
51b65ab77bSMarkus Armbruster     assert(qstring->capacity < SIZE_MAX);
52a372823aSPaolo Bonzini     qstring->string = g_malloc(qstring->capacity + 1);
53a372823aSPaolo Bonzini     memcpy(qstring->string, str + start, qstring->length);
54a372823aSPaolo Bonzini     qstring->string[qstring->length] = 0;
55a372823aSPaolo Bonzini 
56a372823aSPaolo Bonzini     return qstring;
57a372823aSPaolo Bonzini }
58a372823aSPaolo Bonzini 
59a372823aSPaolo Bonzini /**
60a372823aSPaolo Bonzini  * qstring_from_str(): Create a new QString from a regular C string
61a372823aSPaolo Bonzini  *
62a372823aSPaolo Bonzini  * Return strong reference.
63a372823aSPaolo Bonzini  */
64a372823aSPaolo Bonzini QString *qstring_from_str(const char *str)
65a372823aSPaolo Bonzini {
66ba891d68SMarkus Armbruster     return qstring_from_substr(str, 0, strlen(str));
67a372823aSPaolo Bonzini }
68a372823aSPaolo Bonzini 
69*f1cc129dSMarkus Armbruster /**
70*f1cc129dSMarkus Armbruster  * qstring_from_gstring(): Convert a GString to a QString
71*f1cc129dSMarkus Armbruster  *
72*f1cc129dSMarkus Armbruster  * Return strong reference.
73*f1cc129dSMarkus Armbruster  */
74*f1cc129dSMarkus Armbruster 
75*f1cc129dSMarkus Armbruster QString *qstring_from_gstring(GString *gstr)
76*f1cc129dSMarkus Armbruster {
77*f1cc129dSMarkus Armbruster     QString *qstring;
78*f1cc129dSMarkus Armbruster 
79*f1cc129dSMarkus Armbruster     qstring = g_malloc(sizeof(*qstring));
80*f1cc129dSMarkus Armbruster     qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
81*f1cc129dSMarkus Armbruster     qstring->length = gstr->len;
82*f1cc129dSMarkus Armbruster     qstring->capacity = gstr->allocated_len;
83*f1cc129dSMarkus Armbruster     qstring->string = g_string_free(gstr, false);
84*f1cc129dSMarkus Armbruster     return qstring;
85*f1cc129dSMarkus Armbruster }
86*f1cc129dSMarkus Armbruster 
87*f1cc129dSMarkus Armbruster 
88a372823aSPaolo Bonzini static void capacity_increase(QString *qstring, size_t len)
89a372823aSPaolo Bonzini {
90a372823aSPaolo Bonzini     if (qstring->capacity < (qstring->length + len)) {
91b65ab77bSMarkus Armbruster         assert(len <= SIZE_MAX - qstring->capacity);
92a372823aSPaolo Bonzini         qstring->capacity += len;
93b65ab77bSMarkus Armbruster         assert(qstring->capacity <= SIZE_MAX / 2);
94a372823aSPaolo Bonzini         qstring->capacity *= 2; /* use exponential growth */
95a372823aSPaolo Bonzini 
96a372823aSPaolo Bonzini         qstring->string = g_realloc(qstring->string, qstring->capacity + 1);
97a372823aSPaolo Bonzini     }
98a372823aSPaolo Bonzini }
99a372823aSPaolo Bonzini 
100a372823aSPaolo Bonzini /* qstring_append(): Append a C string to a QString
101a372823aSPaolo Bonzini  */
102a372823aSPaolo Bonzini void qstring_append(QString *qstring, const char *str)
103a372823aSPaolo Bonzini {
104a372823aSPaolo Bonzini     size_t len = strlen(str);
105a372823aSPaolo Bonzini 
106a372823aSPaolo Bonzini     capacity_increase(qstring, len);
107a372823aSPaolo Bonzini     memcpy(qstring->string + qstring->length, str, len);
108a372823aSPaolo Bonzini     qstring->length += len;
109a372823aSPaolo Bonzini     qstring->string[qstring->length] = 0;
110a372823aSPaolo Bonzini }
111a372823aSPaolo Bonzini 
112a372823aSPaolo Bonzini void qstring_append_int(QString *qstring, int64_t value)
113a372823aSPaolo Bonzini {
114a372823aSPaolo Bonzini     char num[32];
115a372823aSPaolo Bonzini 
116a372823aSPaolo Bonzini     snprintf(num, sizeof(num), "%" PRId64, value);
117a372823aSPaolo Bonzini     qstring_append(qstring, num);
118a372823aSPaolo Bonzini }
119a372823aSPaolo Bonzini 
120a372823aSPaolo Bonzini /**
121a372823aSPaolo Bonzini  * qstring_append_chr(): Append a C char to a QString
122a372823aSPaolo Bonzini  */
123a372823aSPaolo Bonzini void qstring_append_chr(QString *qstring, int c)
124a372823aSPaolo Bonzini {
125a372823aSPaolo Bonzini     capacity_increase(qstring, 1);
126a372823aSPaolo Bonzini     qstring->string[qstring->length++] = c;
127a372823aSPaolo Bonzini     qstring->string[qstring->length] = 0;
128a372823aSPaolo Bonzini }
129a372823aSPaolo Bonzini 
130a372823aSPaolo Bonzini /**
131a372823aSPaolo Bonzini  * qstring_get_str(): Return a pointer to the stored string
132a372823aSPaolo Bonzini  *
133a372823aSPaolo Bonzini  * NOTE: Should be used with caution, if the object is deallocated
134a372823aSPaolo Bonzini  * this pointer becomes invalid.
135a372823aSPaolo Bonzini  */
136a372823aSPaolo Bonzini const char *qstring_get_str(const QString *qstring)
137a372823aSPaolo Bonzini {
138a372823aSPaolo Bonzini     return qstring->string;
139a372823aSPaolo Bonzini }
140a372823aSPaolo Bonzini 
141a372823aSPaolo Bonzini /**
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 /**
172164c374bSMarc-André Lureau  * qstring_free(): Free the memory allocated by a QString object
173164c374bSMarc-André Lureau  *
174164c374bSMarc-André Lureau  * Return: if @return_str, return the underlying string, to be
175164c374bSMarc-André Lureau  * g_free(), otherwise NULL is returned.
176164c374bSMarc-André Lureau  */
177164c374bSMarc-André Lureau char *qstring_free(QString *qstring, bool return_str)
178164c374bSMarc-André Lureau {
179164c374bSMarc-André Lureau     char *rv = NULL;
180164c374bSMarc-André Lureau 
181164c374bSMarc-André Lureau     if (return_str) {
182164c374bSMarc-André Lureau         rv = qstring->string;
183164c374bSMarc-André Lureau     } else {
184164c374bSMarc-André Lureau         g_free(qstring->string);
185164c374bSMarc-André Lureau     }
186164c374bSMarc-André Lureau 
187164c374bSMarc-André Lureau     g_free(qstring);
188164c374bSMarc-André Lureau 
189164c374bSMarc-André Lureau     return rv;
190164c374bSMarc-André Lureau }
191164c374bSMarc-André Lureau 
192164c374bSMarc-André Lureau /**
193a372823aSPaolo Bonzini  * qstring_destroy_obj(): Free all memory allocated by a QString
194a372823aSPaolo Bonzini  * object
195a372823aSPaolo Bonzini  */
19655e1819cSEric Blake void qstring_destroy_obj(QObject *obj)
197a372823aSPaolo Bonzini {
198a372823aSPaolo Bonzini     assert(obj != NULL);
199164c374bSMarc-André Lureau     qstring_free(qobject_to(QString, obj), FALSE);
200a372823aSPaolo Bonzini }
201