1
0
mirror of https://gitlab.gnome.org/GNOME/glib.git synced 2025-09-22 23:53:05 +02:00
Files
.gitlab-ci
.reuse
LICENSES
docs
fuzzing
gio
completion
gdbus-2.0
inotify
kqueue
tests
cert-tests
de
desktop-files
gdbus-object-manager-example
modules
schema-tests
services
static-link
thumbnails
x-content
111_digit_test.gresource.xml
actions.c
appinfo-test-actions.desktop
appinfo-test-gnome.desktop.in
appinfo-test-notgnome.desktop.in
appinfo-test-path.desktop.in
appinfo-test-static.desktop
appinfo-test.c
appinfo-test.desktop.in
appinfo-test2.desktop.in
appinfo.c
application-command-line.c
appmonitor.c
apps.c
async-close-output-stream.c
async-splice-output-stream.c
autoptr.c
basic-application.c
buffered-input-stream.c
buffered-output-stream.c
cancellable.c
codegen.py
contenttype.c
contexts.c
converter-stream.c
converter.c
credentials.c
cxx.cpp
data-input-stream.c
data-output-stream.c
dbus-appinfo.c
dbus-launch.c
de.po
debugcontroller.c
defaultvalue.c
desktop-app-info.c
echo-server.c
empty.txt
enums.xml.template
error.c
fake-desktop-portal.c
fake-desktop-portal.h
fake-document-portal.c
fake-document-portal.h
fake-service-name.c
fdo-notification-backend.c
file-thumbnail.c
file.c
fileattributematcher.c
filter-cat.c
filter-streams.c
g-file-info-filesystem-readonly.c
g-file-info.c
g-file.c
g-icon.c
gapplication-example-actions.c
gapplication-example-cmdline.c
gapplication-example-cmdline2.c
gapplication-example-cmdline3.c
gapplication-example-cmdline4.c
gapplication-example-dbushooks.c
gapplication-example-open.c
gapplication.c
gdbus-address-get-session.c
gdbus-addresses.c
gdbus-auth.c
gdbus-bz627724.c
gdbus-close-pending.c
gdbus-connection-flush-helper.c
gdbus-connection-flush.c
gdbus-connection-loss.c
gdbus-connection-slow.c
gdbus-connection.c
gdbus-daemon.c
gdbus-error.c
gdbus-example-export.c
gdbus-example-objectmanager-client.c
gdbus-example-objectmanager-server.c
gdbus-example-own-name.c
gdbus-example-peer.c
gdbus-example-proxy-subclass.c
gdbus-example-server.c
gdbus-example-subtree.c
gdbus-example-unix-fd-client.c
gdbus-example-watch-name.c
gdbus-example-watch-proxy.c
gdbus-exit-on-close.c
gdbus-export.c
gdbus-introspection.c
gdbus-message.c
gdbus-method-invocation.c
gdbus-names.c
gdbus-non-socket.c
gdbus-overflow.c
gdbus-peer-object-manager.c
gdbus-peer.c
gdbus-proxy-threads.c
gdbus-proxy-unique-name.c
gdbus-proxy-well-known-name.c
gdbus-proxy.c
gdbus-sasl.c
gdbus-serialization.c
gdbus-server-auth.c
gdbus-sessionbus.c
gdbus-sessionbus.h
gdbus-subscribe.c
gdbus-test-codegen.c
gdbus-test-fixture.c
gdbus-tests.c
gdbus-tests.h
gdbus-testserver.c
gdbus-threading.c
gen-big-test-resource.py
gengiotypefuncs.py
gio-du.c
gio-tool.py
giomodule.c
glistmodel.c
gmenumodel.c
gnotification-server.c
gnotification-server.h
gnotification.c
gschema-compile.c
gsettings.c
gsocketclient-slow.c
gsubprocess-testprog.c
gsubprocess.c
gtesttlsbackend.c
gtesttlsbackend.h
gtlsconsoleinteraction.c
gtlsconsoleinteraction.h
httpd.c
inet-address.c
io-stream.c
live-g-file.c
live-g-file.txt
max-version.c
memory-input-stream.c
memory-monitor-dbus.py.in
memory-monitor-portal.py.in
memory-monitor.c
memory-output-stream.c
memory-settings-backend.c
meson.build
mimeapps.c
mock-resolver.c
mock-resolver.h
mount-operation.c
network-address.c
network-monitor-race.c
network-monitor.c
null-settings-backend.c
org.gtk.schemasourcecheck.gschema.xml
org.gtk.test.dbusappinfo.desktop
org.gtk.test.dbusappinfo.flatpak.desktop
org.gtk.test.gschema.override.orig
org.gtk.test.gschema.xml.orig
osx-appinfo.c
permission.c
pollable.c
portal-support-env-var.c
portal-support-flatpak-full.c
portal-support-flatpak-gsettings-only.c
portal-support-flatpak-network-only.c
portal-support-flatpak-none.c
portal-support-none.c
portal-support-snap-classic.c
portal-support-snap.c
portal-support-utils.c
portal-support-utils.h
power-profile-monitor-dbus.py.in
power-profile-monitor-portal.py.in
power-profile-monitor.c
proxy-test.c
proxy.c
readwrite.c
resolver-parsing.c
resolver.c
resourceplugin.c
resources.c
sandbox.c
send-data.c
simple-async-result.c
simple-proxy.c
sleepy-stream.c
slow-connect-preload.c
socket-address.c
socket-common.c
socket-listener.c
socket-service.c
socket-testclient.c
socket-testserver.c
socket.c
srvtarget.c
static-link.py
stream-rw_all.c
task.c
test-codegen.xml
test-io-stream.c
test-io-stream.h
test-pipe-unix.c
test-pipe-unix.h
test.gresource.xml
test1.overlay
test1.txt
test2.gresource.xml
test2.txt
test3.gresource.xml
test3.txt
test4.gresource.xml
test5.gresource.xml
test6.gresource.xml
testenum.h
testfilemonitor.c
thumbnail-verification.c
tls-bindings.c
tls-certificate.c
tls-database.c
tls-interaction.c
trash.c
unix-fd.c
unix-mounts.c
unix-streams.c
vfs.c
volumemonitor.c
win32-appinfo.c
win32-streams.c
win32
xdgmime
data-to-c.py
dbus-daemon.xml
gaction.c
gaction.h
gactiongroup.c
gactiongroup.h
gactiongroupexporter.c
gactiongroupexporter.h
gactionmap.c
gactionmap.h
gappinfo.c
gappinfo.h
gappinfoprivate.h
gapplication-tool.c
gapplication.c
gapplication.h
gapplicationcommandline.c
gapplicationcommandline.h
gapplicationimpl-dbus.c
gapplicationimpl.h
gasynchelper.c
gasynchelper.h
gasyncinitable.c
gasyncinitable.h
gasyncresult.c
gasyncresult.h
gbufferedinputstream.c
gbufferedinputstream.h
gbufferedoutputstream.c
gbufferedoutputstream.h
gbytesicon.c
gbytesicon.h
gcancellable.c
gcancellable.h
gcharsetconverter.c
gcharsetconverter.h
gcocoanotificationbackend.m
gcontenttype-fdo.c
gcontenttype-osx.m
gcontenttype-win32.c
gcontenttype.c
gcontenttype.h
gcontenttypeprivate.h
gcontextspecificgroup.c
gcontextspecificgroup.h
gconverter.c
gconverter.h
gconverterinputstream.c
gconverterinputstream.h
gconverteroutputstream.c
gconverteroutputstream.h
gcredentials.c
gcredentials.h
gcredentialsprivate.h
gdatagrambased.c
gdatagrambased.h
gdatainputstream.c
gdatainputstream.h
gdataoutputstream.c
gdataoutputstream.h
gdbus-tool.c
gdbusactiongroup-private.h
gdbusactiongroup.c
gdbusactiongroup.h
gdbusaddress.c
gdbusaddress.h
gdbusauth.c
gdbusauth.h
gdbusauthmechanism.c
gdbusauthmechanism.h
gdbusauthmechanismanon.c
gdbusauthmechanismanon.h
gdbusauthmechanismexternal.c
gdbusauthmechanismexternal.h
gdbusauthmechanismsha1.c
gdbusauthmechanismsha1.h
gdbusauthobserver.c
gdbusauthobserver.h
gdbusconnection.c
gdbusconnection.h
gdbusdaemon.c
gdbusdaemon.h
gdbuserror.c
gdbuserror.h
gdbusinterface.c
gdbusinterface.h
gdbusinterfaceskeleton.c
gdbusinterfaceskeleton.h
gdbusintrospection.c
gdbusintrospection.h
gdbusmenumodel.c
gdbusmenumodel.h
gdbusmessage.c
gdbusmessage.h
gdbusmethodinvocation.c
gdbusmethodinvocation.h
gdbusnameowning.c
gdbusnameowning.h
gdbusnamewatching.c
gdbusnamewatching.h
gdbusobject.c
gdbusobject.h
gdbusobjectmanager.c
gdbusobjectmanager.h
gdbusobjectmanagerclient.c
gdbusobjectmanagerclient.h
gdbusobjectmanagerserver.c
gdbusobjectmanagerserver.h
gdbusobjectproxy.c
gdbusobjectproxy.h
gdbusobjectskeleton.c
gdbusobjectskeleton.h
gdbusprivate.c
gdbusprivate.h
gdbusproxy.c
gdbusproxy.h
gdbusserver.c
gdbusserver.h
gdbusutils.c
gdbusutils.h
gdebugcontroller.c
gdebugcontroller.h
gdebugcontrollerdbus.c
gdebugcontrollerdbus.h
gdelayedsettingsbackend.c
gdelayedsettingsbackend.h
gdesktopappinfo.c
gdesktopappinfo.h
gdocumentportal.c
gdocumentportal.h
gdrive.c
gdrive.h
gdtlsclientconnection.c
gdtlsclientconnection.h
gdtlsconnection.c
gdtlsconnection.h
gdtlsserverconnection.c
gdtlsserverconnection.h
gdummyfile.c
gdummyfile.h
gdummyproxyresolver.c
gdummyproxyresolver.h
gdummytlsbackend.c
gdummytlsbackend.h
gemblem.c
gemblem.h
gemblemedicon.c
gemblemedicon.h
gfdonotificationbackend.c
gfile.c
gfile.h
gfileattribute-priv.h
gfileattribute.c
gfileattribute.h
gfiledescriptorbased.c
gfiledescriptorbased.h
gfileenumerator.c
gfileenumerator.h
gfileicon.c
gfileicon.h
gfileinfo-priv.h
gfileinfo.c
gfileinfo.h
gfileinputstream.c
gfileinputstream.h
gfileiostream.c
gfileiostream.h
gfilemonitor.c
gfilemonitor.h
gfilenamecompleter.c
gfilenamecompleter.h
gfileoutputstream.c
gfileoutputstream.h
gfilterinputstream.c
gfilterinputstream.h
gfilteroutputstream.c
gfilteroutputstream.h
ggtknotificationbackend.c
ghttpproxy.c
ghttpproxy.h
gicon.c
gicon.h
ginetaddress.c
ginetaddress.h
ginetaddressmask.c
ginetaddressmask.h
ginetsocketaddress.c
ginetsocketaddress.h
ginitable.c
ginitable.h
ginputstream.c
ginputstream.h
gio-autocleanups.h
gio-launch-desktop.c
gio-querymodules.c
gio-tool-cat.c
gio-tool-copy.c
gio-tool-info.c
gio-tool-launch.c
gio-tool-list.c
gio-tool-mime.c
gio-tool-mkdir.c
gio-tool-monitor.c
gio-tool-mount.c
gio-tool-move.c
gio-tool-open.c
gio-tool-remove.c
gio-tool-rename.c
gio-tool-save.c
gio-tool-set.c
gio-tool-trash.c
gio-tool-tree.c
gio-tool.c
gio-tool.h
gio.h
gio.rc.in
gio.stp.in
gio_probes.d
gio_trace.h
gioenums.h
gioenumtypes.c.template
gioenumtypes.h.template
gioerror.c
gioerror.h
giomodule-priv.c
giomodule-priv.h
giomodule.c
giomodule.h
gioprivate.h
gioscheduler.c
gioscheduler.h
giostream.c
giostream.h
giotypes.h
giounix-private.c
giounix-private.h
giowin32-afunix.h
giowin32-priv.h
giowin32-private.c
gkeyfilesettingsbackend.c
glib-compile-resources.c
glib-compile-schemas.c
glistmodel.c
glistmodel.h
gliststore.c
gliststore.h
gloadableicon.c
gloadableicon.h
glocalfile.c
glocalfile.h
glocalfileenumerator.c
glocalfileenumerator.h
glocalfileinfo.c
glocalfileinfo.h
glocalfileinputstream.c
glocalfileinputstream.h
glocalfileiostream.c
glocalfileiostream.h
glocalfilemonitor.c
glocalfilemonitor.h
glocalfileoutputstream.c
glocalfileoutputstream.h
glocalvfs.c
glocalvfs.h
gmarshal-internal.c
gmarshal-internal.h
gmarshal-internal.list
gmemoryinputstream.c
gmemoryinputstream.h
gmemorymonitor.c
gmemorymonitor.h
gmemorymonitordbus.c
gmemorymonitordbus.h
gmemorymonitorportal.c
gmemorymonitorportal.h
gmemorymonitorwin32.c
gmemoryoutputstream.c
gmemoryoutputstream.h
gmemorysettingsbackend.c
gmenu.c
gmenu.h
gmenuexporter.c
gmenuexporter.h
gmenumodel.c
gmenumodel.h
gmount.c
gmount.h
gmountoperation.c
gmountoperation.h
gmountprivate.h
gnativesocketaddress.c
gnativesocketaddress.h
gnativevolumemonitor.c
gnativevolumemonitor.h
gnetworkaddress.c
gnetworkaddress.h
gnetworking.c
gnetworking.h.in
gnetworkingprivate.h
gnetworkmonitor.c
gnetworkmonitor.h
gnetworkmonitorbase.c
gnetworkmonitorbase.h
gnetworkmonitornetlink.c
gnetworkmonitornetlink.h
gnetworkmonitornm.c
gnetworkmonitornm.h
gnetworkmonitorportal.c
gnetworkmonitorportal.h
gnetworkservice.c
gnetworkservice.h
gnextstepsettingsbackend.m
gnotification-private.h
gnotification.c
gnotification.h
gnotificationbackend.c
gnotificationbackend.h
gnullsettingsbackend.c
gopenuriportal.c
gopenuriportal.h
gosxappinfo.h
gosxappinfo.m
gosxnetworkmonitor.c
gosxnetworkmonitor.h
goutputstream.c
goutputstream.h
gpermission.c
gpermission.h
gpollableinputstream.c
gpollableinputstream.h
gpollableoutputstream.c
gpollableoutputstream.h
gpollableutils.c
gpollableutils.h
gpollfilemonitor.c
gpollfilemonitor.h
gportalnotificationbackend.c
gportalsupport.c
gportalsupport.h
gpowerprofilemonitor.c
gpowerprofilemonitor.h
gpowerprofilemonitordbus.c
gpowerprofilemonitordbus.h
gpowerprofilemonitorportal.c
gpowerprofilemonitorportal.h
gpropertyaction.c
gpropertyaction.h
gproxy.c
gproxy.h
gproxyaddress.c
gproxyaddress.h
gproxyaddressenumerator.c
gproxyaddressenumerator.h
gproxyresolver.c
gproxyresolver.h
gproxyresolverportal.c
gproxyresolverportal.h
gregistrysettingsbackend.c
gregistrysettingsbackend.h
gremoteactiongroup.c
gremoteactiongroup.h
gresolver.c
gresolver.h
gresource-tool.c
gresource.c
gresource.dtd
gresource.h
gresourcefile.c
gresourcefile.h
gsandbox.c
gsandbox.h
gschema.dtd
gschema.its
gschema.loc
gseekable.c
gseekable.h
gsettings-mapping.c
gsettings-mapping.h
gsettings-tool.c
gsettings.c
gsettings.h
gsettingsbackend.c
gsettingsbackend.h
gsettingsbackendinternal.h
gsettingsschema-internal.h
gsettingsschema.c
gsettingsschema.h
gsimpleaction.c
gsimpleaction.h
gsimpleactiongroup.c
gsimpleactiongroup.h
gsimpleasyncresult.c
gsimpleasyncresult.h
gsimpleiostream.c
gsimpleiostream.h
gsimplepermission.c
gsimplepermission.h
gsimpleproxyresolver.c
gsimpleproxyresolver.h
gsocket.c
gsocket.h
gsocketaddress.c
gsocketaddress.h
gsocketaddressenumerator.c
gsocketaddressenumerator.h
gsocketclient.c
gsocketclient.h
gsocketconnectable.c
gsocketconnectable.h
gsocketconnection.c
gsocketconnection.h
gsocketcontrolmessage.c
gsocketcontrolmessage.h
gsocketinputstream.c
gsocketinputstream.h
gsocketlistener.c
gsocketlistener.h
gsocketoutputstream.c
gsocketoutputstream.h
gsocketservice.c
gsocketservice.h
gsocks4aproxy.c
gsocks4aproxy.h
gsocks4proxy.c
gsocks4proxy.h
gsocks5proxy.c
gsocks5proxy.h
gsrvtarget.c
gsrvtarget.h
gsubprocess.c
gsubprocess.h
gsubprocesslauncher-private.h
gsubprocesslauncher.c
gsubprocesslauncher.h
gtask.c
gtask.h
gtcpconnection.c
gtcpconnection.h
gtcpwrapperconnection.c
gtcpwrapperconnection.h
gtestdbus.c
gtestdbus.h
gthemedicon.c
gthemedicon.h
gthreadedresolver-private.h
gthreadedresolver.c
gthreadedresolver.h
gthreadedsocketservice.c
gthreadedsocketservice.h
gtlsbackend.c
gtlsbackend.h
gtlscertificate.c
gtlscertificate.h
gtlsclientconnection.c
gtlsclientconnection.h
gtlsconnection.c
gtlsconnection.h
gtlsdatabase.c
gtlsdatabase.h
gtlsfiledatabase.c
gtlsfiledatabase.h
gtlsinteraction.c
gtlsinteraction.h
gtlspassword.c
gtlspassword.h
gtlsserverconnection.c
gtlsserverconnection.h
gtrashportal.c
gtrashportal.h
gunionvolumemonitor.c
gunionvolumemonitor.h
gunixconnection.c
gunixconnection.h
gunixcredentialsmessage.c
gunixcredentialsmessage.h
gunixfdlist.c
gunixfdlist.h
gunixfdmessage.c
gunixfdmessage.h
gunixinputstream.c
gunixinputstream.h
gunixmount.c
gunixmount.h
gunixmounts.c
gunixmounts.h
gunixoutputstream.c
gunixoutputstream.h
gunixsocketaddress.c
gunixsocketaddress.h
gunixvolume.c
gunixvolume.h
gunixvolumemonitor.c
gunixvolumemonitor.h
gvfs.c
gvfs.h
gvolume.c
gvolume.h
gvolumemonitor.c
gvolumemonitor.h
gwin32api-application-activation-manager.h
gwin32api-iterator.h
gwin32api-misc.h
gwin32api-package.h
gwin32api-storage.h
gwin32appinfo.c
gwin32appinfo.h
gwin32file-sync-stream.c
gwin32file-sync-stream.h
gwin32inputstream.c
gwin32inputstream.h
gwin32mount.c
gwin32mount.h
gwin32networkmonitor.c
gwin32networkmonitor.h
gwin32notificationbackend.c
gwin32outputstream.c
gwin32outputstream.h
gwin32packageparser.c
gwin32packageparser.h
gwin32registrykey.c
gwin32registrykey.h
gwin32sid.c
gwin32sid.h
gwin32volumemonitor.c
gwin32volumemonitor.h
gzlibcompressor.c
gzlibcompressor.h
gzlibdecompressor.c
gzlibdecompressor.h
meson.build
org.freedesktop.portal.Documents.xml
org.freedesktop.portal.OpenURI.xml
org.freedesktop.portal.ProxyResolver.xml
org.freedesktop.portal.Request.xml
org.freedesktop.portal.Trash.xml
strinfo.c
thumbnail-verify.c
thumbnail-verify.h
girepository
glib
gmodule
gobject
gthread
m4macros
po
subprojects
tests
tools
.clang-format
.dir-locals.el
.editorconfig
.gitignore
.gitlab-ci.yml
.gitmodules
.lcovrc
CODE_OF_CONDUCT.md
CONTRIBUTING.md
INSTALL.md
NEWS
README.md
SECURITY.md
glib.doap
meson.build
meson.options
glib/gio/tests/memory-output-stream.c
Gary Li d64336e1a9 g_output_stream_write: Allow NULL buffer if count is 0
We currently fail a buffer != NULL assertion if buffer is NULL and count is 0. Allow this case without critical assertions.

