Linux Audio

Check our new training course

Loading...
v4.17
  1/* Parse JSON files using the JSMN parser. */
  2
  3/*
  4 * Copyright (c) 2014, Intel Corporation
  5 * All rights reserved.
  6 *
  7 * Redistribution and use in source and binary forms, with or without
  8 * modification, are permitted provided that the following conditions are met:
  9 *
 10 * 1. Redistributions of source code must retain the above copyright notice,
 11 * this list of conditions and the following disclaimer.
 12 *
 13 * 2. Redistributions in binary form must reproduce the above copyright
 14 * notice, this list of conditions and the following disclaimer in the
 15 * documentation and/or other materials provided with the distribution.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 28 * OF THE POSSIBILITY OF SUCH DAMAGE.
 29*/
 30
 31#include <stdlib.h>
 32#include <string.h>
 33#include <sys/mman.h>
 34#include <sys/stat.h>
 35#include <fcntl.h>
 36#include <stdio.h>
 37#include <errno.h>
 38#include <unistd.h>
 39#include "jsmn.h"
 40#include "json.h"
 41#include <linux/kernel.h>
 42
 43
 44static char *mapfile(const char *fn, size_t *size)
 45{
 46	unsigned ps = sysconf(_SC_PAGESIZE);
 47	struct stat st;
 48	char *map = NULL;
 49	int err;
 50	int fd = open(fn, O_RDONLY);
 51
 52	if (fd < 0 && verbose > 0 && fn) {
 53		pr_err("Error opening events file '%s': %s\n", fn,
 54				strerror(errno));
 55	}
 56
 57	if (fd < 0)
 58		return NULL;
 59	err = fstat(fd, &st);
 60	if (err < 0)
 61		goto out;
 62	*size = st.st_size;
 63	map = mmap(NULL,
 64		   (st.st_size + ps - 1) & ~(ps - 1),
 65		   PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
 66	if (map == MAP_FAILED)
 67		map = NULL;
 68out:
 69	close(fd);
 70	return map;
 71}
 72
 73static void unmapfile(char *map, size_t size)
 74{
 75	unsigned ps = sysconf(_SC_PAGESIZE);
 76	munmap(map, roundup(size, ps));
 77}
 78
 79/*
 80 * Parse json file using jsmn. Return array of tokens,
 81 * and mapped file. Caller needs to free array.
 82 */
 83jsmntok_t *parse_json(const char *fn, char **map, size_t *size, int *len)
 84{
 85	jsmn_parser parser;
 86	jsmntok_t *tokens;
 87	jsmnerr_t res;
 88	unsigned sz;
 89
 90	*map = mapfile(fn, size);
 91	if (!*map)
 92		return NULL;
 93	/* Heuristic */
 94	sz = *size * 16;
 95	tokens = malloc(sz);
 96	if (!tokens)
 97		goto error;
 98	jsmn_init(&parser);
 99	res = jsmn_parse(&parser, *map, *size, tokens,
100			 sz / sizeof(jsmntok_t));
101	if (res != JSMN_SUCCESS) {
102		pr_err("%s: json error %s\n", fn, jsmn_strerror(res));
103		goto error_free;
104	}
105	if (len)
106		*len = parser.toknext;
107	return tokens;
108error_free:
109	free(tokens);
110error:
111	unmapfile(*map, *size);
112	return NULL;
113}
114
115void free_json(char *map, size_t size, jsmntok_t *tokens)
116{
117	free(tokens);
118	unmapfile(map, size);
119}
120
121static int countchar(char *map, char c, int end)
122{
123	int i;
124	int count = 0;
125	for (i = 0; i < end; i++)
126		if (map[i] == c)
127			count++;
128	return count;
129}
130
131/* Return line number of a jsmn token */
132int json_line(char *map, jsmntok_t *t)
133{
134	return countchar(map, '\n', t->start) + 1;
135}
136
137static const char * const jsmn_types[] = {
138	[JSMN_PRIMITIVE] = "primitive",
139	[JSMN_ARRAY] = "array",
140	[JSMN_OBJECT] = "object",
141	[JSMN_STRING] = "string"
142};
143
144#define LOOKUP(a, i) ((i) < (sizeof(a)/sizeof(*(a))) ? ((a)[i]) : "?")
145
146/* Return type name of a jsmn token */
147const char *json_name(jsmntok_t *t)
148{
149	return LOOKUP(jsmn_types, t->type);
150}
151
152int json_len(jsmntok_t *t)
153{
154	return t->end - t->start;
155}
156
157/* Is string t equal to s? */
158int json_streq(char *map, jsmntok_t *t, const char *s)
159{
160	unsigned len = json_len(t);
161	return len == strlen(s) && !strncasecmp(map + t->start, s, len);
162}
v5.4
  1/* Parse JSON files using the JSMN parser. */
  2
  3/*
  4 * Copyright (c) 2014, Intel Corporation
  5 * All rights reserved.
  6 *
  7 * Redistribution and use in source and binary forms, with or without
  8 * modification, are permitted provided that the following conditions are met:
  9 *
 10 * 1. Redistributions of source code must retain the above copyright notice,
 11 * this list of conditions and the following disclaimer.
 12 *
 13 * 2. Redistributions in binary form must reproduce the above copyright
 14 * notice, this list of conditions and the following disclaimer in the
 15 * documentation and/or other materials provided with the distribution.
 16 *
 17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 21 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 28 * OF THE POSSIBILITY OF SUCH DAMAGE.
 29*/
 30
 31#include <stdlib.h>
 32#include <string.h>
 33#include <sys/mman.h>
 34#include <sys/stat.h>
 35#include <fcntl.h>
 36#include <stdio.h>
 37#include <errno.h>
 38#include <unistd.h>
 39#include "jsmn.h"
 40#include "json.h"
 41#include <linux/kernel.h>
 42
 43
 44static char *mapfile(const char *fn, size_t *size)
 45{
 46	unsigned ps = sysconf(_SC_PAGESIZE);
 47	struct stat st;
 48	char *map = NULL;
 49	int err;
 50	int fd = open(fn, O_RDONLY);
 51
 52	if (fd < 0 && verbose > 0 && fn) {
 53		pr_err("Error opening events file '%s': %s\n", fn,
 54				strerror(errno));
 55	}
 56
 57	if (fd < 0)
 58		return NULL;
 59	err = fstat(fd, &st);
 60	if (err < 0)
 61		goto out;
 62	*size = st.st_size;
 63	map = mmap(NULL,
 64		   (st.st_size + ps - 1) & ~(ps - 1),
 65		   PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
 66	if (map == MAP_FAILED)
 67		map = NULL;
 68out:
 69	close(fd);
 70	return map;
 71}
 72
 73static void unmapfile(char *map, size_t size)
 74{
 75	unsigned ps = sysconf(_SC_PAGESIZE);
 76	munmap(map, roundup(size, ps));
 77}
 78
 79/*
 80 * Parse json file using jsmn. Return array of tokens,
 81 * and mapped file. Caller needs to free array.
 82 */
 83jsmntok_t *parse_json(const char *fn, char **map, size_t *size, int *len)
 84{
 85	jsmn_parser parser;
 86	jsmntok_t *tokens;
 87	jsmnerr_t res;
 88	unsigned sz;
 89
 90	*map = mapfile(fn, size);
 91	if (!*map)
 92		return NULL;
 93	/* Heuristic */
 94	sz = *size * 16;
 95	tokens = malloc(sz);
 96	if (!tokens)
 97		goto error;
 98	jsmn_init(&parser);
 99	res = jsmn_parse(&parser, *map, *size, tokens,
100			 sz / sizeof(jsmntok_t));
101	if (res != JSMN_SUCCESS) {
102		pr_err("%s: json error %s\n", fn, jsmn_strerror(res));
103		goto error_free;
104	}
105	if (len)
106		*len = parser.toknext;
107	return tokens;
108error_free:
109	free(tokens);
110error:
111	unmapfile(*map, *size);
112	return NULL;
113}
114
115void free_json(char *map, size_t size, jsmntok_t *tokens)
116{
117	free(tokens);
118	unmapfile(map, size);
119}
120
121static int countchar(char *map, char c, int end)
122{
123	int i;
124	int count = 0;
125	for (i = 0; i < end; i++)
126		if (map[i] == c)
127			count++;
128	return count;
129}
130
131/* Return line number of a jsmn token */
132int json_line(char *map, jsmntok_t *t)
133{
134	return countchar(map, '\n', t->start) + 1;
135}
136
137static const char * const jsmn_types[] = {
138	[JSMN_PRIMITIVE] = "primitive",
139	[JSMN_ARRAY] = "array",
140	[JSMN_OBJECT] = "object",
141	[JSMN_STRING] = "string"
142};
143
144#define LOOKUP(a, i) ((i) < (sizeof(a)/sizeof(*(a))) ? ((a)[i]) : "?")
145
146/* Return type name of a jsmn token */
147const char *json_name(jsmntok_t *t)
148{
149	return LOOKUP(jsmn_types, t->type);
150}
151
152int json_len(jsmntok_t *t)
153{
154	return t->end - t->start;
155}
156
157/* Is string t equal to s? */
158int json_streq(char *map, jsmntok_t *t, const char *s)
159{
160	unsigned len = json_len(t);
161	return len == strlen(s) && !strncasecmp(map + t->start, s, len);
162}