]> Kevux Git Server - fll/commitdiff
Feature: Add additional network and socket related functions.
authorKevin Day <kevin@kevux.org>
Sat, 24 Jun 2023 03:08:45 +0000 (22:08 -0500)
committerKevin Day <kevin@kevux.org>
Sat, 24 Jun 2023 03:13:40 +0000 (22:13 -0500)
Add the following:
- f_file_poll() for poll().
- f_socket_read_stream() for recv().
- f_socket_write_stream() for send().

Add f_poll_t, f_polls_t, and f_pollss_t typedefs.
This adds the appropriate array management functions.
To be consistent with type_file.h a new type_array_file.h is created to manage these.

Update the existing f_signal_read() to use the new typdef f_poll_t.

This includes unit tests as appropriate.

72 files changed:
build/monolithic/settings
level_0/f_file/c/file.c
level_0/f_file/c/file.h
level_0/f_file/data/build/settings-mocks
level_0/f_file/data/build/settings-tests
level_0/f_file/tests/unit/c/mock-file.c
level_0/f_file/tests/unit/c/mock-file.h
level_0/f_file/tests/unit/c/test-file-poll.c [new file with mode: 0644]
level_0/f_file/tests/unit/c/test-file-poll.h [new file with mode: 0644]
level_0/f_file/tests/unit/c/test-file.c
level_0/f_file/tests/unit/c/test-file.h
level_0/f_signal/c/signal.c
level_0/f_signal/c/signal.h
level_0/f_signal/tests/unit/c/mock-signal.h
level_0/f_signal/tests/unit/c/test-signal.h
level_0/f_socket/c/socket.c
level_0/f_socket/c/socket.h
level_0/f_socket/data/build/settings-mocks
level_0/f_socket/data/build/settings-tests
level_0/f_socket/tests/unit/c/mock-socket.c
level_0/f_socket/tests/unit/c/mock-socket.h
level_0/f_socket/tests/unit/c/test-socket-read_stream.c [new file with mode: 0644]
level_0/f_socket/tests/unit/c/test-socket-read_stream.h [new file with mode: 0644]
level_0/f_socket/tests/unit/c/test-socket-write_stream.c [new file with mode: 0644]
level_0/f_socket/tests/unit/c/test-socket-write_stream.h [new file with mode: 0644]
level_0/f_socket/tests/unit/c/test-socket.c
level_0/f_socket/tests/unit/c/test-socket.h
level_0/f_type/c/type_file.h
level_0/f_type_array/c/type_array/poll.c [new file with mode: 0644]
level_0/f_type_array/c/type_array/poll.h [new file with mode: 0644]
level_0/f_type_array/c/type_array/private-poll.c [new file with mode: 0644]
level_0/f_type_array/c/type_array/private-poll.h [new file with mode: 0644]
level_0/f_type_array/c/type_array_file.h [new file with mode: 0644]
level_0/f_type_array/data/build/settings
level_0/f_type_array/data/build/settings-mocks [new file with mode: 0644]
level_0/f_type_array/data/build/settings-tests
level_0/f_type_array/tests/unit/c/mock-type_array.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/mock-type_array.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_adjust.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_adjust.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_append.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_append.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_append_all.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_append_all.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_decimate_by.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_decimate_by.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_decrease_by.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_decrease_by.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_increase.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_increase.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_increase_by.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_increase_by.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_resize.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-polls_resize.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_adjust.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_adjust.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_append.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_append.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_append_all.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_append_all.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_decimate_by.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_decimate_by.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_decrease_by.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_decrease_by.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase_by.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase_by.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_resize.c [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array-pollss_resize.h [new file with mode: 0644]
level_0/f_type_array/tests/unit/c/test-type_array.c
level_0/f_type_array/tests/unit/c/test-type_array.h

index a0e42b878f632cbc37e0408c266964f8d86ba05d..de210d7bce487921d2f6a5c9dd7971937e548c51 100644 (file)
@@ -128,7 +128,7 @@ build_sources_headers level_0/fss.h level_0/fss/comment.h level_0/fss/common.h l
 build_sources_headers level_0/iki.h level_0/iki/common.h level_0/iki/data.h
 build_sources_headers level_0/limit.h level_0/limit/set.h level_0/limit/value.h
 build_sources_headers level_0/memory.h level_0/memory/structure.h level_0/memory/common.h
-build_sources_headers level_0/network.h network/common.h
+build_sources_headers level_0/network.h level_0/network/common.h
 build_sources_headers level_0/parse.h level_0/parse/utf.h
 build_sources_headers level_0/path.h level_0/path/common.h
 build_sources_headers level_0/pipe.h
index f8452751789be9553af0289983b0f59b43c34893..dd5d4d26aaaa8ec58d5dbd1ea3b99b45453e70df 100644 (file)
@@ -1578,6 +1578,26 @@ extern "C" {
   }
 #endif // _di_f_file_owner_read_
 
+#ifndef _di_f_file_poll_
+  f_status_t f_file_poll(const f_polls_t polls, const int timeout) {
+
+    if (!polls.used) return F_data_not;
+
+    const int result = poll(polls.array, (nfds_t) polls.used, timeout);
+
+    if (result == -1) {
+      if (errno == EFAULT) return F_status_set_error(F_buffer);
+      if (errno == EINTR) return F_status_set_error(F_interrupt);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+
+      return F_status_set_error(F_failure);
+    }
+
+    return result ? F_none : F_time_out;
+  }
+#endif // _di_f_file_poll_
+
 #ifndef _di_f_file_read_
   f_status_t f_file_read(const f_file_t file, f_string_dynamic_t * const buffer) {
     #ifndef _di_level_0_parameter_checking_
index b770f8446362d7dda5a1a1d8e02002a4407fe782..261fc5ec891436e02e3ec39a2a2fce2082381ffa 100644 (file)
@@ -17,6 +17,7 @@
 #include <fcntl.h>
 #include <libgen.h>
 #include <limits.h>
+#include <poll.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -1536,6 +1537,47 @@ extern "C" {
 #endif // _di_f_file_owner_read_
 
 /**
+ * Perform poll on the one of more file descriptors.
+ *
+ * This is a general wrapper around poll.
+ * For more specialized use cases look at f_signal_read().
+ *
+ * This does not check the revent codes in the polls array.
+ *
+ * @todo There also needs to be a ppoll function like this, f_file_poll_lock() perhaps.
+ *
+ * @param polls
+ *   An array of polls representing all file descriptors to poll at once.
+ *
+ *   Warning: The max array length for used is limited to nfds_t which might be different from f_number_unsigned_t.
+ *   The nfds_t is often either uint32_t or an uint64_t.
+ *   The f_number_unsigned_t is often an uint64_t.
+ *
+ *   When a file descriptor (polls.array[].fd) is set to -1, then the file descriptor is ignored and the return events (polls.array[].revents) is set to 0.
+ * @param timeout
+ *   The number of milliseconds that the poll will block, waiting for a file descriptor.
+ *   Once time out is reach, then this will unblock and return.
+ *
+ *   A value of 0 results in immediate return.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not if polls.used is 0.
+ *   F_time_out if time out is reached befoe a signal is received.
+ *
+ *   F_buffer (with error bit) if the buffer is invalid.
+ *   F_interrupt (with error bit) if interrupt was received.
+ *   F_memory_not (with error bit) if out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see poll()
+ */
+#ifndef _di_f_file_poll_
+  extern f_status_t f_file_poll(const f_polls_t polls, const int timeout);
+#endif // _di_f_file_poll_
+
+/**
  * Read until EOF is reached.
  *
  * To determine how much was read into the buffer, record buffer->used before execution and compare to buffer->used after execution.
index 849f9fbb81c33febacb3a9c148958244fbbb435c..aeae42cb6089ab88e7bd06bf7269f21b339724a6 100644 (file)
@@ -97,6 +97,7 @@ flags -Wl,--wrap=mkfifo
 flags -Wl,--wrap=mkfifoat
 flags -Wl,--wrap=mknod
 flags -Wl,--wrap=mknodat
+flags -Wl,--wrap=poll
 flags -Wl,--wrap=open
 flags -Wl,--wrap=openat
 flags -Wl,--wrap=read
index b49d8a77a4a12edae3a4e9b8f23ae9a23e2f12c0..b604c83bad4f54a35a08f431e41a463c4090b57d 100644 (file)
@@ -25,7 +25,7 @@ build_language c
 build_libraries -lc -lcmocka
 build_libraries-individual -lf_memory -lf_string -lf_file
 
-build_sources_program test-file-access.c test-file-access_at.c test-file-clone.c test-file-close.c test-file-copy.c test-file-create.c test-file-create_at.c test-file-create_device.c test-file-create_device_at.c test-file-create_fifo.c test-file-create_fifo_at.c test-file-create_node.c test-file-create_node_at.c test-file-descriptor.c test-file-exists.c test-file-exists_at.c test-file-flush.c test-file-group_read.c test-file-is.c test-file-is_at.c test-file-is_stat.c test-file-link.c test-file-link_at.c test-file-link_hard.c test-file-link_hard_at.c test-file-link_read.c test-file-link_read_at.c test-file-manipulate.c test-file-mode_determine.c test-file-mode_from_string.c test-file-mode_read.c test-file-mode_read_at.c test-file-mode_set.c test-file-mode_set_at.c test-file-mode_to_mode.c test-file-name_base.c test-file-name_directory.c test-file-open.c test-file-open_at.c test-file-owner_read.c test-file-read.c test-file-read_block.c test-file-read_until.c test-file-remove.c test-file-remove_at.c test-file-rename.c test-file-rename_at.c test-file-role_change.c test-file-role_change_at.c test-file-seek.c test-file-size.c test-file-size_at.c test-file-size_by_id.c test-file-stat.c test-file-stat_at.c test-file-stat_by_id.c test-file-stream_close.c test-file-stream_open_descriptor.c test-file-stream_open.c test-file-stream_read.c test-file-stream_read_block.c test-file-stream_read_until.c test-file-stream_reopen.c test-file-stream_write.c test-file-stream_write_block.c test-file-stream_write_until.c test-file-stream_write_range.c test-file-touch.c test-file-touch_at.c test-file-type.c test-file-type_at.c test-file-umask_get.c test-file-umask_set.c test-file-write.c test-file-write_block.c test-file-write_until.c test-file-write_range.c
+build_sources_program test-file-access.c test-file-access_at.c test-file-clone.c test-file-close.c test-file-copy.c test-file-create.c test-file-create_at.c test-file-create_device.c test-file-create_device_at.c test-file-create_fifo.c test-file-create_fifo_at.c test-file-create_node.c test-file-create_node_at.c test-file-descriptor.c test-file-exists.c test-file-exists_at.c test-file-flush.c test-file-group_read.c test-file-is.c test-file-is_at.c test-file-is_stat.c test-file-link.c test-file-link_at.c test-file-link_hard.c test-file-link_hard_at.c test-file-link_read.c test-file-link_read_at.c test-file-manipulate.c test-file-mode_determine.c test-file-mode_from_string.c test-file-mode_read.c test-file-mode_read_at.c test-file-mode_set.c test-file-mode_set_at.c test-file-mode_to_mode.c test-file-name_base.c test-file-name_directory.c test-file-open.c test-file-open_at.c test-file-owner_read.c test-file-read.c test-file-read_block.c test-file-read_until.c test-file-remove.c test-file-remove_at.c test-file-rename.c test-file-rename_at.c test-file-role_change.c test-file-role_change_at.c test-file-poll.c test-file-seek.c test-file-size.c test-file-size_at.c test-file-size_by_id.c test-file-stat.c test-file-stat_at.c test-file-stat_by_id.c test-file-stream_close.c test-file-stream_open_descriptor.c test-file-stream_open.c test-file-stream_read.c test-file-stream_read_block.c test-file-stream_read_until.c test-file-stream_reopen.c test-file-stream_write.c test-file-stream_write_block.c test-file-stream_write_until.c test-file-stream_write_range.c test-file-touch.c test-file-touch_at.c test-file-type.c test-file-type_at.c test-file-umask_get.c test-file-umask_set.c test-file-write.c test-file-write_block.c test-file-write_until.c test-file-write_range.c
 build_sources_program test-file.c
 
 build_script no
index 1aa8aba0351f8fb72cf563f68a10493b3999d9ec..8069930a6480f528090265394b3fd05ad2c0184c 100644 (file)
@@ -494,6 +494,21 @@ int __wrap_openat(int dirfd, const char *pathname, int flags, mode_t mode) {
   return mock_type(int);
 }
 
+int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  fds->revents = mock_type(short);
+
+  return mock_type(int);
+}
+
 ssize_t __wrap_read(int fd, void *buf, size_t count) {
 
   const bool failure = mock_type(bool);
index 7b876f9e66dabb5d587cb4e0b32ae9a793fb06af..76c8fb971f8b19256d2c7a3b4be78e8b1c9a065e 100644 (file)
@@ -66,6 +66,7 @@ extern int __wrap_mknod(const char *pathname, mode_t mode, dev_t dev);
 extern int __wrap_mknodat(int dirfd, const char *pathname, mode_t mode, dev_t dev);
 extern int __wrap_open(const char *pathname, int flags, mode_t mode);
 extern int __wrap_openat(int dirfd, const char *pathname, int flags, mode_t mode);
+extern int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout);
 extern ssize_t __wrap_read(int fd, void *buf, size_t count);
 extern ssize_t __wrap_readlink(const char *pathname, char *buf, size_t bufsiz);
 extern ssize_t __wrap_readlinkat(int dirfd, const char *pathname, char *buf, size_t bufsiz);
diff --git a/level_0/f_file/tests/unit/c/test-file-poll.c b/level_0/f_file/tests/unit/c/test-file-poll.c
new file mode 100644 (file)
index 0000000..60c72d9
--- /dev/null
@@ -0,0 +1,78 @@
+#include "test-file.h"
+#include "test-file-poll.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_file_poll__fails(void **state) {
+
+  {
+    int errnos[] = {
+      EFAULT,
+      EINTR,
+      EINVAL,
+      ENOMEM,
+      mock_errno_generic,
+    };
+
+    f_status_t statuss[] = {
+      F_buffer,
+      F_interrupt,
+      F_parameter,
+      F_memory_not,
+      F_failure,
+    };
+
+    f_polls_t polls = f_polls_t_initialize;
+    polls.used = 1;
+
+    for (int i = 0; i < 5; ++i) {
+
+      will_return(__wrap_poll, true);
+      will_return(__wrap_poll, errnos[i]);
+
+      const f_status_t status = f_file_poll(polls, 0);
+
+      assert_int_equal(status, F_status_set_error(statuss[i]));
+    } // for
+  }
+}
+
+void test__f_file_poll__returns_data_not(void **state) {
+
+  f_polls_t polls = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_file_poll(polls, 0);
+
+    assert_int_equal(status, F_data_not);
+  }
+}
+
+void test__f_file_poll__works(void **state) {
+
+  {
+    const int fd = 0;
+    const int total = 1;
+    const short revents = 5;
+
+    f_poll_t poll = macro_f_poll_t_initialize_1(fd, 1, 2);
+    f_polls_t polls = macro_f_polls_t_initialize_1(&poll, 0, 1);
+
+    will_return(__wrap_poll, false);
+    will_return(__wrap_poll, revents);
+    will_return(__wrap_poll, total);
+
+    const f_status_t status = f_file_poll(polls, 0);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(poll.fd, fd);
+    assert_int_equal(poll.events, total);
+    assert_int_equal(poll.revents, revents);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_file/tests/unit/c/test-file-poll.h b/level_0/f_file/tests/unit/c/test-file-poll.h
new file mode 100644 (file)
index 0000000..ac53fec
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: File
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the file project.
+ */
+#ifndef _TEST__F_file_poll_h
+#define _TEST__F_file_poll_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_file_poll()
+ */
+extern void test__f_file_poll__fails(void **state);
+
+/**
+ * Test that function works but the path is empty.
+ *
+ * @see f_file_poll()
+ */
+extern void test__f_file_poll__returns_data_not(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_file_poll()
+ */
+extern void test__f_file_poll__works(void **state);
+
+#endif // _TEST__F_file_poll_h
index e74a43db9ea64f38592a7e3b14615723e5a1b1aa..55058f2d6c9ed4f081b60f70314fabac3d72cff4 100644 (file)
@@ -210,6 +210,10 @@ int main(void) {
     cmocka_unit_test(test__f_file_owner_read__returns_data_not),
     cmocka_unit_test(test__f_file_owner_read__works),
 
+    cmocka_unit_test(test__f_file_poll__fails),
+    cmocka_unit_test(test__f_file_poll__returns_data_not),
+    cmocka_unit_test(test__f_file_poll__works),
+
     cmocka_unit_test(test__f_file_read__fails),
     cmocka_unit_test(test__f_file_read__returns_file_descriptor_not),
     cmocka_unit_test(test__f_file_read__works),
@@ -414,6 +418,7 @@ int main(void) {
       cmocka_unit_test(test__f_file_open__parameter_checking),
       cmocka_unit_test(test__f_file_open_at__parameter_checking),
       cmocka_unit_test(test__f_file_owner_read__parameter_checking),
+      // f_file_poll() doesn't use parameter checking.
       cmocka_unit_test(test__f_file_read__parameter_checking),
       cmocka_unit_test(test__f_file_read_block__parameter_checking),
       cmocka_unit_test(test__f_file_read_until__parameter_checking),
index 142c0d56d4f95063d6f285ba6e6c7f565264dcb1..0636fc513f2cceba33ae98b1eeefe6a4779f53a8 100644 (file)
@@ -66,6 +66,7 @@
 #include "test-file-open.h"
 #include "test-file-open_at.h"
 #include "test-file-owner_read.h"
+#include "test-file-poll.h"
 #include "test-file-read.h"
 #include "test-file-read_block.h"
 #include "test-file-read_until.h"
index bc91470713780e280b00c0576a6cc1cd5ea11cec..f05c93d676dda12ba767d1860253273d1256d1c2 100644 (file)
@@ -119,11 +119,7 @@ extern "C" {
       if (!information) return F_status_set_error(F_parameter);
     #endif // _di_level_0_parameter_checking_
 
-    struct pollfd data_poll;
-    memset(&data_poll, 0, sizeof(struct pollfd));
-
-    data_poll.fd = signal.id;
-    data_poll.events = POLLIN;
+    f_poll_t data_poll = macro_f_poll_t_initialize_2(signal.id, POLLIN);
 
     const int result = poll(&data_poll, 1, timeout);
 
@@ -137,17 +133,9 @@ extern "C" {
     }
 
     if (result) {
-      if (data_poll.revents & POLLNVAL) {
-        return F_status_set_error(F_parameter);
-      }
-
-      if (data_poll.revents & POLLHUP) {
-        return F_status_set_error(F_file_closed);
-      }
-
-      if (data_poll.revents & POLLERR) {
-        return F_status_set_error(F_stream);
-      }
+      if (data_poll.revents & POLLNVAL) return F_status_set_error(F_parameter);
+      if (data_poll.revents & POLLHUP) return F_status_set_error(F_file_closed);
+      if (data_poll.revents & POLLERR) return F_status_set_error(F_stream);
 
       if (data_poll.revents & POLLIN) {
         const ssize_t total = read(signal.id, information, sizeof(struct signalfd_siginfo));
index f78a97b9f29da01b9cf701123cd85f0657f803b1..0c92ffdb5d196e9247ec95d104aad1d059cabc36 100644 (file)
@@ -19,6 +19,7 @@
 
 // FLL-0 includes.
 #include <fll/level_0/type.h>
+#include <fll/level_0/type_file.h>
 #include <fll/level_0/status.h>
 
 // FLL-0 signal includes.
@@ -177,6 +178,10 @@ extern "C" {
 /**
  * Read a current process signal, if one exists.
  *
+ * For a more generalized call to poll() look at f_file_poll().
+ *
+ * @todo This may be better suited for calling ppoll() instead of poll().
+ *
  * @param signal
  *   The signal settings.
  * @param timeout
index 656f411882a5e3fa52d9576a86a76dcd0cf1e84b..df5632297c84c2c8db794c75d48eb4baa661b9ad 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * FLL - Level 0
  *
- * Project: Account
+ * Project: Signal
  * API Version: 0.7
  * Licenses: lgpl-2.1-or-later
  *
index 96a77d3cede26f2dcaf63945b5d46af94a4d1668..2137074905abcf80b499a9f49eaedc914efeff9e 100644 (file)
@@ -1,7 +1,7 @@
 /**
  * FLL - Level 0
  *
- * Project: Account
+ * Project: Signal
  * API Version: 0.7
  * Licenses: lgpl-2.1-or-later
  *
index 1e95ee93340d1135ab2bbe2ceea6f6d9f7e9ed0f..72935d6694aaf64151b070c675f9f62d06ff0630 100644 (file)
@@ -444,6 +444,45 @@ extern "C" {
   }
 #endif // _di_f_socket_read_message_
 
+#ifndef _di_f_socket_read_stream_
+  f_status_t f_socket_read_stream(f_socket_t * const socket, const int flags, void * const buffer, size_t * const length) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!socket) return F_status_set_error(F_parameter);
+      if (!buffer) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const ssize_t result = recv(socket->id, buffer, socket->size_read, flags);
+
+    if (result < 0) {
+      if (errno == EACCES) return F_status_set_error(F_access_denied);
+      if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
+      if (errno == EALREADY) return F_status_set_error(F_complete_not);
+      if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+      if (errno == ECONNREFUSED) return F_status_set_error(F_connect_refuse);
+      if (errno == ECONNRESET) return F_status_set_error(F_connect_reset);
+      if (errno == EDESTADDRREQ) return F_status_set_error(F_address_not);
+      if (errno == EFAULT) return F_status_set_error(F_buffer);
+      if (errno == EINTR) return F_status_set_error(F_interrupt);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+      if (errno == ENOTCONN) return F_status_set_error(F_connect_not);
+      if (errno == ENOTSOCK) return F_status_set_error(F_socket_not);
+      if (errno == EOPNOTSUPP) return F_status_set_error(F_option_not);
+      if (errno == EPERM) return F_status_set_error(F_prohibited);
+      if (errno == EPIPE) return F_status_set_error(F_pipe);
+      if (errno == ETIMEDOUT) return F_status_set_error(F_time_out);
+
+      return F_status_set_error(F_failure);
+    }
+
+    if (length) {
+      *length = (size_t) result;
+    }
+
+    return F_none;
+  }
+#endif // _di_f_socket_read_stream_
+
 #ifndef _di_f_socket_write_
   f_status_t f_socket_write(f_socket_t * const socket, const int flags, void * const buffer, size_t * const length) {
     #ifndef _di_level_0_parameter_checking_
@@ -528,6 +567,48 @@ extern "C" {
   }
 #endif // _di_f_socket_write_message_
 
+#ifndef _di_f_socket_write_stream_
+  f_status_t f_socket_write_stream(f_socket_t * const socket, const int flags, void * const buffer, size_t * const length) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!socket) return F_status_set_error(F_parameter);
+      if (!buffer) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    const ssize_t result = send(socket->id, buffer, socket->size_write, flags);
+
+    if (result < 0) {
+      if (errno == EACCES) return F_status_set_error(F_access_denied);
+      if (errno == EAGAIN || errno == EWOULDBLOCK) return F_status_set_error(F_block);
+      if (errno == EALREADY) return F_status_set_error(F_complete_not);
+      if (errno == EBADF) return F_status_set_error(F_file_descriptor);
+      if (errno == ECONNREFUSED) return F_status_set_error(F_connect_refuse);
+      if (errno == ECONNRESET) return F_status_set_error(F_connect_reset);
+      if (errno == EDESTADDRREQ) return F_status_set_error(F_address_not);
+      if (errno == EFAULT) return F_status_set_error(F_buffer);
+      if (errno == EINTR) return F_status_set_error(F_interrupt);
+      if (errno == EINVAL) return F_status_set_error(F_parameter);
+      if (errno == EISCONN) return F_status_set_error(F_connect);
+      if (errno == EMSGSIZE) return F_status_set_error(F_size);
+      if (errno == ENOBUFS) return F_status_set_error(F_buffer_not);
+      if (errno == ENOMEM) return F_status_set_error(F_memory_not);
+      if (errno == ENOTCONN) return F_status_set_error(F_connect_not);
+      if (errno == ENOTSOCK) return F_status_set_error(F_socket_not);
+      if (errno == EOPNOTSUPP) return F_status_set_error(F_option_not);
+      if (errno == EPERM) return F_status_set_error(F_prohibited);
+      if (errno == EPIPE) return F_status_set_error(F_pipe);
+      if (errno == ETIMEDOUT) return F_status_set_error(F_time_out);
+
+      return F_status_set_error(F_failure);
+    }
+
+    if (length) {
+      *length = (size_t) result;
+    }
+
+    return F_none;
+  }
+#endif // _di_f_socket_write_stream_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 3ee54b03a52b14b8dde0beb072a93db09fdfdbc7..103f5c6b7f8fc8bd0b1097692dd0718d04c8e367 100644 (file)
@@ -462,6 +462,8 @@ extern "C" {
 /**
  * Read from a socket.
  *
+ * This is the recommneded way to read UDP streams.
+ *
  * @param socket
  *   The socket structure.
  *   The socket.id must represent a valid socket file descriptor.
@@ -548,8 +550,57 @@ extern "C" {
 #endif // _di_f_socket_read_message_
 
 /**
+ * Read from a socket stream.
+ *
+ * This is the recommneded way to read TCP streams.
+ *
+ * @param socket
+ *   The socket structure.
+ *   The socket.id must represent a valid socket file descriptor.
+ *   The socket.size_read is used to represent the buffer size in buffer and must not be larger than the actual size of the buffer.
+ * @param flags
+ *   Read flags.
+ * @param buffer
+ *   The buffer to populate.
+ * @param length
+ *   (optional) The length of the buffer.
+ *   This gets replaced with the value of a positive ssize_t representing the length read.
+ *   Data may be lost if the amount of data read is larger than given buffer length.
+ *   Set to NULL to not use.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_access_denied (with error bit) on access denied.
+ *   F_complete_not (with error bit) if an existing connection is not yet complete.
+ *   F_connect_not (with error bit) if the socket is not connected.
+ *   F_connect_refuse (with error bit) if connection is refused.
+ *   F_connect_reset (with error bit) if connection is reset.
+ *   F_block (with error bit) if socket is blocked.
+ *   F_buffer (with error bit) if the buffer is invalid.
+ *   F_file_descriptor (with error bit) if id is an invalid descriptor.
+ *   F_interrupt (with error bit) if interrupt is received.
+ *   F_memory_not (with error bit) if out of memory.
+ *   F_option_not (with error bit) if a flag is not supported.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_pipe (with error bit) if the local end of a connection oriented socket is closed or SIGPIPE is received.
+ *   F_prohibited (with error bit) if the insufficient privileges to perform read.
+ *   F_socket_not (with error bit) if the id is not a socket descriptor.
+ *   F_time_out (with error bit) if a timeout occurred.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see recv()
+ */
+#ifndef _di_f_socket_read_stream_
+  extern f_status_t f_socket_read_stream(f_socket_t * const socket, const int flags, void * const buffer, size_t * const length);
+#endif // _di_f_socket_read_stream_
+
+/**
  * Send to a socket.
  *
+ * This is the recommneded way to write UDP streams.
+ *
  * @param socket
  *   The socket structure.
  *   The socket.id must represent a valid socket file descriptor.
@@ -643,6 +694,57 @@ extern "C" {
   extern f_status_t f_socket_write_message(f_socket_t * const socket, const int flags, struct msghdr * const header, size_t * const length);
 #endif // _di_f_socket_write_message_
 
+/**
+ * Send to a socket.
+ *
+ * This is the recommneded way to write TCP streams.
+ *
+ * @param socket
+ *   The socket structure.
+ *   The socket.id must represent a valid socket file descriptor.
+ *   The socket.size_write is used to represent the buffer size in buffer and must not be larger than the actual size of the buffer.
+ * @param flags
+ *   Read flags.
+ * @param buffer
+ *   The buffer to populate.
+ * @param length
+ *   (optional) The length of the buffer.
+ *   This gets replaced with the value of a positive ssize_t representing the length send.
+ *   Data may be lost if the amount of data send is larger than given buffer length.
+ *   Set to NULL to not use.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_access_denied (with error bit) on access denied.
+ *   F_address_not (with error bit) if no address is provided and the connection is not "connection-mode".
+ *   F_buffer_not (with error bit) if unable to send message because output buffer is full.
+ *   F_complete_not (with error bit) if an existing connection is not yet complete.
+ *   F_connect (with error bit) if an address is provided and the connection is "connection-mode".
+ *   F_connect_not (with error bit) if the socket is not connected.
+ *   F_connect_refuse (with error bit) if connection is refused.
+ *   F_connect_reset (with error bit) if connection is reset.
+ *   F_block (with error bit) if socket is blocked.
+ *   F_buffer (with error bit) if the buffer is invalid.
+ *   F_file_descriptor (with error bit) if id is an invalid descriptor.
+ *   F_interrupt (with error bit) if interrupt is received.
+ *   F_memory_not (with error bit) if out of memory.
+ *   F_option_not (with error bit) if a flag is not supported.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_pipe (with error bit) if the local end of a connection oriented socket is closed or SIGPIPE is received.
+ *   F_prohibited (with error bit) if the insufficient privileges to perform send.
+ *   F_size (with error bit) if size of message makes atomically sending message impossible on a socket type that requires this to be atomic.
+ *   F_socket_not (with error bit) if the id is not a socket descriptor.
+ *   F_time_out (with error bit) if a timeout occurred.
+ *
+ *   F_failure (with error bit) for any other error.
+ *
+ * @see send()
+ */
+#ifndef _di_f_socket_write_stream_
+  extern f_status_t f_socket_write_stream(f_socket_t * const socket, const int flags, void * const buffer, size_t * const length);
+#endif // _di_f_socket_write_stream_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 77979cf2cf5c8934f9895bfb2b7f76f9731359e2..6d0eda733e252be637688bbed5debcbff16fde0d 100644 (file)
@@ -69,8 +69,10 @@ flags -Wl,--wrap=getsockopt
 flags -Wl,--wrap=listen
 flags -Wl,--wrap=gethostname
 flags -Wl,--wrap=getpeername
+flags -Wl,--wrap=recv
 flags -Wl,--wrap=recvfrom
 flags -Wl,--wrap=recvmsg
+flags -Wl,--wrap=send
 flags -Wl,--wrap=sendmsg
 flags -Wl,--wrap=sendto
 flags -Wl,--wrap=setsockopt
index 19b0f342244c767060b63cef388dadfcadb5cb63..8c11dc5bce882b0eb4ae22b43eda31bb097886c6 100644 (file)
@@ -25,7 +25,7 @@ build_language c
 build_libraries -lc -lcmocka
 build_libraries-individual -lf_memory -lf_string -lf_type_array -lf_socket
 
-build_sources_program test-socket-accept.c test-socket-bind.c test-socket-bind_local.c test-socket-connect.c test-socket-create.c test-socket-create_pair.c test-socket-disconnect.c test-socket-listen.c test-socket-name_host.c test-socket-name_peer.c test-socket-option_get.c test-socket-option_set.c test-socket-read.c test-socket-read_message.c test-socket-write.c test-socket-write_message.c
+build_sources_program test-socket-accept.c test-socket-bind.c test-socket-bind_local.c test-socket-connect.c test-socket-create.c test-socket-create_pair.c test-socket-disconnect.c test-socket-listen.c test-socket-name_host.c test-socket-name_peer.c test-socket-option_get.c test-socket-option_set.c test-socket-read.c test-socket-read_message.c test-socket-read_stream.c test-socket-write.c test-socket-write_message.c test-socket-write_stream.c
 build_sources_program test-socket.c
 
 build_script no
index ea3dbf3bb64f37e4397e126a8b63a02202dcfb98..efe49b8112f38520fc5074e0c58ae7a9861b0dc5 100644 (file)
@@ -108,6 +108,19 @@ int __wrap_listen(int sockfd, int backlog) {
   return 0;
 }
 
+ssize_t __wrap_recv(int sockfd, void *buf, size_t len, int flags) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return mock_type(int);
+}
+
 ssize_t __wrap_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen) {
 
   const bool failure = mock_type(bool);
@@ -134,6 +147,19 @@ ssize_t __wrap_recvmsg(int sockfd, struct msghdr *msg, int flags) {
   return mock_type(int);
 }
 
+ssize_t __wrap_send(int sockfd, const void *buf, size_t len, int flags) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  return mock_type(int);
+}
+
 ssize_t __wrap_sendmsg(int sockfd, const struct msghdr *msg, int flags) {
 
   const bool failure = mock_type(bool);
index 32d2972c671f2df9ef732d861d458adcc607699a..8cbabb7b8eca4d76c25e6f81b8d2a0bd7d061a37 100644 (file)
@@ -36,8 +36,10 @@ int __wrap_gethostname(char *name, size_t len);
 int __wrap_getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
 int __wrap_getsockopt(int sockfd, int level, int optname, void *optval, socklen_t *optlen);
 int __wrap_listen(int sockfd, int backlog);
+ssize_t __wrap_recv(int sockfd, void *buf, size_t len, int flags);
 ssize_t __wrap_recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen);
 ssize_t __wrap_recvmsg(int sockfd, struct msghdr *msg, int flags);
+ssize_t __wrap_send(int sockfd, const void *buf, size_t len, int flags);
 ssize_t __wrap_sendmsg(int sockfd, const struct msghdr *msg, int flags);
 ssize_t __wrap_sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen);
 int __wrap_setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen);
diff --git a/level_0/f_socket/tests/unit/c/test-socket-read_stream.c b/level_0/f_socket/tests/unit/c/test-socket-read_stream.c
new file mode 100644 (file)
index 0000000..726ca31
--- /dev/null
@@ -0,0 +1,113 @@
+#include "test-socket.h"
+#include "test-socket-read_stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_socket_read_stream__fails(void **state) {
+
+  f_socket_t socket = f_socket_t_initialize;
+  char *buffer = "test";
+  size_t length = 0;
+
+  int errnos[] = {
+    EACCES,
+    EAGAIN,
+    EALREADY,
+    EBADF,
+    ECONNREFUSED,
+    ECONNRESET,
+    EDESTADDRREQ,
+    EFAULT,
+    EINTR,
+    EINVAL,
+    ENOMEM,
+    ENOTCONN,
+    ENOTSOCK,
+    EOPNOTSUPP,
+    EPERM,
+    EPIPE,
+    ETIMEDOUT,
+    EWOULDBLOCK,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_access_denied,
+    F_block,
+    F_complete_not,
+    F_file_descriptor,
+    F_connect_refuse,
+    F_connect_reset,
+    F_address_not,
+    F_buffer,
+    F_interrupt,
+    F_parameter,
+    F_memory_not,
+    F_connect_not,
+    F_socket_not,
+    F_option_not,
+    F_prohibited,
+    F_pipe,
+    F_time_out,
+    F_block,
+    F_failure,
+  };
+
+  for (uint8_t i = 0; i < 19; ++i) {
+
+    will_return(__wrap_recv, true);
+    will_return(__wrap_recv, errnos[i]);
+
+    const f_status_t status = f_socket_read_stream(&socket, 0, (void *) buffer, &length);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+    assert_int_equal(length, 0);
+  } // for
+}
+
+void test__f_socket_read_stream__parameter_checking(void **state) {
+
+  f_socket_t socket = f_socket_t_initialize;
+  char *buffer = "test";
+
+  {
+    const f_status_t status = f_socket_read_stream(0, 0, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+
+  {
+    const f_status_t status = f_socket_read_stream(&socket, 0, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+
+  {
+    const f_status_t status = f_socket_read_stream(0, 0, buffer, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_socket_read_stream__works(void **state) {
+
+  f_socket_t socket = f_socket_t_initialize;
+  char *buffer = "test";
+  size_t length = 0;
+
+  {
+    will_return(__wrap_recv, false);
+    will_return(__wrap_recv, 1);
+
+    const f_status_t status = f_socket_read_stream(&socket, 0, (void *) buffer, &length);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(length, 1);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_socket/tests/unit/c/test-socket-read_stream.h b/level_0/f_socket/tests/unit/c/test-socket-read_stream.h
new file mode 100644 (file)
index 0000000..67c3c75
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Socket
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the socket project.
+ */
+#ifndef _TEST__F_socket_read_stream_h
+#define _TEST__F_socket_read_stream_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_socket_read_stream()
+ */
+extern void test__f_socket_read_stream__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_socket_read_stream()
+ */
+extern void test__f_socket_read_stream__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_socket_read_stream()
+ */
+extern void test__f_socket_read_stream__works(void **state);
+
+#endif // _TEST__F_socket_read_stream_h
diff --git a/level_0/f_socket/tests/unit/c/test-socket-write_stream.c b/level_0/f_socket/tests/unit/c/test-socket-write_stream.c
new file mode 100644 (file)
index 0000000..3f71d34
--- /dev/null
@@ -0,0 +1,119 @@
+#include "test-socket.h"
+#include "test-socket-write_stream.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_socket_write_stream__fails(void **state) {
+
+  f_socket_t socket = f_socket_t_initialize;
+  char *buffer = "test";
+  size_t length = 0;
+
+  int errnos[] = {
+    EACCES,
+    EAGAIN,
+    EALREADY,
+    EBADF,
+    ECONNREFUSED,
+    ECONNRESET,
+    EDESTADDRREQ,
+    EFAULT,
+    EINTR,
+    EINVAL,
+    EISCONN,
+    EMSGSIZE,
+    ENOBUFS,
+    ENOMEM,
+    ENOTCONN,
+    ENOTSOCK,
+    EOPNOTSUPP,
+    EPERM,
+    EPIPE,
+    ETIMEDOUT,
+    EWOULDBLOCK,
+    mock_errno_generic,
+  };
+
+  f_status_t statuss[] = {
+    F_access_denied,
+    F_block,
+    F_complete_not,
+    F_file_descriptor,
+    F_connect_refuse,
+    F_connect_reset,
+    F_address_not,
+    F_buffer,
+    F_interrupt,
+    F_parameter,
+    F_connect,
+    F_size,
+    F_buffer_not,
+    F_memory_not,
+    F_connect_not,
+    F_socket_not,
+    F_option_not,
+    F_prohibited,
+    F_pipe,
+    F_time_out,
+    F_block,
+    F_failure,
+  };
+
+  for (uint8_t i = 0; i < 22; ++i) {
+
+    will_return(__wrap_send, true);
+    will_return(__wrap_send, errnos[i]);
+
+    const f_status_t status = f_socket_write_stream(&socket, 0, buffer, &length);
+
+    assert_int_equal(status, F_status_set_error(statuss[i]));
+    assert_int_equal(length, 0);
+  } // for
+}
+
+void test__f_socket_write_stream__parameter_checking(void **state) {
+
+  f_socket_t socket = f_socket_t_initialize;
+  char *buffer = "test";
+
+  {
+    const f_status_t status = f_socket_write_stream(0, 0, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+
+  {
+    const f_status_t status = f_socket_write_stream(&socket, 0, 0, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+
+  {
+    const f_status_t status = f_socket_write_stream(0, 0, buffer, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_socket_write_stream__works(void **state) {
+
+  f_socket_t socket = f_socket_t_initialize;
+  char *buffer = "test";
+  size_t length = 0;
+
+  {
+    will_return(__wrap_send, false);
+    will_return(__wrap_send, 1);
+
+    const f_status_t status = f_socket_write_stream(&socket, 0, buffer, &length);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(length, 1);
+  }
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_socket/tests/unit/c/test-socket-write_stream.h b/level_0/f_socket/tests/unit/c/test-socket-write_stream.h
new file mode 100644 (file)
index 0000000..5bc28e5
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Socket
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the socket project.
+ */
+#ifndef _TEST__F_socket_write_stream_h
+#define _TEST__F_socket_write_stream_h
+
+/**
+ * Test that function fails.
+ *
+ * @see f_socket_write_stream()
+ */
+extern void test__f_socket_write_stream__fails(void **state);
+
+/**
+ * Test that parameter checking works as expected.
+ *
+ * @see f_socket_write_stream()
+ */
+extern void test__f_socket_write_stream__parameter_checking(void **state);
+
+/**
+ * Test that function works.
+ *
+ * @see f_socket_write_stream()
+ */
+extern void test__f_socket_write_stream__works(void **state);
+
+#endif // _TEST__F_socket_write_stream_h
index 8fb134ec989e8e9c8146c1930cf4caf9d90d26de..0b998aae2de566ac5638f7f471cb7da98a1ed22d 100644 (file)
@@ -67,12 +67,18 @@ int main(void) {
     cmocka_unit_test(test__f_socket_read_message__fails),
     cmocka_unit_test(test__f_socket_read_message__works),
 
+    cmocka_unit_test(test__f_socket_read_stream__fails),
+    cmocka_unit_test(test__f_socket_read_stream__works),
+
     cmocka_unit_test(test__f_socket_write__fails),
     cmocka_unit_test(test__f_socket_write__works),
 
     cmocka_unit_test(test__f_socket_write_message__fails),
     cmocka_unit_test(test__f_socket_write_message__works),
 
+    cmocka_unit_test(test__f_socket_write_stream__fails),
+    cmocka_unit_test(test__f_socket_write_stream__works),
+
     #ifndef _di_level_0_parameter_checking_
       cmocka_unit_test(test__f_socket_accept__parameter_checking),
       cmocka_unit_test(test__f_socket_bind__parameter_checking),
@@ -87,8 +93,10 @@ int main(void) {
       cmocka_unit_test(test__f_socket_option_set__parameter_checking),
       cmocka_unit_test(test__f_socket_read__parameter_checking),
       cmocka_unit_test(test__f_socket_read_message__parameter_checking),
+      cmocka_unit_test(test__f_socket_read_stream__parameter_checking),
       cmocka_unit_test(test__f_socket_write__parameter_checking),
       cmocka_unit_test(test__f_socket_write_message__parameter_checking),
+      cmocka_unit_test(test__f_socket_write_stream__parameter_checking),
     #endif // _di_level_0_parameter_checking_
   };
 
index d8e56b5213ca2e5dde14445f14735d0fa1c4b78b..084a75e4082e51b8b84cfe29d8f2476b2c5f8217 100644 (file)
 #include "test-socket-option_set.h"
 #include "test-socket-read.h"
 #include "test-socket-read_message.h"
+#include "test-socket-read_stream.h"
 #include "test-socket-write.h"
 #include "test-socket-write_message.h"
+#include "test-socket-write_stream.h"
 
 #ifdef __cplusplus
 extern "C" {
index c7814c0a937b493b989b5aef7fc0ba5fb9c009a5..2420401dd145c90b52a26e304aabe495dbe1f04d 100644 (file)
@@ -18,6 +18,7 @@
 // Libc includes.
 #include <stdio.h>
 #include <fcntl.h>
+#include <poll.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -185,6 +186,70 @@ extern "C" {
     file.size_write = F_file_default_size_write_d;
 #endif // _di_f_file_t_
 
+/**
+ * A typdef for representing struct pollfd.
+ */
+#ifndef _di_f_poll_t_
+  typedef struct pollfd f_poll_t;
+
+  #define f_poll_t_initialize { 0 }
+
+  #define macro_f_poll_t_initialize_1(fd, events, revents) { fd, events, revents }
+  #define macro_f_poll_t_initialize_2(fd, events) { fd, events, 0 }
+  #define macro_f_poll_t_initialize_3(fd) { fd, 0, 0 }
+  #define macro_f_poll_t_initialize_4(events) { 0, events, 0 }
+#endif // _di_f_poll_t_
+
+/**
+ * An array of pollfd structures.
+ *
+ * The macros are defined in type_array.h or type_array-common.h.
+ *
+ * If used for functions like poll() (a common use) then the max array length for used is limited to nfds_t which might be different from f_number_unsigned_t.
+ * The nfds_t is often either uint32_t or an uint64_t.
+ * The f_number_unsigned_t is often an uint64_t.
+ *
+ * array: An array of f_poll_t.
+ * size:  Total amount of allocated space.
+ * used:  Total number of allocated spaces used.
+ */
+#ifndef _di_f_polls_t_
+  typedef struct {
+    f_poll_t *array;
+
+    f_number_unsigned_t size;
+    f_number_unsigned_t used;
+  } f_polls_t;
+
+  #define f_polls_t_initialize { 0, 0, 0 }
+
+  #define macro_f_polls_t_initialize_1(array, size, used) { array, size, used }
+  #define macro_f_polls_t_initialize_2(array, length) { array, length, length }
+#endif // _di_f_polls_t_
+
+/**
+ * An array of f_polls_t.
+ *
+ * The macros are defined in type_array.h or type_array-common.h.
+ *
+ * array: The array of f_polls_t.
+ * size:  Total amount of allocated space.
+ * used:  Total number of allocated spaces used.
+ */
+#ifndef _di_f_pollss_t_
+  typedef struct {
+    f_polls_t *array;
+
+    f_number_unsigned_t size;
+    f_number_unsigned_t used;
+  } f_pollss_t;
+
+  #define f_pollss_t_initialize { 0, 0, 0 }
+
+  #define macro_f_pollss_t_initialize_1(array, size, used) { array, size, used }
+  #define macro_f_pollss_t_initialize_2(array, length) { array, length, length }
+#endif // _di_f_pollss_t_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
diff --git a/level_0/f_type_array/c/type_array/poll.c b/level_0/f_type_array/c/type_array/poll.c
new file mode 100644 (file)
index 0000000..5a5a69a
--- /dev/null
@@ -0,0 +1,259 @@
+#include "../type_array.h"
+#include "../type_array_file.h"
+#include "poll.h"
+#include "private-poll.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_f_polls_adjust_
+  f_status_t f_polls_adjust(const f_number_unsigned_t length, f_polls_t *polls) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!polls) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_polls_adjust(length, polls);
+  }
+#endif // _di_f_polls_adjust_
+
+#ifndef _di_f_polls_append_
+  f_status_t f_polls_append(const f_poll_t source, f_polls_t *destination) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!destination) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_polls_append(source, destination);
+  }
+#endif // _di_f_polls_append_
+
+#ifndef _di_f_polls_append_all_
+  f_status_t f_polls_append_all(const f_polls_t source, f_polls_t *destination) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!destination) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!source.used) return F_data_not;
+
+    return private_f_polls_append_all(source, destination);
+  }
+#endif // _di_f_polls_append_all_
+
+#ifndef _di_f_polls_decimate_by_
+  f_status_t f_polls_decimate_by(const f_number_unsigned_t amount, f_polls_t *polls) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!polls) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!amount) return F_data_not;
+    if (polls->size - amount > 0) return private_f_polls_adjust(polls->size - amount, polls);
+
+    return private_f_polls_adjust(0, polls);
+  }
+#endif // _di_f_polls_decimate_by_
+
+#ifndef _di_f_polls_decrease_by_
+  f_status_t f_polls_decrease_by(const f_number_unsigned_t amount, f_polls_t *polls) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!polls) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!amount) return F_data_not;
+    if (polls->size - amount > 0) return private_f_polls_resize(polls->size - amount, polls);
+
+    return private_f_polls_resize(0, polls);
+  }
+#endif // _di_f_polls_decrease_by_
+
+#ifndef _di_f_polls_increase_
+  f_status_t f_polls_increase(const f_number_unsigned_t step, f_polls_t *polls) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!polls) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (step && polls->used + 1 > polls->size) {
+      f_number_unsigned_t size = polls->used + step;
+
+      if (size > F_number_t_size_unsigned_d) {
+        if (polls->used + 1 > F_number_t_size_unsigned_d) return F_status_set_error(F_array_too_large);
+
+        size = F_number_t_size_unsigned_d;
+      }
+
+      return private_f_polls_resize(size, polls);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_polls_increase_
+
+#ifndef _di_f_polls_increase_by_
+  f_status_t f_polls_increase_by(const f_number_unsigned_t amount, f_polls_t *polls) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!polls) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!amount) return F_data_not;
+
+    if (polls->used + amount > polls->size) {
+      if (polls->used + amount > F_number_t_size_unsigned_d) return F_status_set_error(F_array_too_large);
+
+      return private_f_polls_resize(polls->used + amount, polls);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_polls_increase_by_
+
+#ifndef _di_f_polls_resize_
+  f_status_t f_polls_resize(const f_number_unsigned_t length, f_polls_t *polls) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!polls) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_polls_resize(length, polls);
+  }
+#endif // _di_f_polls_resize_
+
+#ifndef _di_f_pollss_adjust_
+  f_status_t f_pollss_adjust(const f_number_unsigned_t length, f_pollss_t *pollss) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!pollss) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_pollss_adjust(length, pollss);
+  }
+#endif // _di_f_pollss_adjust_
+
+#ifndef _di_f_pollss_append_
+  f_status_t f_pollss_append(const f_polls_t source, f_pollss_t *destination) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!destination) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!source.used) return F_data_not;
+
+    f_status_t status = F_none;
+
+    if (destination->used + 1 > destination->size) {
+      status = private_f_pollss_resize(destination->used + F_memory_default_allocation_small_d, destination);
+      if (F_status_is_error(status)) return status;
+    }
+
+    status = private_f_polls_append_all(source, &destination->array[destination->used]);
+    if (F_status_is_error(status)) return status;
+
+    ++destination->used;
+
+    return F_none;
+  }
+#endif // _di_f_pollss_append_
+
+#ifndef _di_f_pollss_append_all_
+  f_status_t f_pollss_append_all(const f_pollss_t source, f_pollss_t *destination) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!destination) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!source.used) return F_data_not;
+
+    f_status_t status = F_none;
+
+    if (destination->used + source.used > destination->size) {
+      status = private_f_pollss_resize(destination->used + source.used, destination);
+      if (F_status_is_error(status)) return status;
+    }
+
+    for (f_number_unsigned_t i = 0; i < source.used; ++i, ++destination->used) {
+
+      destination->array[destination->used].used = 0;
+
+      if (source.array[i].used) {
+        status = private_f_polls_append_all(source.array[i], &destination->array[destination->used]);
+        if (F_status_is_error(status)) return status;
+      }
+    } // for
+
+    return F_none;
+  }
+#endif // _di_f_pollss_append_all_
+
+#ifndef _di_f_pollss_decimate_by_
+  f_status_t f_pollss_decimate_by(const f_number_unsigned_t amount, f_pollss_t *pollss) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!pollss) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!amount) return F_data_not;
+    if (pollss->size - amount > 0) return private_f_pollss_adjust(pollss->size - amount, pollss);
+
+    return private_f_pollss_adjust(0, pollss);
+  }
+#endif // _di_f_pollss_decimate_by_
+
+#ifndef _di_f_pollss_decrease_by_
+  f_status_t f_pollss_decrease_by(const f_number_unsigned_t amount, f_pollss_t *pollss) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!pollss) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!amount) return F_data_not;
+    if (pollss->size - amount > 0) return private_f_pollss_resize(pollss->size - amount, pollss);
+
+    return private_f_pollss_resize(0, pollss);
+  }
+#endif // _di_f_pollss_decrease_by_
+
+#ifndef _di_f_pollss_increase_
+  f_status_t f_pollss_increase(const f_number_unsigned_t step, f_pollss_t *pollss) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!pollss) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (step && pollss->used + 1 > pollss->size) {
+      f_number_unsigned_t size = pollss->used + step;
+
+      if (size > F_number_t_size_unsigned_d) {
+        if (pollss->used + 1 > F_number_t_size_unsigned_d) return F_status_set_error(F_array_too_large);
+
+        size = F_number_t_size_unsigned_d;
+      }
+
+      return private_f_pollss_resize(size, pollss);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_pollss_increase_
+
+#ifndef _di_f_pollss_increase_by_
+  f_status_t f_pollss_increase_by(const f_number_unsigned_t amount, f_pollss_t *pollss) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!pollss) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    if (!amount) return F_data_not;
+
+    if (pollss->used + amount > pollss->size) {
+      if (pollss->used + amount > F_number_t_size_unsigned_d) return F_status_set_error(F_array_too_large);
+
+      return private_f_pollss_resize(pollss->used + amount, pollss);
+    }
+
+    return F_data_not;
+  }
+#endif // _di_f_pollss_increase_by_
+
+#ifndef _di_f_pollss_resize_
+  f_status_t f_pollss_resize(const f_number_unsigned_t length, f_pollss_t *pollss) {
+    #ifndef _di_level_0_parameter_checking_
+      if (!pollss) return F_status_set_error(F_parameter);
+    #endif // _di_level_0_parameter_checking_
+
+    return private_f_pollss_resize(length, pollss);
+  }
+#endif // _di_f_pollss_resize_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/c/type_array/poll.h b/level_0/f_type_array/c/type_array/poll.h
new file mode 100644 (file)
index 0000000..ee33efd
--- /dev/null
@@ -0,0 +1,379 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Defines data to be used for/by type (array) related functionality.
+ *
+ * This is auto-included by type_array.h and should not need to be explicitly included.
+ */
+#ifndef _F_type_array_poll_h
+#define _F_type_array_poll_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Resize the string polls array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param polls
+ *   The string polls array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ */
+#ifndef _di_f_polls_adjust_
+  extern f_status_t f_polls_adjust(const f_number_unsigned_t length, f_polls_t *polls);
+#endif // _di_f_polls_adjust_
+
+/**
+ * Append the single source poll onto the destination.
+ *
+ * @param source
+ *   The source poll to append.
+ * @param destination
+ *   The destination polls the source is appended onto.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is nothing to append (size == 0).
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_polls_append_
+  extern f_status_t f_polls_append(const f_poll_t source, f_polls_t *destination);
+#endif // _di_f_polls_append_
+
+/**
+ * Append the source polls onto the destination.
+ *
+ * @param source
+ *   The source polls to append.
+ * @param destination
+ *   The destination polls the source is appended onto.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is nothing to append (size == 0).
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_polls_append_all_
+  extern f_status_t f_polls_append_all(const f_polls_t source, f_polls_t *destination);
+#endif // _di_f_polls_append_all_
+
+/**
+ * Resize the string polls array to a smaller size.
+ *
+ * This will resize making the array smaller based on (size - given length).
+ * If the given length is too small, then the resize will fail.
+ * This will not shrink the size to les than 0.
+ *
+ * @param amount
+ *   A positive number representing how much to decimate the size by.
+ * @param polls
+ *   The string polls array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not if amount is 0.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ */
+#ifndef _di_f_polls_decimate_by_
+  extern f_status_t f_polls_decimate_by(const f_number_unsigned_t amount, f_polls_t *polls);
+#endif // _di_f_polls_decimate_by_
+
+/**
+ * Resize the string polls array to a smaller size.
+ *
+ * This will resize making the array smaller based on (size - given length).
+ * If the given length is too small, then the resize will fail.
+ * This will not shrink the size to les than 0.
+ *
+ * @param amount
+ *   A positive number representing how much to decrease the size by.
+ * @param polls
+ *   The string polls array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not if amount is 0.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_polls_decrease_by_
+  extern f_status_t f_polls_decrease_by(const f_number_unsigned_t amount, f_polls_t *polls);
+#endif // _di_f_polls_decrease_by_
+
+/**
+ * Increase the size of the string polls array, but only if necesary.
+ *
+ * If the given length is too large for the buffer, then attempt to set max buffer size (F_number_t_size_unsigned_d).
+ * If already set to the maximum buffer size, then the resize will fail.
+ *
+ * @param step
+ *   The allocation step to use.
+ *   Must be greater than 0.
+ * @param polls
+ *   The string polls array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_polls_increase_
+  extern f_status_t f_polls_increase(const f_number_unsigned_t step, f_polls_t *polls);
+#endif // _di_f_polls_increase_
+
+/**
+ * Resize the string polls array to a larger size.
+ *
+ * This will resize making the array larger based on the given length.
+ * If the given length is too large for the buffer, then attempt to set max buffer size (F_number_t_size_unsigned_d).
+ * If already set to the maximum buffer size, then the resize will fail.
+ *
+ * @param amount
+ *   A positive number representing how much to increase the size by.
+ * @param polls
+ *   The string polls array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + amount <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_polls_increase_by_
+  extern f_status_t f_polls_increase_by(const f_number_unsigned_t amount, f_polls_t *polls);
+#endif // _di_f_polls_increase_by_
+
+/**
+ * Resize the string polls array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param polls
+ *   The string polls array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_polls_resize_
+  extern f_status_t f_polls_resize(const f_number_unsigned_t length, f_polls_t *polls);
+#endif // _di_f_polls_resize_
+
+/**
+ * Resize the string pollss array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param pollss
+ *   The string pollss array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *   Errors (with error bit) from: f_memory_destroy().
+ */
+#ifndef _di_f_pollss_adjust_
+  extern f_status_t f_pollss_adjust(const f_number_unsigned_t length, f_pollss_t *pollss);
+#endif // _di_f_pollss_adjust_
+
+/**
+ * Append the single source polls onto the destination.
+ *
+ * @param source
+ *   The source polls to append.
+ * @param destination
+ *   The destination ranges the source is appended onto.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is nothing to append (size == 0).
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_pollss_append_
+  extern f_status_t f_pollss_append(const f_polls_t source, f_pollss_t *destination);
+#endif // _di_f_pollss_append_
+
+/**
+ * Append the source pollss onto the destination.
+ *
+ * @param source
+ *   The source pollss to append.
+ * @param destination
+ *   The destination ranges the source is appended onto.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is nothing to append (size == 0).
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_pollss_append_all_
+  extern f_status_t f_pollss_append_all(const f_pollss_t source, f_pollss_t *destination);
+#endif // _di_f_pollss_append_all_
+
+/**
+ * Resize the string pollss array to a smaller size.
+ *
+ * This will resize making the array smaller based on (size - given length).
+ * If the given length is too small, then the resize will fail.
+ * This will not shrink the size to less than 0.
+ *
+ * @param amount
+ *   A positive number representing how much to decimate the size by.
+ * @param pollss
+ *   The string pollss array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not if amount is 0.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *   Errors (with error bit) from: f_memory_destroy().
+ */
+#ifndef _di_f_pollss_decimate_by_
+  extern f_status_t f_pollss_decimate_by(const f_number_unsigned_t amount, f_pollss_t *pollss);
+#endif // _di_f_pollss_decimate_by_
+
+/**
+ * Resize the string pollss array to a smaller size.
+ *
+ * This will resize making the array smaller based on (size - given length).
+ * If the given length is too small, then the resize will fail.
+ * This will not shrink the size to less than 0.
+ *
+ * @param amount
+ *   A positive number representing how much to decrease the size by.
+ * @param pollss
+ *   The string pollss array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not if amount is 0.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_delete().
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_pollss_decrease_by_
+  extern f_status_t f_pollss_decrease_by(const f_number_unsigned_t amount, f_pollss_t *pollss);
+#endif // _di_f_pollss_decrease_by_
+
+/**
+ * Increase the size of the string pollss array, but only if necessary.
+ *
+ * If the given length is too large for the buffer, then attempt to set max buffer size (F_number_t_size_unsigned_d).
+ * If already set to the maximum buffer size, then the resize will fail.
+ *
+ * @param step
+ *   The allocation step to use.
+ *   Must be greater than 0.
+ * @param pollss
+ *   The string pollss array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_pollss_increase_
+  extern f_status_t f_pollss_increase(const f_number_unsigned_t step, f_pollss_t *pollss);
+#endif // _di_f_pollss_increase_
+
+/**
+ * Resize the string pollss array to a larger size.
+ *
+ * This will resize making the array larger based on the given length.
+ * If the given length is too large for the buffer, then attempt to set max buffer size (F_number_t_size_unsigned_d).
+ * If already set to the maximum buffer size, then the resize will fail.
+ *
+ * @param amount
+ *   A positive number representing how much to increase the size by.
+ * @param pollss
+ *   The string pollss array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + amount <= size).
+ *
+ *   F_array_too_large (with error bit) if the new array length is too large.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_pollss_increase_by_
+  extern f_status_t f_pollss_increase_by(const f_number_unsigned_t amount, f_pollss_t *pollss);
+#endif // _di_f_pollss_increase_by_
+
+/**
+ * Resize the string pollss array.
+ *
+ * @param length
+ *   The new size to use.
+ * @param pollss
+ *   The string pollss array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_delete().
+ *   Errors (with error bit) from: f_memory_resize().
+ */
+#ifndef _di_f_pollss_resize_
+  extern f_status_t f_pollss_resize(const f_number_unsigned_t length, f_pollss_t *pollss);
+#endif // _di_f_pollss_resize_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _F_type_array_poll_h
diff --git a/level_0/f_type_array/c/type_array/private-poll.c b/level_0/f_type_array/c/type_array/private-poll.c
new file mode 100644 (file)
index 0000000..2d27207
--- /dev/null
@@ -0,0 +1,127 @@
+#include "../type_array.h"
+#include "../type_array_file.h"
+#include "private-poll.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_f_polls_adjust_) || !defined(_di_f_polls_decimate_by_)
+  f_status_t private_f_polls_adjust(const f_number_unsigned_t length, f_polls_t *polls) {
+
+    const f_status_t status = f_memory_adjust(polls->size, length, sizeof(f_poll_t), (void **) & polls->array);
+    if (F_status_is_error(status)) return status;
+
+    polls->size = length;
+
+    if (polls->used > polls->size) {
+      polls->used = length;
+    }
+
+    return F_none;
+  }
+#endif // !defined(_di_f_polls_adjust_) || !defined(_di_f_polls_decimate_by_)
+
+#if !defined(_di_f_polls_append_) || !defined(_di_f_pollss_append_)
+  extern f_status_t private_f_polls_append(const f_poll_t source, f_polls_t *destination) {
+
+    if (destination->used + 1 > destination->size) {
+      const f_status_t status = private_f_polls_resize(destination->used + F_memory_default_allocation_small_d, destination);
+      if (F_status_is_error(status)) return status;
+    }
+
+    destination->array[destination->used++] = source;
+
+    return F_none;
+  }
+#endif // !defined(_di_f_polls_append_) || !defined(_di_f_pollss_append_)
+
+#if !defined(_di_f_polls_append_) || !defined(_di_f_polls_append_all_) || !defined(_di_f_pollss_append_all_)
+  extern f_status_t private_f_polls_append_all(const f_polls_t source, f_polls_t *destination) {
+
+    if (destination->used + source.used > destination->size) {
+      const f_status_t status = private_f_polls_resize(destination->used + source.used, destination);
+      if (F_status_is_error(status)) return status;
+    }
+
+    for (f_number_unsigned_t i = 0; i < source.used; ++i) {
+      destination->array[destination->used++] = source.array[i];
+    } // for
+
+    return F_none;
+  }
+#endif // !defined(_di_f_polls_append_) || !defined(_di_f_polls_append_all_) || !defined(_di_f_pollss_append_all_)
+
+#if !defined(_di_f_polls_resize_) || !defined(_di_f_polls_append_) || !defined(_di_f_polls_decrease_by_) || !defined(_di_f_pollss_append_)
+  f_status_t private_f_polls_resize(const f_number_unsigned_t length, f_polls_t *polls) {
+
+    const f_status_t status = f_memory_resize(polls->size, length, sizeof(f_poll_t), (void **) & polls->array);
+    if (F_status_is_error(status)) return status;
+
+    polls->size = length;
+
+    if (polls->used > polls->size) {
+      polls->used = length;
+    }
+
+    return F_none;
+  }
+#endif // !defined(_di_f_polls_resize_) || !defined(_di_f_polls_append_) || !defined(_di_f_polls_decrease_by_) || !defined(_di_f_pollss_append_)
+
+#if !defined(_di_f_pollss_adjust_) || !defined(_di_f_pollss_decimate_by_)
+  f_status_t private_f_pollss_adjust(const f_number_unsigned_t length, f_pollss_t *pollss) {
+
+    f_status_t status = F_none;
+
+    for (f_number_unsigned_t i = length; i < pollss->size; ++i) {
+
+      status = f_memory_destroy(pollss->array[i].size, sizeof(f_polls_t), (void **) & pollss->array[i].array);
+      if (F_status_is_error(status)) return status;
+
+      pollss->array[i].size = 0;
+      pollss->array[i].used = 0;
+    } // for
+
+    status = f_memory_adjust(pollss->size, length, sizeof(f_polls_t), (void **) & pollss->array);
+    if (F_status_is_error(status)) return status;
+
+    pollss->size = length;
+
+    if (pollss->used > pollss->size) {
+      pollss->used = length;
+    }
+
+    return F_none;
+  }
+#endif // !defined(_di_f_pollss_adjust_) || !defined(_di_f_pollss_decimate_by_)
+
+#if !defined(_di_f_pollss_decrease_by_) || !defined(_di_f_pollss_increase_) || !defined(_di_f_pollss_increase_by_) || !defined(_di_f_pollss_resize_)
+  f_status_t private_f_pollss_resize(const f_number_unsigned_t length, f_pollss_t *pollss) {
+
+    f_status_t status = F_none;
+
+    for (f_number_unsigned_t i = length; i < pollss->size; ++i) {
+
+      status = f_memory_delete(pollss->array[i].size, sizeof(f_polls_t), (void **) & pollss->array[i].array);
+      if (F_status_is_error(status)) return status;
+
+      pollss->array[i].size = 0;
+      pollss->array[i].used = 0;
+    } // for
+
+    status = f_memory_resize(pollss->size, length, sizeof(f_polls_t), (void **) & pollss->array);
+    if (F_status_is_error(status)) return status;
+
+    pollss->size = length;
+
+    if (pollss->used > pollss->size) {
+      pollss->used = length;
+    }
+
+    return F_none;
+  }
+#endif // !defined(_di_f_pollss_decrease_by_) || !defined(_di_f_pollss_increase_) || !defined(_di_f_pollss_increase_by_) || !defined(_di_f_pollss_resize_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/c/type_array/private-poll.h b/level_0/f_type_array/c/type_array/private-poll.h
new file mode 100644 (file)
index 0000000..4bdab09
--- /dev/null
@@ -0,0 +1,175 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * These are provided for internal reduction in redundant code.
+ * These should not be exposed/used outside of this project.
+ */
+#ifndef _PRIVATE_F_type_array_poll_h
+#define _PRIVATE_F_type_array_poll_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Private implementation for resizing the polls array.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The length to adjust to.
+ * @param polls
+ *   The polls array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *
+ * @see f_polls_adjust()
+ * @see f_polls_decimate_by()
+ */
+#if !defined(_di_f_polls_adjust_) || !defined(_di_f_polls_decimate_by_)
+  extern f_status_t private_f_polls_adjust(const f_number_unsigned_t length, f_polls_t *polls) F_attribute_visibility_internal_d;
+#endif // !defined(_di_f_polls_adjust_) || !defined(_di_f_polls_decimate_by_)
+
+/**
+ * Private implementation for appending the poll array.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param source
+ *   The source poll to append.
+ * @param destination
+ *   The destination lengths the source is appended onto.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_polls_append()
+ * @see f_pollss_append()
+ */
+#if !defined(_di_f_polls_append_) || !defined(_di_f_pollss_append_)
+  extern f_status_t private_f_polls_append(const f_poll_t source, f_polls_t *destination) F_attribute_visibility_internal_d;
+#endif // !defined(_di_f_polls_append_) || !defined(_di_f_pollss_append_)
+
+/**
+ * Private implementation for appending the poll array.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param source
+ *   The source polls to append.
+ * @param destination
+ *   The destination lengths the source is appended onto.
+ *
+ * @return
+ *   F_none on success.
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ *
+ * @see f_memory_resize()
+ * @see f_polls_append_all()
+ * @see f_pollss_append()
+ * @see f_pollss_append_all()
+ */
+#if !defined(_di_f_polls_append_) || !defined(_di_f_polls_append_all_) || !defined(_di_f_pollss_append_all_)
+  extern f_status_t private_f_polls_append_all(const f_polls_t source, f_polls_t *destination) F_attribute_visibility_internal_d;
+#endif // !defined(_di_f_polls_append_) || !defined(_di_f_polls_append_all_) || !defined(_di_f_pollss_append_all_)
+
+/**
+ * Private implementation for resizing the polls array.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The length to adjust to.
+ * @param polls
+ *   The polls array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   Errors (with error bit) from: f_memory_resize().
+ *
+ * @see f_polls_resize()
+ * @see f_polls_append()
+ * @see f_polls_decrease_by()
+ * @see f_pollss_append()
+ */
+#if !defined(_di_f_polls_resize_) || !defined(_di_f_polls_append_) || !defined(_di_f_polls_decrease_by_) || !defined(_di_f_pollss_append_)
+  extern f_status_t private_f_polls_resize(const f_number_unsigned_t length, f_polls_t *polls) F_attribute_visibility_internal_d;
+#endif // !defined(_di_f_polls_resize_) || !defined(_di_f_polls_append_) || !defined(_di_f_polls_decrease_by_) || !defined(_di_f_pollss_append_)
+
+/**
+ * Private implementation for resizing the pollss array.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The length to adjust to.
+ * @param pollss
+ *   The pollss array to adjust.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if new length is larger than max array length.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_adjust().
+ *   Errors (with error bit) from: f_memory_destroy().
+ *
+ * @see f_pollss_adjust()
+ * @see f_pollss_decimate_by()
+ */
+#if !defined(_di_f_pollss_adjust_) || !defined(_di_f_pollss_decimate_by_)
+  extern f_status_t private_f_pollss_adjust(const f_number_unsigned_t length, f_pollss_t *pollss) F_attribute_visibility_internal_d;
+#endif // !defined(_di_f_pollss_adjust_) || !defined(_di_f_pollss_decimate_by_)
+
+/**
+ * Private implementation for resizing the pollss array.
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param length
+ *   The length to resize to.
+ * @param pollss
+ *   The pollss array to resize.
+ *
+ * @return
+ *   F_none on success.
+ *   F_data_not on success, but there is no reason to increase size (used + 1 <= size).
+ *
+ *   F_array_too_large (with error bit) if new length is larger than max array length.
+ *   F_memory_not (with error bit) on out of memory.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *
+ *   Errors (with error bit) from: f_memory_delete().
+ *   Errors (with error bit) from: f_memory_resize().
+ *
+ * @see f_pollss_decrease_by()
+ * @see f_pollss_increase()
+ * @see f_pollss_increase_by()
+ * @see f_pollss_resize()
+ */
+#if !defined(_di_f_pollss_decrease_by_) || !defined(_di_f_pollss_increase_) || !defined(_di_f_pollss_increase_by_) || !defined(_di_f_pollss_resize_)
+  extern f_status_t private_f_pollss_resize(const f_number_unsigned_t length, f_pollss_t *pollss) F_attribute_visibility_internal_d;
+#endif // !defined(_di_f_pollss_decrease_by_) || !defined(_di_f_pollss_increase_) || !defined(_di_f_pollss_increase_by_) || !defined(_di_f_pollss_resize_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_F_type_array_poll_h
diff --git a/level_0/f_type_array/c/type_array_file.h b/level_0/f_type_array/c/type_array_file.h
new file mode 100644 (file)
index 0000000..dddc0fb
--- /dev/null
@@ -0,0 +1,32 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Provides an extension to the Type project (f_type) that depends on f_memory (linking to the f_memory library).
+ *
+ * As an exceptional case, this is an extension to f_type to avoid circular dependency issues with f_memory.
+ * The functions and macros in this project therefore are prefixed with 'f_type_' instead of 'f_type_array_'.
+ */
+#ifndef _F_type_array_file_h
+#define _F_type_array_file_h
+
+// FLL-0 includes.
+#include <fll/level_0/type.h>
+#include <fll/level_0/type_file.h>
+#include <fll/level_0/memory.h>
+
+// FLL-0 type_array includes.
+#include <fll/level_0/type_array/poll.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _F_type_array_file_h
index e69100eaae6f044afb7f3f38db8115cb35ff0f10..76dbae7e4eff79ccbc5b2778b14648503726392d 100644 (file)
@@ -32,10 +32,10 @@ build_language c
 build_libraries -lc
 build_libraries-individual -lf_memory
 
