1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-01-18 04:58:51 +02:00

Abstract IO layer out of the storage layer.

This allows the routines to be used for IO objects that do not have a storage representation.

Implement buffer read and write IO objects.
This commit is contained in:
David Steele 2018-07-19 16:04:20 -04:00
parent 5dc8a2ec08
commit 0ac176b722
35 changed files with 1185 additions and 320 deletions

View File

@ -37,6 +37,10 @@
<p>Allow <code>Buffer</code> object <quote>used size</quote> to be different than <quote>allocated size</quote>. Add functions to manage used size and remaining size and update automatically when possible.</p>
</release-item>
<release-item>
<p>Abstract IO layer out of the storage layer. This allows the routines to be used for IO objects that do not have a storage representation. Implement buffer read and write IO objects.</p>
</release-item>
<release-item>
<p><code>storageFileRead()</code> accepts a buffer for output rather than creating one. This is more efficient overall and allows the caller to specify how many bytes will be read on each call. Reads are appended if the buffer already contains data but the buffer size will never increase.</p>
</release-item>

View File

@ -48,7 +48,11 @@ my @stryCFile =
'common/encode/base64.c',
'common/error.c',
'common/ini.c',
'common/io/bufferRead.c',
'common/io/handle.c',
'common/io/io.c',
'common/io/read.c',
'common/io/write.c',
'common/lock.c',
'common/log.c',
'common/memContext.c',

View File

@ -65,7 +65,11 @@ SRCS = \
common/error.c \
common/exit.c \
common/fork.c \
common/io/bufferRead.c \
common/io/handle.c \
common/io/io.c \
common/io/read.c \
common/io/write.c \
common/ini.c \
common/lock.c \
common/log.c \
@ -123,13 +127,13 @@ install: pgbackrest
####################################################################################################################################
# Compile rules
####################################################################################################################################
command/archive/common.o: command/archive/common.c command/archive/common.h common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h postgres/version.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
command/archive/common.o: command/archive/common.c command/archive/common.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h postgres/version.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c command/archive/common.c -o command/archive/common.o
command/archive/get/get.o: command/archive/get/get.c command/archive/common.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/fork.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/info.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
command/archive/get/get.o: command/archive/get/get.c command/archive/common.h command/command.h common/assert.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h postgres/info.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c command/archive/get/get.c -o command/archive/get/get.o
command/archive/push/push.o: command/archive/push/push.c command/archive/common.h command/command.h common/debug.h common/error.auto.h common/error.h common/fork.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
command/archive/push/push.o: command/archive/push/push.c command/archive/common.h command/command.h common/debug.h common/error.auto.h common/error.h common/fork.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h perl/exec.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c command/archive/push/push.c -o command/archive/push/push.o
command/command.o: command/command.c common/assert.h common/debug.h common/error.auto.h common/error.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h version.h
@ -156,13 +160,28 @@ common/exit.o: common/exit.c command/command.h common/debug.h common/error.auto.
common/fork.o: common/fork.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/type/convert.h
$(CC) $(CFLAGS) -c common/fork.c -o common/fork.o
common/ini.o: common/ini.c common/debug.h common/error.auto.h common/error.h common/ini.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
common/ini.o: common/ini.c common/debug.h common/error.auto.h common/error.h common/ini.h common/io/read.h common/io/write.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c common/ini.c -o common/ini.o
common/io/bufferRead.o: common/io/bufferRead.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferRead.h common/io/read.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h
$(CC) $(CFLAGS) -c common/io/bufferRead.c -o common/io/bufferRead.o
common/io/bufferWrite.o: common/io/bufferWrite.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/bufferWrite.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h
$(CC) $(CFLAGS) -c common/io/bufferWrite.c -o common/io/bufferWrite.o
common/io/handle.o: common/io/handle.c common/debug.h common/error.auto.h common/error.h common/io/handle.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h
$(CC) $(CFLAGS) -c common/io/handle.c -o common/io/handle.o
common/lock.o: common/lock.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/handle.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
common/io/io.o: common/io/io.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/io.h common/log.h common/logLevel.h common/stackTrace.h common/type/convert.h
$(CC) $(CFLAGS) -c common/io/io.c -o common/io/io.o
common/io/read.o: common/io/read.c common/debug.h common/error.auto.h common/error.h common/io/read.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h
$(CC) $(CFLAGS) -c common/io/read.c -o common/io/read.o
common/io/write.o: common/io/write.c common/debug.h common/error.auto.h common/error.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h
$(CC) $(CFLAGS) -c common/io/write.c -o common/io/write.o
common/lock.o: common/lock.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/handle.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c common/lock.c -o common/lock.o
common/log.o: common/log.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/time.h common/type/convert.h
@ -213,10 +232,10 @@ config/config.o: config/config.c common/assert.h common/debug.h common/error.aut
config/define.o: config/define.c common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/stackTrace.h common/type/convert.h config/define.auto.c config/define.auto.h config/define.h
$(CC) $(CFLAGS) -c config/define.c -o config/define.o
config/load.o: config/load.c command/command.h common/debug.h common/error.auto.h common/error.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h config/parse.h
config/load.o: config/load.c command/command.h common/debug.h common/error.auto.h common/error.h common/io/io.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h config/parse.h
$(CC) $(CFLAGS) -c config/load.c -o config/load.o
config/parse.o: config/parse.c common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/parse.auto.c config/parse.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
config/parse.o: config/parse.c common/assert.h common/debug.h common/error.auto.h common/error.h common/ini.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/parse.auto.c config/parse.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c config/parse.c -o config/parse.o
crypto/cipherBlock.o: crypto/cipherBlock.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/convert.h crypto/cipher.h crypto/cipherBlock.h crypto/crypto.h crypto/random.h
@ -240,13 +259,13 @@ perl/config.o: perl/config.c common/debug.h common/error.auto.h common/error.h c
perl/exec.o: perl/exec.c ../libc/LibC.h common/debug.h common/encode.h common/error.auto.h common/error.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h config/load.h config/parse.h crypto/cipher.h crypto/cipherBlock.h crypto/hash.h crypto/random.h perl/config.h perl/embed.auto.c perl/exec.h perl/libc.auto.c postgres/pageChecksum.h storage/driver/posix/driver.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/info.h version.h ../libc/xs/common/encode.xsh ../libc/xs/crypto/cipherBlock.xsh ../libc/xs/crypto/hash.xsh
$(CC) $(CFLAGS) -c perl/exec.c -o perl/exec.o
postgres/info.o: postgres/info.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h postgres/info.h postgres/type.h postgres/version.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
postgres/info.o: postgres/info.c common/debug.h common/error.auto.h common/error.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h postgres/info.h postgres/type.h postgres/version.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c postgres/info.c -o postgres/info.o
postgres/pageChecksum.o: postgres/pageChecksum.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/stackTrace.h common/type/convert.h postgres/pageChecksum.h postgres/type.h
$(CC) $(CFLAGS) -funroll-loops -ftree-vectorize -c postgres/pageChecksum.c -o postgres/pageChecksum.o
storage/driver/posix/driver.o: storage/driver/posix/driver.c common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/driver.h storage/driver/posix/driverFile.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h version.h
storage/driver/posix/driver.o: storage/driver/posix/driver.c common/debug.h common/error.auto.h common/error.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/regExp.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/driver.h storage/driver/posix/driverFile.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c storage/driver/posix/driver.c -o storage/driver/posix/driver.o
storage/driver/posix/driverFile.o: storage/driver/posix/driverFile.c common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/driverFile.h
@ -255,17 +274,17 @@ storage/driver/posix/driverFile.o: storage/driver/posix/driverFile.c common/asse
storage/driver/posix/driverRead.o: storage/driver/posix/driverRead.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/driverFile.h storage/driver/posix/driverRead.h
$(CC) $(CFLAGS) -c storage/driver/posix/driverRead.c -o storage/driver/posix/driverRead.o
storage/driver/posix/driverWrite.o: storage/driver/posix/driverWrite.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/driver.h storage/driver/posix/driverFile.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileWrite.h storage/info.h version.h
storage/driver/posix/driverWrite.o: storage/driver/posix/driverWrite.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/driver/posix/driver.h storage/driver/posix/driverFile.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileWrite.h storage/info.h version.h
$(CC) $(CFLAGS) -c storage/driver/posix/driverWrite.c -o storage/driver/posix/driverWrite.o
storage/fileRead.o: storage/fileRead.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/driverRead.h storage/fileRead.h
storage/fileRead.o: storage/fileRead.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/read.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/driverRead.h storage/fileRead.h
$(CC) $(CFLAGS) -c storage/fileRead.c -o storage/fileRead.o
storage/fileWrite.o: storage/fileWrite.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/driverWrite.h storage/fileWrite.h version.h
storage/fileWrite.o: storage/fileWrite.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h storage/driver/posix/driverWrite.h storage/fileWrite.h version.h
$(CC) $(CFLAGS) -c storage/fileWrite.c -o storage/fileWrite.o
storage/helper.o: storage/helper.c common/debug.h common/error.auto.h common/error.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
storage/helper.o: storage/helper.c common/debug.h common/error.auto.h common/error.h common/io/read.h common/io/write.h common/lock.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h config/config.auto.h config/config.h config/define.auto.h config/define.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/helper.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c storage/helper.c -o storage/helper.o
storage/storage.o: storage/storage.c common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/driver/posix/driver.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h version.h
storage/storage.o: storage/storage.c common/assert.h common/debug.h common/error.auto.h common/error.h common/io/io.h common/io/read.h common/io/write.h common/log.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/wait.h storage/driver/posix/driver.h storage/driver/posix/driverRead.h storage/driver/posix/driverWrite.h storage/fileRead.h storage/fileWrite.h storage/info.h storage/storage.h version.h
$(CC) $(CFLAGS) -c storage/storage.c -o storage/storage.o

146
src/common/io/bufferRead.c Normal file
View File

