xref: /openbmc/qemu/qobject/qstring.c (revision ba891d68b4ff17faaea3d3a8bfd82af3eed0a134)
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 #include "qemu-common.h"
16a372823aSPaolo Bonzini 
17a372823aSPaolo Bonzini /**
18a372823aSPaolo Bonzini  * qstring_new(): Create a new empty QString
19a372823aSPaolo Bonzini  *
20a372823aSPaolo Bonzini  * Return strong reference.
21a372823aSPaolo Bonzini  */
22a372823aSPaolo Bonzini QString *qstring_new(void)
23a372823aSPaolo Bonzini {
24a372823aSPaolo Bonzini     return qstring_from_str("");
25a372823aSPaolo Bonzini }
26a372823aSPaolo Bonzini 
27a372823aSPaolo Bonzini /**
2854d49ac9SLuiz Capitulino  * qstring_get_length(): Get the length of a QString
2954d49ac9SLuiz Capitulino  */
3054d49ac9SLuiz Capitulino size_t qstring_get_length(const QString *qstring)
3154d49ac9SLuiz Capitulino {
3254d49ac9SLuiz Capitulino     return qstring->length;
3354d49ac9SLuiz Capitulino }
3454d49ac9SLuiz Capitulino 
3554d49ac9SLuiz Capitulino /**
36a372823aSPaolo Bonzini  * qstring_from_substr(): Create a new QString from a C string substring
37a372823aSPaolo Bonzini  *
38a372823aSPaolo Bonzini  * Return string reference
39a372823aSPaolo Bonzini  */
40ad63c549Sliujunjie QString *qstring_from_substr(const char *str, size_t start, size_t end)
41a372823aSPaolo Bonzini {
42a372823aSPaolo Bonzini     QString *qstring;
43a372823aSPaolo Bonzini 
44*ba891d68SMarkus Armbruster     assert(start <= end);
45b65ab77bSMarkus Armbruster 
46a372823aSPaolo Bonzini     qstring = g_malloc(sizeof(*qstring));
4755e1819cSEric Blake     qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
48a372823aSPaolo Bonzini 
49*ba891d68SMarkus Armbruster     qstring->length = end - start;
50a372823aSPaolo Bonzini     qstring->capacity = qstring->length;
51a372823aSPaolo Bonzini 
52b65ab77bSMarkus Armbruster     assert(qstring->capacity < SIZE_MAX);
53a372823aSPaolo Bonzini     qstring->string = g_malloc(qstring->capacity + 1);
54a372823aSPaolo Bonzini     memcpy(qstring->string, str + start, qstring->length);
55a372823aSPaolo Bonzini     qstring->string[qstring->length] = 0;
56a372823aSPaolo Bonzini 
57a372823aSPaolo Bonzini     return qstring;
58a372823aSPaolo Bonzini }
59a372823aSPaolo Bonzini 
60a372823aSPaolo Bonzini /**
61a372823aSPaolo Bonzini  * qstring_from_str(): Create a new QString from a regular C string
62a372823aSPaolo Bonzini  *
63a372823aSPaolo Bonzini  * Return strong reference.
64a372823aSPaolo Bonzini  */
65a372823aSPaolo Bonzini QString *qstring_from_str(const char *str)
66a372823aSPaolo Bonzini {
67*ba891d68SMarkus Armbruster     return qstring_from_substr(str, 0, strlen(str));
68a372823aSPaolo Bonzini }
69a372823aSPaolo Bonzini 
70a372823aSPaolo Bonzini static void capacity_increase(QString *qstring, size_t len)
71a372823aSPaolo Bonzini {
72a372823aSPaolo Bonzini     if (qstring->capacity < (qstring->length + len)) {
73b65ab77bSMarkus Armbruster         assert(len <= SIZE_MAX - qstring->capacity);
74a372823aSPaolo Bonzini         qstring->capacity += len;
75b65ab77bSMarkus Armbruster         assert(qstring->capacity <= SIZE_MAX / 2);
76a372823aSPaolo Bonzini         qstring->capacity *= 2; /* use exponential growth */
77a372823aSPaolo Bonzini 
78a372823aSPaolo Bonzini         qstring->string = g_realloc(qstring->string, qstring->capacity + 1);
79a372823aSPaolo Bonzini     }
80a372823aSPaolo Bonzini }
81a372823aSPaolo Bonzini 
82a372823aSPaolo Bonzini /* qstring_append(): Append a C string to a QString
83a372823aSPaolo Bonzini  */
84a372823aSPaolo Bonzini void qstring_append(QString *qstring, const char *str)
85a372823aSPaolo Bonzini {
86a372823aSPaolo Bonzini     size_t len = strlen(str);
87a372823aSPaolo Bonzini 
88a372823aSPaolo Bonzini     capacity_increase(qstring, len);
89a372823aSPaolo Bonzini     memcpy(qstring->string + qstring->length, str, len);
90a372823aSPaolo Bonzini     qstring->length += len;
91a372823aSPaolo Bonzini     qstring->string[qstring->length] = 0;
92a372823aSPaolo Bonzini }
93a372823aSPaolo Bonzini 
94a372823aSPaolo Bonzini void qstring_append_int(QString *qstring, int64_t value)
95a372823aSPaolo Bonzini {
96a372823aSPaolo Bonzini     char num[32];
97a372823aSPaolo Bonzini 
98a372823aSPaolo Bonzini     snprintf(num, sizeof(num), "%" PRId64, value);
99a372823aSPaolo Bonzini     qstring_append(qstring, num);
100a372823aSPaolo Bonzini }
101a372823aSPaolo Bonzini 
102a372823aSPaolo Bonzini /**
103a372823aSPaolo Bonzini  * qstring_append_chr(): Append a C char to a QString
104a372823aSPaolo Bonzini  */
105a372823aSPaolo Bonzini void qstring_append_chr(QString *qstring, int c)
106a372823aSPaolo Bonzini {
107a372823aSPaolo Bonzini     capacity_increase(qstring, 1);
108a372823aSPaolo Bonzini     qstring->string[qstring->length++] = c;
109a372823aSPaolo Bonzini     qstring->string[qstring->length] = 0;
110a372823aSPaolo Bonzini }
111a372823aSPaolo Bonzini 
112a372823aSPaolo Bonzini /**
113a372823aSPaolo Bonzini  * qstring_get_str(): Return a pointer to the stored string
114a372823aSPaolo Bonzini  *
115a372823aSPaolo Bonzini  * NOTE: Should be used with caution, if the object is deallocated
116a372823aSPaolo Bonzini  * this pointer becomes invalid.
117a372823aSPaolo Bonzini  */
118a372823aSPaolo Bonzini const char *qstring_get_str(const QString *qstring)
119a372823aSPaolo Bonzini {
120a372823aSPaolo Bonzini     return qstring->string;
121a372823aSPaolo Bonzini }
122a372823aSPaolo Bonzini 
123a372823aSPaolo Bonzini /**
12477593202SPeter Xu  * qstring_get_try_str(): Return a pointer to the stored string
12577593202SPeter Xu  *
12677593202SPeter Xu  * NOTE: will return NULL if qstring is not provided.
12777593202SPeter Xu  */
12877593202SPeter Xu const char *qstring_get_try_str(const QString *qstring)
12977593202SPeter Xu {
13077593202SPeter Xu     return qstring ? qstring_get_str(qstring) : NULL;
13177593202SPeter Xu }
13277593202SPeter Xu 
13377593202SPeter Xu /**
134b26ae1cbSPeter Xu  * qobject_get_try_str(): Return a pointer to the corresponding string
135b26ae1cbSPeter Xu  *
136b26ae1cbSPeter Xu  * NOTE: the string will only be returned if the object is valid, and
137b26ae1cbSPeter Xu  * its type is QString, otherwise NULL is returned.
138b26ae1cbSPeter Xu  */
139b26ae1cbSPeter Xu const char *qobject_get_try_str(const QObject *qstring)
140b26ae1cbSPeter Xu {
141b26ae1cbSPeter Xu     return qstring_get_try_str(qobject_to(QString, qstring));
142b26ae1cbSPeter Xu }
143b26ae1cbSPeter Xu 
144b26ae1cbSPeter Xu /**
145b38dd678SMax Reitz  * qstring_is_equal(): Test whether the two QStrings are equal
146b38dd678SMax Reitz  */
147b38dd678SMax Reitz bool qstring_is_equal(const QObject *x, const QObject *y)
148b38dd678SMax Reitz {
1497dc847ebSMax Reitz     return !strcmp(qobject_to(QString, x)->string,
1507dc847ebSMax Reitz                    qobject_to(QString, y)->string);
151b38dd678SMax Reitz }
152b38dd678SMax Reitz 
153b38dd678SMax Reitz /**
154a372823aSPaolo Bonzini  * qstring_destroy_obj(): Free all memory allocated by a QString
155a372823aSPaolo Bonzini  * object
156a372823aSPaolo Bonzini  */
15755e1819cSEric Blake void qstring_destroy_obj(QObject *obj)
158a372823aSPaolo Bonzini {
159a372823aSPaolo Bonzini     QString *qs;
160a372823aSPaolo Bonzini 
161a372823aSPaolo Bonzini     assert(obj != NULL);
1627dc847ebSMax Reitz     qs = qobject_to(QString, obj);
163a372823aSPaolo Bonzini     g_free(qs->string);
164a372823aSPaolo Bonzini     g_free(qs);
165a372823aSPaolo Bonzini }
166