Pagini recente » Cod sursa (job #3030041) | Cod sursa (job #993037) | Cod sursa (job #1992467) | Cod sursa (job #325062) | Cod sursa (job #1349954)
/*
* Fisierul in format JSON este un vector cu elemente hash-uri.
* Fiecare hash este format din perechi cheie:valoare.
*
* Parsez fiecare linie caracter cu caracter si stochez caracterele pe care le
* intalnesc intr-un buffer pentru cuvinte. Cand intalnesc un caracter
* delimitator sterg simbolurile specifice JSON si adaug cuvantul curent fie in
* stringul de valori, fie in cel de chei.
*
* La sfarsitul fiecarui hash scriu cele doua stringuri in fisier.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define LG_MAX 9999
#define START_CHEIE '"' /* inceput cheie */
#define SEP_CV ':' /* separa cheia de valoare */
#define SEP_EL ',' /* separa elementele hash-ului */
#define START_DATE '[' /* inceputul datelor de citit */
#define STOP_DATE ']' /* sfarsitul datelor de citit */
#define START_HASH '{' /* semnaleaza inceputul unui hash */
#define STOP_HASH '}' /* semnaleaza sfarsitul unui hash */
/* Masturbare intelectuala */
#undef END_OF_LINE
#define END_OF_LINE(a) (((a) == EOF || (a) == '\n' || (a) == '\0') ? 1 : 0)
#undef EROARE
#define EROARE(c, s) do { \
fprintf(stderr, "\nEROARE - %s\n\n", (s));\
return (c); \
} while(0)
/* Sterge caracterele nevalide */
char *strip_key(char *s, int len);
char *strip_val(char *s, int len);
/* Adauga cuvantul curent */
char *add_word(char *dest, char *cuv);
/* Scrie datele in fisier, returneaza 0 in caz de eroare */
int flush_data(FILE *f, char *s);
/* Initializeaza bufferul */
void init_buf(char *s, int *len);
struct flag {
unsigned short citit_antet;
unsigned short in_hash;
unsigned short in_date;
unsigned short in_valoare;
};
int main(void)
{
FILE *in, *out;
char *buflin = NULL; /* buffer citire linia curenta */
char antet[LG_MAX]; /* antetul cu cheile */
char valori[LG_MAX]; /* valorile de scris */
char *bufcuv; /* cuvintul curent parsat */
int maloc_cuv;
struct flag flags = {0};
int ibuf; /* iterator pentru buffer cuvinte */
size_t nbuf = 0;
int i;
if ((in = fopen("convertor.in", "r")) == NULL)
EROARE(1, "Fisierul convertor.in nu a putut fi deschis");
if ((out = fopen("convertor.out", "w")) == NULL)
EROARE(2, "Fisierul convertor.out nu a putut fi scris");
maloc_cuv = LG_MAX;
bufcuv = (char *)malloc(maloc_cuv * sizeof(char));
while (getline(&buflin, &nbuf, in) != -1 || buflin[0] == EOF) {
/* Caut inceputul datelor de citit */
if (flags.in_date == 0) {
for (i = 0; buflin[i] != START_DATE &&
!END_OF_LINE(buflin[i]); i++);
if (!END_OF_LINE(buflin[i])) {
flags.in_date = 1;
i++;
}
} else {
i = 0;
}
for (; !END_OF_LINE(buflin[i]); i++) {
if (buflin[i] == STOP_DATE)
return 0;
if (flags.in_hash) {
if (buflin[i] == STOP_HASH) {
if (flags.citit_antet == 0) {
flush_data(out, antet);
flags.citit_antet = 1;
}
strip_val(bufcuv, ibuf);
add_word(valori, bufcuv);
flush_data(out, valori);
flags.in_hash = 0;
flags.in_valoare = 0;
/* Sunt in interiorul unei valori */
} else if (flags.in_valoare) {
if (buflin[i] != SEP_EL) {
if (maloc_cuv < ibuf - 1) {
for (; maloc_cuv < (ibuf -1);
maloc_cuv <<= 1)
;
bufcuv = (char *)realloc(bufcuv,
maloc_cuv * sizeof(char));
}
bufcuv[ibuf++] = buflin[i];
} else {
strip_val(bufcuv, ibuf);
add_word(valori, bufcuv);
init_buf(bufcuv, &ibuf);
flags.in_valoare = 0;
}
/* Am terminat de citit cheia */
} else if (buflin[i] == SEP_CV) {
if (flags.citit_antet == 0) {
strip_key(bufcuv, ibuf);
add_word(antet, bufcuv);
}
init_buf(bufcuv, &ibuf);
flags.in_valoare = 1;
/* Citesc o cheie */
} else if (flags.citit_antet == 0) {
if (maloc_cuv < ibuf - 1) {
for (; maloc_cuv < (ibuf -1);
maloc_cuv <<= 1)
;
bufcuv = (char *)realloc(bufcuv,
maloc_cuv * sizeof(char));
}
bufcuv[ibuf++] = buflin[i];
}
} else if (buflin[i] == START_HASH) {
init_buf(bufcuv, &ibuf);
antet[0] = '\0';
valori[0] = '\0';
flags.in_hash = 1;
}
}
/* Fortez getline sa imi realoce memorie pentru buffer */
free(buflin);
buflin = NULL;
nbuf = 0;
}
EROARE(5, "Date JSON incomplete sau inexistente");
}
/* Sterge caracterele nevalide din cheie */
char *strip_key(char *s, int len)
{
int i, j;
s[len] = '\0';
for (i = 0; s[i] != '"'; i++)
;
i++;
j = 0;
while (s[i] != '"')
if (isprint(s[i]))
s[j++] = s[i++];
else
i++;
s[j] = '\0';
return s;
}
/* Sterge caracterele nevalide din valoare */
char *strip_val(char *s, int len)
{
int i, j;
s[len] = '\0';
for (i = 0; isblank(s[i]) || (!isprint(s[i])); i++)
;
if (s[i] == '"')
return strip_key(s, len);
j = 0;
/* Blankurile apar numai intre ghilimele */
while (s[i] != '\0' && !isblank(s[i]))
if (isprint(s[i]))
s[j++] = s[i++];
else
i++;
s[j] = '\0';
return s;
}
/* Adauga cuvantul curent */
char *add_word(char *dest, char *cuv)
{
strcat(dest, cuv);
strcat(dest, ",");
return dest;
}
/* Scrie datele in fisier, returneaza 0 in caz de eroare */
int flush_data(FILE *f, char *s)
{
if (fprintf(f, "%s\n", s) == 0)
return 0;
fflush(f);
return 1;
}
/* Initializeaza stringurile folosite la citirea datelor */
void init_buf(char *s, int *len)
{
s[0] = '\0';
*len = 0;
}