mirror of
https://github.com/rupertwh/bmplib.git
synced 2026-02-04 05:35:48 +00:00
add unit tests for write_<xnn>_le() functions
This commit is contained in:
15
meson.build
15
meson.build
@@ -93,6 +93,17 @@ test_read_io = executable('test_read_io',
|
||||
dependencies: m_dep,
|
||||
)
|
||||
|
||||
test_write_io = executable('test_write_io',
|
||||
'test-write-io.c',
|
||||
'bmp-common.c',
|
||||
'bmp-read.c',
|
||||
'huffman.c',
|
||||
'logging.c',
|
||||
'test-fileio-pipes.c',
|
||||
huff_codes[0],
|
||||
dependencies: m_dep,
|
||||
)
|
||||
|
||||
test('read - s_s2_13_to_float', test_read_conversions, args : ['s_s2_13_to_float'])
|
||||
test('read - s_convert64', test_read_conversions, args : ['s_convert64'])
|
||||
test('read - s_float_to_s2_13', test_read_conversions, args : ['s_float_to_s2_13'])
|
||||
@@ -108,3 +119,7 @@ test('read - read_u16_le', test_read_io, args : ['read_u16_le'
|
||||
test('read - read_s16_le', test_read_io, args : ['read_s16_le'])
|
||||
test('read - read_u32_le', test_read_io, args : ['read_u32_le'])
|
||||
test('read - read_s32_le', test_read_io, args : ['read_s32_le'])
|
||||
test('write - write_u32_le', test_write_io, args : ['write_u32_le'])
|
||||
test('write - write_s32_le', test_write_io, args : ['write_s32_le'])
|
||||
test('write - write_u16_le', test_write_io, args : ['write_u16_le'])
|
||||
test('write - write_s16_le', test_write_io, args : ['write_s16_le'])
|
||||
|
||||
@@ -69,3 +69,77 @@ abort:
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FILE* open_write_pipe(struct WritePipe **hwp)
|
||||
{
|
||||
int fd[2] = { -1, -1 };
|
||||
FILE *file_read = NULL, *file_write = NULL;
|
||||
struct WritePipe *wp = NULL;
|
||||
|
||||
if (!hwp)
|
||||
return NULL;
|
||||
*hwp = NULL;
|
||||
|
||||
if (!(wp = malloc(sizeof *wp))) {
|
||||
perror(__func__);
|
||||
goto abort;
|
||||
}
|
||||
memset(wp, 0, sizeof *wp);
|
||||
|
||||
if (pipe(fd)) {
|
||||
perror("pipe");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (!(file_read = fdopen(fd[0], "rb"))) {
|
||||
perror("fdopen read pipe");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
if (!(file_write = fdopen(fd[1], "w"))) {
|
||||
perror("fdopen write pipe");
|
||||
goto abort;
|
||||
}
|
||||
|
||||
wp->file_read = file_read;
|
||||
*hwp = wp;
|
||||
|
||||
return file_write;
|
||||
|
||||
abort:
|
||||
if (file_write)
|
||||
fclose(file_write);
|
||||
else if (fd[1] != -1)
|
||||
close(fd[1]);
|
||||
|
||||
if (file_read)
|
||||
fclose(file_read);
|
||||
else if (fd[0] != -1)
|
||||
close(fd[0]);
|
||||
|
||||
if (wp)
|
||||
free(wp);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int data_from_write_pipe(struct WritePipe *wp, unsigned char *buffer, int size)
|
||||
{
|
||||
int nread;
|
||||
|
||||
if (!(wp && buffer)) {
|
||||
fprintf(stderr, "%s(): invalid NULL argument(s)\n", __func__);
|
||||
exit(3);
|
||||
}
|
||||
if (!wp->file_read) {
|
||||
fprintf(stderr, "%s(): FILE* is NULL\n", __func__);
|
||||
exit(3);
|
||||
}
|
||||
nread = fread(buffer, 1, size, wp->file_read);
|
||||
fclose(wp->file_read);
|
||||
free(wp);
|
||||
|
||||
return nread;
|
||||
}
|
||||
|
||||
@@ -18,4 +18,12 @@
|
||||
* If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
struct WritePipe {
|
||||
FILE *file_read;
|
||||
};
|
||||
|
||||
|
||||
FILE* provide_as_file(const unsigned char *data, size_t size);
|
||||
|
||||
FILE* open_write_pipe(struct WritePipe **hwp);
|
||||
int data_from_write_pipe(struct WritePipe *wp, unsigned char *buffer, int size);
|
||||
|
||||
235
test-write-io.c
Normal file
235
test-write-io.c
Normal file
@@ -0,0 +1,235 @@
|
||||
/* bmplib - test-read-io.c
|
||||
*
|
||||
* Copyright (c) 2025, Rupert Weber.
|
||||
*
|
||||
* This file is part of bmplib.
|
||||
* bmplib is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as
|
||||
* published by the Free Software Foundation, either version 3 of
|
||||
* the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library.
|
||||
* If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
|
||||
#include "bmp-write.c"
|
||||
|
||||
#include "test-fileio-pipes.h"
|
||||
|
||||
#define ARRAY_LEN(a) ((int)(sizeof (a) / sizeof ((a)[0])))
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
const char *func /*, *subtest =""*/;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Invalid invocation\n");
|
||||
return 2;
|
||||
}
|
||||
func = argv[1];
|
||||
/*if (argc >= 3)
|
||||
subtest = argv[2];*/
|
||||
|
||||
|
||||
|
||||
if (!strcmp(func, "write_u32_le")) {
|
||||
const int expected_len = 4;
|
||||
|
||||
struct {
|
||||
uint32_t value;
|
||||
unsigned char *expected;
|
||||
} data[] = {
|
||||
{ .expected = (unsigned char[]){0x00,0x00,0x00,0x00}, .value = 0 },
|
||||
{ .expected = (unsigned char[]){0x01,0x00,0x00,0x00}, .value = 1 },
|
||||
{ .expected = (unsigned char[]){0xfe,0xff,0xff,0xff}, .value = 0xfffffffeUL },
|
||||
{ .expected = (unsigned char[]){0xff,0xff,0xff,0xff}, .value = 0xffffffffUL },
|
||||
{ .expected = (unsigned char[]){0x12,0x34,0x56,0x78}, .value = 0x78563412UL },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_LEN(data); i++) {
|
||||
struct WritePipe *wp = NULL;
|
||||
unsigned char buf[expected_len];
|
||||
|
||||
FILE *file = open_write_pipe(&wp);
|
||||
if (!file)
|
||||
return 2;
|
||||
|
||||
if (!write_u32_le(file, data[i].value)) {
|
||||
perror(func);
|
||||
return 3;
|
||||
}
|
||||
fflush(file); /* important, otherwise read will get stuck */
|
||||
|
||||
int nbytes = data_from_write_pipe(wp, buf, (int) sizeof buf);
|
||||
fclose(file);
|
||||
if (nbytes != expected_len) {
|
||||
printf("%s() failed on dataset %d (%lu):\n", func, i, (unsigned long)data[i].value);
|
||||
printf("expected to read %d bytes, got %d bytes\n", expected_len, nbytes);
|
||||
return 1;
|
||||
}
|
||||
if (memcmp(data[i].expected, buf, expected_len) != 0) {
|
||||
printf("%s() failed on dataset %d (%lu):\n", func, i, (unsigned long)data[i].value);
|
||||
printf("expected 0x%02x%02x%02x%02x, got 0x%02x%02x%02x%02x\n",
|
||||
(unsigned)data[i].expected[0], (unsigned)data[i].expected[1],
|
||||
(unsigned)data[i].expected[2], (unsigned)data[i].expected[3],
|
||||
(unsigned)buf[0], (unsigned)buf[1], (unsigned)buf[2], (unsigned)buf[3]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (!strcmp(func, "write_s32_le")) {
|
||||
const int expected_len = 4;
|
||||
|
||||
struct {
|
||||
int32_t value;
|
||||
unsigned char *expected;
|
||||
} data[] = {
|
||||
{ .expected = (unsigned char[]){0x00,0x00,0x00,0x00}, .value = 0 },
|
||||
{ .expected = (unsigned char[]){0x01,0x00,0x00,0x00}, .value = 1 },
|
||||
{ .expected = (unsigned char[]){0xff,0xff,0xff,0xff}, .value = -1 },
|
||||
{ .expected = (unsigned char[]){0x00,0x00,0x00,0x80}, .value = -2147483648L },
|
||||
{ .expected = (unsigned char[]){0x01,0x00,0x00,0x80}, .value = -2147483647L },
|
||||
{ .expected = (unsigned char[]){0xfe,0xff,0xff,0x7f}, .value = 2147483646L },
|
||||
{ .expected = (unsigned char[]){0xff,0xff,0xff,0x7f}, .value = 2147483647L },
|
||||
{ .expected = (unsigned char[]){0x12,0x34,0x56,0x78}, .value = 2018915346L },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_LEN(data); i++) {
|
||||
struct WritePipe *wp = NULL;
|
||||
unsigned char buf[expected_len];
|
||||
|
||||
FILE *file = open_write_pipe(&wp);
|
||||
if (!file)
|
||||
return 2;
|
||||
|
||||
if (!write_s32_le(file, data[i].value)) {
|
||||
perror(func);
|
||||
return 3;
|
||||
}
|
||||
fflush(file); /* important, otherwise read will get stuck */
|
||||
|
||||
int nbytes = data_from_write_pipe(wp, buf, (int) sizeof buf);
|
||||
fclose(file);
|
||||
if (nbytes != expected_len) {
|
||||
printf("%s() failed on dataset %d (%ld):\n", func, i, (long)data[i].value);
|
||||
printf("expected to read %d bytes, got %d bytes\n", expected_len, nbytes);
|
||||
return 1;
|
||||
}
|
||||
if (memcmp(data[i].expected, buf, expected_len) != 0) {
|
||||
printf("%s() failed on dataset %d (%ld):\n", func, i, (long)data[i].value);
|
||||
printf("expected 0x%02x%02x%02x%02x, got 0x%02x%02x%02x%02x\n",
|
||||
(unsigned)data[i].expected[0], (unsigned)data[i].expected[1],
|
||||
(unsigned)data[i].expected[2], (unsigned)data[i].expected[3],
|
||||
(unsigned)buf[0], (unsigned)buf[1], (unsigned)buf[2], (unsigned)buf[3]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (!strcmp(func, "write_u16_le")) {
|
||||
const int expected_len = 2;
|
||||
|
||||
struct {
|
||||
uint16_t value;
|
||||
unsigned char *expected;
|
||||
} data[] = {
|
||||
{ .expected = (unsigned char[]){0x00,0x00}, .value = 0 },
|
||||
{ .expected = (unsigned char[]){0x01,0x00}, .value = 1 },
|
||||
{ .expected = (unsigned char[]){0xfe,0xff}, .value = 65534 },
|
||||
{ .expected = (unsigned char[]){0xff,0xff}, .value = 65535 },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_LEN(data); i++) {
|
||||
struct WritePipe *wp = NULL;
|
||||
unsigned char buf[expected_len];
|
||||
|
||||
FILE *file = open_write_pipe(&wp);
|
||||
if (!file)
|
||||
return 2;
|
||||
|
||||
if (!write_u16_le(file, data[i].value)) {
|
||||
perror(func);
|
||||
return 3;
|
||||
}
|
||||
fflush(file); /* important, otherwise read will get stuck */
|
||||
|
||||
int nbytes = data_from_write_pipe(wp, buf, (int) sizeof buf);
|
||||
fclose(file);
|
||||
if (nbytes != expected_len) {
|
||||
printf("%s() failed on dataset %d (%u):\n", func, i, (unsigned)data[i].value);
|
||||
printf("expected to read %d bytes, got %d bytes\n", expected_len, nbytes);
|
||||
return 1;
|
||||
}
|
||||
if (memcmp(data[i].expected, buf, expected_len) != 0) {
|
||||
printf("%s() failed on dataset %d (%u):\n", func, i, (unsigned)data[i].value);
|
||||
printf("expected 0x%02x%02x, got 0x%02x%02x\n",
|
||||
(unsigned)data[i].expected[0], (unsigned)data[i].expected[1],
|
||||
(unsigned)buf[0], (unsigned)buf[1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (!strcmp(func, "write_s16_le")) {
|
||||
const int expected_len = 2;
|
||||
|
||||
struct {
|
||||
int16_t value;
|
||||
unsigned char *expected;
|
||||
} data[] = {
|
||||
{ .expected = (unsigned char[]){0x00,0x00}, .value = 0 },
|
||||
{ .expected = (unsigned char[]){0x01,0x00}, .value = 1 },
|
||||
{ .expected = (unsigned char[]){0x00,0x80}, .value = -32768 },
|
||||
{ .expected = (unsigned char[]){0x01,0x80}, .value = -32767 },
|
||||
{ .expected = (unsigned char[]){0xfe,0x7f}, .value = 32766 },
|
||||
{ .expected = (unsigned char[]){0xff,0x7f}, .value = 32767 },
|
||||
};
|
||||
|
||||
for (int i = 0; i < ARRAY_LEN(data); i++) {
|
||||
struct WritePipe *wp = NULL;
|
||||
unsigned char buf[expected_len];
|
||||
|
||||
FILE *file = open_write_pipe(&wp);
|
||||
if (!file)
|
||||
return 2;
|
||||
|
||||
if (!write_s16_le(file, data[i].value)) {
|
||||
perror(func);
|
||||
return 3;
|
||||
}
|
||||
fflush(file); /* important, otherwise read will get stuck */
|
||||
|
||||
int nbytes = data_from_write_pipe(wp, buf, (int) sizeof buf);
|
||||
fclose(file);
|
||||
if (nbytes != expected_len) {
|
||||
printf("%s() failed on dataset %d (%d):\n", func, i, (int)data[i].value);
|
||||
printf("expected to read %d bytes, got %d bytes\n", expected_len, nbytes);
|
||||
return 1;
|
||||
}
|
||||
if (memcmp(data[i].expected, buf, expected_len) != 0) {
|
||||
printf("%s() failed on dataset %d (%d):\n", func, i, (int)data[i].value);
|
||||
printf("expected 0x%02x%02x, got 0x%02x%02x\n",
|
||||
(unsigned)data[i].expected[0], (unsigned)data[i].expected[1],
|
||||
(unsigned)buf[0], (unsigned)buf[1]);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
fprintf(stderr, "Invalid test '%s'\n", func);
|
||||
return 2;
|
||||
}
|
||||
Reference in New Issue
Block a user