Blame json_util.c

Packit Service def718
/*
Packit Service def718
 * $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $
Packit Service def718
 *
Packit Service def718
 * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
Packit Service def718
 * Michael Clark <michael@metaparadigm.com>
Packit Service def718
 *
Packit Service def718
 * This library is free software; you can redistribute it and/or modify
Packit Service def718
 * it under the terms of the MIT license. See COPYING for details.
Packit Service def718
 *
Packit Service def718
 */
Packit Service def718
Packit Service def718
#include "config.h"
Packit Service def718
#undef realloc
Packit Service def718
Packit Service def718
#include "strerror_override.h"
Packit Service def718
Packit Service def718
#include <stdarg.h>
Packit Service def718
#include <stdio.h>
Packit Service def718
#include <stdlib.h>
Packit Service def718
#include <stddef.h>
Packit Service def718
#include <limits.h>
Packit Service def718
#include <string.h>
Packit Service def718
#include <ctype.h>
Packit Service def718
Packit Service def718
#ifdef HAVE_SYS_TYPES_H
Packit Service def718
#include <sys/types.h>
Packit Service def718
#endif /* HAVE_SYS_TYPES_H */
Packit Service def718
Packit Service def718
#ifdef HAVE_SYS_STAT_H
Packit Service def718
#include <sys/stat.h>
Packit Service def718
#endif /* HAVE_SYS_STAT_H */
Packit Service def718
Packit Service def718
#ifdef HAVE_FCNTL_H
Packit Service def718
#include <fcntl.h>
Packit Service def718
#endif /* HAVE_FCNTL_H */
Packit Service def718
Packit Service def718
#ifdef HAVE_UNISTD_H
Packit Service def718
# include <unistd.h>
Packit Service def718
#endif /* HAVE_UNISTD_H */
Packit Service def718
Packit Service def718
#ifdef WIN32
Packit Service def718
# if MSC_VER < 1800
Packit Service def718
/* strtoll is available only since Visual Studio 2013 */
Packit Service def718
#  define strtoll _strtoi64
Packit Service def718
# endif
Packit Service def718
# define WIN32_LEAN_AND_MEAN
Packit Service def718
# include <windows.h>
Packit Service def718
# include <io.h>
Packit Service def718
#endif /* defined(WIN32) */
Packit Service def718
Packit Service def718
#if !defined(HAVE_OPEN) && defined(WIN32)
Packit Service def718
# define open _open
Packit Service def718
#endif
Packit Service def718
Packit Service def718
#include "snprintf_compat.h"
Packit Service def718
Packit Service def718
#include "debug.h"
Packit Service def718
#include "printbuf.h"
Packit Service def718
#include "json_inttypes.h"
Packit Service def718
#include "json_object.h"
Packit Service def718
#include "json_tokener.h"
Packit Service def718
#include "json_util.h"
Packit Service def718
Packit Service def718
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename);
Packit Service def718
Packit Service def718
static char _last_err[256] = "";
Packit Service def718
Packit Service def718
const char *json_util_get_last_err()
Packit Service def718
{
Packit Service def718
	if (_last_err[0] == '\0')
Packit Service def718
		return NULL;
Packit Service def718
	return _last_err;
Packit Service def718
}
Packit Service def718
Packit Service def718
void _json_c_set_last_err(const char *err_fmt, ...)
Packit Service def718
{
Packit Service def718
	va_list ap;
Packit Service def718
	va_start(ap, err_fmt);
Packit Service def718
	// Ignore (attempted) overruns from snprintf
Packit Service def718
	(void)vsnprintf(_last_err, sizeof(_last_err), err_fmt, ap);
Packit Service def718
	va_end(ap);
Packit Service def718
}
Packit Service def718
Packit Service def718
struct json_object* json_object_from_fd(int fd)
Packit Service def718
{
Packit Service def718
  struct printbuf *pb;
Packit Service def718
  struct json_object *obj;
Packit Service def718
  char buf[JSON_FILE_BUF_SIZE];
Packit Service def718
  int ret;
Packit Service def718
Packit Service def718
  if(!(pb = printbuf_new())) {
Packit Service def718
    _json_c_set_last_err("json_object_from_file: printbuf_new failed\n");
Packit Service def718
    return NULL;
Packit Service def718
  }
Packit Service def718
  while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
Packit Service def718
    printbuf_memappend(pb, buf, ret);
Packit Service def718
  }
Packit Service def718
  if(ret < 0) {
Packit Service def718
    _json_c_set_last_err("json_object_from_fd: error reading fd %d: %s\n", fd, strerror(errno));
Packit Service def718
    printbuf_free(pb);
Packit Service def718
    return NULL;
Packit Service def718
  }
Packit Service def718
  obj = json_tokener_parse(pb->buf);
Packit Service def718
  printbuf_free(pb);
Packit Service def718
  return obj;
