Distinguish between 2013 and 2014.
authorThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Thu, 6 Mar 2014 11:42:07 +0000 (08:42 -0300)
committerThadeu Lima de Souza Cascardo <cascardo@cascardo.info>
Thu, 6 Mar 2014 11:42:07 +0000 (08:42 -0300)
The file format changes throughout the years, with added fields in the
header. Verify the size of the header and the year indicated, and add
support for year 2014.

decfile.c

index 98501b1..bfaf1ee 100644 (file)
--- a/decfile.c
+++ b/decfile.c
@@ -73,15 +73,23 @@ static void decfile_release_lines(struct rnet_decfile *decfile)
 }
 
 static char * get_header(struct rnet_decfile *decfile);
-static int parse_header(struct pmhash *hash, char *buffer);
+static int parse_header_2013(struct pmhash *hash, char *buffer);
+static int parse_header_2014(struct pmhash *hash, char *buffer);
 static int decfile_parse_file(struct rnet_decfile *decfile);
 
 static int decfile_parse_header(struct rnet_decfile *decfile)
 {
        char *buffer = get_header(decfile);
-       if (!buffer || strlen(buffer) != 765)
+       if (!buffer)
                return -EINVAL;
-       return parse_header(decfile->header, buffer);
+       switch (strlen(buffer)) {
+       case 765:
+               return parse_header_2013(decfile->header, buffer);
+       case 793:
+               return parse_header_2014(decfile->header, buffer);
+       default:
+               return -EINVAL;
+       }
 }
 
 static int decfile_parse(struct rnet_decfile *decfile)
@@ -162,13 +170,136 @@ static char * get_header(struct rnet_decfile *decfile)
        return NULL;
 }
 
-static int parse_header(struct pmhash *hash, char *buffer)
+static int parse_header_2014(struct pmhash *hash, char *buffer)
+{
+       int r;
+       char *p = buffer;
+       char *key;
+       char *val;
+
+#define parse(field, sz) \
+       r = -ENOMEM; \
+       val = malloc(sz + 1); \
+       if (!val) \
+               goto out_val; \
+       val[sz] = 0; \
+       memcpy(val, p, sz); \
+       p += sz; \
+       key = strdup(field); \
+       if (!key) \
+               goto out_key; \
+       if (pmhash_add(&hash, key, val)) \
+               goto out_add;
+
+       parse("sistema", 8);
+       parse("exerc", 4);
+       if (strcmp(val, "2014")) {
+               r = -EINVAL;
+               goto out_val;
+       }
+       parse("ano", 4);
+       parse("codigo_recnet", 4);
+       parse("in_ret", 1);
+       parse("cpf", 11);
+       parse("filler", 3);
+       parse("tipo_ni", 1);
+       parse("nr_versao", 3);
+       parse("nome", 60);
+       parse("uf", 2);
+       parse("hash", 10);
+       parse("in_cert", 1);
+       parse("dt_nasc", 8);
+       parse("in_comp", 1);
+       parse("in_res", 1);
+       parse("in_gerada", 1);
+       parse("nr_recibo_anterior", 10);
+       parse("in_pgd", 1);
+       parse("so", 14);
+       parse("versao_so", 7);
+       parse("jvm", 9);
+       parse("nr_recibo", 10);
+       parse("municipio", 4);
+       parse("conjuge", 11);
+       parse("obrig", 1);
+       parse("impdevido", 13);
+       parse("nr_recibo", 10);
+       parse("in_seg", 1);
+       parse("imppago", 2);
+       parse("impant", 1);
+       parse("mudend", 1);
+       parse("cep", 8);
+       parse("debito", 1);
+       parse("banco", 3);
+       parse("agencia", 4);
+       parse("filler", 1);
+       parse("data_julgado", 8);
+       parse("imppagar", 13);
+       parse("tribfonte", 1);
+       parse("cpfrra", 11);
+       parse("trib_rra", 1);
+       parse("cpf_rra2", 11);
+       parse("trib_3rra", 1);
+       parse("cpf_rra3", 11);
+       parse("trib_4rra", 1);
+       parse("cpf_rra4", 11);
+       parse("vr_doacao", 13);
+       parse("cnpj1", 14);
+       parse("cnpj2", 14);
+       parse("cnpj3", 14);
+       parse("cnpj4", 14);
+       parse("cpf_dep1", 11);
+       parse("dnas_dep1", 8);
+       parse("cpf_dep2", 11);
+       parse("dnas_dep2", 8);
+       parse("cpf_dep3", 11);
+       parse("dnas_dep3", 8);
+       parse("cpf_dep4", 11);
+       parse("dnas_dep4", 8);
+       parse("cpf_dep5", 11);
+       parse("dnas_dep5", 8);
+       parse("cpf_dep6", 11);
+       parse("dnas_dep6", 8);
+       parse("cnpj_med1", 14);
+       parse("cnpj_med2", 14);
+       parse("cpf_alim", 11);
+       parse("cpf_invent", 11);
+       parse("municipio", 40);
+       parse("contribuinte", 60);
+       parse("cpf_empregada", 11);
+       parse("hashcode", 12);
+       parse("data_nao_residente", 8);
+       parse("cpf_procurador", 11);
+       parse("obrigatoriedade", 3);
+       parse("rendtrib", 13);
+       parse("cnpj_prev", 14);
+       parse("cnpj_prev2", 14);
+       parse("vr_totisentos", 13);
+       parse("vr_totexclusivo", 13);
+       parse("vr_totpagamentos", 13);
+       parse("nr_conta", 13);
+       parse("nr_dv_conta", 2);
+       parse("in_dv_conta", 1);
+       parse("versaotestpgd", 3);
+       parse("controle", 10);
+
+       return 0;
+out_add:
+       free(key);
+out_key:
+       free(val);
+out_val:
+       return r;
+}
+
+static int parse_header_2013(struct pmhash *hash, char *buffer)
 {
+       int r;
        char *p = buffer;
        char *key;
        char *val;
 
 #define parse(field, sz) \
+       r = -ENOMEM; \
        val = malloc(sz + 1); \
        if (!val) \
                goto out_val; \
@@ -183,6 +314,10 @@ static int parse_header(struct pmhash *hash, char *buffer)
 
        parse("sistema", 8);
        parse("exerc", 4);
+       if (strcmp(val, "2013")) {
+               r = -EINVAL;
+               goto out_val;
+       }
        parse("ano", 4);
        parse("codigo_recnet", 4);
        parse("in_ret", 1);
@@ -269,7 +404,7 @@ out_add:
 out_key:
        free(val);
 out_val:
-       return -1;
+       return r;
 }
 
 char *rnet_decfile_get_header_field(struct rnet_decfile *decfile, char *field)