9511_project03

project 3 for algorithms & programming I (9511) prof. Cardozo
Index Commits Files Refs README LICENSE
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:
MMakefile | 2+-
Minclude/user.h | 3++-
Minclude/utils.h | 6+++++-
Minclude/vector.h | 11+++++++----
Msource/main.c | 136++-----------------------------------------------------------------------------
Msource/user.c | 13++++++++++++-
Msource/utils.c | 129+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
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;
+}