Skip to content

Commit 0e561e1

Browse files
committed
Add to type
1 parent 3cba52b commit 0e561e1

File tree

3 files changed

+237
-0
lines changed

3 files changed

+237
-0
lines changed

include/copy_data.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,14 @@ typedef struct {
1919
void *(*apply_func)(void *vl);
2020
} apply_data_t;
2121

22+
typedef struct {
23+
dataframe_t *dst;
24+
dataframe_t *src;
25+
int col_idx;
26+
int row;
27+
column_type_t downcast;
28+
} type_data_t;
29+
2230
bool copy_columns_type(dataframe_t *dst, dataframe_t *src);
2331
bool copy_columns_name(dataframe_t *dst, dataframe_t *src);
2432
bool copy_data(dataframe_t *dst, dataframe_t *src, int nb_rows);

include/dataframe.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,6 @@ void *df_get_value(dataframe_t *df, int row, char const *column);
7474
void **df_get_values(dataframe_t *df, char const *column);
7575
dataframe_t *df_apply(dataframe_t *df, const char *column,
7676
void *(*apply_func)(void *vl));
77+
dataframe_t *df_to_type(dataframe_t *df, char const *column,
78+
column_type_t downcast);
7779
#endif /* !DATAFRAME_H_ */

src/df_to_type.c

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
/*
2+
** EPITECH PROJECT, 2025
3+
** __
4+
** File description:
5+
** _
6+
*/
7+
8+
#include <limits.h>
9+
#include <string.h>
10+
11+
#include "dataframe.h"
12+
#include "copy_data.h"
13+
#include "utils.h"
14+
15+
static
16+
void *to_string(void *src, column_type_t src_type)
17+
{
18+
char *result = NULL;
19+
20+
if (src_type == BOOL)
21+
result = my_memdup(src, sizeof(char) * (strlen(src) + 1));
22+
if (src_type == INT)
23+
if (asprintf(&result, "%d", *(int *)src) == -1)
24+
return NULL;
25+
if (src_type == UINT)
26+
if (asprintf(&result, "%u", *(unsigned int *)src) == -1)
27+
return NULL;
28+
if (src_type == FLOAT)
29+
if (asprintf(&result, "%f", *(float *)src) == -1)
30+
return NULL;
31+
return result;
32+
}
33+
34+
static
35+
void *to_int(void *src, column_type_t src_type)
36+
{
37+
int *result = malloc(sizeof(int));
38+
char *endptr;
39+
long value;
40+
41+
if (!result)
42+
return NULL;
43+
if (src_type == BOOL)
44+
*result = (strcasecmp((char *)src, "true") == 0) ? 1 : 0;
45+
if (src_type == STRING) {
46+
value = strtol((char *)src, &endptr, 10);
47+
if (*endptr != '\0')
48+
return (free(result), NULL);
49+
*result = (int)value;
50+
}
51+
if (src_type == FLOAT)
52+
*result = (int)(*(float *)src);
53+
if (src_type == UINT)
54+
*result = (int)(*(unsigned int *)src);
55+
return result;
56+
}
57+
58+
static
59+
void *to_uint2(void *src, unsigned int *result)
60+
{
61+
if (*(int *)src < 0)
62+
return (free(result), NULL);
63+
*result = (unsigned int)(*(int *)src);
64+
return result;
65+
}
66+
67+
static
68+
void *to_uint(void *src, column_type_t src_type)
69+
{
70+
unsigned int *result = malloc(sizeof(unsigned int));
71+
char *endptr;
72+
unsigned long value;
73+
74+
if (!result)
75+
return NULL;
76+
if (src_type == BOOL)
77+
*result = (strcasecmp((char *)src, "true") == 0) ? 1 : 0;
78+
if (src_type == STRING) {
79+
value = strtoul((char *)src, &endptr, 10);
80+
if (*endptr != '\0' || value > UINT_MAX)
81+
return (free(result), NULL);
82+
*result = (unsigned int)value;
83+
}
84+
if (src_type == FLOAT)
85+
*result = (unsigned int)(*(float *)src);
86+
if (src_type == INT)
87+
return to_uint2(src, result);
88+
return result;
89+
}
90+
91+
static
92+
void *to_float(void *src, column_type_t src_type)
93+
{
94+
float *result = malloc(sizeof(float));
95+
char *endptr;
96+
97+
if (!result)
98+
return NULL;
99+
if (src_type == BOOL)
100+
*result = (strcasecmp((char *)src, "true") == 0) ? 1.0F : 0.0F;
101+
if (src_type == STRING) {
102+
*result = strtof((char *)src, &endptr);
103+
if (*endptr != '\0') {
104+
free(result);
105+
return NULL;
106+
}
107+
}
108+
if (src_type == INT)
109+
*result = (float)(*(int *)src);
110+
if (src_type == UINT)
111+
*result = (float)(*(unsigned int *)src);
112+
return result;
113+
}
114+
115+
static
116+
void *to_bool(void *src, column_type_t src_type)
117+
{
118+
char *result;
119+
int is_true = 0;
120+
121+
if (src_type == STRING)
122+
is_true = (strlen((char *)src) > 0);
123+
if (src_type == INT)
124+
is_true = (*(int *)src != 0);
125+
if (src_type == UINT)
126+
is_true = (*(unsigned int *)src != 0);
127+
if (src_type == FLOAT)
128+
is_true = (*(float *)src != 0.0F);
129+
if (asprintf(&result, "%s", is_true ? "true" : "false") == -1)
130+
return NULL;
131+
return result;
132+
}
133+
134+
static
135+
void *get_type_data(void *src, column_type_t src_type, column_type_t downcast)
136+
{
137+
switch (downcast) {
138+
case STRING:
139+
return to_string(src, src_type);
140+
case BOOL:
141+
return to_bool(src, src_type);
142+
case INT:
143+
return to_int(src, src_type);
144+
case UINT:
145+
return to_uint(src, src_type);
146+
case FLOAT:
147+
return to_float(src, src_type);
148+
default:
149+
return NULL;
150+
}
151+
}
152+
153+
static
154+
bool copy_col_values(type_data_t *d)
155+
{
156+
size_t sz;
157+
158+
for (int col = 0; col < d->src->nb_columns; col++) {
159+
if (col == d->col_idx &&
160+
d->src->column_type[d->col_idx] != d->downcast) {
161+
d->dst->data[d->row][col] = get_type_data(
162+
d->src->data[d->row][col], d->src->column_type[d->col_idx],
163+
d->downcast);
164+
continue;
165+
}
166+
sz = TYPES[d->src->column_type[col]].sz ?
167+
TYPES[d->src->column_type[col]].sz : strlen(
168+
(char *)d->src->data[d->row][col]) + 1;
169+
if (!sz)
170+
return false;
171+
d->dst->data[d->row][col] = my_memdup(d->src->data[d->row][col], sz);
172+
if (d->dst->data[d->row][col] == NULL)
173+
return false;
174+
}
175+
return true;
176+
}
177+
178+
#pragma GCC diagnostic push
179+
#pragma GCC diagnostic ignored "-Wanalyzer-malloc-leak"
180+
static
181+
dataframe_t *type_copy_data(dataframe_t *dst, dataframe_t *src,
182+
column_type_t downcast, int col_idx)
183+
{
184+
type_data_t typ_dat = { .dst = dst, .src = src, .col_idx = col_idx,
185+
.downcast = downcast };
186+
187+
for (int row = 0; row < src->nb_rows; row++) {
188+
dst->data[row] = (void **)malloc(sizeof(void *) *
189+
src->nb_columns);
190+
if ((void *)dst->data[row] == NULL)
191+
return NULL;
192+
typ_dat.row = row;
193+
if (!copy_col_values(&typ_dat))
194+
return (free((void *)dst->data[row]), NULL);
195+
if (dst->data[row][col_idx] == NULL)
196+
return NULL;
197+
}
198+
dst->nb_rows = src->nb_rows;
199+
dst->column_type[col_idx] = downcast;
200+
return dst;
201+
}
202+
#pragma GCC diagnostic pop
203+
204+
dataframe_t *df_to_type(dataframe_t *df, char const *column,
205+
column_type_t downcast)
206+
{
207+
int col_idx;
208+
dataframe_t *new_df = malloc(sizeof(dataframe_t));
209+
210+
if (new_df == NULL)
211+
return NULL;
212+
if (df == NULL || column == NULL || downcast == UNDEFINED)
213+
return (free(new_df), NULL);
214+
col_idx = get_col_idx(df, column);
215+
if (col_idx < 0)
216+
return (free(new_df), NULL);
217+
if (!copy_columns_type(new_df, df) || !copy_columns_name(new_df, df))
218+
return (free(new_df), NULL);
219+
new_df->data = (void ***)malloc(sizeof(void *) * df->nb_rows);
220+
if ((void *)new_df->data == NULL)
221+
return (free(new_df), NULL);
222+
new_df->separator = strdup(df->separator);
223+
if (new_df->separator == NULL)
224+
return ((free((void *)new_df->data), free(new_df)), NULL);
225+
new_df->nb_columns = df->nb_columns;
226+
return type_copy_data(new_df, df, downcast, col_idx);
227+
}

0 commit comments

Comments
 (0)