@ -0,0 +1,146 @@
/***********************************************************************************************************************************
Buffer IO Read
***********************************************************************************************************************************/
#include "common/assert.h"
#include "common/debug.h"
#include "common/io/bufferRead.h"
#include "common/log.h"
#include "common/memContext.h"
/***********************************************************************************************************************************
Buffer read object
***********************************************************************************************************************************/
struct IoBufferRead
{
MemContext *memContext;
IoRead *io;
const Buffer *read;
size_t readPos;
bool eof;
};
/***********************************************************************************************************************************
Read from the buffer
***********************************************************************************************************************************/
static size_t
ioBufferRead(IoBufferRead *this, Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_BUFFER_READ, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(buffer != NULL);
FUNCTION_DEBUG_END();
size_t actualBytes = 0;
if (!this->eof)
{
// Determine how many bytes can actually be read from the buffer (if all bytes will be read then EOF)
actualBytes = bufUsed(this->read) - this->readPos;
if (actualBytes > bufRemains(buffer))
actualBytes = bufRemains(buffer);
else
this->eof = true;
// Copy bytes to buffer
bufCatSub(buffer, this->read, this->readPos, actualBytes);
this->readPos += actualBytes;
}
FUNCTION_DEBUG_RESULT(SIZE, actualBytes);
}
/***********************************************************************************************************************************
Have all bytes been read from the buffer?
***********************************************************************************************************************************/
static bool
ioBufferReadEof(IoBufferRead *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_BUFFER_READ, this);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
FUNCTION_DEBUG_RESULT(BOOL, this->eof);
}
/***********************************************************************************************************************************
Create object
***********************************************************************************************************************************/
IoBufferRead *
ioBufferReadNew(const Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_DEBUG_END();
IoBufferRead *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoBufferRead")
{
this = memNew(sizeof(IoBufferRead));
this->memContext = memContextCurrent();
this->read = buffer;
this->io = ioReadNew(this, NULL, (IoReadProcess)ioBufferRead, NULL, (IoReadEof)ioBufferReadEof);
}
MEM_CONTEXT_NEW_END();
FUNCTION_DEBUG_RESULT(IO_BUFFER_READ, this);
}
/***********************************************************************************************************************************
Move the object to a new context
***********************************************************************************************************************************/
IoBufferRead *
ioBufferReadMove(IoBufferRead *this, MemContext *parentNew)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER_READ, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_ASSERT(parentNew != NULL);
FUNCTION_TEST_END();
if (this != NULL)
memContextMove(this->memContext, parentNew);
FUNCTION_TEST_RESULT(IO_BUFFER_READ, this);
}
/***********************************************************************************************************************************
Get io interface
***********************************************************************************************************************************/
IoRead *
ioBufferReadIo(const IoBufferRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(IO_READ, this->io);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/
void
ioBufferReadFree(IoBufferRead *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_BUFFER_READ, this);
FUNCTION_DEBUG_END();
if (this != NULL)
memContextFree(this->memContext);
FUNCTION_DEBUG_RESULT_VOID();
}

View File