Packit Service def718
}
Packit Service def718
Packit Service def718
struct json_object* json_object_from_file(const char *filename)
Packit Service def718
{
Packit Service def718
  struct json_object *obj;
Packit Service def718
  int fd;
Packit Service def718
Packit Service def718
  if((fd = open(filename, O_RDONLY)) < 0) {
Packit Service def718
    _json_c_set_last_err("json_object_from_file: error opening file %s: %s\n",
Packit Service def718
	     filename, strerror(errno));
Packit Service def718
    return NULL;
Packit Service def718
  }
Packit Service def718
  obj = json_object_from_fd(fd);
Packit Service def718
  close(fd);
Packit Service def718
  return obj;
Packit Service def718
}
Packit Service def718
Packit Service def718
/* extended "format and write to file" function */
Packit Service def718
Packit Service def718
int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags)
Packit Service def718
{
Packit Service def718
	int fd, ret;
Packit Service def718
	int saved_errno;
Packit Service def718
Packit Service def718
	if (!obj) {
Packit Service def718
		_json_c_set_last_err("json_object_to_file: object is null\n");
Packit Service def718
		return -1;
Packit Service def718
	}
Packit Service def718
Packit Service def718
	if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
Packit Service def718
		_json_c_set_last_err("json_object_to_file: error opening file %s: %s\n",
Packit Service def718
		              filename, strerror(errno));
Packit Service def718
		return -1;
Packit Service def718
	}
Packit Service def718
	ret = _json_object_to_fd(fd, obj, flags, filename);
Packit Service def718
	saved_errno = errno;
Packit Service def718
	close(fd);
Packit Service def718
	errno = saved_errno;
Packit Service def718
	return ret;
Packit Service def718
}
Packit Service def718
Packit Service def718
int json_object_to_fd(int fd, struct json_object *obj, int flags)
Packit Service def718
{
Packit Service def718
	if (!obj) {
Packit Service def718
		_json_c_set_last_err("json_object_to_fd: object is null\n");
Packit Service def718
		return -1;
Packit Service def718
	}
Packit Service def718
Packit Service def718
	return _json_object_to_fd(fd, obj, flags, NULL);
Packit Service def718
}
Packit Service def718
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename)
Packit Service def718
{
Packit Service def718
	int ret;
Packit Service def718
	const char *json_str;
Packit Service def718
	unsigned int wpos, wsize;
Packit Service def718
Packit Service def718
	filename = filename ? filename : "(fd)";
Packit Service def718
Packit Service def718
	if (!(json_str = json_object_to_json_string_ext(obj,flags))) {
Packit Service def718
		return -1;
Packit Service def718
	}
Packit Service def718
Packit Service def718
	wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
Packit Service def718
	wpos = 0;
Packit Service def718
	while(wpos < wsize) {
Packit Service def718
		if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
Packit Service def718
		  _json_c_set_last_err("json_object_to_file: error writing file %s: %s\n",
Packit Service def718
			 filename, strerror(errno));
Packit Service def718
		  return -1;
Packit Service def718
		}
Packit Service def718
Packit Service def718
		/* because of the above check for ret < 0, we can safely cast and add */
Packit Service def718
		wpos += (unsigned int)ret;
Packit Service def718
	}
Packit Service def718
Packit Service def718
	return 0;
Packit Service def718
}
Packit Service def718
Packit Service def718
// backwards compatible "format and write to file" function
Packit Service def718
Packit Service def718
int json_object_to_file(const char *filename, struct json_object *obj)
Packit Service def718
{
Packit Service def718
  return json_object_to_file_ext(filename, obj, JSON_C_TO_STRING_PLAIN);
Packit Service def718
}
Packit Service def718
Packit Service def718
int json_parse_double(const char *buf, double *retval)
Packit Service def718
{
Packit Service def718
  char *end;
Packit Service def718
  *retval = strtod(buf, &end;;
Packit Service def718
  return end == buf ? 1 : 0;
Packit Service def718
}
Packit Service def718
Packit Service def718
int json_parse_int64(const char *buf, int64_t *retval)
Packit Service def718
{
Packit Service def718
	char *end = NULL;
Packit Service def718
	int64_t val;
Packit Service def718
Packit Service def718
	errno = 0;
Packit Service def718
	val = strtoll(buf, &end, 10);
Packit Service def718
	if (end != buf)
Packit Service def718
		*retval = val;
Packit Service def718
	return ((val == 0 && errno != 0) || (end == buf)) ? 1 : 0;
Packit Service def718
}
Packit Service def718
Packit Service def718
#ifndef HAVE_REALLOC
Packit Service def718
void* rpl_realloc(void* p, size_t n)
Packit Service def718
{
Packit Service def718
	if (n == 0)
Packit Service def718
		n = 1;
Packit Service def718
	if (p == 0)
Packit Service def718
		return malloc(n);
Packit Service def718
	return realloc(p, n);
Packit Service def718
}
Packit Service def718
#endif
Packit Service def718
Packit Service def718
#define NELEM(a)        (sizeof(a) / sizeof(a[0]))
Packit Service def718
static const char* json_type_name[] = {
Packit Service def718
  /* If you change this, be sure to update the enum json_type definition too */
Packit Service def718
  "null",
Packit Service def718
  "boolean",
Packit Service def718
  "double",
Packit Service def718
  "int",
Packit Service def718
  "object",
Packit Service def718
  "array",
Packit Service def718
  "string",
Packit Service def718
};
Packit Service def718
Packit Service def718
const char *json_type_to_name(enum json_type o_type)
Packit Service def718
{
Packit Service def718
	int o_type_int = (int)o_type;
Packit Service def718
	if (o_type_int < 0 || o_type_int >= (int)NELEM(json_type_name))
Packit Service def718
	{
Packit Service def718
		_json_c_set_last_err("json_type_to_name: type %d is out of range [0,%d]\n", o_type, NELEM(json_type_name));
Packit Service def718
		return NULL;
Packit Service def718
	}
Packit Service def718
	return json_type_name[o_type];
Packit Service def718
}
Packit Service def718