-build_sources_library type_array/cell.c type_array/fll_id.c type_array/int8.c type_array/int16.c type_array/int32.c type_array/int64.c type_array/int128.c type_array/number_unsigned.c type_array/state.c type_array/status.c type_array/uint8.c type_array/uint16.c type_array/uint32.c type_array/uint64.c type_array/uint128.c
-build_sources_library type_array/private-cell.c type_array/private-fll_id.c type_array/private-int8.c type_array/private-int16.c type_array/private-int32.c type_array/private-int64.c type_array/private-int128.c type_array/private-number_unsigned.c type_array/private-state.c type_array/private-status.c type_array/private-uint8.c type_array/private-uint16.c type_array/private-uint32.c type_array/private-uint64.c type_array/private-uint128.c
+build_sources_library type_array/cell.c type_array/fll_id.c type_array/int8.c type_array/int16.c type_array/int32.c type_array/int64.c type_array/int128.c type_array/number_unsigned.c type_array/poll.c type_array/state.c type_array/status.c type_array/uint8.c type_array/uint16.c type_array/uint32.c type_array/uint64.c type_array/uint128.c
+build_sources_library type_array/private-cell.c type_array/private-fll_id.c type_array/private-int8.c type_array/private-int16.c type_array/private-int32.c type_array/private-int64.c type_array/private-int128.c type_array/private-number_unsigned.c type_array/private-poll.c type_array/private-state.c type_array/private-status.c type_array/private-uint8.c type_array/private-uint16.c type_array/private-uint32.c type_array/private-uint64.c type_array/private-uint128.c
 
