commit 95ef9920529da0a2511562604ff2b1813601259b
parent e89839f281cac8a05411172f4294b3e714e6377d
Author: klewer-martin <martin.cachari@gmail.com>
Date: Thu, 5 Aug 2021 19:15:14 -0300
New function to load users to the vector
Diffstat:
7 files changed, 153 insertions(+), 147 deletions(-)
diff --git a/Makefile b/Makefile
@@ -21,7 +21,7 @@ vector.o: $(HFOLDER)/vector.h $(HFOLDER)/status.h
status.o: $(HFOLDER)/status.h
$(CC) $(CFLAGS) -c $(SRCFOLDER)/status.c
-utils.o: $(HFOLDER)/status.h $(HFOLDER)/user.h
+utils.o: $(HFOLDER)/status.h $(HFOLDER)/user.h $(HFOLDER)/vector.h
$(CC) $(CFLAGS) -c $(SRCFOLDER)/utils.c
user.o: $(HFOLDER)/status.h $(HFOLDER)/user.h
diff --git a/include/user.h b/include/user.h
@@ -15,7 +15,8 @@ typedef struct {
status_t user_create(ADT_user_t **);
status_t user_destroy(ADT_user_t **);
-status_t user_set_data(ADT_user_t *, char **);
+status_t user_set_data_from_str(ADT_user_t *, char **);
+status_t user_set_data(ADT_user_t *, ulong, ulong, ulong);
status_t user_add_amount(ADT_user_t *, long);
int user_equals(const void *, const void *);
diff --git a/include/utils.h b/include/utils.h
@@ -9,6 +9,7 @@
#include "cla.h"
#include "user.h"
#include "status.h"
+#include "vector.h"
#define _XOPEN_SOURCE
#define __USE_XOPEN
@@ -31,9 +32,12 @@
#define XML_STR_CREDIT "credits"
#define XML_STR_DEBIT "debits"
-status_t get_date(time_t *, char **);
+status_t get_date(time_t *, char *);
+
status_t array_destroy(char **, size_t);
+
status_t string_split(char *, char **, char *);
+status_t load_users_to_vector(ADT_Vector_t **, ADT_cla_t *);
bool is_valid_card(char *);
diff --git a/include/vector.h b/include/vector.h
@@ -1,14 +1,17 @@
#ifndef VECTOR__H
#define VECTOR__H
-#define VECTOR_INIT_SIZE 10
-#define VECTOR_GROWTH_FACTOR 2
-
#include <stdlib.h>
-#include "utils.h"
#include "status.h"
+#define VECTOR_INIT_SIZE 10
+#define VECTOR_GROWTH_FACTOR 2
+
+#define XML_STR_HEADER "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+#define XML_STR_ROOT "root"
+#define XML_STR_ROW "row"
+
typedef status_t (*printer_t)(const void *, FILE *);
typedef int (*comparator_t)(const void *, const void *);
diff --git a/source/main.c b/source/main.c
@@ -9,12 +9,6 @@ int main (int argc, char *argv[])
status_t st;
cla_t cla;
ADT_Vector_t *v;
- ADT_user_t *user, *user_tmp;
- char buffer[IN_FILE_MAX_LEN];
- char *endptr, **data;
- size_t i;
- long amount;
- time_t epoch;
/* Asigna memoria a cla (c.l.a.: "command line arguments") */
if((st = cla_create(&cla)) != OK) {
@@ -36,162 +30,43 @@ int main (int argc, char *argv[])
return st;
}
- /* Crea un arreglo de cadenas de caracteres */
- if((data = malloc(sizeof(char *) * IN_FILE_FIELDS)) == NULL) {
- show_status(ERROR_MEMORY);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- return ERROR_MEMORY;
- }
-
- for(i = 0; i < IN_FILE_FIELDS; i++) {
- if((data[i] = calloc(sizeof(char), IN_FILE_FIELDS_MAX_LEN)) == NULL) {
- show_status(ERROR_MEMORY);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
- return ERROR_MEMORY;
- }
- }
-
/* Setea el comparador a ADT_Vector */
if((st = ADT_Vector_set_comparator(v, user_equals)) != OK) {
show_status(st);
cla_destroy(cla);
ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
return st;
}
- /* Crea un usuario temporal */
- if((st = user_create(&user_tmp)) != OK) {
+ /* Carga el vector con los usuarios del archivo de entrada */
+ if((st = load_users_to_vector(&v, cla)) != OK) {
show_status(st);
cla_destroy(cla);
ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
return st;
}
- /* Lee linea por linea del archivo de entrada */
- while(fgets(buffer, IN_FILE_MAX_LEN, cla->fi)) {
-
- /* Separa la linea leida segun un caracter delimitador */
- if((st = string_split(buffer, data, IN_FILE_DELIM)) != OK) {
- show_status(st);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
- free(user_tmp);
- return st;
- }
-
- /* Setea el usuario temporal con los datos obtenidos de la linea */
- if((st = user_set_data(user_tmp, data)) != OK) {
- show_status(st);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
- free(user_tmp);
- return st;
- }
-
- amount = strtol(data[POS_AMOUNT], &endptr, 10);
- if(*endptr != '\0') {
- show_status(st);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
- free(user_tmp);
- return ERROR_CORRUPT_DATA;
- }
-
- /* Transforma el tiempo de la linea leida a formato UNIX */
- get_date(&epoch, data);
-
- /* Comprueba que el tiempo de la linea leida no supere los argumentos ingresados */
- if(epoch < cla->ti) continue;
- else if(epoch > cla->tf) break;
-
- /* Solo imprime en el archivo de salida las transacciones realizadas con una tarjeta valida */
- if(!is_valid_card(data[POS_CARD_NUMBER])) {
- fprintf(stderr, "%s: %s\n",STR_INVALID_CARD_NUMBER, data[POS_CARD_NUMBER]);
- continue;
- }
-
- /* Busca el id del usuario en el vector */
- if((user = ADT_Vector_get_elem(v, user_tmp)) != NULL) {
- /* Si lo encuentra le suma el monto correspondiente */
- if((st = user_add_amount(user, amount)) != OK) {
- show_status(st);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
- free(user_tmp);
- return st;
- }
- }
-
- /* Si no lo encuentra crea un usuario nuevo */
- else {
- if((st = user_create(&user)) != OK) {
- show_status(st);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
- free(user_tmp);
- return st;
- }
-
- if((st = user_set_data(user, data))) {
- show_status(st);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
- free(user_tmp);
- return st;
- }
-
- /* Y lo agrega al vector */
- if((st = ADT_Vector_add(&v, user)) != OK){
- show_status(st);
- free(user_tmp);
- cla_destroy(cla);
- ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
- free(user_tmp);
- return st;
- }
- }
- clean_buffer(buffer);
- clean_array(data);
- } /* End while */
-
/* Ordena el vector con los usuarios */
if((st = ADT_Vector_sort(v, user_comparator_credits_maxmin)) != OK) {
show_status(st);
- free(user_tmp);
cla_destroy(cla);
ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
return st;
}
- /* Setea el impresor a ADT_Vector */
+ /* Setea el impresor e imprime ADT_Vector segĂșn el argumento ingresado */
if(!strcmp(cla->fmt, STR_FMT_CSV)) {
if((st = ADT_Vector_set_printer(v, user_print_as_csv)) != OK) {
show_status(st);
cla_destroy(cla);
ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
return st;
}
/* E imprime el vector con los usuarios */
if((st = ADT_Vector_export_as_csv(v, cla->fo)) != OK) {
show_status(st);
- free(user_tmp);
cla_destroy(cla);
ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
return st;
}
}
@@ -200,22 +75,17 @@ int main (int argc, char *argv[])
show_status(st);
cla_destroy(cla);
ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
return st;
}
if((st = ADT_Vector_export_as_xml(v, cla->fo)) != OK) {
show_status(st);
- free(user_tmp);
cla_destroy(cla);
ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
return st;
}
}
- free(user_tmp);
cla_destroy(cla);
ADT_Vector_destroy(&v);
- array_destroy(data, IN_FILE_FIELDS);
return OK;
}
diff --git a/source/user.c b/source/user.c
@@ -22,7 +22,7 @@ status_t user_destroy(ADT_user_t **user)
return OK;
}
-status_t user_set_data(ADT_user_t *user, char **data)
+status_t user_set_data_from_str(ADT_user_t *user, char **data)
{
char *endptr;
long amount;
@@ -41,6 +41,17 @@ status_t user_set_data(ADT_user_t *user, char **data)
return OK;
}
+status_t user_set_data(ADT_user_t *user, ulong id, ulong c, ulong d)
+{
+ if(user == NULL) return ERROR_NULL_POINTER;
+
+ user->id = id;
+ user->c = c;
+ user->d = d;
+
+ return OK;
+}
+
status_t user_add_amount(ADT_user_t *user, long amount)
{
if(user == NULL) return ERROR_NULL_POINTER;
diff --git a/source/utils.c b/source/utils.c
@@ -51,26 +51,26 @@ status_t array_destroy(char **data, size_t fields)
return OK;
}
-status_t get_date(time_t *e, char **data)
+status_t get_date(time_t *e, char *str)
{
struct tm tm;
- if(e == NULL || data == NULL) return ERROR_NULL_POINTER;
+ if(e == NULL || str == NULL) return ERROR_NULL_POINTER;
/* Desactiva el horario de verano */
tm.tm_isdst = 0;
- switch(data[POS_TXN_DATE][2]) {
+ switch(str[2]) {
case '/':
- strptime(data[2], "%d/%m/%Y %H:%M:%S", &tm);
+ strptime(str, "%d/%m/%Y %H:%M:%S", &tm);
*e = mktime(&tm);
break;
case '-':
- strptime(data[2], "%d-%m-%Y %H:%M:%S", &tm);
+ strptime(str, "%d-%m-%Y %H:%M:%S", &tm);
*e = mktime(&tm);
break;
case '.':
- strptime(data[2], "%d.%m.%Y %H:%M:%S", &tm);
+ strptime(str, "%d.%m.%Y %H:%M:%S", &tm);
*e = mktime(&tm);
break;
@@ -104,3 +104,120 @@ bool is_valid_card(char *card_no)
return (sum % 10) ? false : true;
}
+
+status_t load_users_to_vector(ADT_Vector_t **v, ADT_cla_t *cla)
+{
+ status_t st;
+ char buffer[IN_FILE_MAX_LEN];
+ char *endptr, **data;
+ ADT_user_t *user, *user_tmp;
+ time_t epoch;
+ long long amount;
+ ulong id, c, d;
+ size_t i;
+
+ if(v == NULL || cla == NULL) return ERROR_NULL_POINTER;
+ /* Asigna memoria a data */
+ if((data = malloc(sizeof(char *) * IN_FILE_FIELDS)) == NULL)
+ return ERROR_MEMORY;
+
+ for(i = 0; i < IN_FILE_FIELDS; i++) {
+ if((data[i] = calloc(sizeof(char), IN_FILE_FIELDS_MAX_LEN)) == NULL) {
+ array_destroy(data, IN_FILE_FIELDS);
+ return ERROR_MEMORY;
+ }
+ }
+
+ /* Crea un usuario temporal */
+ if((st = user_create(&user_tmp)) != OK) {
+ array_destroy(data, IN_FILE_FIELDS);
+ return st;
+ }
+
+ while(fgets(buffer, IN_FILE_MAX_LEN, cla->fi)) {
+ if((st = string_split(buffer, data, IN_FILE_DELIM)) != OK) {
+ free(user_tmp);
+ array_destroy(data, IN_FILE_FIELDS);
+ return st;
+ }
+
+ id = strtol(data[POS_USER_ID], &endptr, 10);
+ if(*endptr != '\0') {
+ free(user_tmp);
+ array_destroy(data, IN_FILE_FIELDS);
+ return ERROR_CORRUPT_DATA;
+ }
+
+ amount = strtol(data[POS_AMOUNT], &endptr, 10);
+ if(*endptr != '\0') {
+ free(user_tmp);
+ array_destroy(data, IN_FILE_FIELDS);
+ return ERROR_CORRUPT_DATA;
+ }
+
+ if(amount > 0) { c = amount; d = 0; }
+ else if(amount < 0) { c = 0; d = -amount; }
+
+ if((st = user_set_data(user_tmp, id, c, d)) != OK) {
+ free(user_tmp);
+ array_destroy(data, IN_FILE_FIELDS);
+ return ERROR_CORRUPT_DATA;
+ }
+
+ if((st = get_date(&epoch, data[POS_TXN_DATE])) != OK){
+ free(user_tmp);
+ array_destroy(data, IN_FILE_FIELDS);
+ return ERROR_CORRUPT_DATA;
+ }
+
+ /* Comprueba el que el tiempo este dentro de los valores pasados como argumentos */
+ if(epoch < cla->ti) continue;
+ else if(epoch > cla->tf) break;
+
+ /* Comprueba que la tarjeta usada en la transaccion sea la correcta */
+ if(!is_valid_card(data[POS_CARD_NUMBER])) {
+ fprintf(stderr, "%s: %s\n",STR_INVALID_CARD_NUMBER, data[POS_CARD_NUMBER]);
+ continue;
+ }
+
+ /* Busca el id del usuario en el vector */
+ if((user = ADT_Vector_get_elem(*v, user_tmp)) != NULL) {
+ /* Si lo encuentra le suma el monto correspondiente */
+ if((st = user_add_amount(user, amount)) != OK) {
+ array_destroy(data, IN_FILE_FIELDS);
+ free(user_tmp);
+ return st;
+ }
+ }
+
+ /* Si no lo encuentra crea un usuario nuevo */
+ else {
+ if((st = user_create(&user)) != OK) {
+ array_destroy(data, IN_FILE_FIELDS);
+ free(user_tmp);
+ return st;
+ }
+
+ if((st = user_set_data(user, id, c, d))) {
+ array_destroy(data, IN_FILE_FIELDS);
+ free(user_tmp);
+ return st;
+ }
+
+ /* Y lo agrega al vector */
+ if((st = ADT_Vector_add(v, user)) != OK){
+ array_destroy(data, IN_FILE_FIELDS);
+ free(user_tmp);
+ return st;
+ }
+ }
+ clean_buffer(buffer);
+ clean_array(data);
+ } /* End while */
+
+
+ array_destroy(data, IN_FILE_FIELDS);
+ free(user_tmp);
+
+ return OK;
+}