2 * $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $
4 * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5 * Michael Clark <michael@metaparadigm.com>
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the MIT license. See COPYING for details.
15 #include "strerror_override.h"
25 #ifdef HAVE_SYS_TYPES_H
26 #include <sys/types.h>
27 #endif /* HAVE_SYS_TYPES_H */
29 #ifdef HAVE_SYS_STAT_H
31 #endif /* HAVE_SYS_STAT_H */
35 #endif /* HAVE_FCNTL_H */
39 #endif /* HAVE_UNISTD_H */
43 /* strtoll is available only since Visual Studio 2013 */
44 # define strtoll _strtoi64
46 # define WIN32_LEAN_AND_MEAN
49 #endif /* defined(WIN32) */
51 #if !defined(HAVE_OPEN) && defined(WIN32)
55 #include "snprintf_compat.h"
59 #include "json_inttypes.h"
60 #include "json_object.h"
61 #include "json_tokener.h"
62 #include "json_util.h"
64 static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename);
66 static char _last_err[256] = "";
68 const char *json_util_get_last_err()
70 if (_last_err[0] == '\0')
75 void _json_c_set_last_err(const char *err_fmt, ...)
78 va_start(ap, err_fmt);
79 // Ignore (attempted) overruns from snprintf
80 (void)vsnprintf(_last_err, sizeof(_last_err), err_fmt, ap);
84 struct json_object* json_object_from_fd(int fd)
87 struct json_object *obj;
88 char buf[JSON_FILE_BUF_SIZE];
91 if(!(pb = printbuf_new())) {
92 _json_c_set_last_err("json_object_from_file: printbuf_new failed\n");
95 while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
96 printbuf_memappend(pb, buf, ret);
99 _json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, strerror(errno));
103 obj = json_tokener_parse(pb->buf);
108 struct json_object* json_object_from_file(const char *filename)
110 struct json_object *obj;
113 if((fd = open(filename, O_RDONLY)) < 0) {
114 _json_c_set_last_err("json_object_from_file: error opening file %s: %s\n",
115 filename, strerror(errno));
118 obj = json_object_from_fd(fd);
123 /* extended "format and write to file" function */
125 int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags)
131 _json_c_set_last_err("json_object_to_file: object is null\n");
135 if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
136 _json_c_set_last_err("json_object_to_file: error opening file %s: %s\n",
137 filename, strerror(errno));
140 ret = _json_object_to_fd(fd, obj, flags, filename);
147 int json_object_to_fd(int fd, struct json_object *obj, int flags)
150 _json_c_set_last_err("json_object_to_fd: object is null\n");
154 return _json_object_to_fd(fd, obj, flags, NULL);
156 static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename)
159 const char *json_str;
160 unsigned int wpos, wsize;
162 filename = filename ? filename : "(fd)";
164 if (!(json_str = json_object_to_json_string_ext(obj,flags))) {
168 wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
170 while(wpos < wsize) {
171 if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
172 _json_c_set_last_err("json_object_to_file: error writing file %s: %s\n",
173 filename, strerror(errno));
177 /* because of the above check for ret < 0, we can safely cast and add */
178 wpos += (unsigned int)ret;
184 // backwards compatible "format and write to file" function
186 int json_object_to_file(const char *filename, struct json_object *obj)
188 return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
191 int json_parse_double(const char *buf, double *retval)
194 *retval = strtod(buf, &end);
195 return end == buf ? 1 : 0;
198 int json_parse_int64(const char *buf, int64_t *retval)
204 val = strtoll(buf, &end, 10);
207 return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0;
211 void* rpl_realloc(void* p, size_t n)
217 return realloc(p, n);
221 #define NELEM(a) (sizeof(a) / sizeof(a[0]))
222 static const char* json_type_name[] = {
223 /* If you change this, be sure to update the enum json_type definition too */
233 const char *json_type_to_name(enum json_type o_type)
235 int o_type_int = (int)o_type;
236 if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
238 _json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type, NELEM(json_type_name));
241 return json_type_name[o_type];