Пример #1
0
uint16_t json_object(char **in_buf, uint16_t len, char *name){
    return put_json(in_buf, len, OBJ_BEGIN, name, 0, 0);
}
Пример #2
0
uint16_t json_end(char **in_buf, uint16_t len){
    return put_json(in_buf, len, END, NULL, 0, 0);
}
Пример #3
0
void put_json_str (char *str, FILE *fp)
{
    char c;
    int i = 0;
    while ((c = str[i++]) != '\0') put_json(c, fp);
}
Пример #4
0
uint16_t json_start(char **in_buf, uint16_t len){
    return put_json(in_buf, len, ROOT_BEGIN, NULL, 0, 0);
}
Пример #5
0
int main (int argc, char *argv[])
{
    FILE *fpi = stdin, *fpo = stdout, *fpmap;
    struct mapper mapper;
    struct record record;
    struct map *map;
    struct field *field;
    struct buf *val_buf = buf_new(1024), *xml_buf = NULL;
    char *xml_key, *key_buf, prev_seq[9], seq[9], tag[4], ind1, ind2;
    int file_args = 0, array = 1, xml = 0, mapfile = 0, count = 0,
        first = 0, first_sub = 0, first_char, skip_sub = 0, c, i, j;

    tag[3] = '\0';

    for (i = 1; i < argc; i++) {
        if (!strcmp(argv[i], "--usage") || !strcmp(argv[i], "--help") || !strcmp(argv[i], "-?")) {
            usage(argv[0], 0);
        } else if (!strcmp(argv[i], "--newline")) {
            array = 0;
        } else if (!strcmp(argv[i], "--xml")) {
            xml = 1;
        } else if (!strcmp(argv[i], "--json")) {
            xml = 0;
        } else if (!strcmp(argv[i], "--xmlkey")) {
            if (++i == argc) usage(argv[0], 1);
            xml_key = argv[i];
            xml_buf = buf_new(2048);
        } else if (!strcmp(argv[i], "--mapfile")) {
            if (++i == argc) usage(argv[0], 1);

            key_buf = malloc(256);

            if ((fpmap = fopen(argv[i], "r")) == NULL) {
                fprintf(stderr, "Can't open %s for reading\n", argv[i]);
                return 1;
            }

            if (!mapfile) {
                mapfile = 1;

                mapper.size = mapper.grow = 100;
                mapper.used = 0;
                mapper.maps = malloc(sizeof(struct map) * mapper.size);

                record.size = record.grow = 100;
                record.used = 0;
                record.fields = malloc(sizeof(struct field) * record.size);
                for (j = 0; j < record.size; j++) {
                    record.fields[j].val = buf_new(1024);
                }
            }

            while ((c = getc(fpmap)) != EOF) {
                if (isspace(c)) continue;
                if (c == '#') {
                    while (more(c = getc(fpmap)));
                    continue;
                }
                map = mapper.maps + mapper.used;
                map->key = NULL;
                map->tag[0] = c;
                map->tag[1] = getc(fpmap);
                map->tag[2] = getc(fpmap);
                if (isspace(c = getc(fpmap))) {
                    map->op = '\0';
                } else {
                    map->op = c;
                    fscanf(fpmap, "%s", map->subfields);
                }
                fscanf(fpmap, "%s", key_buf);
                for (j = 0; j < mapper.used; j++) {
                    if (!strcmp(mapper.maps[j].key, key_buf)) {
                        map->key = mapper.maps[j].key;
                        break;
                    }
                }
                if (!map->key) {
                    map->key = malloc(strlen(key_buf) + 1);
                    strcpy(map->key, key_buf);
                }

                mapper.used++;
                if (mapper.used == mapper.size) {
                    mapper.size += mapper.grow;
                    mapper.maps = realloc(mapper.maps, sizeof(struct map) * mapper.size);
                }
            }

            free(key_buf);
            fclose(fpmap);
        } else {
            switch (++file_args) {
            case 1:
                if ((fpi = fopen(argv[i], "r")) == NULL) {
                    fprintf(stderr, "Can't open %s for reading\n", argv[i]);
                    return 1;
                }
                break;
            case 2:
                if ((fpo = fopen(argv[i], "w")) == NULL) {
                    fprintf(stderr, "Can't open %s for writing\n", argv[i]);
                    return 1;
                }
                break;
            }
        }
    }

    if (xml) {
        fputs("<?xml version=\"1.0\" encoding=\"UTF-8\"?><collection xmlns=\"http://www.loc.gov/MARC21/slim\">", fpo);
    } else if (array) {
        fputs("[", fpo);
    }

    while ((c = getc(fpi)) != EOF) {
        if (isspace(c)) continue;
        seq[0] = c;
        for (i = 1; i < 9; ++i) seq[i] = getc(fpi);
        getc(fpi);
        for (i = 0; i < 3; ++i) tag[i] = getc(fpi);
        ind1 = getc(fpi);
        ind2 = getc(fpi);
        for (i = 0; i < 3; ++i) getc(fpi);
        val_buf->used = 0;
        while (more(c = getc(fpi))) buf_add(val_buf, c);
        buf_add(val_buf, '\0');

        if (!count || strncmp(seq, prev_seq, 9)) {
            if (count++) {
                if (xml_buf) {
                    buf_add_str(xml_buf, "</record>");
                    buf_add(xml_buf, '\0');
                }
                if (mapfile) {
                    fputs("{", fpo);
                    for (i = 0; i < record.used; i++) {
                        field = record.fields + i;
                        if (i) putc(',', fpo);
                        buf_add(field->val, '\0');
                        fprintf(fpo, "\"%s\":[%s]", field->key, field->val->str);
                    }
                    if (xml_buf) {
                        if (i) putc(',', fpo);
                        fprintf(fpo, "\"%s\":\"", xml_key);
                        put_json_str(xml_buf->str, fpo);
                        putc('\"', fpo);
                    }
                    fputs(array ? "},\n" : "}\n", fpo);
                    record.used = 0;
                } else if (xml) {
                    fputs("</record>\n", fpo);
                } else {
                    fputs(array ? "]},\n" : "]}\n", fpo);
                }
                if (xml_buf) {
                    xml_buf->used = 0;
                }
            }
        }

        for (i = 0; i < 9; ++i) prev_seq[i] = seq[i];

        if (mapfile) {
            for (i = 0; i < mapper.used; i++) {
                map = mapper.maps + i;
                if ((map->tag[0] == '*' || map->tag[0] == tag[0]) &&
                    (map->tag[1] == '*' || map->tag[1] == tag[1]) &&
                    (map->tag[2] == '*' || map->tag[2] == tag[2])) {
                    field = NULL;
                    for (j = 0; j < record.used; j++) {
                        field = record.fields + j;
                        if (field->key == map->key) {
                            break;
                        }
                        field = NULL;
                    }
                    if (!field) {
                        field = record.fields + record.used;
                        field->key = map->key;
                        field->val->used = 0;
                        record.used++;
                    }
                    skip_sub = 0;
                    first_char = 1;
                    for (j = 0; j < val_buf->used-1; j++) {
                        if (val_buf->str[j] == '$' && val_buf->str[j+1] == '$') {
                            j+= 2;
                            if ( (map->op == '+' && strchr(map->subfields, val_buf->str[j]) == NULL) ||
                                 (map->op == '-' && strchr(map->subfields, val_buf->str[j]) != NULL) ) {
                                skip_sub = 1;
                                continue;
                            }
                            skip_sub = 0;
                            j++;
                            if (j == val_buf->used-1) break;
                        }

                        if (!skip_sub) {
                            if (first_char) {
                                if (field->val->used) buf_add(field->val, ',');
                                buf_add(field->val, '"');
                                first_char = 0;
                            }
                            if (val_buf->str[j] == '"') buf_add(field->val, '\\');
                            if (val_buf->str[j] == '\\') buf_add(field->val, '\\');
                            buf_add(field->val, val_buf->str[j]);
                        }
                    }
                    if (!first_char) buf_add(field->val, '"');
                }
            }
        }

        if (!strncmp(tag, "FMT", 3)) continue;

        if (!strncmp(tag, "LDR", 3)) {
            if (xml_buf) {
                buf_add_str(xml_buf, "<record><leader>");
                buf_add_str(xml_buf, val_buf->str);
                buf_add_str(xml_buf, "</leader>");
            } else if (xml) {
                fprintf(fpo, "<record><leader>%s</leader>", val_buf->str);
            } else if (!mapfile) {
                fprintf(fpo, "{\"leader\":\"%s\",\"fields\":[", val_buf->str);
            }
            first = 1;
            continue;
        }

        if (first) {
            first = 0;
        } else if (!xml_buf && !xml && !mapfile) {
            putc(',', fpo);
        }

        if (tag[0] == '0' && tag[1] == '0') {
            if (xml_buf) {
                buf_add_str(xml_buf, "<controlfield tag=\"");
                for (i = 0; i < 3; i++) buf_add(xml_buf, tag[i]);
                buf_add_str(xml_buf, "\">");
                buf_add_xml_str(xml_buf, val_buf->str);
                buf_add_str(xml_buf, "</controlfield>");
            } else if (xml) {
                fprintf(fpo, "<controlfield tag=\"%3s\">", tag);
                for (i = 0; i < val_buf->used-1; i++) put_xml(val_buf->str[i], fpo);
                fputs("</controlfield>", fpo);
            } else if (!mapfile) {
                fprintf(fpo, "{\"%3s\":\"", tag);
                for (i = 0; i < val_buf->used-1; i++) put_json(val_buf->str[i], fpo);
                fputs("\"}", fpo);
            }
        } else {
            if (xml_buf) {
                buf_add_str(xml_buf, "<datafield tag=\"");
                for (i = 0; i < 3; i++) buf_add(xml_buf, tag[i]);
                buf_add_str(xml_buf, "\" ind1=\"");
                buf_add(xml_buf, ind1);
                buf_add_str(xml_buf, "\" ind2=\"");
                buf_add(xml_buf, ind2);
                buf_add_str(xml_buf, "\">");
            } else if (xml) {
                fprintf(fpo, "<datafield tag=\"%3s\" ind1=\"%c\" ind2=\"%c\">", tag, ind1, ind2);
            } else if (!mapfile) {
                fprintf(fpo, "{\"%3s\":{\"ind1\":\"%c\",\"ind2\":\"%c\",\"subfields\":[", tag, ind1, ind2);
            }
            first_sub = 1;
            for (i = 0; i < val_buf->used-1; i++) {
                if (val_buf->str[i] == '$' && val_buf->str[i+1] == '$') {
                    i+= 2;
                    if (first_sub) {
                        first_sub = 0;
                    } else {
                        if (xml_buf) {
                            buf_add_str(xml_buf, "</subfield>");
                        } else if (xml) {
                            fputs("</subfield>", fpo);
                        } else if (!mapfile) {
                            fputs("\"},", fpo);
                        }
                    }
                    if (xml_buf) {
                        buf_add_str(xml_buf, "<subfield code=\"");
                        buf_add(xml_buf, val_buf->str[i]);
                        buf_add_str(xml_buf, "\">");
                    } else if (xml) {
                        fprintf(fpo, "<subfield code=\"%c\">", val_buf->str[i]);
                    } else if (!mapfile) {
                        fprintf(fpo, "{\"%c\":\"", val_buf->str[i]);
                    }
                    continue;
                }
                if (xml_buf) {
                    buf_add_xml(xml_buf, val_buf->str[i]);
                } else if (xml) {
                    put_xml(val_buf->str[i], fpo);
                } else if (!mapfile) {
                    put_json(val_buf->str[i], fpo);
                }
            }
            if (!first_sub) {
                if (xml_buf) {
                    buf_add_str(xml_buf, "</subfield>");
                } else if (xml) {
                    fputs("</subfield>", fpo);
                } else if (!mapfile) {
                    fputs("\"}", fpo);
                }
            }
            if (xml_buf) {
                buf_add_str(xml_buf, "</datafield>");
            } else if (xml) {
                fputs("</datafield>", fpo);
            } else if (!mapfile) {
                fputs("]", fpo);
            }
        }
    }

    if (count && mapfile) {
        fputs("{", fpo);
        for (i = 0; i < record.used; i++) {
            field = record.fields + i;
            if (i) putc(',', fpo);
            buf_add(field->val, '\0');
            fprintf(fpo, "\"%s\":[%s]", field->key, field->val->str);
        }
        if (xml_buf) {
            if (i) putc(',', fpo);
            fprintf(fpo, "\"%s\":\"", xml_key);
            put_json_str(xml_buf->str, fpo);
            putc('\"', fpo);
        }
    }

    if (xml) {
        if (count) fputs("</record>", fpo);
        fputs("</collection>", fpo);
    } else {
        if (count) fputs("}", fpo);
        if (array) fputs("]", fpo);
    }

    fclose(fpi);
    fclose(fpo);

    return 0;
}