Stock Control System
Loading...
Searching...
No Matches
Pool.c
Go to the documentation of this file.
1/*
2 * Copyright (c) All Rights Reserved
3 * 2025 Oliver Dixon <od641@york.ac.uk>
4 */
5
14#include <assert.h>
15#include <errno.h>
16#include <math.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20
21#include "Pool.h"
22#include "Product.h"
23
24struct Pool
25{
26 unsigned int capacity;
27 unsigned int index;
29 struct Product **products;
30};
31
37static void print_dashed_header(FILE *const buffer)
38{
39 static const unsigned int line_length = 4 + 3 + MAX_NAME_LENGTH + 3 + 11;
40 for (unsigned int counter = 0; counter < line_length; ++counter)
41 fputc('-', buffer);
42
43 fputc('\n', buffer);
44}
45
46struct Pool *pool_create(const unsigned int initial_capacity, const float growth_factor)
47{
48 assert(growth_factor > 1.0f);
49
50 struct Pool *pool = malloc(sizeof(struct Pool));
51 if (pool == NULL)
52 return NULL;
53
54 pool->products = malloc(sizeof(struct Product *) * initial_capacity);
55 if (pool->products == NULL) {
56 pool_delete(&pool);
57 return NULL;
58 }
59
60 pool->capacity = initial_capacity;
61 pool->index = 0;
63
64 return pool;
65}
66
67void pool_delete(struct Pool **const this)
68{
69 const unsigned int product_count = (*this)->index;
70 for (unsigned int product_idx = 0; product_idx < product_count; ++product_idx)
71 product_delete(&(*this)->products[product_idx]);
72
73 free((*this)->products);
74 free(*this);
75 *this = NULL;
76}
77
78bool pool_insert_element(struct Pool *const this, struct Product *const product)
79{
80 errno = 0;
81
82 if (this->index >= this->capacity) {
83 /*
84 * The pool does not have sufficient capacity of accommodate another element. Try to increase it by the stated
85 * growth factor. If the re-allocation fails, errno will be set. The responsibility for verification is on the
86 * caller.
87 */
88 const unsigned int new_capacity = (unsigned int) ceilf(this->capacity * this->growth_factor);
89
90 struct Product **new_products = realloc(this->products, sizeof(struct Product *) * new_capacity);
91 if (new_products == NULL)
92 return false;
93
94 this->products = new_products;
95 this->capacity = new_capacity;
96 }
97
98 this->products[this->index++] = product;
99 return true;
100}
101
102int pool_serialise_report(const struct Pool *const this, FILE *const buffer)
103{
104 const unsigned int count = this->index;
105 struct Product *sorted[count];
106 int retcode = 0;
107
108 // Create a new temporary array to store the sorted product pool elements.
109 memcpy(sorted, this->products, sizeof(struct Product *) * count);
110 qsort(sorted, count, sizeof(struct Product *), &product_ptr_compare);
111
112 print_dashed_header(buffer);
113 fprintf(buffer, "%-4s | %-" XSTR(MAX_NAME_LENGTH) "s | Stock Level\n", "ID", "Name");
114 print_dashed_header(buffer);
115
116 // Print the sorted elements.
117 for (unsigned int product_idx = 0; product_idx < count; ++product_idx)
118 if ((retcode = product_report_serialise(sorted[product_idx], buffer)) < 0)
119 break;
120
121 if (count > 0)
122 print_dashed_header(buffer);
123
124 fputc('\n', buffer);
125 return retcode;
126}
127
128int pool_serialise_stock_file(const struct Pool *const this, FILE *const buffer)
129{
130 const unsigned int product_count = this->index;
131 int retcode = 0;
132
133 for (unsigned int product_idx = 0; product_idx < product_count; ++product_idx)
134 if ((retcode = product_file_serialise(this->products[product_idx], buffer)) < 0)
135 break;
136
137 return retcode;
138}
139
140struct Product *pool_get_product_by_index(const struct Pool *const this, const unsigned int index)
141{
142 return index < this->index ? this->products[index] : NULL;
143}
int pool_serialise_report(const struct Pool *const this, FILE *const buffer)
Definition Pool.c:102
bool pool_insert_element(struct Pool *const this, struct Product *const product)
Definition Pool.c:78
struct Product * pool_get_product_by_index(const struct Pool *const this, const unsigned int index)
Definition Pool.c:140
void pool_delete(struct Pool **const this)
Definition Pool.c:67
struct Pool * pool_create(const unsigned int initial_capacity, const float growth_factor)
Definition Pool.c:46
int pool_serialise_stock_file(const struct Pool *const this, FILE *const buffer)
Definition Pool.c:128
Pool class specification.
int product_report_serialise(const struct Product *const this, FILE *const buffer)
Definition Product.c:59
int product_file_serialise(const struct Product *const this, FILE *const buffer)
Definition Product.c:64
void product_delete(struct Product **this)
Definition Product.c:53
int product_ptr_compare(const void *const product_lhs, const void *const product_rhs)
Definition Product.c:78
Product class specification.
#define MAX_NAME_LENGTH
Maximum number of bytes for a Product name, excluding the NULL-terminator.
Definition Product.h:26
#define XSTR(VALUE)
Definition Product.h:20
An ordered expandable collection of dynamically allocated Product records.
Definition Pool.c:25
unsigned int capacity
Maximum capacity of the Pool.
Definition Pool.c:26
static void print_dashed_header(FILE *const buffer)
Print the common header separator consisting of repeated hyphens.
Definition Pool.c:37
struct Product ** products
Pool elements.
Definition Pool.c:29
unsigned int index
Index of next available item in the Pool for products.
Definition Pool.c:27
float growth_factor
Factor by which the Pool capacity should be expanded.
Definition Pool.c:28
The Product represents a single product with a unique numerical identifier, human-readable name,...
Definition Product.c:22