@ -0,0 +1,42 @@
/***********************************************************************************************************************************
Buffer IO Read
***********************************************************************************************************************************/
#ifndef COMMON_IO_BUFFERREAD_H
#define COMMON_IO_BUFFERREAD_H
/***********************************************************************************************************************************
Buffer read object
***********************************************************************************************************************************/
typedef struct IoBufferRead IoBufferRead;
#include "common/io/read.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoBufferRead *ioBufferReadNew(const Buffer *buffer);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
IoBufferRead *ioBufferReadMove(IoBufferRead *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
IoRead *ioBufferReadIo(const IoBufferRead *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioBufferReadFree(IoBufferRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_IO_BUFFER_READ_TYPE \
IoBufferRead *
#define FUNCTION_DEBUG_IO_BUFFER_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoBufferRead", buffer, bufferSize)
#endif

114
src/common/io/bufferWrite.c Normal file
View File

@ -0,0 +1,114 @@
/***********************************************************************************************************************************
Buffer IO Write
***********************************************************************************************************************************/
#include "common/assert.h"
#include "common/debug.h"
#include "common/io/bufferWrite.h"
#include "common/log.h"
#include "common/memContext.h"
/***********************************************************************************************************************************
Buffer write object
***********************************************************************************************************************************/
struct IoBufferWrite
{
MemContext *memContext;
IoWrite *io;
Buffer *write;
};
/***********************************************************************************************************************************
Write to the buffer
***********************************************************************************************************************************/
static void
ioBufferWrite(IoBufferWrite *this, Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_DEBUG_ASSERT(this != NULL);
FUNCTION_DEBUG_ASSERT(buffer != NULL);
FUNCTION_DEBUG_END();
bufCat(this->write, buffer);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Create object
***********************************************************************************************************************************/
IoBufferWrite *
ioBufferWriteNew(Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_DEBUG_END();
IoBufferWrite *this = NULL;
MEM_CONTEXT_NEW_BEGIN("IoBufferWrite")
{
this = memNew(sizeof(IoBufferWrite));
this->memContext = memContextCurrent();
this->write = buffer;
this->io = ioWriteNew(this, NULL, (IoWriteProcess)ioBufferWrite, NULL);
}
MEM_CONTEXT_NEW_END();
FUNCTION_DEBUG_RESULT(IO_BUFFER_WRITE, this);
}
/***********************************************************************************************************************************
Move the object to a new context
***********************************************************************************************************************************/
IoBufferWrite *
ioBufferWriteMove(IoBufferWrite *this, MemContext *parentNew)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_TEST_PARAM(MEM_CONTEXT, parentNew);
FUNCTION_TEST_ASSERT(parentNew != NULL);
FUNCTION_TEST_END();
if (this != NULL)
memContextMove(this->memContext, parentNew);
FUNCTION_TEST_RESULT(IO_BUFFER_WRITE, this);
}
/***********************************************************************************************************************************
Get io interface
***********************************************************************************************************************************/
IoWrite *
ioBufferWriteIo(const IoBufferWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(IO_WRITE, this->io);
}
/***********************************************************************************************************************************
Free the object
***********************************************************************************************************************************/
void
ioBufferWriteFree(IoBufferWrite *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_BUFFER_WRITE, this);
FUNCTION_DEBUG_END();
if (this != NULL)
memContextFree(this->memContext);
FUNCTION_DEBUG_RESULT_VOID();
}

View File

@ -0,0 +1,42 @@
/***********************************************************************************************************************************
Buffer IO Write
***********************************************************************************************************************************/
#ifndef COMMON_IO_BUFFERWRITE_H
#define COMMON_IO_BUFFERWRITE_H
/***********************************************************************************************************************************
Buffer write object
***********************************************************************************************************************************/
typedef struct IoBufferWrite IoBufferWrite;
#include "common/io/write.h"
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoBufferWrite *ioBufferWriteNew(Buffer *buffer);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
IoBufferWrite *ioBufferWriteMove(IoBufferWrite *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
IoWrite *ioBufferWriteIo(const IoBufferWrite *this);
/***********************************************************************************************************************************
Destructor
***********************************************************************************************************************************/
void ioBufferWriteFree(IoBufferWrite *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_IO_BUFFER_WRITE_TYPE \
IoBufferWrite *
#define FUNCTION_DEBUG_IO_BUFFER_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoBufferWrite", buffer, bufferSize)
#endif

40
src/common/io/io.c Normal file
View File

@ -0,0 +1,40 @@
/***********************************************************************************************************************************
IO Functions
***********************************************************************************************************************************/
#include "common/assert.h"
#include "common/debug.h"
#include "common/io/io.h"
#include "common/log.h"
/***********************************************************************************************************************************
Buffer size
This buffer size will be used for all IO operations that require buffers not passed by the caller. Initially it is set to a
conservative default with the expectation that it will be changed to a new value after options have been loaded. In general callers
should set their buffer size using ioBufferSize() but there may be cases where an alternative buffer size makes sense.
***********************************************************************************************************************************/
#define IO_BUFFER_BLOCK_SIZE (8 * 1024)
static size_t bufferSize = (8 * IO_BUFFER_BLOCK_SIZE);
/***********************************************************************************************************************************
Get/set buffer size
***********************************************************************************************************************************/
size_t
ioBufferSize()
{
FUNCTION_TEST_VOID();
FUNCTION_TEST_RESULT(SIZE, bufferSize);
}
void
ioBufferSizeSet(size_t bufferSizeParam)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(SIZE, bufferSizeParam);
FUNCTION_TEST_END();
bufferSize = bufferSizeParam;
FUNCTION_TEST_RESULT_VOID();
}

15
src/common/io/io.h Normal file
View File

@ -0,0 +1,15 @@
/***********************************************************************************************************************************
IO Functions
***********************************************************************************************************************************/
#ifndef COMMON_IO_IO_H
#define COMMON_IO_IO_H
#include <stddef.h>
/***********************************************************************************************************************************
Getters/Setters
***********************************************************************************************************************************/
size_t ioBufferSize();
void ioBufferSizeSet(size_t bufferSize);
#endif

133
src/common/io/read.c Normal file
View File

@ -0,0 +1,133 @@
/***********************************************************************************************************************************
IO Read
***********************************************************************************************************************************/
#include "common/debug.h"
#include "common/io/read.h"
#include "common/log.h"
#include "common/memContext.h"
/***********************************************************************************************************************************
IO read object
***********************************************************************************************************************************/
struct IoRead
{
MemContext *memContext; // Mem context of driver
void *driver; // Driver object
IoReadOpen open; // Driver open
IoReadProcess process; // Driver read
IoReadClose close; // Driver close
IoReadEof eof; // Driver eof
size_t size; // Total bytes read
};
/***********************************************************************************************************************************
Create a new read IO
Allocations will be in the memory context of the caller.
***********************************************************************************************************************************/
IoRead *
ioReadNew(void *driver, IoReadOpen open, IoReadProcess process, IoReadClose close, IoReadEof eof)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(VOIDP, driver);
FUNCTION_DEBUG_PARAM(FUNCTIONP, open);
FUNCTION_DEBUG_PARAM(FUNCTIONP, process);
FUNCTION_DEBUG_PARAM(FUNCTIONP, close);
FUNCTION_DEBUG_PARAM(FUNCTIONP, eof);
FUNCTION_TEST_ASSERT(driver != NULL);
FUNCTION_TEST_ASSERT(process != NULL);
FUNCTION_DEBUG_END();
IoRead *this = memNew(sizeof(IoRead));
this->memContext = memContextCurrent();
this->driver = driver;
this->open = open;
this->process = process;
this->close = close;
this->eof = eof;
FUNCTION_DEBUG_RESULT(IO_READ, this);
}
/***********************************************************************************************************************************
Open the IO
***********************************************************************************************************************************/
bool
ioReadOpen(IoRead *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
FUNCTION_DEBUG_RESULT(BOOL, this->open != NULL ? this->open(this->driver) : true);
}
/***********************************************************************************************************************************
Read data from IO
***********************************************************************************************************************************/
size_t
ioRead(IoRead *this, Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(buffer != NULL);
FUNCTION_DEBUG_END();
size_t result = this->process(this->driver, buffer);
this->size += result;
FUNCTION_DEBUG_RESULT(SIZE, result);
}
/***********************************************************************************************************************************
Close the IO
***********************************************************************************************************************************/
void
ioReadClose(IoRead *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
if (this->close != NULL)
this->close(this->driver);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Is IO at EOF?
***********************************************************************************************************************************/
bool
ioReadEof(const IoRead *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
FUNCTION_DEBUG_RESULT(BOOL, this->eof != NULL ? this->eof(this->driver) : false);
}
/***********************************************************************************************************************************
Total bytes read
***********************************************************************************************************************************/
size_t
ioReadSize(const IoRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, this->size);
}

48
src/common/io/read.h Normal file
View File

@ -0,0 +1,48 @@
/***********************************************************************************************************************************
IO Read
***********************************************************************************************************************************/
#ifndef COMMON_IO_READ_H
#define COMMON_IO_READ_H
/***********************************************************************************************************************************
IO read object
***********************************************************************************************************************************/
typedef struct IoRead IoRead;
#include "common/type/buffer.h"
/***********************************************************************************************************************************
Function pointer types
***********************************************************************************************************************************/
typedef bool (*IoReadOpen)(void *driver);
typedef size_t (*IoReadProcess)(void *driver, Buffer *buffer);
typedef void (*IoReadClose)(void *driver);
typedef bool (*IoReadEof)(void *driver);
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoRead *ioReadNew(void *driver, IoReadOpen open, IoReadProcess process, IoReadClose close, IoReadEof eof);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool ioReadOpen(IoRead *this);
size_t ioRead(IoRead *this, Buffer *buffer);
void ioReadClose(IoRead *this);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
bool ioReadEof(const IoRead *this);
size_t ioReadSize(const IoRead *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_IO_READ_TYPE \
IoRead *
#define FUNCTION_DEBUG_IO_READ_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoRead", buffer, bufferSize)
#endif

121
src/common/io/write.c Normal file
View File

@ -0,0 +1,121 @@
/***********************************************************************************************************************************
IO Write
***********************************************************************************************************************************/
#include "common/debug.h"
#include "common/io/write.h"
#include "common/log.h"
#include "common/memContext.h"
/***********************************************************************************************************************************
IO write object
***********************************************************************************************************************************/
struct IoWrite
{
MemContext *memContext; // Mem context of driver
void *driver; // Driver object
IoWriteOpen open; // Driver open
IoWriteProcess process; // Driver write
IoWriteClose close; // Driver close
size_t size; // Total bytes written
};
/***********************************************************************************************************************************
Create a new write IO
Allocations will be in the memory context of the caller.
***********************************************************************************************************************************/
IoWrite *
ioWriteNew(void *driver, IoWriteOpen open, IoWriteProcess process, IoWriteClose close)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(VOIDP, driver);
FUNCTION_DEBUG_PARAM(FUNCTIONP, open);
FUNCTION_DEBUG_PARAM(FUNCTIONP, process);
FUNCTION_DEBUG_PARAM(FUNCTIONP, close);
FUNCTION_TEST_ASSERT(driver != NULL);
FUNCTION_TEST_ASSERT(process != NULL);
FUNCTION_DEBUG_END();
IoWrite *this = memNew(sizeof(IoWrite));
this->memContext = memContextCurrent();
this->driver = driver;
this->open = open;
this->process = process;
this->close = close;
FUNCTION_DEBUG_RESULT(IO_WRITE, this);
}
/***********************************************************************************************************************************
Open the IO
***********************************************************************************************************************************/
void
ioWriteOpen(IoWrite *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
if (this->open != NULL)
this->open(this->driver);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Write data to IO
***********************************************************************************************************************************/
void
ioWrite(IoWrite *this, const Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Only write if there is data to write
if (buffer != NULL && bufSize(buffer) > 0)
{
this->process(this->driver, buffer);
this->size += bufUsed(buffer);
}
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Close the IO
***********************************************************************************************************************************/
void
ioWriteClose(IoWrite *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(IO_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
if (this->close != NULL)
this->close(this->driver);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Total bytes written
***********************************************************************************************************************************/
size_t
ioWriteSize(const IoWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(IO_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, this->size);
}

46
src/common/io/write.h Normal file
View File

@ -0,0 +1,46 @@
/***********************************************************************************************************************************
IO Write
***********************************************************************************************************************************/
#ifndef COMMON_IO_WRITE_H
#define COMMON_IO_WRITE_H
/***********************************************************************************************************************************
IO write object
***********************************************************************************************************************************/
typedef struct IoWrite IoWrite;
#include "common/type/buffer.h"
/***********************************************************************************************************************************
Function pointer types
***********************************************************************************************************************************/
typedef void (*IoWriteOpen)(void *driver);
typedef void (*IoWriteProcess)(void *driver, const Buffer *buffer);
typedef void (*IoWriteClose)(void *driver);
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
IoWrite *ioWriteNew(void *driver, IoWriteOpen open, IoWriteProcess process, IoWriteClose close);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void ioWriteOpen(IoWrite *this);
void ioWrite(IoWrite *this, const Buffer *buffer);
void ioWriteClose(IoWrite *this);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
size_t ioWriteSize(const IoWrite *this);
/***********************************************************************************************************************************
Macros for function logging
***********************************************************************************************************************************/
#define FUNCTION_DEBUG_IO_WRITE_TYPE \
IoWrite *
#define FUNCTION_DEBUG_IO_WRITE_FORMAT(value, buffer, bufferSize) \
objToLog(value, "IoWrite", buffer, bufferSize)
#endif

View File

@ -102,16 +102,64 @@ bufCat(Buffer *this, const Buffer *cat)
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
if (cat != NULL && cat->used > 0)
if (cat != NULL)
bufCatC(this, cat->buffer, 0, cat->used);
FUNCTION_TEST_RESULT(BUFFER, this);
}
/***********************************************************************************************************************************
Append a C buffer
***********************************************************************************************************************************/
Buffer *
bufCatC(Buffer *this, const unsigned char *cat, size_t catOffset, size_t catSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_PARAM(UCHARP, cat);
FUNCTION_TEST_PARAM(SIZE, catOffset);
FUNCTION_TEST_PARAM(SIZE, catSize);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_ASSERT(catSize == 0 || cat != NULL);
FUNCTION_TEST_END();
if (catSize > 0)
{
if (this->used + cat->used > this->size)
bufResize(this, this->used + cat->used);
if (this->used + catSize > this->size)
bufResize(this, this->used + catSize);
// Just here to silence nonnull warnings from clang static analyzer
ASSERT_DEBUG(this->buffer != NULL);
memcpy(this->buffer + this->used, cat->buffer, cat->used);
this->used = this->used + cat->used;
memcpy(this->buffer + this->used, cat + catOffset, catSize);
this->used += catSize;
}
FUNCTION_TEST_RESULT(BUFFER, this);
}
/***********************************************************************************************************************************
Append a subset of another buffer
***********************************************************************************************************************************/
Buffer *
bufCatSub(Buffer *this, const Buffer *cat, size_t catOffset, size_t catSize)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(BUFFER, this);
FUNCTION_TEST_PARAM(BUFFER, cat);
FUNCTION_TEST_PARAM(SIZE, catOffset);
FUNCTION_TEST_PARAM(SIZE, catSize);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
if (cat != NULL)
{
ASSERT(catOffset <= cat->used);
ASSERT(catSize <= cat->used - catOffset);
bufCatC(this, cat->buffer, catOffset, catSize);
}
FUNCTION_TEST_RESULT(BUFFER, this);

View File

@ -20,6 +20,8 @@ Buffer *bufNewC(size_t size, const void *buffer);
Buffer *bufNewStr(const String *string);
Buffer *bufCat(Buffer *this, const Buffer *cat);
Buffer *bufCatC(Buffer *this, const unsigned char *cat, size_t catOffset, size_t catSize);
Buffer *bufCatSub(Buffer *this, const Buffer *cat, size_t catOffset, size_t catSize);
bool bufEq(const Buffer *this, const Buffer *compare);
Buffer *bufMove(Buffer *this, MemContext *parentNew);
Buffer *bufResize(Buffer *this, size_t size);

View File

@ -64,7 +64,7 @@ strNewBuf(const Buffer *buffer)
// Create object
String *this = memNew(sizeof(String));
this->memContext = memContextCurrent();
this->size = bufSize(buffer);
this->size = bufUsed(buffer);
// Allocate and assign string
this->buffer = memNewRaw(this->size + 1);

View File

@ -7,6 +7,7 @@ Configuration Load
#include "command/command.h"
#include "common/memContext.h"
#include "common/debug.h"
#include "common/io/io.h"
#include "common/lock.h"
#include "common/log.h"
#include "config/config.h"
@ -223,6 +224,10 @@ cfgLoad(unsigned int argListSize, const char *argList[])
// If a command is set
if (cfgCommand() != cfgCmdNone)
{
// Set IO buffer size
if (cfgOptionValid(cfgOptBufferSize))
ioBufferSizeSet((size_t)cfgOptionInt(cfgOptBufferSize));
// Open the log file if this command logs to a file
if (cfgLogFile() && !cfgCommandHelp())
{
@ -234,7 +239,7 @@ cfgLoad(unsigned int argListSize, const char *argList[])
// Begin the command
cmdBegin(true);
// Open the log file if this command logs to a file
// Acquire a lock if this command requires a lock
if (cfgLockRequired() && !cfgCommandHelp())
lockAcquire(cfgOptionStr(cfgOptLockPath), cfgOptionStr(cfgOptStanza), cfgLockType(), 0, true);

View File

@ -23,7 +23,6 @@ struct StorageFileReadPosix
int handle;
bool eof;
size_t size;
};
/***********************************************************************************************************************************
@ -87,7 +86,7 @@ storageFileReadPosixOpen(StorageFileReadPosix *this)
/***********************************************************************************************************************************
Read from a file
***********************************************************************************************************************************/
void
size_t
storageFileReadPosix(StorageFileReadPosix *this, Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
@ -99,19 +98,20 @@ storageFileReadPosix(StorageFileReadPosix *this, Buffer *buffer)
FUNCTION_DEBUG_END();
// Read if EOF has not been reached
ssize_t actualBytes = 0;
if (!this->eof)
{
// Read and handle errors
size_t expectedBytes = bufRemains(buffer);
ssize_t actualBytes = read(this->handle, bufRemainsPtr(buffer), expectedBytes);
actualBytes = read(this->handle, bufRemainsPtr(buffer), expectedBytes);
// Error occurred during write
if (actualBytes == -1)
THROW_SYS_ERROR_FMT(FileReadError, "unable to read '%s'", strPtr(this->name));
// Update amount of buffer used and total size
// Update amount of buffer used
bufUsedInc(buffer, (size_t)actualBytes);
this->size += (size_t)actualBytes;
// If less data than expected was read then EOF. The file may not actually be EOF but we are not concerned with files that
// are growing. Just read up to the point where the file is being extended.
@ -119,7 +119,7 @@ storageFileReadPosix(StorageFileReadPosix *this, Buffer *buffer)
this->eof = true;
}
FUNCTION_DEBUG_RESULT_VOID();
FUNCTION_DEBUG_RESULT(SIZE, (size_t)actualBytes);
}
/***********************************************************************************************************************************
@ -191,21 +191,6 @@ storageFileReadPosixName(StorageFileReadPosix *this)
FUNCTION_TEST_RESULT(CONST_STRING, this->name);
}
/***********************************************************************************************************************************
File size
***********************************************************************************************************************************/
size_t
storageFileReadPosixSize(StorageFileReadPosix *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ_POSIX, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, this->size);
}
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/

View File

@ -21,7 +21,7 @@ StorageFileReadPosix *storageFileReadPosixNew(const String *name, bool ignoreMis
Functions
***********************************************************************************************************************************/
bool storageFileReadPosixOpen(StorageFileReadPosix *this);
void storageFileReadPosix(StorageFileReadPosix *this, Buffer *buffer);
size_t storageFileReadPosix(StorageFileReadPosix *this, Buffer *buffer);
void storageFileReadPosixClose(StorageFileReadPosix *this);
/***********************************************************************************************************************************
@ -30,7 +30,6 @@ Getters
bool storageFileReadPosixEof(StorageFileReadPosix *this);
bool storageFileReadPosixIgnoreMissing(StorageFileReadPosix *this);
const String *storageFileReadPosixName(StorageFileReadPosix *this);
size_t storageFileReadPosixSize(StorageFileReadPosix *this);
/***********************************************************************************************************************************
Destructor

View File

@ -14,22 +14,20 @@ struct StorageFileRead
{
MemContext *memContext;
StorageFileReadPosix *fileDriver;
size_t bufferSize;
IoRead *io;
};
/***********************************************************************************************************************************
Create a new storage file
***********************************************************************************************************************************/
StorageFileRead *
storageFileReadNew(const String *name, bool ignoreMissing, size_t bufferSize)
storageFileReadNew(const String *name, bool ignoreMissing)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STRING, name);
FUNCTION_DEBUG_PARAM(BOOL, ignoreMissing);
FUNCTION_DEBUG_PARAM(BOOL, bufferSize);
FUNCTION_TEST_ASSERT(name != NULL);
FUNCTION_TEST_ASSERT(bufferSize > 0);
FUNCTION_DEBUG_END();
StorageFileRead *this = NULL;
@ -40,45 +38,16 @@ storageFileReadNew(const String *name, bool ignoreMissing, size_t bufferSize)
this->memContext = memContextCurrent();
this->fileDriver = storageFileReadPosixNew(name, ignoreMissing);
this->bufferSize = bufferSize;
this->io = ioReadNew(
this->fileDriver, (IoReadOpen)storageFileReadPosixOpen, (IoReadProcess)storageFileReadPosix,
(IoReadClose)storageFileReadPosixClose, (IoReadEof)storageFileReadPosixEof);
}
MEM_CONTEXT_NEW_END();
FUNCTION_DEBUG_RESULT(STORAGE_FILE_READ, this);
}
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
bool
storageFileReadOpen(StorageFileRead *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
FUNCTION_DEBUG_RESULT(BOOL, storageFileReadPosixOpen(this->fileDriver));
}
/***********************************************************************************************************************************
Read data from the file
***********************************************************************************************************************************/
void
storageFileRead(StorageFileRead *this, Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
storageFileReadPosix(this->fileDriver, buffer);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Move the file object to a new context
***********************************************************************************************************************************/
@ -98,38 +67,6 @@ storageFileReadMove(StorageFileRead *this, MemContext *parentNew)
FUNCTION_TEST_RESULT(STORAGE_FILE_READ, this);
}
/***********************************************************************************************************************************
Close the file
***********************************************************************************************************************************/
void
storageFileReadClose(StorageFileRead *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
storageFileReadPosixClose(this->fileDriver);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Get buffer size
***********************************************************************************************************************************/
size_t
storageFileReadBufferSize(const StorageFileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, this->bufferSize);
}
/***********************************************************************************************************************************
Get file driver
***********************************************************************************************************************************/
@ -146,10 +83,10 @@ storageFileReadFileDriver(const StorageFileRead *this)
}
/***********************************************************************************************************************************
Has file reached EOF?
Get io interface
***********************************************************************************************************************************/
bool
storageFileReadEof(const StorageFileRead *this)
IoRead *
storageFileReadIo(const StorageFileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ, this);
@ -157,7 +94,7 @@ storageFileReadEof(const StorageFileRead *this)
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(BOOL, storageFileReadPosixEof(this->fileDriver));
FUNCTION_TEST_RESULT(IO_READ, this->io);
}
/***********************************************************************************************************************************
@ -190,21 +127,6 @@ storageFileReadName(const StorageFileRead *this)
FUNCTION_TEST_RESULT(CONST_STRING, storageFileReadPosixName(this->fileDriver));
}
/***********************************************************************************************************************************
Get file size
***********************************************************************************************************************************/
size_t
storageFileReadSize(const StorageFileRead *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_READ, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(SIZE, storageFileReadPosixSize(this->fileDriver));
}
/***********************************************************************************************************************************
Free the file
***********************************************************************************************************************************/

View File

@ -9,6 +9,7 @@ Storage file read object
***********************************************************************************************************************************/
typedef struct StorageFileRead StorageFileRead;
#include "common/io/read.h"
#include "common/type/buffer.h"
#include "common/type/string.h"
#include "storage/driver/posix/driverRead.h"
@ -16,26 +17,20 @@ typedef struct StorageFileRead StorageFileRead;
/***********************************************************************************************************************************
Constructor
***********************************************************************************************************************************/
StorageFileRead *storageFileReadNew(const String *name, bool ignoreMissing, size_t bufferSize);
StorageFileRead *storageFileReadNew(const String *name, bool ignoreMissing);
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
bool storageFileReadOpen(StorageFileRead *this);
void storageFileRead(StorageFileRead *this, Buffer *buffer);
void storageFileReadClose(StorageFileRead *this);
StorageFileRead *storageFileReadMove(StorageFileRead *this, MemContext *parentNew);
/***********************************************************************************************************************************
Getters
***********************************************************************************************************************************/
size_t storageFileReadBufferSize(const StorageFileRead *this);
StorageFileReadPosix *storageFileReadFileDriver(const StorageFileRead *this);
bool storageFileReadEof(const StorageFileRead *this);
IoRead *storageFileReadIo(const StorageFileRead *this);
bool storageFileReadIgnoreMissing(const StorageFileRead *this);
const String *storageFileReadName(const StorageFileRead *this);
size_t storageFileReadSize(const StorageFileRead *this);
/***********************************************************************************************************************************
Destructor

View File

@ -14,6 +14,7 @@ struct StorageFileWrite
{
MemContext *memContext;
StorageFileWritePosix *fileDriver;
IoWrite *io;
};
/***********************************************************************************************************************************
@ -42,58 +43,22 @@ storageFileWriteNew(
ASSERT_DEBUG(name != NULL);
// Create the file. The file driver is not created here because we don't want to open the file for write until we know that
// there is a source file.
MEM_CONTEXT_NEW_BEGIN("StorageFileWrite")
{
this = memNew(sizeof(StorageFileWrite));
this->memContext = MEM_CONTEXT_NEW();
this->fileDriver = storageFileWritePosixNew(name, modeFile, modePath, noCreatePath, noSyncFile, noSyncPath, noAtomic);
this->io = ioWriteNew(
this->fileDriver, (IoWriteOpen)storageFileWritePosixOpen, (IoWriteProcess)storageFileWritePosix,
(IoWriteClose)storageFileWritePosixClose);
}
MEM_CONTEXT_NEW_END();
FUNCTION_DEBUG_RESULT(STORAGE_FILE_WRITE, this);
}
/***********************************************************************************************************************************
Open the file
***********************************************************************************************************************************/
void
storageFileWriteOpen(StorageFileWrite *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Open the file
storageFileWritePosixOpen(this->fileDriver);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Write to a file
***********************************************************************************************************************************/
void
storageFileWrite(StorageFileWrite *this, const Buffer *buffer)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_DEBUG_PARAM(BUFFER, buffer);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
// Only write if there is data to write
if (buffer != NULL && bufSize(buffer) > 0)
storageFileWritePosix(this->fileDriver, buffer);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Move the file object to a new context
***********************************************************************************************************************************/
@ -113,23 +78,6 @@ storageFileWriteMove(StorageFileWrite *this, MemContext *parentNew)
FUNCTION_TEST_RESULT(STORAGE_FILE_WRITE, this);
}
/***********************************************************************************************************************************
Close the file
***********************************************************************************************************************************/
void
storageFileWriteClose(StorageFileWrite *this)
{
FUNCTION_DEBUG_BEGIN(logLevelTrace);
FUNCTION_DEBUG_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_DEBUG_END();
storageFileWritePosixClose(this->fileDriver);
FUNCTION_DEBUG_RESULT_VOID();
}
/***********************************************************************************************************************************
Will the file be written atomically?
@ -177,6 +125,21 @@ storageFileWriteFileDriver(const StorageFileWrite *this)
FUNCTION_TEST_RESULT(STORAGE_FILE_WRITE_POSIX, this->fileDriver);
}
/***********************************************************************************************************************************
Get the IO object
***********************************************************************************************************************************/
IoWrite *
storageFileWriteIo(const StorageFileWrite *this)
{
FUNCTION_TEST_BEGIN();
FUNCTION_TEST_PARAM(STORAGE_FILE_WRITE, this);
FUNCTION_TEST_ASSERT(this != NULL);
FUNCTION_TEST_END();
FUNCTION_TEST_RESULT(IO_WRITE, this->io);
}
/***********************************************************************************************************************************
Get file mode
***********************************************************************************************************************************/

View File

@ -11,6 +11,7 @@ Storage file read object
***********************************************************************************************************************************/
typedef struct StorageFileWrite StorageFileWrite;
#include "common/io/write.h"
#include "common/type/buffer.h"
#include "common/type/string.h"
#include "storage/driver/posix/driverWrite.h"
@ -30,10 +31,6 @@ StorageFileWrite *storageFileWriteNew(
/***********************************************************************************************************************************
Functions
***********************************************************************************************************************************/
void storageFileWriteOpen(StorageFileWrite *this);
void storageFileWrite(StorageFileWrite *this, const Buffer *buffer);
void storageFileWriteClose(StorageFileWrite *this);
StorageFileWrite *storageFileWriteMove(StorageFileWrite *this, MemContext *parentNew);
/***********************************************************************************************************************************
@ -42,6 +39,7 @@ Getters
bool storageFileWriteAtomic(const StorageFileWrite *this);
bool storageFileWriteCreatePath(const StorageFileWrite *this);
StorageFileWritePosix *storageFileWriteFileDriver(const StorageFileWrite *this);
IoWrite *storageFileWriteIo(const StorageFileWrite *this);
mode_t storageFileWriteModeFile(const StorageFileWrite *this);
mode_t storageFileWriteModePath(const StorageFileWrite *this);
const String *storageFileWriteName(const StorageFileWrite *this);

View File

@ -142,8 +142,7 @@ storageSpool()
{
storageSpoolStanza = strDup(cfgOptionStr(cfgOptStanza));
storageSpoolData = storageNewP(
cfgOptionStr(cfgOptSpoolPath), .bufferSize = (size_t)cfgOptionInt(cfgOptBufferSize),
.pathExpressionFunction = storageSpoolPathExpression, .write = true);
cfgOptionStr(cfgOptSpoolPath), .pathExpressionFunction = storageSpoolPathExpression, .write = true);
}
MEM_CONTEXT_END();
}

View File

@ -6,6 +6,7 @@ Storage Manager
#include "common/assert.h"
#include "common/debug.h"
#include "common/io/io.h"
#include "common/log.h"
#include "common/memContext.h"
#include "common/wait.h"
@ -21,7 +22,6 @@ struct Storage
String *path;
mode_t modeFile;
mode_t modePath;
size_t bufferSize;
bool write;
StoragePathExpressionCallback pathExpressionFunction;
};
@ -36,7 +36,6 @@ storageNew(const String *path, StorageNewParam param)
FUNCTION_DEBUG_PARAM(STRING, path);
FUNCTION_DEBUG_PARAM(MODE, param.modeFile);
FUNCTION_DEBUG_PARAM(MODE, param.modePath);
FUNCTION_DEBUG_PARAM(SIZE, param.bufferSize);
FUNCTION_DEBUG_PARAM(BOOL, param.write);
FUNCTION_DEBUG_PARAM(FUNCTIONP, param.pathExpressionFunction);
@ -53,7 +52,6 @@ storageNew(const String *path, StorageNewParam param)
this->path = strDup(path);
this->modeFile = param.modeFile == 0 ? STORAGE_FILE_MODE_DEFAULT : param.modeFile;
this->modePath = param.modePath == 0 ? STORAGE_PATH_MODE_DEFAULT : param.modePath;
this->bufferSize = param.bufferSize == 0 ? STORAGE_BUFFER_SIZE_DEFAULT : param.bufferSize;
this->write = param.write;
this->pathExpressionFunction = param.pathExpressionFunction;
}
@ -81,25 +79,25 @@ storageCopy(StorageFileRead *source, StorageFileWrite *destination)
MEM_CONTEXT_TEMP_BEGIN()
{
// Open source file
if (storageFileReadOpen(source))
if (ioReadOpen(storageFileReadIo(source)))
{
// Open the destination file now that we know the source file exists and is readable
storageFileWriteOpen(destination);
ioWriteOpen(storageFileWriteIo(destination));
// Copy data from source to destination
Buffer *read = bufNew(storageFileReadBufferSize(source));
Buffer *read = bufNew(ioBufferSize(source));
do
{
storageFileRead(source, read);
storageFileWrite(destination, read);
ioRead(storageFileReadIo(source), read);
ioWrite(storageFileWriteIo(destination), read);
bufUsedZero(read);
}
while (!storageFileReadEof(source));
while (!ioReadEof(storageFileReadIo(source)));
// Close the source and destination files
storageFileReadClose(source);
storageFileWriteClose(destination);
ioReadClose(storageFileReadIo(source));
ioWriteClose(storageFileWriteIo(destination));
// Set result to indicate that the file was copied
result = true;
@ -164,7 +162,7 @@ storageGet(StorageFileRead *file, StorageGetParam param)
Buffer *result = NULL;
// If the file exists
if (storageFileReadOpen(file))
if (ioReadOpen(storageFileReadIo(file)))
{
MEM_CONTEXT_TEMP_BEGIN()
{
@ -172,7 +170,7 @@ storageGet(StorageFileRead *file, StorageGetParam param)
if (param.exactSize > 0)
{
result = bufNew(param.exactSize);
storageFileRead(file, result);
ioRead(storageFileReadIo(file), result);
// If an exact read make sure the size is as expected
if (bufUsed(result) != param.exactSize)
@ -185,18 +183,18 @@ storageGet(StorageFileRead *file, StorageGetParam param)
else
{
result = bufNew(0);
Buffer *read = bufNew(storageFileReadBufferSize(file));
Buffer *read = bufNew(ioBufferSize(file));
do
{
// Read data
storageFileRead(file, read);
ioRead(storageFileReadIo(file), read);
// Add to result and free read buffer
bufCat(result, read);
bufUsedZero(read);
}
while (!storageFileReadEof(file));
while (!ioReadEof(storageFileReadIo(file)));
}
// Move buffer to parent context on success
@ -204,7 +202,7 @@ storageGet(StorageFileRead *file, StorageGetParam param)
}
MEM_CONTEXT_TEMP_END();
storageFileReadClose(file);
ioReadClose(storageFileReadIo(file));
}
FUNCTION_DEBUG_RESULT(BUFFER, result);
@ -324,8 +322,7 @@ storageNewRead(const Storage *this, const String *fileExp, StorageNewReadParam p
MEM_CONTEXT_TEMP_BEGIN()
{
result = storageFileReadMove(
storageFileReadNew(storagePathNP(this, fileExp), param.ignoreMissing, this->bufferSize), MEM_CONTEXT_OLD());
result = storageFileReadMove(storageFileReadNew(storagePathNP(this, fileExp), param.ignoreMissing), MEM_CONTEXT_OLD());
}
MEM_CONTEXT_TEMP_END();
@ -575,9 +572,9 @@ storagePut(StorageFileWrite *file, const Buffer *buffer)
FUNCTION_DEBUG_ASSERT(file != NULL);
FUNCTION_DEBUG_END();
storageFileWriteOpen(file);
storageFileWrite(file, buffer);
storageFileWriteClose(file);
ioWriteOpen(storageFileWriteIo(file));
ioWrite(storageFileWriteIo(file), buffer);
ioWriteClose(storageFileWriteIo(file));
FUNCTION_DEBUG_RESULT_VOID();
}

View File

@ -17,14 +17,6 @@ typedef struct Storage Storage;
#include "storage/fileWrite.h"
#include "storage/info.h"
/***********************************************************************************************************************************
Default buffer size
Generally buffer size should be pulled out of options but some storage is created without access to options. In those cases we'll
assume they are not doing any heavy lifting and have a moderate default.
***********************************************************************************************************************************/
#define STORAGE_BUFFER_SIZE_DEFAULT (64 * 1024)
/***********************************************************************************************************************************
Default file and path modes
***********************************************************************************************************************************/
@ -43,7 +35,6 @@ typedef struct StorageNewParam
{
mode_t modeFile;
mode_t modePath;
size_t bufferSize;
bool write;
StoragePathExpressionCallback pathExpressionFunction;
} StorageNewParam;

View File

@ -123,11 +123,16 @@ unit:
common/lock: full
# ----------------------------------------------------------------------------------------------------------------------------
- name: io-handle
total: 1
- name: io
total: 4
coverage:
common/io/io: full
common/io/handle: full
common/io/read: full
common/io/bufferRead: full
common/io/write: full
common/io/bufferWrite: full
# ----------------------------------------------------------------------------------------------------------------------------
- name: exit

View File

@ -254,6 +254,13 @@ Macros to ease the use of common data types
#define TEST_RESULT_PTR_NE(statement, resultExpected, ...) \
TEST_RESULT_PTR_PARAM(statement, resultExpected, !=, __VA_ARGS__);
#define TEST_RESULT_SIZE_PARAM(statement, resultExpected, typeOp, ...) \
TEST_RESULT(statement, resultExpected, size_t, "%zu", TEST_TYPE_FORMAT, typeOp, TEST_TYPE_COMPARE, __VA_ARGS__);
#define TEST_RESULT_SIZE(statement, resultExpected, ...) \
TEST_RESULT_SIZE_PARAM(statement, resultExpected, ==, __VA_ARGS__);
#define TEST_RESULT_SIZE_NE(statement, resultExpected, ...) \
TEST_RESULT_SIZE_PARAM(statement, resultExpected, !=, __VA_ARGS__);
#define TEST_RESULT_STR_PARAM(statement, resultExpected, typeOp, ...) \
TEST_RESULT(statement, resultExpected, char *, "%s", TEST_TYPE_FORMAT_PTR, typeOp, TEST_TYPE_COMPARE_STR, __VA_ARGS__);
#define TEST_RESULT_STR(statement, resultExpected, ...) \

View File

@ -1,29 +0,0 @@
/***********************************************************************************************************************************
Test Handle IO
***********************************************************************************************************************************/
#include <fcntl.h>
/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
void
testRun()
{
FUNCTION_HARNESS_VOID();
// *****************************************************************************************************************************
if (testBegin("ioHandleWriteOneStr()"))
{
TEST_ERROR(
ioHandleWriteOneStr(999999, strNew("test")), FileWriteError,
"unable to write to 4 byte(s) to handle: [9] Bad file descriptor");
// -------------------------------------------------------------------------------------------------------------------------
String *fileName = strNewFmt("%s/test.txt", testPath());
int fileHandle = open(strPtr(fileName), O_CREAT | O_TRUNC | O_WRONLY, 0700);
TEST_RESULT_VOID(ioHandleWriteOneStr(fileHandle, strNew("test1\ntest2")), "write string to file");
}
FUNCTION_HARNESS_RESULT_VOID();
}

View File

@ -0,0 +1,184 @@
/***********************************************************************************************************************************
Test IO
***********************************************************************************************************************************/
#include <fcntl.h>
#include "common/assert.h"
/***********************************************************************************************************************************
Test functions for IoRead that are not covered by testing the IoBufferRead object
***********************************************************************************************************************************/
static bool
testIoReadOpen(void *driver)
{
ASSERT(driver == (void *)999);
return false;
}
static size_t
testIoReadProcess(void *driver, Buffer *buffer)
{
ASSERT(driver == (void *)999);
bufCat(buffer, bufNewStr(strNew("Z")));
return 1;
}
static bool testIoReadCloseCalled = false;
static void
testIoReadClose(void *driver)
{
ASSERT(driver == (void *)999);
testIoReadCloseCalled = true;
}
/***********************************************************************************************************************************
Test functions for IoWrite that are not covered by testing the IoBufferWrite object
***********************************************************************************************************************************/
static bool testIoWriteOpenCalled = false;
static void
testIoWriteOpen(void *driver)
{
ASSERT(driver == (void *)999);
testIoWriteOpenCalled = true;
}
static void
testIoWriteProcess(void *driver, const Buffer *buffer)
{
ASSERT(driver == (void *)999);
ASSERT(strEq(strNewBuf(buffer), strNew("ABC")));
}
static bool testIoWriteCloseCalled = false;
static void
testIoWriteClose(void *driver)
{
ASSERT(driver == (void *)999);
testIoWriteCloseCalled = true;
}
/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
void
testRun()
{
FUNCTION_HARNESS_VOID();
// *****************************************************************************************************************************
if (testBegin("ioBufferSize() and ioBufferSizeSet()"))
{
TEST_RESULT_SIZE(ioBufferSize(), 65536, "check initial buffer size");
TEST_RESULT_VOID(ioBufferSizeSet(16384), "set buffer size");
TEST_RESULT_SIZE(ioBufferSize(), 16384, "check buffer size");
}
// *****************************************************************************************************************************
if (testBegin("IoRead and IoBufferRead"))
{
IoRead *read = NULL;
Buffer *buffer = bufNew(2);
TEST_ASSIGN(
read, ioReadNew((void *)999, testIoReadOpen, testIoReadProcess, testIoReadClose, NULL), "create io read object");
TEST_RESULT_BOOL(ioReadOpen(read), false, " open io object");
TEST_RESULT_SIZE(ioRead(read, buffer), 1, " read 1 byte");
TEST_RESULT_BOOL(ioReadEof(read), false, " no eof");
TEST_RESULT_VOID(ioReadClose(read), " close io object");
TEST_RESULT_BOOL(testIoReadCloseCalled, true, " check io object closed");
// -------------------------------------------------------------------------------------------------------------------------
IoBufferRead *bufferRead = NULL;
buffer = bufNew(2);
Buffer *bufferOriginal = bufNewStr(strNew("123"));
MEM_CONTEXT_TEMP_BEGIN()
{
TEST_ASSIGN(bufferRead, ioBufferReadNew(bufferOriginal), "create buffer read object");
TEST_RESULT_VOID(ioBufferReadMove(bufferRead, MEM_CONTEXT_OLD()), " move object to new context");
TEST_RESULT_VOID(ioBufferReadMove(NULL, MEM_CONTEXT_OLD()), " move NULL object to new context");
}
MEM_CONTEXT_TEMP_END();
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), false, " not eof");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 2, " read 2 bytes");
TEST_RESULT_BOOL(memcmp(bufPtr(buffer), "12", 2) == 0, true, " memcmp");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "12", " check read");
TEST_RESULT_SIZE(ioReadSize(ioBufferReadIo(bufferRead)), 2, " read size is 2");
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), false, " not eof");
TEST_RESULT_VOID(bufUsedZero(buffer), " zero buffer");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 1, " read 1 byte");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "3", " check read");
TEST_RESULT_BOOL(ioReadEof(ioBufferReadIo(bufferRead)), true, " eof");
TEST_RESULT_SIZE(ioRead(ioBufferReadIo(bufferRead), buffer), 0, " read 0 bytes");
TEST_RESULT_SIZE(ioReadSize(ioBufferReadIo(bufferRead)), 3, " read size is 3");
TEST_RESULT_VOID(ioReadClose(ioBufferReadIo(bufferRead)), " close buffer read object");
TEST_RESULT_VOID(ioBufferReadFree(bufferRead), " free buffer read object");
TEST_RESULT_VOID(ioBufferReadFree(NULL), " free NULL buffer read object");
}
// *****************************************************************************************************************************
if (testBegin("IoWrite and IoBufferWrite"))
{
IoWrite *write = NULL;
TEST_ASSIGN(
write, ioWriteNew((void *)999, testIoWriteOpen, testIoWriteProcess, testIoWriteClose), "create io write object");
TEST_RESULT_VOID(ioWriteOpen(write), " open io object");
TEST_RESULT_BOOL(testIoWriteOpenCalled, true, " check io object open");
TEST_RESULT_VOID(ioWrite(write, bufNewStr(strNew("ABC"))), " write 3 bytes");
TEST_RESULT_VOID(ioWriteClose(write), " close io object");
TEST_RESULT_BOOL(testIoWriteCloseCalled, true, " check io object closed");
// -------------------------------------------------------------------------------------------------------------------------
IoBufferWrite *bufferWrite = NULL;
Buffer *buffer = bufNew(0);
MEM_CONTEXT_TEMP_BEGIN()
{
TEST_ASSIGN(bufferWrite, ioBufferWriteNew(buffer), "create buffer write object");
TEST_RESULT_VOID(ioBufferWriteMove(bufferWrite, MEM_CONTEXT_OLD()), " move object to new context");
TEST_RESULT_VOID(ioBufferWriteMove(NULL, MEM_CONTEXT_OLD()), " move NULL object to new context");
}
MEM_CONTEXT_TEMP_END();
TEST_RESULT_VOID(ioWriteOpen(ioBufferWriteIo(bufferWrite)), " open buffer write object");
TEST_RESULT_VOID(ioWrite(ioBufferWriteIo(bufferWrite), bufNewStr(strNew("ABC"))), " write 3 bytes");
TEST_RESULT_VOID(ioWrite(ioBufferWriteIo(bufferWrite), bufNewStr(strNew(""))), " write 0 bytes");
TEST_RESULT_VOID(ioWrite(ioBufferWriteIo(bufferWrite), NULL), " write 0 bytes");
TEST_RESULT_SIZE(ioWriteSize(ioBufferWriteIo(bufferWrite)), 3, " write size is 3");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "ABC", " check write");
TEST_RESULT_VOID(ioWrite(ioBufferWriteIo(bufferWrite), bufNewStr(strNew("1234"))), " write 4 bytes");
TEST_RESULT_SIZE(ioWriteSize(ioBufferWriteIo(bufferWrite)), 7, " write size is 7");
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "ABC1234", " check write");
TEST_RESULT_VOID(ioWriteClose(ioBufferWriteIo(bufferWrite)), " close buffer write object");
TEST_RESULT_VOID(ioBufferWriteFree(bufferWrite), " free buffer write object");
TEST_RESULT_VOID(ioBufferWriteFree(NULL), " free NULL buffer write object");
}
// *****************************************************************************************************************************
if (testBegin("ioHandleWriteOneStr()"))
{
TEST_ERROR(
ioHandleWriteOneStr(999999, strNew("test")), FileWriteError,
"unable to write to 4 byte(s) to handle: [9] Bad file descriptor");
// -------------------------------------------------------------------------------------------------------------------------
String *fileName = strNewFmt("%s/test.txt", testPath());
int fileHandle = open(strPtr(fileName), O_CREAT | O_TRUNC | O_WRONLY, 0700);
TEST_RESULT_VOID(ioHandleWriteOneStr(fileHandle, strNew("test1\ntest2")), "write string to file");
}
FUNCTION_HARNESS_RESULT_VOID();
}

