diff options
| author | Ben Pfaff <blp@nicira.com> | 2009-11-04 14:55:53 -0800 |
|---|---|---|
| committer | Ben Pfaff <blp@nicira.com> | 2009-11-04 15:24:40 -0800 |
| commit | f38b84ea2b6b61d309c604faedd41ab3b0fcf16b (patch) | |
| tree | b7f130e0f5c5da46840716560905252a6d0762de /tests/test-json.c | |
| parent | e7f1bf58e44a3449ba6dcf637a51191006bd2324 (diff) | |
| download | openvswitch-f38b84ea2b6b61d309c604faedd41ab3b0fcf16b.tar.gz | |
Implement JSON parsing and serialization.
This will be used by the upcoming Open vSwitch configuration database.
Diffstat (limited to 'tests/test-json.c')
| -rw-r--r-- | tests/test-json.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/tests/test-json.c b/tests/test-json.c new file mode 100644 index 000000000..bb9fadb06 --- /dev/null +++ b/tests/test-json.c @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2009 Nicira Networks. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <config.h> + +#include "json.h" + +#include <ctype.h> +#include <errno.h> +#include <getopt.h> +#include <stdio.h> + +#include "util.h" + +/* --pretty: If set, the JSON output is pretty-printed, instead of printed as + * compactly as possible. */ +static int pretty = 0; + +/* --multiple: If set, the input is a sequence of JSON objects or arrays, + * instead of exactly one object or array. */ +static int multiple = 0; + +static bool +print_and_free_json(struct json *json) +{ + bool ok; + if (json->type == JSON_STRING) { + printf("error: %s\n", json->u.string); + ok = false; + } else { + char *s = json_to_string(json, JSSF_SORT | (pretty ? JSSF_PRETTY : 0)); + puts(s); + free(s); + ok = true; + } + json_destroy(json); + return ok; +} + +static bool +refill(FILE *file, void *buffer, size_t buffer_size, size_t *n, size_t *used) +{ + *used = 0; + if (feof(file)) { + *n = 0; + return false; + } else { + *n = fread(buffer, 1, buffer_size, file); + if (ferror(file)) { + ovs_fatal(errno, "Error reading input file"); + } + return *n > 0; + } +} + +static bool +parse_multiple(const char *input_file) +{ + struct json_parser *parser; + char buffer[BUFSIZ]; + size_t n, used; + FILE *file; + bool ok; + + file = fopen(input_file, "r"); + if (!file) { + ovs_fatal(errno, "Cannot open \"%s\"", input_file); + } + + parser = NULL; + n = used = 0; + ok = true; + while (used < n || refill(file, buffer, sizeof buffer, &n, &used)) { + if (!parser && isspace((unsigned char) buffer[used])) { + /* Skip white space. */ + used++; + } else { + if (!parser) { + parser = json_parser_create(0); + } + + used = n - json_parser_feed(parser, &buffer[used], n - used); + if (used < n) { + if (!print_and_free_json(json_parser_finish(parser))) { + ok = false; + } + parser = NULL; + } + } + } + if (parser) { + if (!print_and_free_json(json_parser_finish(parser))) { + ok = false; + } + } + return ok; +} + +int +main(int argc, char *argv[]) +{ + const char *input_file; + bool ok; + + set_program_name(argv[0]); + + for (;;) { + static const struct option options[] = { + {"pretty", no_argument, &pretty, 1}, + {"multiple", no_argument, &multiple, 1}, + }; + int option_index = 0; + int c = getopt_long (argc, argv, "", options, &option_index); + + if (c == -1) { + break; + } + switch (c) { + case 0: + break; + + case '?': + exit(1); + + default: + abort(); + } + } + + if (argc - optind != 1) { + ovs_fatal(0, "usage: %s [--pretty] [--multiple] INPUT.json", + program_name); + } + + input_file = argv[optind]; + if (!strcmp(input_file, "-")) { + input_file = "/dev/stdin"; + } + + if (multiple) { + ok = parse_multiple(input_file); + } else { + ok = print_and_free_json(json_from_file(input_file)); + } + + return !ok; +} |
