#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
/* usual filesystem block size is 4 KB
* so a read of 4 KB should minimize the time
* spent on IO.
**/
#define BLOCK_SIZE 4096
/* use macros as no function stack operations are nedded
* better time performance
* */
/* reading is done in chuncks
* this macro checks if the chunck
* is at the end.
**/
#define check(temp_string, orig, in) if(*temp_string == '\0') { \
temp_string = orig; \
fgets(temp_string, BLOCK_SIZE, in);\
if(feof(in)) break; \
}
/* reads through the chunck and
* until it finds the specified char
**/
#define skip_to_char(str, orig, c, ctrl, fp) do { \
while(*str != c) { \
check(str, orig, fp); \
if(*str == c) { \
break; \
} \
if(*str == ctrl) { \
break; \
} \
++ str; \
} \
break; \
} while(0)
int main() {
FILE *in, *out;
/* assuming files can be opened
* so no checking
**/
in = fopen("convertor.in", "rt");
out = fopen("convertor.out", "wt");
if(in == NULL) {
/* something wierd with infoarena
* no input file
**/
return -1;
}
if(out == NULL) {
/* something wierd with infoarena
* no output file can be opened
**/
fclose(in); /* file was opened */
return -2;
}
/* original chunck */
char *string = malloc(BLOCK_SIZE * sizeof(char));
/* used to know when to print a \n*/
short number_of_keys = 0;
/* chunck iterator */
char *temp_string = string;
fgets(temp_string, BLOCK_SIZE, in);
/* read labels
* read the string between ""
* until } is found
**/
while(1) {
skip_to_char(temp_string, string, '"', '}', in);
++ temp_string; /* skip " char */
check(temp_string, string, in);
while(*temp_string != '"') {
fprintf(out, "%c", *temp_string);
++ temp_string;
check(temp_string, string, in);
}
fprintf(out, ",");
++ number_of_keys;
++ temp_string; /* skip the last " */
/* go to next label */
skip_to_char(temp_string, string, ',', '}', in);
/* end of first JSON object */
if(*temp_string == '}') {
break;
}
}
fprintf(out, "\n");
/* reset file position */
fseek(in, 0, SEEK_SET);
temp_string = string;
fgets(temp_string, BLOCK_SIZE, in);
/* read values */
short k = 1;
while(!feof(in)) {
check(temp_string, string, in);
skip_to_char(temp_string, string, ':', 0, in);
if(feof(in)) break;
++ temp_string;
check(temp_string, string, in);
/* skip to value
* meaning skipping each space,\t,\n etc.
* until either a " or a digit is found
**/
while(!isdigit(*temp_string) && !(*temp_string == '"')) {
++ temp_string;
check(temp_string, string, in);
}
if(isdigit(*temp_string)) {
/* read the integer value */
while(isdigit(*temp_string)) {
fprintf(out, "%c", *temp_string);
++ temp_string;
check(temp_string, string, in);
}
} else {
++ temp_string; /* skip the " */
check(temp_string, string, in);
while(*temp_string != '"') {
fprintf(out, "%c", *temp_string);
++ temp_string;
check(temp_string, string, in);
}
}
if(k == number_of_keys) {
k = 1;
fprintf(out, ",\n");
} else {
++ k;
fprintf(out, ",");
}
}
/* cleanup */
free(string);
fclose(in);
fclose(out);
return 0;
}