View File

@ -110,12 +110,17 @@ testRun()
}
// *****************************************************************************************************************************
if (testBegin("bufCat()"))
if (testBegin("bufCat*()"))
{
TEST_RESULT_STR(strPtr(strNewBuf(bufCat(bufNewStr(strNew("123")), NULL))), "123", "cat null buffer");
TEST_RESULT_STR(strPtr(strNewBuf(bufCat(bufNewStr(strNew("123")), bufNew(0)))), "123", "cat empty buffer");
TEST_RESULT_STR(strPtr(strNewBuf(bufCat(bufNewStr(strNew("123")), bufNewStr(strNew("ABC"))))), "123ABC", "cat buffer");
TEST_RESULT_STR(strPtr(strNewBuf(bufCatSub(bufNewStr(strNew("123")), NULL, 0, 0))), "123", "cat sub null buffer");
TEST_RESULT_STR(strPtr(strNewBuf(bufCatSub(bufNewStr(strNew("123")), bufNew(0), 0, 0))), "123", "cat sub empty buffer");
TEST_RESULT_STR(
strPtr(strNewBuf(bufCatSub(bufNewStr(strNew("123")), bufNewStr(strNew("ABC")), 1, 2))), "123BC", "cat sub buffer");
Buffer *buffer = NULL;
TEST_ASSIGN(buffer, bufNew(2), "new buffer with space");
TEST_RESULT_STR(strPtr(strNewBuf(bufCat(buffer, bufNewStr(strNew("AB"))))), "AB", "cat buffer with space");

View File

@ -28,6 +28,7 @@ testRun()
// -------------------------------------------------------------------------------------------------------------------------
Buffer *buffer = bufNew(8);
memcpy(bufPtr(buffer), "12345678", 8);
bufUsedSet(buffer, 8);
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "12345678", "new string from buffer");

