From nobody Sun Feb 8 15:41:55 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 205.139.110.120 as permitted sender) client-ip=205.139.110.120; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-1.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zoho.com: domain of redhat.com designates 205.139.110.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1571925489; cv=none; d=zoho.com; s=zohoarc; b=HB+0Tn12TT7CXbyGR8pAOl+R8gcgDnhCKVjoD/SelSRfoQFBGsGeUh4LdRTP5dTpr7pGPjJLAeK6yt3f2AbGzBCiK3bZsgk8rPoivpnz30itF+LSnrIu7GgnXDSxrsCkZdzFMaQSJSxRGChD9KQidwSjL0yiZ7q9REAknnmwSjM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571925489; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=TEb9TNVcGBUfHQHl0KJGZjrKtJOwiOXleqdJNMab6dU=; b=QeSANf60MthiFYvZfREk3XtpVb0w7RKJqahYWBbX6r9NcSTmYE8Qp+PA5Hks4CAzLN2Pkvy3xY8o/konpJ1ChA/eDcZOD4uOnE7QLWmKbXVIp981xizmjyRV6OZr50enqMp3JTG0MGu2xtSI3opAy8kKa5cv13HF6SvSYA5+Hs0= ARC-Authentication-Results: i=1; mx.zoho.com; dkim=pass; spf=pass (zoho.com: domain of redhat.com designates 205.139.110.120 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) by mx.zohomail.com with SMTPS id 1571925489119211.80370156225172; Thu, 24 Oct 2019 06:58:09 -0700 (PDT) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-316-wh5_qaODPPKIPoBKBOkiHw-1; Thu, 24 Oct 2019 09:57:22 -0400 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BADC0107AD3E; Thu, 24 Oct 2019 13:57:17 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 91D39194B6; Thu, 24 Oct 2019 13:57:17 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 4F42E4EEBD; Thu, 24 Oct 2019 13:57:17 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id x9ODv7BY026428 for ; Thu, 24 Oct 2019 09:57:07 -0400 Received: by smtp.corp.redhat.com (Postfix) id B6736100164D; Thu, 24 Oct 2019 13:57:07 +0000 (UTC) Received: from angien.redhat.com (unknown [10.43.2.229]) by smtp.corp.redhat.com (Postfix) with ESMTP id 404B710027AB for ; Thu, 24 Oct 2019 13:57:07 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1571925487; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=TEb9TNVcGBUfHQHl0KJGZjrKtJOwiOXleqdJNMab6dU=; b=AVNApn4mIz/YjSRSXNhk3cHUlLRdPLvwaUsyO0ecAEkxslD1E8jyUdl/u9sVEs62zPPv6t aeuVL3u18sEX2E3zA8NiRty8oBiPchwm+Vl/wv5CJ2MXzESOnFZY02xQOhULXBxBV2q/XH MR7QkZPCXHrKhFZ/KBf0nLfQh6bFH1s= From: Peter Krempa To: libvir-list@redhat.com Date: Thu, 24 Oct 2019 15:56:33 +0200 Message-Id: <0f49f04549b07e3c9ac822dee50e9e96361a6ccc.1571925291.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 15/19] util: buffer: Reimplement virBuffer internals using glib's GString X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 X-MC-Unique: wh5_qaODPPKIPoBKBOkiHw-1 X-Mimecast-Spam-Score: 0 Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" GString is surprisingly similar to what libvirt was doing painstaikingly manually. Yet it doesn't support the automatic indentation features we use for XML so we rather keep those in form of virBuffer using GString internally. Signed-off-by: Peter Krempa Reviewed-by: J=C3=A1n Tomko --- src/util/virbuffer.c | 205 +++++++++++++++---------------------------- src/util/virbuffer.h | 6 +- 2 files changed, 71 insertions(+), 140 deletions(-) diff --git a/src/util/virbuffer.c b/src/util/virbuffer.c index 2256bd5de5..9306b79703 100644 --- a/src/util/virbuffer.c +++ b/src/util/virbuffer.c @@ -21,7 +21,6 @@ #include #include -#include "c-ctype.h" #include "virbuffer.h" #include "virerror.h" @@ -40,10 +39,7 @@ static void virBufferSetError(virBufferPtr buf, int error) { - VIR_FREE(buf->content); - buf->size =3D 0; - buf->use =3D 0; - buf->indent =3D 0; + virBufferFreeAndReset(buf); buf->error =3D error; } @@ -122,7 +118,7 @@ virBufferGetIndent(const virBuffer *buf) size_t virBufferGetEffectiveIndent(const virBuffer *buf) { - if (buf->use && buf->content[buf->use - 1] !=3D '\n') + if (buf->str && buf->str->len && buf->str->str[buf->str->len - 1] !=3D= '\n') return 0; return buf->indent; @@ -130,35 +126,38 @@ virBufferGetEffectiveIndent(const virBuffer *buf) /** - * virBufferGrow: + * virBufferInitialize * @buf: the buffer - * @len: the minimum free size to allocate on top of existing used space * - * Grow the available space of a buffer to at least @len bytes. - * - * Returns zero on success or -1 on error + * Ensures that the internal GString container is allocated. */ -static int -virBufferGrow(virBufferPtr buf, unsigned int len) +static void +virBufferInitialize(virBufferPtr buf) { - int size; + if (!buf->str) + buf->str =3D g_string_new(NULL); +} - if (buf->error) - return -1; - if ((len + buf->use) < buf->size) - return 0; +static void +virBufferApplyIndent(virBufferPtr buf) +{ + const char space[] =3D " "; + size_t spacesz =3D sizeof(space) - 1; + size_t toindent =3D virBufferGetEffectiveIndent(buf); - size =3D buf->use + len + 1000; + if (toindent =3D=3D 0) + return; - if (VIR_REALLOC_N_QUIET(buf->content, size) < 0) { - virBufferSetError(buf, errno); - return -1; + while (toindent > spacesz) { + g_string_append_len(buf->str, space, spacesz); + toindent -=3D spacesz; } - buf->size =3D size; - return 0; + + g_string_append_len(buf->str, space, toindent); } + /** * virBufferAdd: * @buf: the buffer to append to @@ -172,25 +171,16 @@ virBufferGrow(virBufferPtr buf, unsigned int len) void virBufferAdd(virBufferPtr buf, const char *str, int len) { - unsigned int needSize; - size_t indent; - if (!str || !buf || buf->error || (len =3D=3D 0 && buf->indent =3D=3D = 0)) return; - indent =3D virBufferGetEffectiveIndent(buf); + virBufferInitialize(buf); + virBufferApplyIndent(buf); if (len < 0) - len =3D strlen(str); - - needSize =3D buf->use + indent + len + 2; - if (virBufferGrow(buf, needSize - buf->use) < 0) - return; - - memset(&buf->content[buf->use], ' ', indent); - memcpy(&buf->content[buf->use + indent], str, len); - buf->use +=3D indent + len; - buf->content[buf->use] =3D '\0'; + g_string_append(buf->str, str); + else + g_string_append_len(buf->str, str, len); } /** @@ -207,7 +197,7 @@ virBufferAdd(virBufferPtr buf, const char *str, int len) void virBufferAddBuffer(virBufferPtr buf, virBufferPtr toadd) { - if (!toadd) + if (!toadd || !toadd->str) return; if (!buf) @@ -219,12 +209,8 @@ virBufferAddBuffer(virBufferPtr buf, virBufferPtr toad= d) goto cleanup; } - if (virBufferGrow(buf, toadd->use) < 0) - goto cleanup; - - memcpy(&buf->content[buf->use], toadd->content, toadd->use); - buf->use +=3D toadd->use; - buf->content[buf->use] =3D '\0'; + virBufferInitialize(buf); + g_string_append_len(buf->str, toadd->str->str, toadd->str->len); cleanup: virBufferFreeAndReset(toadd); @@ -259,7 +245,12 @@ virBufferCurrentContent(virBufferPtr buf) { if (!buf || buf->error) return NULL; - return buf->use ? buf->content : ""; + + if (!buf->str || + buf->str->len =3D=3D 0) + return ""; + + return buf->str->str; } /** @@ -277,16 +268,14 @@ virBufferCurrentContent(virBufferPtr buf) char * virBufferContentAndReset(virBufferPtr buf) { - char *str; - if (buf =3D=3D NULL) - return NULL; + char *str =3D NULL; - if (buf->error) { - memset(buf, 0, sizeof(*buf)); + if (!buf) return NULL; - } - str =3D buf->content; + if (buf->str) + str =3D g_string_free(buf->str, false); + memset(buf, 0, sizeof(*buf)); return str; } @@ -299,8 +288,13 @@ virBufferContentAndReset(virBufferPtr buf) */ void virBufferFreeAndReset(virBufferPtr buf) { - if (buf) - virBufferSetError(buf, 0); + if (!buf) + return; + + if (buf->str) + g_string_free(buf->str, true); + + memset(buf, 0, sizeof(*buf)); } /** @@ -360,10 +354,10 @@ virBufferCheckErrorInternal(const virBuffer *buf, size_t virBufferUse(const virBuffer *buf) { - if (buf =3D=3D NULL) + if (!buf || !buf->str) return 0; - return buf->use; + return buf->str->len; } /** @@ -394,48 +388,16 @@ virBufferAsprintf(virBufferPtr buf, const char *forma= t, ...) void virBufferVasprintf(virBufferPtr buf, const char *format, va_list argptr) { - int size, count, grow_size; - va_list copy; - if ((format =3D=3D NULL) || (buf =3D=3D NULL)) return; if (buf->error) return; - virBufferAddLit(buf, ""); /* auto-indent */ + virBufferInitialize(buf); + virBufferApplyIndent(buf); - if (buf->size =3D=3D 0 && - virBufferGrow(buf, 100) < 0) - return; - - va_copy(copy, argptr); - - size =3D buf->size - buf->use; - if ((count =3D vsnprintf(&buf->content[buf->use], - size, format, copy)) < 0) { - virBufferSetError(buf, errno); - va_end(copy); - return; - } - va_end(copy); - - /* Grow buffer if necessary and retry */ - if (count >=3D size) { - buf->content[buf->use] =3D 0; - - grow_size =3D (count + 1 > 1000) ? count + 1 : 1000; - if (virBufferGrow(buf, grow_size) < 0) - return; - - size =3D buf->size - buf->use; - if ((count =3D vsnprintf(&buf->content[buf->use], - size, format, argptr)) < 0) { - virBufferSetError(buf, errno); - return; - } - } - buf->use +=3D count; + g_string_append_vprintf(buf->str, format, argptr); } @@ -638,16 +600,6 @@ virBufferEscape(virBufferPtr buf, char escape, const c= har *toescape, } -static bool -virBufferURIEncodeCharIsUnencoded(char c) -{ - if (c =3D=3D '-' || c =3D=3D '.' || c =3D=3D '_' || c =3D=3D '~') - return true; - - return c_isalnum(c); -} - - /** * virBufferURIEncodeString: * @buf: the buffer to append to @@ -660,41 +612,16 @@ virBufferURIEncodeCharIsUnencoded(char c) void virBufferURIEncodeString(virBufferPtr buf, const char *str) { - int grow_size =3D 0; - const char *p; - unsigned char uc; - const char *hex =3D "0123456789ABCDEF"; - if ((buf =3D=3D NULL) || (str =3D=3D NULL)) return; if (buf->error) return; - virBufferAddLit(buf, ""); /* auto-indent */ - - for (p =3D str; *p; ++p) { - if (virBufferURIEncodeCharIsUnencoded(*p)) - grow_size++; - else - grow_size +=3D 3; /* %ab */ - } - - if (virBufferGrow(buf, grow_size) < 0) - return; - - for (p =3D str; *p; ++p) { - if (virBufferURIEncodeCharIsUnencoded(*p)) { - buf->content[buf->use++] =3D *p; - } else { - uc =3D (unsigned char) *p; - buf->content[buf->use++] =3D '%'; - buf->content[buf->use++] =3D hex[uc >> 4]; - buf->content[buf->use++] =3D hex[uc & 0xf]; - } - } + virBufferInitialize(buf); + virBufferApplyIndent(buf); - buf->content[buf->use] =3D '\0'; + g_string_append_uri_escaped(buf->str, str, NULL, false); } /** @@ -810,21 +737,27 @@ virBufferTrim(virBufferPtr buf, const char *str, int = len) { size_t len2 =3D 0; - if (!buf || buf->error) + if (!buf || buf->error || !buf->str) return; + if (!str && len < 0) return; - if (len > 0 && len > buf->use) + + if (len > 0 && len > buf->str->len) return; + if (str) { len2 =3D strlen(str); - if (len2 > buf->use || - memcmp(&buf->content[buf->use - len2], str, len2) !=3D 0) + if (len2 > buf->str->len || + memcmp(&buf->str->str[buf->str->len - len2], str, len2) !=3D 0) return; } - buf->use -=3D len < 0 ? len2 : len; - buf->content[buf->use] =3D '\0'; + + if (len < 0) + len =3D len2; + + g_string_truncate(buf->str, buf->str->len - len); } diff --git a/src/util/virbuffer.h b/src/util/virbuffer.h index 6c41a7ea20..f5b3961f9b 100644 --- a/src/util/virbuffer.h +++ b/src/util/virbuffer.h @@ -33,14 +33,12 @@ typedef struct _virBuffer virBuffer; typedef virBuffer *virBufferPtr; -#define VIR_BUFFER_INITIALIZER { 0, 0, 0, 0, NULL } +#define VIR_BUFFER_INITIALIZER { NULL, 0, 0 } struct _virBuffer { - size_t size; - size_t use; + GString *str; int error; /* errno value, or -1 for usage error */ int indent; - char *content; }; const char *virBufferCurrentContent(virBufferPtr buf); --=20 2.21.0 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list