-build_sources_headers type_array.h type_array/common.h type_array/cell.h type_array/fll_id.h type_array/int8.h type_array/int16.h type_array/int32.h type_array/int64.h type_array/int128.h type_array/number_unsigned.h type_array/state.h type_array/status.h type_array/uint8.h type_array/uint16.h type_array/uint32.h type_array/uint64.h type_array/uint128.h
+build_sources_headers type_array.h type_array_file.h type_array/common.h type_array/cell.h type_array/fll_id.h type_array/int8.h type_array/int16.h type_array/int32.h type_array/int64.h type_array/int128.h type_array/number_unsigned.h type_array/poll.h type_array/state.h type_array/status.h type_array/uint8.h type_array/uint16.h type_array/uint32.h type_array/uint64.h type_array/uint128.h
 
 build_script yes
 build_shared yes
diff --git a/level_0/f_type_array/data/build/settings-mocks b/level_0/f_type_array/data/build/settings-mocks
new file mode 100644 (file)
index 0000000..1f0f920
--- /dev/null
@@ -0,0 +1,66 @@
+# fss-0001
+#
+# Build the project with appropriate mocks linked in via the dynamic linker's "--wrap" functionality.
+#
+# The -Wl,--wrap does not work across shared files.
+# Therefore, this file is a work-around to inject the mocks into the library for testing purposes.
+# This should exactly match the "settings" file, except for the additional "-Wl,--wrap" parts and the additional mock source file.
+#
+# The flags -o0 must be passed to prevent the compiler from optimizing away any functions being mocked (which results in the mock not happening and a real function being called).
+# Alternatively, figure out which optimization that is disabled by -o0 and have that specific optimization disabled.
+#
+
+build_name f_type_array
+
+version_major 0
+version_minor 7
+version_micro 0
+version_file micro
+version_target minor
+
+modes individual clang test coverage
+modes_default individual test
+
+build_compiler gcc
+build_compiler-clang clang
+build_indexer ar
+build_indexer_arguments rcs
+build_language c
+
+build_libraries -lc
+build_libraries-individual -lf_memory
+
+build_sources_library type_array/cell.c type_array/fll_id.c type_array/int8.c type_array/int16.c type_array/int32.c type_array/int64.c type_array/int128.c type_array/number_unsigned.c type_array/poll.c type_array/state.c type_array/status.c type_array/uint8.c type_array/uint16.c type_array/uint32.c type_array/uint64.c type_array/uint128.c
+build_sources_library type_array/private-cell.c type_array/private-fll_id.c type_array/private-int8.c type_array/private-int16.c type_array/private-int32.c type_array/private-int64.c type_array/private-int128.c type_array/private-number_unsigned.c type_array/private-poll.c type_array/private-state.c type_array/private-status.c type_array/private-uint8.c type_array/private-uint16.c type_array/private-uint32.c type_array/private-uint64.c type_array/private-uint128.c
+build_sources_library ../../tests/unit/c/mock-type_array.c
+
+build_sources_headers type_array.h type_array_file.h type_array/common.h type_array/cell.h type_array/fll_id.h type_array/int8.h type_array/int16.h type_array/int32.h type_array/int64.h type_array/int128.h type_array/number_unsigned.h type_array/poll.h type_array/state.h type_array/status.h type_array/uint8.h type_array/uint16.h type_array/uint32.h type_array/uint64.h type_array/uint128.h
+
+build_script yes
+build_shared yes
+build_static no
+
+path_headers fll/level_0
+path_library_script script
+path_library_shared shared
+path_library_static static
+
+has_path_standard yes
+preserve_path_headers yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+environment PATH LD_LIBRARY_PATH
+environment LANG LC_ALL LC_COLLATE LC_CTYPE LC_FASTMSG LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME LOCPATH NLSPATH
+
+flags -O0 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-parentheses
+flags-clang -Wno-logical-op-parentheses
+flags-test -fstack-protector -Wall -Wno-missing-braces
+flags-coverage --coverage -fprofile-abs-path -fprofile-dir=build/coverage/
+
+flags_library -fPIC
+
+# Inject mocks.
+flags -Wl,--wrap=poll
index d8e36542c88f1b5f0de604b6093aef64871056f1..32bf164107a9d067ee93ddd69bf0188599e69e9d 100644 (file)
@@ -39,6 +39,8 @@ build_sources_program test-type_array-int128s_adjust.c test-type_array-int128s_a
 build_sources_program test-type_array-int128ss_adjust.c test-type_array-int128ss_append.c test-type_array-int128ss_append_all.c test-type_array-int128ss_decimate_by.c test-type_array-int128ss_decrease_by.c test-type_array-int128ss_increase.c test-type_array-int128ss_increase_by.c test-type_array-int128ss_resize.c
 build_sources_program test-type_array-number_unsigneds_adjust.c test-type_array-number_unsigneds_append.c test-type_array-number_unsigneds_append_all.c test-type_array-number_unsigneds_decimate_by.c test-type_array-number_unsigneds_decrease_by.c test-type_array-number_unsigneds_increase.c test-type_array-number_unsigneds_increase_by.c test-type_array-number_unsigneds_resize.c
 build_sources_program test-type_array-number_unsignedss_adjust.c test-type_array-number_unsignedss_append.c test-type_array-number_unsignedss_append_all.c test-type_array-number_unsignedss_decimate_by.c test-type_array-number_unsignedss_decrease_by.c test-type_array-number_unsignedss_increase.c test-type_array-number_unsignedss_increase_by.c test-type_array-number_unsignedss_resize.c