View File

@ -1,6 +1,7 @@
/***********************************************************************************************************************************
Test Configuration Load
***********************************************************************************************************************************/
#include "common/io/io.h"
#include "common/log.h"
#include "version.h"
@ -268,7 +269,17 @@ testRun()
TEST_RESULT_VOID(cfgLoad(strLstSize(argList), strLstPtr(argList)), "no command");
// Help command
// Help command only
// -------------------------------------------------------------------------------------------------------------------------
argList = strLstNew();
strLstAdd(argList, strNew("pgbackrest"));
strLstAdd(argList, strNew("help"));
ioBufferSizeSet(333);
TEST_RESULT_VOID(cfgLoad(strLstSize(argList), strLstPtr(argList)), "help command");
TEST_RESULT_SIZE(ioBufferSize(), 333, "buffer size not updated by help command");
// Help command for backup
// -------------------------------------------------------------------------------------------------------------------------
argList = strLstNew();
strLstAdd(argList, strNew("pgbackrest"));
@ -276,7 +287,8 @@ testRun()
strLstAdd(argList, strNew("backup"));
strLstAdd(argList, strNew("--repo1-retention-full=2"));
TEST_RESULT_VOID(cfgLoad(strLstSize(argList), strLstPtr(argList)), "help command");
TEST_RESULT_VOID(cfgLoad(strLstSize(argList), strLstPtr(argList)), "help command for backup");
TEST_RESULT_SIZE(ioBufferSize(), 4 * 1024 * 1024, "buffer size set to option default");
// Command takes lock and opens log file
// -------------------------------------------------------------------------------------------------------------------------

