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