#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;
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
* move to the first "
* read until the first "
* print while reading
* skip to the first ,
* and loop this way until } is
* encountered
**/
while(1) {
skip_to_char(temp_string, string, '"', '}', in);
++ temp_string; /* skip " char */
check(temp_string, string, in);
while(*temp_string != '"') {
fputc(*temp_string, out);
++ temp_string;
check(temp_string, string, in);
}
fputc(',', 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
* skip to the first :
* then skip to the first digit
* or " character
* read until digits are found or
* no " character is found
* repeat until file is not at
* EOF
**/
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)) {
fputc(*temp_string, out);
++ temp_string;
check(temp_string, string, in);
}
} else {
++ temp_string; /* skip the " */
check(temp_string, string, in);
/* read the string value */
while(*temp_string != '"') {
fputc(*temp_string, out);
++ temp_string;
check(temp_string, string, in);
}
}
if(k == number_of_keys) {
k = 1;
fputc(',', out);
fputc('\n', out);
} else {
++ k;
fputc(',', out);
}
}
/* cleanup */
free(string);
fclose(in);
fclose(out);
return 0;
}