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