+build_sources_program test-type_array-polls_adjust.c test-type_array-polls_append.c test-type_array-polls_append_all.c test-type_array-polls_decimate_by.c test-type_array-polls_decrease_by.c test-type_array-polls_increase.c test-type_array-polls_increase_by.c test-type_array-polls_resize.c
+build_sources_program test-type_array-pollss_adjust.c test-type_array-pollss_append.c test-type_array-pollss_append_all.c test-type_array-pollss_decimate_by.c test-type_array-pollss_decrease_by.c test-type_array-pollss_increase.c test-type_array-pollss_increase_by.c test-type_array-pollss_resize.c
 build_sources_program test-type_array-states_adjust.c test-type_array-states_append.c test-type_array-states_append_all.c test-type_array-states_decimate_by.c test-type_array-states_decrease_by.c test-type_array-states_increase.c test-type_array-states_increase_by.c test-type_array-states_resize.c
 build_sources_program test-type_array-statess_adjust.c test-type_array-statess_append.c test-type_array-statess_append_all.c test-type_array-statess_decimate_by.c test-type_array-statess_decrease_by.c test-type_array-statess_increase.c test-type_array-statess_increase_by.c test-type_array-statess_resize.c
 build_sources_program test-type_array-statuss_adjust.c test-type_array-statuss_append.c test-type_array-statuss_append_all.c test-type_array-statuss_decimate_by.c test-type_array-statuss_decrease_by.c test-type_array-statuss_increase.c test-type_array-statuss_increase_by.c test-type_array-statuss_resize.c