Fixes https://gitlab.gnome.org/GNOME/glib/-/issues/3402
2024-06-26 14:18:41 -04:00

473 lines
16 KiB
C

/* GLib testing framework examples and tests
* Copyright (C) 2008 Red Hat, Inc.
* Author: Matthias Clasen
*
* SPDX-License-Identifier: LicenseRef-old-glib-tests
*
* This work is provided "as is"; redistribution and modification
* in whole or in part, in any medium, physical or electronic is
* permitted without restriction.
*
* This work is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* In no event shall the authors or contributors be liable for any
* direct, indirect, incidental, special, exemplary, or consequential
* damages (including, but not limited to, procurement of substitute
* goods or services; loss of use, data, or profits; or business
* interruption) however caused and on any theory of liability, whether
* in contract, strict liability, or tort (including negligence or
* otherwise) arising in any way out of the use of this software, even
* if advised of the possibility of such damage.
*/
#include <glib/glib.h>
#include <gio/gio.h>
#include <stdlib.h>
#include <string.h>
static void
test_truncate (void)
{
GOutputStream *mo;
GDataOutputStream *o;
int i;
GError *error = NULL;
guint8 *data;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540423");
mo = g_memory_output_stream_new_resizable ();
g_assert (g_seekable_can_truncate (G_SEEKABLE (mo)));
o = g_data_output_stream_new (mo);
for (i = 0; i < 1000; i++)
{
g_data_output_stream_put_byte (o, 1, NULL, &error);
g_assert_no_error (error);
}
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 1000);
g_seekable_truncate (G_SEEKABLE (mo), 0, NULL, &error);
g_assert_cmpuint (g_seekable_tell (G_SEEKABLE (mo)), ==, 1000);
g_assert_no_error (error);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 0);
for (i = 0; i < 2000; i++)
{
g_data_output_stream_put_byte (o, 2, NULL, &error);
g_assert_no_error (error);
}
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 3000);
data = (guint8 *)g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
/* The 1's written initially were lost when we truncated to 0
* and then started writing at position 1000.
*/
for (i = 0; i < 1000; i++)
g_assert_cmpuint (data[i], ==, 0);
for (i = 1000; i < 3000; i++)
g_assert_cmpuint (data[i], ==, 2);
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=720080");
g_seekable_truncate (G_SEEKABLE (mo), 8192, NULL, &error);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 8192);
data = (guint8 *)g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
for (i = 3000; i < 8192; i++)
g_assert_cmpuint (data[i], ==, 0);
g_object_unref (o);
g_object_unref (mo);
}
static void
test_seek_fixed (void)
{
GOutputStream *mo;
GError *error;
mo = g_memory_output_stream_new (g_new (gchar, 100), 100, NULL, g_free);
g_assert (G_IS_SEEKABLE (mo));
g_assert (g_seekable_can_seek (G_SEEKABLE (mo)));
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
error = NULL;
g_assert (!g_seekable_seek (G_SEEKABLE (mo), 222, G_SEEK_CUR, NULL, &error));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_clear_error (&error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
g_assert (g_seekable_seek (G_SEEKABLE (mo), 26, G_SEEK_SET, NULL, &error));
g_assert_no_error (error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 26);
g_assert (g_seekable_seek (G_SEEKABLE (mo), 20, G_SEEK_CUR, NULL, &error));
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46);
g_assert_no_error (error);
g_assert (!g_seekable_seek (G_SEEKABLE (mo), 200, G_SEEK_CUR, NULL, &error));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_clear_error (&error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46);
g_assert (!g_seekable_seek (G_SEEKABLE (mo), 1, G_SEEK_END, NULL, &error));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_clear_error (&error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46);
g_assert (g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_END, NULL, &error));
g_assert_no_error (error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 100);
g_assert (g_seekable_seek (G_SEEKABLE (mo), -1, G_SEEK_END, NULL, &error));
g_assert_no_error (error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 99);
g_object_unref (mo);
}
static void
test_seek_resizable_stream (GOutputStream *mo)
{
GError *error;
g_assert (G_IS_SEEKABLE (mo));
g_assert (g_seekable_can_seek (G_SEEKABLE (mo)));
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
error = NULL;
g_assert (g_seekable_seek (G_SEEKABLE (mo), 222, G_SEEK_CUR, NULL, &error));
g_assert_no_error (error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 222);
g_assert (g_seekable_seek (G_SEEKABLE (mo), 26, G_SEEK_SET, NULL, &error));
g_assert_no_error (error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 26);
g_assert (g_seekable_seek (G_SEEKABLE (mo), 20, G_SEEK_CUR, NULL, &error));
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 46);
g_assert_no_error (error);
g_assert (g_seekable_seek (G_SEEKABLE (mo), 200, G_SEEK_CUR, NULL, &error));
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 246);
g_assert_no_error (error);
g_assert (g_seekable_seek (G_SEEKABLE (mo), 1, G_SEEK_END, NULL, &error));
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 1);
g_assert_no_error (error);
g_assert (g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_END, NULL, &error));
g_assert_no_error (error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
/* The 'end' is still zero, so this should fail */
g_assert (!g_seekable_seek (G_SEEKABLE (mo), -1, G_SEEK_END, NULL, &error));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT);
g_clear_error (&error);
g_assert_cmpint (g_seekable_tell (G_SEEKABLE (mo)), ==, 0);
}
static void
test_seek_resizable (void)
{
GOutputStream *mo;
gint i;
/* For resizable streams, the initially allocated size is purely an
* implementation detail. We should not be able to tell the
* difference based on the seek API, so make a bunch of streams with
* different sizes and subject them to the same test.
*/
for (i = 0; i < 1024; i++)
{
mo = g_memory_output_stream_new (g_malloc (i), i, g_realloc, g_free);
test_seek_resizable_stream (mo);
g_assert_cmpint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 0);
/* No writes = no resizes */
g_assert_cmpint (g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, i);
g_object_unref (mo);
}
}
static void
test_data_size (void)
{
GOutputStream *mo;
GDataOutputStream *o;
int pos;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540459");
mo = g_memory_output_stream_new_resizable ();
o = g_data_output_stream_new (mo);
g_data_output_stream_put_byte (o, 1, NULL, NULL);
pos = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo));
g_assert_cmpint (pos, ==, 1);
g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_CUR, NULL, NULL);
pos = g_seekable_tell (G_SEEKABLE (mo));
g_assert_cmpint (pos, ==, 1);
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=540461");
g_seekable_seek (G_SEEKABLE (mo), 0, G_SEEK_SET, NULL, NULL);
pos = g_seekable_tell (G_SEEKABLE (mo));
g_assert_cmpint (pos, ==, 0);
pos = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo));
g_assert_cmpint (pos, ==, 1);
g_assert_cmpint (g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, 16);
g_object_unref (o);
g_object_unref (mo);
}
static void
test_properties (void)
{
GOutputStream *mo;
GDataOutputStream *o;
int i;
GError *error = NULL;
gsize data_size_fun;
gsize data_size_prop = 0;
gpointer data_fun;
gpointer data_prop;
gpointer func;
g_test_bug ("https://bugzilla.gnome.org/show_bug.cgi?id=605733");
mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
"realloc-function", g_realloc,
"destroy-function", g_free,
NULL);
o = g_data_output_stream_new (mo);
for (i = 0; i < 1000; i++)
{
g_data_output_stream_put_byte (o, 1, NULL, &error);
g_assert_no_error (error);
}
data_size_fun = g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo));
g_object_get (mo, "data-size", &data_size_prop, NULL);
g_assert_cmpint (data_size_fun, ==, data_size_prop);
data_fun = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
g_object_get (mo, "data", &data_prop, NULL);
g_assert_cmphex (GPOINTER_TO_SIZE (data_fun), ==, GPOINTER_TO_SIZE (data_prop));
g_object_get (mo, "realloc-function", &func, NULL);
g_assert (func == g_realloc);
g_object_get (mo, "destroy-function", &func, NULL);
g_assert (func == g_free);
data_size_fun = g_memory_output_stream_get_size (G_MEMORY_OUTPUT_STREAM (mo));
g_object_get (mo, "size", &data_size_prop, NULL);
g_assert_cmpint (data_size_fun, ==, data_size_prop);
g_object_unref (o);
g_object_unref (mo);
}
static void
test_write_bytes (void)
{
GOutputStream *mo;
GBytes *bytes, *bytes2;
GError *error = NULL;
mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
"realloc-function", g_realloc,
"destroy-function", g_free,
NULL);
bytes = g_bytes_new_static ("hello world!", strlen ("hello world!") + 1);
g_output_stream_write_bytes (mo, bytes, NULL, &error);
g_assert_no_error (error);
g_output_stream_close (mo, NULL, &error);
g_assert_no_error (error);
bytes2 = g_memory_output_stream_steal_as_bytes (G_MEMORY_OUTPUT_STREAM (mo));
g_object_unref (mo);
g_assert (g_bytes_equal (bytes, bytes2));
g_bytes_unref (bytes);
g_bytes_unref (bytes2);
}
static void
test_write_null (void)
{
GOutputStream *mo;
GError *error = NULL;
gssize bytes_written;
g_test_bug ("https://gitlab.gnome.org/GNOME/glib/-/issues/2471");
mo = g_memory_output_stream_new_resizable ();
g_output_stream_write_all (mo, NULL, 0, NULL, NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (0, ==, g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)));
bytes_written = g_output_stream_write (mo, NULL, 0, NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (0, ==, bytes_written);
g_output_stream_close (mo, NULL, &error);
g_assert_no_error (error);
g_object_unref (mo);
}
/* Test that writev() works on #GMemoryOutputStream with a non-empty set of vectors. This
* covers the default writev() implementation around write(). */
static void
test_writev (void)
{
GOutputStream *mo;
GError *error = NULL;
gboolean res;
gsize bytes_written;
GOutputVector vectors[3];
const guint8 buffer[] = {1, 2, 3, 4, 5,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1, 2, 3};
guint8 *output_buffer;
vectors[0].buffer = buffer;
vectors[0].size = 5;
vectors[1].buffer = buffer + vectors[0].size;
vectors[1].size = 12;
vectors[2].buffer = buffer + vectors[0].size + vectors[1].size;
vectors[2].size = 3;
mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
"realloc-function", g_realloc,
"destroy-function", g_free,
NULL);
res = g_output_stream_writev_all (mo, vectors, G_N_ELEMENTS (vectors), &bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert_true (res);
g_assert_cmpuint (bytes_written, ==, sizeof buffer);
g_output_stream_close (mo, NULL, &error);
g_assert_no_error (error);
g_assert_cmpuint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, sizeof buffer);
output_buffer = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
g_assert_cmpmem (output_buffer, sizeof buffer, buffer, sizeof buffer);
g_object_unref (mo);
}
/* Test that writev_nonblocking() works on #GMemoryOutputStream with a non-empty set of vectors. This
* covers the default writev_nonblocking() implementation around write_nonblocking(). */
static void
test_writev_nonblocking (void)
{
GOutputStream *mo;
GError *error = NULL;
gboolean res;
gsize bytes_written;
GOutputVector vectors[3];
const guint8 buffer[] = {1, 2, 3, 4, 5,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1, 2, 3};
guint8 *output_buffer;
vectors[0].buffer = buffer;
vectors[0].size = 5;
vectors[1].buffer = buffer + vectors[0].size;
vectors[1].size = 12;
vectors[2].buffer = buffer + vectors[0].size + vectors[1].size;
vectors[2].size = 3;
mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
"realloc-function", g_realloc,
"destroy-function", g_free,
NULL);
res = g_pollable_output_stream_writev_nonblocking (G_POLLABLE_OUTPUT_STREAM (mo),
vectors, G_N_ELEMENTS (vectors),
&bytes_written, NULL, &error);
g_assert_no_error (error);
g_assert_cmpint (res, ==, G_POLLABLE_RETURN_OK);
g_assert_cmpuint (bytes_written, ==, sizeof buffer);
g_output_stream_close (mo, NULL, &error);
g_assert_no_error (error);
g_assert_cmpuint (g_memory_output_stream_get_data_size (G_MEMORY_OUTPUT_STREAM (mo)), ==, sizeof buffer);
output_buffer = g_memory_output_stream_get_data (G_MEMORY_OUTPUT_STREAM (mo));
g_assert_cmpmem (output_buffer, sizeof buffer, buffer, sizeof buffer);
g_object_unref (mo);
}
static void
test_steal_as_bytes (void)
{
GOutputStream *mo;
GDataOutputStream *o;
GError *error = NULL;
GBytes *bytes;
gsize size;
mo = (GOutputStream*) g_object_new (G_TYPE_MEMORY_OUTPUT_STREAM,
"realloc-function", g_realloc,
"destroy-function", g_free,
NULL);
o = g_data_output_stream_new (mo);
g_data_output_stream_put_string (o, "hello ", NULL, &error);
g_assert_no_error (error);
g_data_output_stream_put_string (o, "world!", NULL, &error);
g_assert_no_error (error);
g_data_output_stream_put_byte (o, '\0', NULL, &error);
g_assert_no_error (error);
g_output_stream_close ((GOutputStream*) o, NULL, &error);
g_assert_no_error (error);
bytes = g_memory_output_stream_steal_as_bytes ((GMemoryOutputStream*)mo);
g_object_unref (mo);
g_assert_cmpint (g_bytes_get_size (bytes), ==, strlen ("hello world!") + 1);
g_assert_cmpstr (g_bytes_get_data (bytes, &size), ==, "hello world!");
g_bytes_unref (bytes);
g_object_unref (o);
}
int
main (int argc,
char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/memory-output-stream/truncate", test_truncate);
g_test_add_func ("/memory-output-stream/seek/fixed", test_seek_fixed);
g_test_add_func ("/memory-output-stream/seek/resizable", test_seek_resizable);
g_test_add_func ("/memory-output-stream/get-data-size", test_data_size);
g_test_add_func ("/memory-output-stream/properties", test_properties);
g_test_add_func ("/memory-output-stream/write-bytes", test_write_bytes);
g_test_add_func ("/memory-output-stream/write-null", test_write_null);
g_test_add_func ("/memory-output-stream/writev", test_writev);
g_test_add_func ("/memory-output-stream/writev_nonblocking", test_writev_nonblocking);
g_test_add_func ("/memory-output-stream/steal_as_bytes", test_steal_as_bytes);
return g_test_run();
}