View File

@ -1,6 +1,7 @@
/***********************************************************************************************************************************
Test Storage File
***********************************************************************************************************************************/
#include "common/io/io.h"
#include "storage/storage.h"
/***********************************************************************************************************************************
@ -12,7 +13,8 @@ testRun()
FUNCTION_HARNESS_VOID();
// Create default storage object for testing
Storage *storageTest = storageNewP(strNew(testPath()), .write = true, .bufferSize = 2);
Storage *storageTest = storageNewP(strNew(testPath()), .write = true);
ioBufferSizeSet(2);
// Create a directory and file that cannot be accessed to test permissions errors
String *fileNoPerm = strNewFmt("%s/noperm/noperm", testPath());
@ -79,7 +81,7 @@ testRun()
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(file, storageNewReadNP(storageTest, fileNoPerm), "new no perm read file");
TEST_ERROR_FMT(
storageFileReadOpen(file), FileOpenError,
ioReadOpen(storageFileReadIo(file)), FileOpenError,
"unable to open '%s' for read: [13] Permission denied", strPtr(fileNoPerm));
// -------------------------------------------------------------------------------------------------------------------------
@ -87,12 +89,12 @@ testRun()
TEST_ASSIGN(file, storageNewReadNP(storageTest, fileName), "new missing read file");
TEST_ERROR_FMT(
storageFileReadOpen(file), FileOpenError,
ioReadOpen(storageFileReadIo(file)), FileOpenError,
"unable to open '%s' for read: [2] No such file or directory", strPtr(fileName));
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(file, storageNewReadP(storageTest, fileName, .ignoreMissing = true), "new missing read file");
TEST_RESULT_BOOL(storageFileReadOpen(file), false, " missing file ignored");
TEST_RESULT_BOOL(ioReadOpen(storageFileReadIo(file)), false, " missing file ignored");
// -------------------------------------------------------------------------------------------------------------------------
Buffer *outBuffer = bufNew(2);
@ -100,16 +102,16 @@ testRun()
TEST_RESULT_VOID(storagePutNP(storageNewWriteNP(storageTest, fileName), expectedBuffer), "write test file");
TEST_ASSIGN(file, storageNewReadNP(storageTest, fileName), "new read file");
TEST_RESULT_BOOL(storageFileReadOpen(file), true, " open file");
TEST_RESULT_BOOL(ioReadOpen(storageFileReadIo(file)), true, " open file");
// Close the file handle so operations will fail
close(file->fileDriver->handle);
TEST_ERROR_FMT(
storageFileRead(file, outBuffer), FileReadError,
ioRead(storageFileReadIo(file), outBuffer), FileReadError,
"unable to read '%s': [9] Bad file descriptor", strPtr(fileName));
TEST_ERROR_FMT(
storageFileReadClose(file), FileCloseError,
ioReadClose(storageFileReadIo(file)), FileCloseError,
"unable to close '%s': [9] Bad file descriptor", strPtr(fileName));
// Set file handle to -1 so the close on free with not fail
@ -124,41 +126,41 @@ testRun()
}
MEM_CONTEXT_TEMP_END();
TEST_RESULT_BOOL(storageFileReadOpen(file), true, " open file");
TEST_RESULT_BOOL(ioReadOpen(storageFileReadIo(file)), true, " open file");
TEST_RESULT_STR(strPtr(storageFileReadName(file)), strPtr(fileName), " check file name");
TEST_RESULT_INT(storageFileReadSize(file), 0, " check size");
TEST_RESULT_INT(ioReadSize(storageFileReadIo(file)), 0, " check size");
TEST_RESULT_VOID(storageFileRead(file, outBuffer), " load data");
TEST_RESULT_VOID(ioRead(storageFileReadIo(file), outBuffer), " load data");
bufCat(buffer, outBuffer);
bufUsedZero(outBuffer);
TEST_RESULT_VOID(storageFileRead(file, outBuffer), " load data");
TEST_RESULT_VOID(ioRead(storageFileReadIo(file), outBuffer), " load data");
bufCat(buffer, outBuffer);
bufUsedZero(outBuffer);
TEST_RESULT_VOID(storageFileRead(file, outBuffer), " load data");
TEST_RESULT_VOID(ioRead(storageFileReadIo(file), outBuffer), " load data");
bufCat(buffer, outBuffer);
bufUsedZero(outBuffer);
TEST_RESULT_VOID(storageFileRead(file, outBuffer), " load data");
TEST_RESULT_VOID(ioRead(storageFileReadIo(file), outBuffer), " load data");
bufCat(buffer, outBuffer);
bufUsedZero(outBuffer);
TEST_RESULT_BOOL(bufEq(buffer, expectedBuffer), false, " check file contents (not all loaded yet)");
TEST_RESULT_INT(storageFileReadSize(file), 8, " check size");
TEST_RESULT_INT(ioReadSize(storageFileReadIo(file)), 8, " check size");
TEST_RESULT_VOID(storageFileRead(file, outBuffer), " load data");
TEST_RESULT_VOID(ioRead(storageFileReadIo(file), outBuffer), " load data");
bufCat(buffer, outBuffer);
bufUsedZero(outBuffer);
TEST_RESULT_VOID(storageFileRead(file, outBuffer), " no data to load");
TEST_RESULT_VOID(ioRead(storageFileReadIo(file), outBuffer), " no data to load");
TEST_RESULT_INT(bufUsed(outBuffer), 0, " buffer is empty");
TEST_RESULT_BOOL(bufEq(buffer, expectedBuffer), true, " check file contents (all loaded)");
TEST_RESULT_INT(storageFileReadSize(file), 9, " check size");
TEST_RESULT_INT(ioReadSize(storageFileReadIo(file)), 9, " check size");
TEST_RESULT_BOOL(storageFileReadEof(file), true, " eof");
TEST_RESULT_BOOL(storageFileReadEof(file), true, " still eof");
TEST_RESULT_BOOL(ioReadEof(storageFileReadIo(file)), true, " eof");
TEST_RESULT_BOOL(ioReadEof(storageFileReadIo(file)), true, " still eof");
TEST_RESULT_VOID(storageFileReadClose(file), " close file");
TEST_RESULT_VOID(storageFileReadClose(file), " close again");
TEST_RESULT_INT(storageFileReadSize(file), 9, " check size");
TEST_RESULT_VOID(ioReadClose(storageFileReadIo(file)), " close file");
TEST_RESULT_VOID(ioReadClose(storageFileReadIo(file)), " close again");
TEST_RESULT_INT(ioReadSize(storageFileReadIo(file)), 9, " check size");
TEST_RESULT_VOID(storageFileReadFree(file), " free file");
TEST_RESULT_VOID(storageFileReadFree(NULL), " free null file");
@ -192,7 +194,7 @@ testRun()
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true), "new write file");
TEST_ERROR_FMT(
storageFileWriteOpen(file), FileOpenError,
ioWriteOpen(storageFileWriteIo(file)), FileOpenError,
"unable to open '%s' for write: [13] Permission denied", strPtr(fileNoPerm));
// -------------------------------------------------------------------------------------------------------------------------
@ -200,7 +202,7 @@ testRun()
TEST_ASSIGN(file, storageNewWriteP(storageTest, fileName, .noCreatePath = true, .noAtomic = true), "new write file");
TEST_ERROR_FMT(
storageFileWriteOpen(file), FileOpenError,
ioWriteOpen(storageFileWriteIo(file)), FileOpenError,
"unable to open '%s' for write: [2] No such file or directory", strPtr(fileName));
// -------------------------------------------------------------------------------------------------------------------------
@ -209,24 +211,24 @@ testRun()
TEST_ASSIGN(file, storageNewWriteNP(storageTest, fileName), "new write file");
TEST_RESULT_STR(strPtr(storageFileWriteName(file)), strPtr(fileName), " check file name");
TEST_RESULT_VOID(storageFileWriteOpen(file), " open file");
TEST_RESULT_VOID(ioWriteOpen(storageFileWriteIo(file)), " open file");
// Close the file handle so operations will fail
close(file->fileDriver->handle);
storageRemoveP(storageTest, fileTmp, .errorOnMissing = true);
TEST_ERROR_FMT(
storageFileWrite(file, buffer), FileWriteError,
ioWrite(storageFileWriteIo(file), buffer), FileWriteError,
"unable to write '%s': [9] Bad file descriptor", strPtr(fileName));
TEST_ERROR_FMT(
storageFileWriteClose(file), FileSyncError,
ioWriteClose(storageFileWriteIo(file)), FileSyncError,
"unable to sync '%s': [9] Bad file descriptor", strPtr(fileName));
// Disable file sync so the close can be reached
file->fileDriver->noSyncFile = true;
TEST_ERROR_FMT(
storageFileWriteClose(file), FileCloseError,
ioWriteClose(storageFileWriteIo(file)), FileCloseError,
"unable to close '%s': [9] Bad file descriptor", strPtr(fileName));
// Set file handle to -1 so the close on free with not fail
@ -235,12 +237,12 @@ testRun()
// -------------------------------------------------------------------------------------------------------------------------
TEST_ASSIGN(file, storageNewWriteNP(storageTest, fileName), "new write file");
TEST_RESULT_STR(strPtr(storageFileWriteName(file)), strPtr(fileName), " check file name");
TEST_RESULT_VOID(storageFileWriteOpen(file), " open file");
TEST_RESULT_VOID(ioWriteOpen(storageFileWriteIo(file)), " open file");
// Rename the file back to original name from tmp -- this will cause the rename in close to fail
TEST_RESULT_INT(rename(strPtr(fileTmp), strPtr(fileName)), 0, " rename tmp file");
TEST_ERROR_FMT(
storageFileWriteClose(file), FileMoveError,
ioWriteClose(storageFileWriteIo(file)), FileMoveError,
"unable to move '%s' to '%s': [2] No such file or directory", strPtr(fileTmp), strPtr(fileName));
// Set file handle to -1 so the close on free with not fail
@ -255,11 +257,12 @@ testRun()
}
MEM_CONTEXT_TEMP_END();
TEST_RESULT_VOID(storageFileWriteOpen(file), " open file");
TEST_RESULT_VOID(storageFileWrite(file, NULL), " write null buffer to file");
TEST_RESULT_VOID(storageFileWrite(file, bufNew(0)), " write zero buffer to file");
TEST_RESULT_VOID(storageFileWrite(file, buffer), " write to file");
TEST_RESULT_VOID(storageFileWriteClose(file), " close file");
TEST_RESULT_VOID(ioWriteOpen(storageFileWriteIo(file)), " open file");
TEST_RESULT_VOID(ioWrite(storageFileWriteIo(file), NULL), " write null buffer to file");
TEST_RESULT_VOID(ioWrite(storageFileWriteIo(file), bufNew(0)), " write zero buffer to file");
TEST_RESULT_VOID(ioWrite(storageFileWriteIo(file), buffer), " write to file");
TEST_RESULT_VOID(ioWriteClose(storageFileWriteIo(file)), " close file");
TEST_RESULT_SIZE(ioWriteSize(storageFileWriteIo(file)), 9, " check size");
TEST_RESULT_VOID(storageFileWriteFree(file), " free file");
TEST_RESULT_VOID(storageFileWriteFree(NULL), " free null file");
TEST_RESULT_VOID(storageFileWritePosixFree(NULL), " free null posix file");
@ -281,9 +284,9 @@ testRun()
storageTest, fileName, .modePath = 0700, .modeFile = 0600, .noSyncPath = true, .noSyncFile = true,
.noAtomic = true),
"new write file");
TEST_RESULT_VOID(storageFileWriteOpen(file), " open file");
TEST_RESULT_VOID(storageFileWrite(file, buffer), " write to file");
TEST_RESULT_VOID(storageFileWriteClose(file), " close file");
TEST_RESULT_VOID(ioWriteOpen(storageFileWriteIo(file)), " open file");
TEST_RESULT_VOID(ioWrite(storageFileWriteIo(file), buffer), " write to file");
TEST_RESULT_VOID(ioWriteClose(storageFileWriteIo(file)), " close file");
expectedBuffer = storageGetNP(storageNewReadNP(storageTest, fileName));
TEST_RESULT_BOOL(bufEq(buffer, expectedBuffer), true, " check file contents");

View File

@ -1,6 +1,7 @@
/***********************************************************************************************************************************
Test Storage Manager
***********************************************************************************************************************************/
#include "common/io/io.h"
#include "common/time.h"
#include "storage/fileRead.h"
#include "storage/fileWrite.h"
@ -32,8 +33,9 @@ testRun()
FUNCTION_HARNESS_VOID();
// Create default storage object for testing
Storage *storageTest = storageNewP(strNew(testPath()), .write = true, .bufferSize = 3);
Storage *storageTest = storageNewP(strNew(testPath()), .write = true);
Storage *storageTmp = storageNewP(strNew("/tmp"), .write = true);
ioBufferSizeSet(2);
// Create a directory and file that cannot be accessed to test permissions errors
String *fileNoPerm = strNewFmt("%s/noperm/noperm", testPath());
@ -56,20 +58,18 @@ testRun()
TEST_RESULT_STR(strPtr(storageTest->path), "/", " check path");
TEST_RESULT_INT(storageTest->modeFile, 0640, " check file mode");
TEST_RESULT_INT(storageTest->modePath, 0750, " check path mode");
TEST_RESULT_INT(storageTest->bufferSize, 65536, " check buffer size");
TEST_RESULT_BOOL(storageTest->write, false, " check write");
TEST_RESULT_BOOL(storageTest->pathExpressionFunction == NULL, true, " check expression function is not set");
TEST_ASSIGN(
storageTest,
storageNewP(
strNew("/path/to"), .modeFile = 0600, .modePath = 0700, .bufferSize = 8192, .write = true,
strNew("/path/to"), .modeFile = 0600, .modePath = 0700, .write = true,
.pathExpressionFunction = storageTestPathExpression),
"new storage (non-default)");
TEST_RESULT_STR(strPtr(storageTest->path), "/path/to", " check path");
TEST_RESULT_INT(storageTest->modeFile, 0600, " check file mode");
TEST_RESULT_INT(storageTest->modePath, 0700, " check path mode");
TEST_RESULT_INT(storageTest->bufferSize, 8192, " check buffer size");
TEST_RESULT_BOOL(storageTest->write, true, " check write");
TEST_RESULT_BOOL(storageTest->pathExpressionFunction != NULL, true, " check expression function is set");
@ -475,14 +475,14 @@ testRun()
TEST_ASSIGN(file, storageNewReadNP(storageTest, fileName), "new read file (defaults)");
TEST_ERROR_FMT(
storageFileReadOpen(file), FileOpenError,
ioReadOpen(storageFileReadIo(file)), FileOpenError,
"unable to open '%s' for read: [2] No such file or directory", strPtr(fileName));
// -------------------------------------------------------------------------------------------------------------------------
TEST_RESULT_INT(system(strPtr(strNewFmt("touch %s", strPtr(fileName)))), 0, "create read file");
TEST_RESULT_BOOL(storageFileReadOpen(file), true, " open file");
TEST_RESULT_VOID(storageFileReadClose(file), " close file");
TEST_RESULT_BOOL(ioReadOpen(storageFileReadIo(file)), true, " open file");
TEST_RESULT_VOID(ioReadClose(storageFileReadIo(file)), " close file");
}
// *****************************************************************************************************************************
@ -492,15 +492,15 @@ testRun()
TEST_ASSIGN(file, storageNewWriteP(storageTest, fileNoPerm, .noAtomic = true), "new write file (defaults)");
TEST_ERROR_FMT(
storageFileWriteOpen(file), FileOpenError,
ioWriteOpen(storageFileWriteIo(file)), FileOpenError,
"unable to open '%s' for write: [13] Permission denied", strPtr(fileNoPerm));
// -------------------------------------------------------------------------------------------------------------------------
String *fileName = strNewFmt("%s/sub1/testfile", testPath());
TEST_ASSIGN(file, storageNewWriteNP(storageTest, fileName), "new write file (defaults)");
TEST_RESULT_VOID(storageFileWriteOpen(file), " open file");
TEST_RESULT_VOID(storageFileWriteClose(file), " close file");
TEST_RESULT_VOID(ioWriteOpen(storageFileWriteIo(file)), " open file");
TEST_RESULT_VOID(ioWriteClose(storageFileWriteIo(file)), " close file");
TEST_RESULT_INT(storageInfoNP(storageTest, strPath(fileName)).mode, 0750, " check path mode");
TEST_RESULT_INT(storageInfoNP(storageTest, fileName).mode, 0640, " check file mode");
@ -509,8 +509,8 @@ testRun()
TEST_ASSIGN(
file, storageNewWriteP(storageTest, fileName, .modePath = 0700, .modeFile = 0600), "new write file (set mode)");
TEST_RESULT_VOID(storageFileWriteOpen(file), " open file");
TEST_RESULT_VOID(storageFileWriteClose(file), " close file");
TEST_RESULT_VOID(ioWriteOpen(storageFileWriteIo(file)), " open file");
TEST_RESULT_VOID(ioWriteClose(storageFileWriteIo(file)), " close file");
TEST_RESULT_INT(storageInfoNP(storageTest, strPath(fileName)).mode, 0700, " check path mode");
TEST_RESULT_INT(storageInfoNP(storageTest, fileName).mode, 0600, " check file mode");
}
@ -560,8 +560,7 @@ testRun()
"unable to read 64 byte(s) from '%s/test.txt'", testPath());
// -------------------------------------------------------------------------------------------------------------------------
const Storage *storage = storageTest;
((Storage *)storage)->bufferSize = 2;
ioBufferSizeSet(2);
TEST_ASSIGN(buffer, storageGetNP(storageNewReadNP(storageTest, strNewFmt("%s/test.txt", testPath()))), "get text");
TEST_RESULT_INT(bufSize(buffer), 9, "check size");