diff --git a/level_0/f_type_array/tests/unit/c/mock-type_array.c b/level_0/f_type_array/tests/unit/c/mock-type_array.c
new file mode 100644 (file)
index 0000000..cef5a0d
--- /dev/null
@@ -0,0 +1,24 @@
+#include "mock-type_array.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int __wrap_poll(f_poll_t *fds, nfds_t nfds, int timeout) {
+
+  const bool failure = mock_type(bool);
+
+  if (failure) {
+    errno = mock_type(int);
+
+    return -1;
+  }
+
+  fds->revents = mock_type(short);
+
+  return mock_type(int);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/mock-type_array.h b/level_0/f_type_array/tests/unit/c/mock-type_array.h
new file mode 100644 (file)
index 0000000..534130c
--- /dev/null
@@ -0,0 +1,38 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the type_array project.
+ */
+#ifndef _MOCK__type_array_h
+#define _MOCK__type_array_h
+
+// Libc includes.
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdint.h>
+
+// cmocka includes.
+#include <cmocka.h>
+
+// FLL-0 includes.
+#include <fll/level_0/type.h>
+#include <fll/level_0/type_array.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const static int mock_errno_generic = 32767;
+
+extern int __wrap_poll(f_poll_t *fds, nfds_t nfds, int timeout);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _MOCK__type_array_h
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_adjust.c b/level_0/f_type_array/tests/unit/c/test-type_array-polls_adjust.c
new file mode 100644 (file)
index 0000000..3b8669f
--- /dev/null
@@ -0,0 +1,42 @@
+#include "test-type_array.h"
+#include "test-type_array-polls_adjust.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_polls_adjust__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_adjust(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_polls_adjust__works(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_adjust(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_adjust.h b/level_0/f_type_array/tests/unit/c/test-type_array-polls_adjust.h
new file mode 100644 (file)
index 0000000..540f21c
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__polls_adjust
+#define _TEST__F_type_array__polls_adjust
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_polls_adjust()
+ */
+extern void test__f_type_array_polls_adjust__parameter_checking(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_polls_adjust()
+ */
+extern void test__f_type_array_polls_adjust__works(void **poll);
+
+#endif // _TEST__F_type_array__polls_adjust
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_append.c b/level_0/f_type_array/tests/unit/c/test-type_array-polls_append.c
new file mode 100644 (file)
index 0000000..f455a42
--- /dev/null
@@ -0,0 +1,39 @@
+#include "test-type_array.h"
+#include "test-type_array-polls_append.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_polls_append__parameter_checking(void **poll) {
+
+  const f_poll_t data = f_poll_t_initialize;
+
+  {
+    const f_status_t status = f_polls_append(data, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_type_array_polls_append__works(void **poll) {
+
+  const f_poll_t source = macro_f_poll_t_initialize_1(0, 1, 2);
+  f_polls_t destination = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_append(source, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(destination.used, 1);
+    assert_int_equal(destination.array[0].fd, source.fd);
+    assert_int_equal(destination.array[0].events, source.events);
+    assert_int_equal(destination.array[0].revents, source.revents);
+  }
+
+  free((void *) destination.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_append.h b/level_0/f_type_array/tests/unit/c/test-type_array-polls_append.h
new file mode 100644 (file)
index 0000000..3b5b519
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__polls_append
+#define _TEST__F_type_array__polls_append
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_polls_append()
+ */
+extern void test__f_type_array_polls_append__parameter_checking(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_polls_append()
+ */
+extern void test__f_type_array_polls_append__works(void **poll);
+
+#endif // _TEST__F_type_array__polls_append
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_append_all.c b/level_0/f_type_array/tests/unit/c/test-type_array-polls_append_all.c
new file mode 100644 (file)
index 0000000..25f096c
--- /dev/null
@@ -0,0 +1,86 @@
+#include "test-type_array.h"
+#include "test-type_array-polls_append_all.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_polls_append_all__parameter_checking(void **poll) {
+
+  const f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_append_all(data, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_type_array_polls_append_all__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_polls_t source = f_polls_t_initialize;
+  f_polls_t destination = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &source);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(source.used, 0);
+    assert_int_equal(source.size, length);
+  }
+
+  {
+    const f_status_t status = f_polls_append_all(source, &destination);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(destination.used, 0);
+    assert_int_equal(destination.size, 0);
+    assert_null(destination.array);
+  }
+
+  free((void *) source.array);
+}
+
+void test__f_type_array_polls_append_all__works(void **poll) {
+
+  const int length = 5;
+  f_polls_t source = f_polls_t_initialize;
+  f_polls_t destination = f_polls_t_initialize;
+
+  const f_poll_t poll_0 = { 0, 1, 2 };
+  const f_poll_t poll_1 = { 0, 2, 3 };
+
+  {
+    const f_status_t status = f_polls_resize(length, &source);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(source.used, 0);
+    assert_int_equal(source.size, length);
+  }
+
+  memcpy(&source.array[source.used++], (void *) &poll_0, sizeof(f_poll_t));
+  memcpy(&source.array[source.used++], (void *) &poll_1, sizeof(f_poll_t));
+
+  {
+    const f_status_t status = f_polls_append_all(source, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(destination.used, source.used);
+    assert_int_equal(destination.size, source.used);
+
+    for (f_number_unsigned_t i = 0; i < source.used; ++i) {
+
+      assert_int_equal(destination.array[i].fd, source.array[i].fd);
+      assert_int_equal(destination.array[i].events, source.array[i].events);
+      assert_int_equal(destination.array[i].revents, source.array[i].revents);
+    } // for
+  }
+
+  free((void *) source.array);
+  free((void *) destination.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_append_all.h b/level_0/f_type_array/tests/unit/c/test-type_array-polls_append_all.h
new file mode 100644 (file)
index 0000000..15bf28f
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__polls_append_all
+#define _TEST__F_type_array__polls_append_all
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_polls_append_all()
+ */
+extern void test__f_type_array_polls_append_all__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_polls_append_all()
+ */
+extern void test__f_type_array_polls_append_all__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_polls_append_all()
+ */
+extern void test__f_type_array_polls_append_all__works(void **poll);
+
+#endif // _TEST__F_type_array__polls_append_all
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_decimate_by.c b/level_0/f_type_array/tests/unit/c/test-type_array-polls_decimate_by.c
new file mode 100644 (file)
index 0000000..7efb151
--- /dev/null
@@ -0,0 +1,74 @@
+#include "test-type_array.h"
+#include "test-type_array-polls_decimate_by.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_polls_decimate_by__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_decimate_by(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_polls_decimate_by__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_polls_decimate_by(0, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_polls_decimate_by__works(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_polls_decimate_by(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_decimate_by.h b/level_0/f_type_array/tests/unit/c/test-type_array-polls_decimate_by.h
new file mode 100644 (file)
index 0000000..359403f
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__polls_decimate_by
+#define _TEST__F_type_array__polls_decimate_by
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_polls_decimate_by()
+ */
+extern void test__f_type_array_polls_decimate_by__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_polls_decimate_by()
+ */
+extern void test__f_type_array_polls_decimate_by__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_polls_decimate_by()
+ */
+extern void test__f_type_array_polls_decimate_by__works(void **poll);
+
+#endif // _TEST__F_type_array__polls_decimate_by
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_decrease_by.c b/level_0/f_type_array/tests/unit/c/test-type_array-polls_decrease_by.c
new file mode 100644 (file)
index 0000000..1c7fb64
--- /dev/null
@@ -0,0 +1,74 @@
+#include "test-type_array.h"
+#include "test-type_array-polls_decrease_by.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_polls_decrease_by__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_decrease_by(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_polls_decrease_by__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_polls_decrease_by(0, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_polls_decrease_by__works(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_polls_decrease_by(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_decrease_by.h b/level_0/f_type_array/tests/unit/c/test-type_array-polls_decrease_by.h
new file mode 100644 (file)
index 0000000..3024366
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__polls_decrease_by
+#define _TEST__F_type_array__polls_decrease_by
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_polls_decrease_by()
+ */
+extern void test__f_type_array_polls_decrease_by__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_polls_decrease_by()
+ */
+extern void test__f_type_array_polls_decrease_by__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_polls_decrease_by()
+ */
+extern void test__f_type_array_polls_decrease_by__works(void **poll);
+
+#endif // _TEST__F_type_array__polls_decrease_by
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_increase.c b/level_0/f_type_array/tests/unit/c/test-type_array-polls_increase.c
new file mode 100644 (file)
index 0000000..f5a8826
--- /dev/null
@@ -0,0 +1,76 @@
+#include "test-type_array.h"
+#include "test-type_array-polls_increase.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_polls_increase__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_increase(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_polls_increase__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_polls_increase(length, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_polls_increase__works(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    data.used = length;
+
+    const f_status_t status = f_polls_increase(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, length);
+    assert_in_range(data.size, length + 1, length + 1 + F_memory_default_allocation_small_d);
+  }
+
+  free((void *) data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_increase.h b/level_0/f_type_array/tests/unit/c/test-type_array-polls_increase.h
new file mode 100644 (file)
index 0000000..4856646
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__polls_increase
+#define _TEST__F_type_array__polls_increase
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_polls_increase()
+ */
+extern void test__f_type_array_polls_increase__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_polls_increase()
+ */
+extern void test__f_type_array_polls_increase__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_polls_increase()
+ */
+extern void test__f_type_array_polls_increase__works(void **poll);
+
+#endif // _TEST__F_type_array__polls_increase
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_increase_by.c b/level_0/f_type_array/tests/unit/c/test-type_array-polls_increase_by.c
new file mode 100644 (file)
index 0000000..535b4f3
--- /dev/null
@@ -0,0 +1,76 @@
+#include "test-type_array.h"
+#include "test-type_array-polls_increase_by.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_polls_increase_by__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_increase_by(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_polls_increase_by__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_polls_increase_by(0, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_polls_increase_by__works(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    data.used = length;
+
+    const f_status_t status = f_polls_increase_by(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, length);
+    assert_int_equal(data.size, length * 2);
+  }
+
+  free((void *) data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_increase_by.h b/level_0/f_type_array/tests/unit/c/test-type_array-polls_increase_by.h
new file mode 100644 (file)
index 0000000..f6356c4
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__polls_increase_by
+#define _TEST__F_type_array__polls_increase_by
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_polls_increase_by()
+ */
+extern void test__f_type_array_polls_increase_by__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_polls_increase_by()
+ */
+extern void test__f_type_array_polls_increase_by__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_polls_increase_by()
+ */
+extern void test__f_type_array_polls_increase_by__works(void **poll);
+
+#endif // _TEST__F_type_array__polls_increase_by
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_resize.c b/level_0/f_type_array/tests/unit/c/test-type_array-polls_resize.c
new file mode 100644 (file)
index 0000000..87f01e2
--- /dev/null
@@ -0,0 +1,42 @@
+#include "test-type_array.h"
+#include "test-type_array-polls_resize.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_polls_resize__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_polls_resize__works(void **poll) {
+
+  const int length = 5;
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-polls_resize.h b/level_0/f_type_array/tests/unit/c/test-type_array-polls_resize.h
new file mode 100644 (file)
index 0000000..52e3e94
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__polls_resize
+#define _TEST__F_type_array__polls_resize
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_polls_resize()
+ */
+extern void test__f_type_array_polls_resize__parameter_checking(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_polls_resize()
+ */
+extern void test__f_type_array_polls_resize__works(void **poll);
+
+#endif // _TEST__F_type_array__polls_resize
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_adjust.c b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_adjust.c
new file mode 100644 (file)
index 0000000..007cf1a
--- /dev/null
@@ -0,0 +1,42 @@
+#include "test-type_array.h"
+#include "test-type_array-pollss_adjust.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_pollss_adjust__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_adjust(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_pollss_adjust__works(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_adjust(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_adjust.h b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_adjust.h
new file mode 100644 (file)
index 0000000..51481a3
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__pollss_adjust
+#define _TEST__F_type_array__pollss_adjust
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_pollss_adjust()
+ */
+extern void test__f_type_array_pollss_adjust__parameter_checking(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_pollss_adjust()
+ */
+extern void test__f_type_array_pollss_adjust__works(void **poll);
+
+#endif // _TEST__F_type_array__pollss_adjust
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_append.c b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_append.c
new file mode 100644 (file)
index 0000000..8f22b02
--- /dev/null
@@ -0,0 +1,91 @@
+#include "test-type_array.h"
+#include "test-type_array-pollss_append.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_pollss_append__parameter_checking(void **poll) {
+
+  f_polls_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_append(data, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_type_array_pollss_append__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_polls_t source = f_polls_t_initialize;
+  f_pollss_t destination = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_polls_resize(length, &source);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(source.used, 0);
+    assert_int_equal(source.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_append(source, &destination);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(destination.used, 0);
+    assert_int_equal(destination.size, 0);
+    assert_null(destination.array);
+  }
+
+  free((void *) source.array);
+}
+
+void test__f_type_array_pollss_append__works(void **poll) {
+
+  const int length = 5;
+  f_polls_t source = f_polls_t_initialize;
+  f_pollss_t destination = f_pollss_t_initialize;
+
+  const f_poll_t poll_data = macro_f_poll_t_initialize_1(0, 1, 2);
+
+  {
+    const f_status_t status = f_polls_resize(length, &source);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(source.used, 0);
+    assert_int_equal(source.size, length);
+  }
+
+  while (source.used < length) {
+    memcpy(&source.array[source.used++], (void *) &poll_data, sizeof(f_poll_t));
+  } // while
+
+  {
+    const f_status_t status = f_pollss_append(source, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(destination.used, 1);
+    assert_int_equal(destination.array[0].used, source.used);
+    assert_int_equal(destination.array[0].size, source.used);
+
+    for (f_number_unsigned_t i = 0; i < destination.array[0].used; ++i) {
+
+      assert_int_equal(destination.array[0].array[i].fd, source.array[0].fd);
+      assert_int_equal(destination.array[0].array[i].events, source.array[0].events);
+      assert_int_equal(destination.array[0].array[i].revents, source.array[0].revents);
+    } // for
+  }
+
+  for (f_number_unsigned_t i = 0; i < destination.used; ++i) {
+    free((void *) destination.array[i].array);
+  } // for
+
+  free((void *) source.array);
+  free((void *) destination.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_append.h b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_append.h
new file mode 100644 (file)
index 0000000..c61f63e
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__pollss_append
+#define _TEST__F_type_array__pollss_append
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_pollss_append()
+ */
+extern void test__f_type_array_pollss_append__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_pollss_append()
+ */
+extern void test__f_type_array_pollss_append__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_pollss_append()
+ */
+extern void test__f_type_array_pollss_append__works(void **poll);
+
+#endif // _TEST__F_type_array__pollss_append
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_append_all.c b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_append_all.c
new file mode 100644 (file)
index 0000000..a8be357
--- /dev/null
@@ -0,0 +1,110 @@
+#include "test-type_array.h"
+#include "test-type_array-pollss_append_all.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_pollss_append_all__parameter_checking(void **poll) {
+
+  const f_pollss_t data = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_append_all(data, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+  }
+}
+
+void test__f_type_array_pollss_append_all__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_pollss_t source = f_pollss_t_initialize;
+  f_pollss_t destination = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &source);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(source.used, 0);
+    assert_int_equal(source.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_append_all(source, &destination);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(destination.used, 0);
+    assert_int_equal(destination.size, 0);
+    assert_null(destination.array);
+  }
+
+  free((void *) source.array);
+}
+
+void test__f_type_array_pollss_append_all__works(void **poll) {
+
+  const int length = 5;
+  const int length_inner = 2;
+  f_pollss_t source = f_pollss_t_initialize;
+  f_pollss_t destination = f_pollss_t_initialize;
+
+  const f_poll_t poll_0 = { 0, 1, 2 };
+  const f_poll_t poll_1 = { 0, 3, 4 };
+
+  {
+    const f_status_t status = f_pollss_resize(length, &source);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(source.used, 0);
+    assert_int_equal(source.size, length);
+  }
+
+  {
+    for (; source.used < length; ++source.used) {
+
+      const f_status_t status = f_polls_resize(length_inner, &source.array[source.used]);
+
+      assert_int_equal(status, F_none);
+
+      memcpy(&source.array[source.used].array[source.array[source.used].used++], (void *) &poll_0, sizeof(f_poll_t));
+      memcpy(&source.array[source.used].array[source.array[source.used].used++], (void *) &poll_1, sizeof(f_poll_t));
+    } // for
+  }
+
+  {
+    const f_status_t status = f_pollss_append_all(source, &destination);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(destination.used, source.used);
+    assert_int_equal(destination.size, source.used);
+
+    for (f_number_unsigned_t i = 0; i < destination.used; ++i) {
+
+      assert_int_equal(destination.array[i].used, length_inner);
+      assert_int_equal(destination.array[i].size, length_inner);
+
+      for (f_number_unsigned_t j = 0; j < length_inner; ++j) {
+
+        assert_int_equal(destination.array[i].array[j].fd, source.array[i].array[j].fd);
+        assert_int_equal(destination.array[i].array[j].events, source.array[i].array[j].events);
+        assert_int_equal(destination.array[i].array[j].revents, source.array[i].array[j].revents);
+      } // for
+    } // for
+  }
+
+  for (f_number_unsigned_t i = 0; i < source.used; ++i) {
+    free((void *) source.array[i].array);
+  } // for
+
+  for (f_number_unsigned_t i = 0; i < destination.used; ++i) {
+    free((void *) destination.array[i].array);
+  } // for
+
+  free((void *) source.array);
+  free((void *) destination.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_append_all.h b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_append_all.h
new file mode 100644 (file)
index 0000000..b07cfb0
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__pollss_append_all
+#define _TEST__F_type_array__pollss_append_all
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_pollss_append_all()
+ */
+extern void test__f_type_array_pollss_append_all__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_pollss_append_all()
+ */
+extern void test__f_type_array_pollss_append_all__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_pollss_append_all()
+ */
+extern void test__f_type_array_pollss_append_all__works(void **poll);
+
+#endif // _TEST__F_type_array__pollss_append_all
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_decimate_by.c b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_decimate_by.c
new file mode 100644 (file)
index 0000000..f76b136
--- /dev/null
@@ -0,0 +1,74 @@
+#include "test-type_array.h"
+#include "test-type_array-pollss_decimate_by.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_pollss_decimate_by__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_decimate_by(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_pollss_decimate_by__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_decimate_by(0, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_pollss_decimate_by__works(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_decimate_by(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_decimate_by.h b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_decimate_by.h
new file mode 100644 (file)
index 0000000..d67aed4
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__pollss_decimate_by
+#define _TEST__F_type_array__pollss_decimate_by
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_pollss_decimate_by()
+ */
+extern void test__f_type_array_pollss_decimate_by__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_type_array_pollss_decimate_by()
+ */
+extern void test__f_type_array_pollss_decimate_by__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_pollss_decimate_by()
+ */
+extern void test__f_type_array_pollss_decimate_by__works(void **poll);
+
+#endif // _TEST__F_type_array__pollss_decimate_by
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_decrease_by.c b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_decrease_by.c
new file mode 100644 (file)
index 0000000..68bc836
--- /dev/null
@@ -0,0 +1,74 @@
+#include "test-type_array.h"
+#include "test-type_array-pollss_decrease_by.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_pollss_decrease_by__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_decrease_by(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_pollss_decrease_by__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_decrease_by(0, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_pollss_decrease_by__works(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_decrease_by(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_decrease_by.h b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_decrease_by.h
new file mode 100644 (file)
index 0000000..48919c0
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__pollss_decrease_by
+#define _TEST__F_type_array__pollss_decrease_by
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_pollss_decrease_by()
+ */
+extern void test__f_type_array_pollss_decrease_by__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_pollss_decrease_by()
+ */
+extern void test__f_type_array_pollss_decrease_by__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_pollss_decrease_by()
+ */
+extern void test__f_type_array_pollss_decrease_by__works(void **poll);
+
+#endif // _TEST__F_type_array__pollss_decrease_by
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase.c b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase.c
new file mode 100644 (file)
index 0000000..518f191
--- /dev/null
@@ -0,0 +1,76 @@
+#include "test-type_array.h"
+#include "test-type_array-pollss_increase.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_pollss_increase__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_increase(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_pollss_increase__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_increase(length, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_pollss_increase__works(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    data.used = length;
+
+    const f_status_t status = f_pollss_increase(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, length);
+    assert_in_range(data.size, length + 1, length + 1 + F_memory_default_allocation_small_d);
+  }
+
+  free((void *) data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase.h b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase.h
new file mode 100644 (file)
index 0000000..78956f2
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__pollss_increase
+#define _TEST__F_type_array__pollss_increase
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_pollss_increase()
+ */
+extern void test__f_type_array_pollss_increase__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_pollss_increase()
+ */
+extern void test__f_type_array_pollss_increase__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_pollss_increase()
+ */
+extern void test__f_type_array_pollss_increase__works(void **poll);
+
+#endif // _TEST__F_type_array__pollss_increase
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase_by.c b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase_by.c
new file mode 100644 (file)
index 0000000..0cd5a63
--- /dev/null
@@ -0,0 +1,84 @@
+#include "test-type_array.h"
+#include "test-type_array-pollss_increase_by.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_pollss_increase_by__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_increase_by(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_pollss_increase_by__returns_data_not(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_increase_by(0, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    const f_status_t status = f_pollss_increase_by(length, &data);
+
+    assert_int_equal(status, F_data_not);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+void test__f_type_array_pollss_increase_by__works(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_polls_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  {
+    data.used = length;
+
+    const f_status_t status = f_pollss_increase_by(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, length);
+    assert_int_equal(data.size, length * 2);
+  }
+
+  free((void *) data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase_by.h b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_increase_by.h
new file mode 100644 (file)
index 0000000..af7fb3f
--- /dev/null
@@ -0,0 +1,34 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__pollss_increase_by
+#define _TEST__F_type_array__pollss_increase_by
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_pollss_increase_by()
+ */
+extern void test__f_type_array_pollss_increase_by__parameter_checking(void **poll);
+
+/**
+ * Test that the function returns F_data_not.
+ *
+ * @see f_pollss_increase_by()
+ */
+extern void test__f_type_array_pollss_increase_by__returns_data_not(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_pollss_increase_by()
+ */
+extern void test__f_type_array_pollss_increase_by__works(void **poll);
+
+#endif // _TEST__F_type_array__pollss_increase_by
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_resize.c b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_resize.c
new file mode 100644 (file)
index 0000000..d553ed6
--- /dev/null
@@ -0,0 +1,42 @@
+#include "test-type_array.h"
+#include "test-type_array-pollss_resize.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void test__f_type_array_pollss_resize__parameter_checking(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, 0);
+
+    assert_int_equal(status, F_status_set_error(F_parameter));
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, 0);
+  }
+
+  assert_null(data.array);
+}
+
+void test__f_type_array_pollss_resize__works(void **poll) {
+
+  const int length = 5;
+  f_pollss_t data = f_pollss_t_initialize;
+
+  {
+    const f_status_t status = f_pollss_resize(length, &data);
+
+    assert_int_equal(status, F_none);
+    assert_int_equal(data.used, 0);
+    assert_int_equal(data.size, length);
+  }
+
+  free((void *) data.array);
+}
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
diff --git a/level_0/f_type_array/tests/unit/c/test-type_array-pollss_resize.h b/level_0/f_type_array/tests/unit/c/test-type_array-pollss_resize.h
new file mode 100644 (file)
index 0000000..35ff454
--- /dev/null
@@ -0,0 +1,27 @@
+/**
+ * FLL - Level 0
+ *
+ * Project: Type
+ * API Version: 0.7
+ * Licenses: lgpl-2.1-or-later
+ *
+ * Test the array types in the type project.
+ */
+#ifndef _TEST__F_type_array__pollss_resize
+#define _TEST__F_type_array__pollss_resize
+
+/**
+ * Test that the function correctly fails on invalid parameter.
+ *
+ * @see f_pollss_resize()
+ */
+extern void test__f_type_array_pollss_resize__parameter_checking(void **poll);
+
+/**
+ * Test that the function works.
+ *
+ * @see f_pollss_resize()
+ */
+extern void test__f_type_array_pollss_resize__works(void **poll);
+
+#endif // _TEST__F_type_array__pollss_resize
index e8fbd28967e1745d79c801b21d1eec755549c876..85f92ea374edcc27dc5e1330f3862d6d75be1ba3 100644 (file)
@@ -265,6 +265,36 @@ int main(void) {
     cmocka_unit_test(test__f_type_array_int128ss_increase_by__works),
     cmocka_unit_test(test__f_type_array_int128ss_resize__works),
 
+    cmocka_unit_test(test__f_type_array_polls_append_all__returns_data_not),
+    cmocka_unit_test(test__f_type_array_polls_decimate_by__returns_data_not),
+    cmocka_unit_test(test__f_type_array_polls_decrease_by__returns_data_not),
+    cmocka_unit_test(test__f_type_array_polls_increase__returns_data_not),
+    cmocka_unit_test(test__f_type_array_polls_increase_by__returns_data_not),
+
+    cmocka_unit_test(test__f_type_array_polls_adjust__works),
+    cmocka_unit_test(test__f_type_array_polls_append__works),
+    cmocka_unit_test(test__f_type_array_polls_append_all__works),
+    cmocka_unit_test(test__f_type_array_polls_decimate_by__works),
+    cmocka_unit_test(test__f_type_array_polls_decrease_by__works),
+    cmocka_unit_test(test__f_type_array_polls_increase__works),
+    cmocka_unit_test(test__f_type_array_polls_increase_by__works),
+    cmocka_unit_test(test__f_type_array_polls_resize__works),
+
+    cmocka_unit_test(test__f_type_array_pollss_append_all__returns_data_not),
+    cmocka_unit_test(test__f_type_array_pollss_decimate_by__returns_data_not),
+    cmocka_unit_test(test__f_type_array_pollss_decrease_by__returns_data_not),
+    cmocka_unit_test(test__f_type_array_pollss_increase__returns_data_not),
+    cmocka_unit_test(test__f_type_array_pollss_increase_by__returns_data_not),
+
+    cmocka_unit_test(test__f_type_array_pollss_adjust__works),
+    cmocka_unit_test(test__f_type_array_pollss_append__works),
+    cmocka_unit_test(test__f_type_array_pollss_append_all__works),
+    cmocka_unit_test(test__f_type_array_pollss_decimate_by__works),
+    cmocka_unit_test(test__f_type_array_pollss_decrease_by__works),
+    cmocka_unit_test(test__f_type_array_pollss_increase__works),
+    cmocka_unit_test(test__f_type_array_pollss_increase_by__works),
+    cmocka_unit_test(test__f_type_array_pollss_resize__works),
+
     cmocka_unit_test(test__f_type_array_states_append_all__returns_data_not),
     cmocka_unit_test(test__f_type_array_states_decimate_by__returns_data_not),
     cmocka_unit_test(test__f_type_array_states_decrease_by__returns_data_not),
@@ -627,6 +657,24 @@ int main(void) {
       cmocka_unit_test(test__f_type_array_int128ss_increase_by__parameter_checking),
       cmocka_unit_test(test__f_type_array_int128ss_resize__parameter_checking),
 
+      cmocka_unit_test(test__f_type_array_polls_adjust__parameter_checking),
+      cmocka_unit_test(test__f_type_array_polls_append__parameter_checking),
+      cmocka_unit_test(test__f_type_array_polls_append_all__parameter_checking),
+      cmocka_unit_test(test__f_type_array_polls_decimate_by__parameter_checking),
+      cmocka_unit_test(test__f_type_array_polls_decrease_by__parameter_checking),
+      cmocka_unit_test(test__f_type_array_polls_increase__parameter_checking),
+      cmocka_unit_test(test__f_type_array_polls_increase_by__parameter_checking),
+      cmocka_unit_test(test__f_type_array_polls_resize__parameter_checking),
+
+      cmocka_unit_test(test__f_type_array_pollss_adjust__parameter_checking),
+      cmocka_unit_test(test__f_type_array_pollss_append__parameter_checking),
+      cmocka_unit_test(test__f_type_array_pollss_append_all__parameter_checking),
+      cmocka_unit_test(test__f_type_array_pollss_decimate_by__parameter_checking),
+      cmocka_unit_test(test__f_type_array_pollss_decrease_by__parameter_checking),
+      cmocka_unit_test(test__f_type_array_pollss_increase__parameter_checking),
+      cmocka_unit_test(test__f_type_array_pollss_increase_by__parameter_checking),
+      cmocka_unit_test(test__f_type_array_pollss_resize__parameter_checking),
+
       cmocka_unit_test(test__f_type_array_states_adjust__parameter_checking),
       cmocka_unit_test(test__f_type_array_states_append__parameter_checking),
       cmocka_unit_test(test__f_type_array_states_append_all__parameter_checking),
index 701e47ded1275ba456d34a08a3731e43f58801e3..e7f228af972fb0e16ef26c1d1ec2e8bc216d986f 100644 (file)
 
 // fll-0 includes.
 #include <fll/level_0/type.h>
+#include <fll/level_0/type_file.h>
 #include <fll/level_0/memory.h>
 #include <fll/level_0/type_array.h>
+#include <fll/level_0/type_array_file.h>
 
 // Test includes.
 #include "test-type_array-cells_adjust.h"
 #include "test-type_array-number_unsignedss_increase.h"
 #include "test-type_array-number_unsignedss_increase_by.h"
 #include "test-type_array-number_unsignedss_resize.h"
+#include "test-type_array-polls_adjust.h"
+#include "test-type_array-polls_append.h"
+#include "test-type_array-polls_append_all.h"
+#include "test-type_array-polls_decimate_by.h"
+#include "test-type_array-polls_decrease_by.h"
+#include "test-type_array-polls_increase.h"
+#include "test-type_array-polls_increase_by.h"
+#include "test-type_array-polls_resize.h"
+#include "test-type_array-pollss_adjust.h"
+#include "test-type_array-pollss_append.h"
+#include "test-type_array-pollss_append_all.h"
+#include "test-type_array-pollss_decimate_by.h"
+#include "test-type_array-pollss_decrease_by.h"
+#include "test-type_array-pollss_increase.h"
+#include "test-type_array-pollss_increase_by.h"
+#include "test-type_array-pollss_resize.h"
 #include "test-type_array-states_adjust.h"
 #include "test-type_array-states_append.h"
 #include "test-type_array-states_append_all.h"