12910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/*
2fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner * QString Module
32910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
42910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Copyright (C) 2009 Red Hat Inc.
52910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
62910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Authors:
72910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *  Luiz Capitulino <lcapitulino@redhat.com>
82910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
9fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner * This work is licensed under the terms of the GNU LGPL, version 2.1 or later.
10fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner * See the COPYING.LIB file in the top-level directory.
112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
12fd4c0076b7470f5962ff462bae9cd9f208e059b7David Turner
131c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qapi/qmp/qobject.h"
141c31e3e43ce4cca85a707dfff631e5e102fdecedDavid 'Digit' Turner#include "qapi/qmp/qstring.h"
152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner#include "qemu-common.h"
162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qstring_destroy_obj(QObject *obj);
182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic const QType qstring_type = {
202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    .code = QTYPE_QSTRING,
212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    .destroy = qstring_destroy_obj,
222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner};
232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qstring_new(): Create a new empty QString
262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return strong reference.
282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQString *qstring_new(void)
302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qstring_from_str("");
322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
35910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner * qstring_get_length(): Get the length of a QString
36910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner */
37910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turnersize_t qstring_get_length(const QString *qstring)
38910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner{
39910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner    return qstring->length;
40910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner}
41910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner
42910aea96b67d7f0357f586c47f20848ec435aa1bDavid 'Digit' Turner/**
432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qstring_from_substr(): Create a new QString from a C string substring
442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return string reference
462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
472910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQString *qstring_from_substr(const char *str, int start, int end)
482910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QString *qstring;
502910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
51aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    qstring = g_malloc(sizeof(*qstring));
522910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
532910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qstring->length = end - start + 1;
542910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qstring->capacity = qstring->length;
552910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
56aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    qstring->string = g_malloc(qstring->capacity + 1);
572910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    memcpy(qstring->string, str + start, qstring->length);
582910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qstring->string[qstring->length] = 0;
592910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
602910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QOBJECT_INIT(qstring, &qstring_type);
612910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
622910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qstring;
632910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
642910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
652910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
662910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qstring_from_str(): Create a new QString from a regular C string
672910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
682910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * Return strong reference.
692910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
702910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQString *qstring_from_str(const char *str)
712910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
722910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qstring_from_substr(str, 0, strlen(str) - 1);
732910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
742910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
752910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void capacity_increase(QString *qstring, size_t len)
762910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
772910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    if (qstring->capacity < (qstring->length + len)) {
782910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        qstring->capacity += len;
792910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        qstring->capacity *= 2; /* use exponential growth */
802910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
81aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner        qstring->string = g_realloc(qstring->string, qstring->capacity + 1);
822910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    }
832910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
842910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
852910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/* qstring_append(): Append a C string to a QString
862910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
872910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qstring_append(QString *qstring, const char *str)
882910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
892910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    size_t len = strlen(str);
902910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
912910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    capacity_increase(qstring, len);
922910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    memcpy(qstring->string + qstring->length, str, len);
932910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qstring->length += len;
942910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qstring->string[qstring->length] = 0;
952910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
962910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
972910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qstring_append_int(QString *qstring, int64_t value)
982910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
992910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    char num[32];
1002910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1012910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    snprintf(num, sizeof(num), "%" PRId64, value);
1022910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qstring_append(qstring, num);
1032910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1042910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1052910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1062910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qstring_append_chr(): Append a C char to a QString
1072910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1082910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnervoid qstring_append_chr(QString *qstring, int c)
1092910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
1102910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    capacity_increase(qstring, 1);
1112910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qstring->string[qstring->length++] = c;
1122910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qstring->string[qstring->length] = 0;
1132910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1142910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1152910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1162910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qobject_to_qstring(): Convert a QObject to a QString
1172910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1182910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' TurnerQString *qobject_to_qstring(const QObject *obj)
1192910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
1202910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    if (qobject_type(obj) != QTYPE_QSTRING)
1212910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner        return NULL;
1222910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1232910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return container_of(obj, QString, base);
1242910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1252910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1262910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1272910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qstring_get_str(): Return a pointer to the stored string
1282910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner *
1292910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * NOTE: Should be used with caution, if the object is deallocated
1302910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * this pointer becomes invalid.
1312910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1322910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerconst char *qstring_get_str(const QString *qstring)
1332910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
1342910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    return qstring->string;
1352910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
1362910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1372910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner/**
1382910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * qstring_destroy_obj(): Free all memory allocated by a QString
1392910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner * object
1402910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner */
1412910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turnerstatic void qstring_destroy_obj(QObject *obj)
1422910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner{
1432910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    QString *qs;
1442910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner
1452910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    assert(obj != NULL);
1462910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner    qs = qobject_to_qstring(obj);
147aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_free(qs->string);
148aa8236dc1b1ea300ab18716db5b8fab42aca3ca7David 'Digit' Turner    g_free(qs);
1492910f183ddd5286911bc1e3499ea93cb57de8b75David 'Digit' Turner}
150