Browse Source

Optimize algorithm

master
Kirill Nikolaev 1 month ago
parent
commit
02e29a701a
Signed by: sokket <sokket@oceancraft.ru> GPG Key ID: 082FDA12D688C5C1
1 changed files with 54 additions and 59 deletions
  1. +54
    -59
      main.c

+ 54
- 59
main.c View File

@@ -53,39 +53,44 @@ char *append(char *str, char c) {
return str;
}

#define UNKNOWN 1
#define OPEN 2
#define CLOSE 3
#define VALUE 4
enum Type {
UNKNOWN = 1,
OPEN = 2,
CLOSE = 3,
VALUE = 4
};

typedef struct obj {
int depth;
int type;
enum Type type;
char *key;
char *value;
} Obj;

int pretty_print = 1;

void print_white_space(int depth) {
for (int i = 0; i < depth; i++)
printf(WHITE_SPACE);
if (pretty_print)
for (int i = 0; i < depth; i++)
printf(WHITE_SPACE);
}

void print_obj(Obj tag, int next_obj_is_val, int prev_obj_is_val, int comma) {
switch (tag.type) {
case OPEN:
print_white_space(tag.depth);
printf("\"%s\": %s", tag.key, next_obj_is_val ? "" : "{\n");
printf("\"%s\":%s", tag.key, next_obj_is_val ? (pretty_print ? " " : "") : (pretty_print ? " {\n" : "{"));
break;
case CLOSE:
if (!prev_obj_is_val) {
print_white_space(tag.depth);
printf("%s\n", comma ? "}," : "}");
printf("%s%s", comma ? "}," : "}", pretty_print ? "\n" : "");
}
break;
case VALUE:
if (tag.value) {
if (count(tag.value, '\n') > 1) {
printf("\n");
printf("%s", pretty_print ? "\n" : "");
int printStart = 0;
for (char *p = strtok(tag.value, "\n"); p;) {
print_white_space(tag.depth);
@@ -95,23 +100,25 @@ void print_obj(Obj tag, int next_obj_is_val, int prev_obj_is_val, int comma) {
}
printf("%s", trim(p));
p = strtok(0, "\n");
printf("%s\n", p ? "" : "\"");
printf("%s%s", p ? "" : "\"", pretty_print ? "\n" : "");
}
} else {
char *text = trim(tag.value);
if (is_number(text) || !strcmp(text, "true") || !strcmp(text, "false"))
printf("%s%s\n", text, comma ? "," : "");
printf("%s%s%s", text, comma ? "," : "", pretty_print ? "\n" : "");
else
printf("\"%s\"%s\n", text, comma ? "," : "");
printf("\"%s\"%s%s", text, comma ? "," : "", pretty_print ? "\n" : "");
}
}
default:
break;
}
}

int prev_is_val = 0;

void print_obj_array(Obj *obj, int count) {
for (int i = 0; i < count; ++i) {
void print_obj_array(Obj *obj, int count, int force) {
for (int i = 0; i < count + (force ? 0 : -3); ++i) {
print_obj(
obj[i],
i + 1 < count && obj[i + 1].type == VALUE,
@@ -131,65 +138,48 @@ void init_obj(Obj *obj) {
obj->depth = 0;
}

Obj *create_obj_array(int size) {
Obj *array = malloc(size * sizeof(Obj));
for (int i = 0; i < size; i++)
init_obj(&array[i]);
return array;
}

void free_obj(Obj *obj) {
if (obj->key) {
if (obj->key)
free(obj->key);
obj->key = 0;
}
if (obj->value) {
if (obj->value)
free(obj->value);
obj->value = 0;
}
obj->type = VALUE;
obj->depth = 0;
init_obj(obj);
}

void free_obj_array(Obj *obj, int size) {
for (int i = 0; i < size; ++i)
free_obj(&obj[i]);
free(obj);
}

Obj *reallocate_obj_array(int *array_current_index, int *array_size, Obj **array, int init_array_size) {
if (++(*array_current_index) == *array_size) {
if ((*array)[*array_size - 1].type != VALUE
&& (*array)[*array_size - 2].type != VALUE
&& (*array)[*array_size - 3].type != VALUE
) {
print_obj_array((*array), *array_size);
for (int j = init_array_size; j < *array_size; ++j)
free_obj(&(*array)[j]);
*array_size = init_array_size;
*array = realloc(*array, *array_size * sizeof(Obj));
*array_current_index = 0;
} else {
*array_size += 3;
*array = realloc(*array, *array_size * sizeof(Obj));
for (int ib = *array_current_index; ib < *array_size; ib++)
init_obj(&(*array)[ib]);
}
void move_item(Obj *array, int from, int to) {
array[to] = array[from];
init_obj(&array[from]);
}

Obj *proceed(Obj *array, int *array_pos, int array_size) {
if (++*array_pos == array_size) {
print_obj_array(array, array_size, 0);
free_obj_array(array, array_size - 3);
for (int i = 0; i < 3; i++)
move_item(array, array_size - (3 - i), i);
*array_pos = 3;
} else {
init_obj(&array[*array_pos]);
}
Obj *tag = &(*array)[*array_current_index];
free_obj(tag);
return tag;
return &array[*array_pos];
}

void print_json(FILE *file) {
int ignore_tag_options = 0;
int depth = -1;
int depth = 0;

int init_array_size = XML_PARSE_ARRAY_SIZE;
int array_size = init_array_size;
int array_size = XML_PARSE_ARRAY_SIZE;
int array_pos = 0;
Obj *array = create_obj_array(array_size);
Obj array[array_size];
for (int i = 0; i < array_size; i++)
init_obj(&array[i]);

printf("{%s", pretty_print ? "\n" : "");
char buffer[READ_BUFFER_SIZE];
while (fgets(buffer, READ_BUFFER_SIZE, file)) {
Obj *tag = &array[array_pos];
@@ -199,7 +189,7 @@ void print_json(FILE *file) {
case '<':
if (tag->value && strlen(trim(tag->value)) != 0) {
tag->depth = depth + 1;
tag = reallocate_obj_array(&array_pos, &array_size, &array, init_array_size);
tag = proceed(array, &array_pos, array_size);
}
tag->type = UNKNOWN;
ignore_tag_options = 0;
@@ -215,7 +205,7 @@ void print_json(FILE *file) {
tag->depth = depth--;
if (tag->type == OPEN)
tag->depth = ++depth;
tag = reallocate_obj_array(&array_pos, &array_size, &array, init_array_size);
tag = proceed(array, &array_pos, array_size);
break;
default:
if (tag->type == UNKNOWN && buffer[i] == ' ')
@@ -226,7 +216,8 @@ void print_json(FILE *file) {
tag->value = append(tag->value, buffer[i]);
}
}
print_obj_array(array, array_pos);
print_obj_array(array, array_pos, 1);
printf("}%s", pretty_print ? "\n" : "");
free_obj_array(array, array_size);
}

@@ -234,6 +225,10 @@ int main(int argc, char *args[]) {
if (argc < 2) {
printf("Usage:\n./xml2json <xml_file>\n");
} else {
if (argc > 2) {
if (!strcmp(args[2], "-z"))
pretty_print = 0;
}
FILE *file = fopen(args[1], "r");
if (file)
print_json(file);


Loading…
Cancel
Save