1 : /*
2 : * $Id: json_util.c,v 1.4 2006/01/30 23:07:57 mclark Exp $
3 : *
4 : * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
5 : * Michael Clark <michael@metaparadigm.com>
6 : *
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.
9 : *
10 : */
11 :
12 : #include "config.h"
13 :
14 : #include <stdio.h>
15 : #include <stdlib.h>
16 : #include <stddef.h>
17 : #include <limits.h>
18 : #include <string.h>
19 : #include <errno.h>
20 :
21 : #if HAVE_SYS_TYPES_H
22 : #include <sys/types.h>
23 : #endif /* HAVE_SYS_TYPES_H */
24 :
25 : #if HAVE_SYS_STAT_H
26 : #include <sys/stat.h>
27 : #endif /* HAVE_SYS_STAT_H */
28 :
29 : #if HAVE_FCNTL_H
30 : #include <fcntl.h>
31 : #endif /* HAVE_FCNTL_H */
32 :
33 : #if HAVE_UNISTD_H
34 : # include <unistd.h>
35 : #endif /* HAVE_UNISTD_H */
36 :
37 : #ifdef WIN32
38 : # define WIN32_LEAN_AND_MEAN
39 : # include <windows.h>
40 : # include <io.h>
41 : #endif /* defined(WIN32) */
42 :
43 : #if !HAVE_OPEN && defined(WIN32)
44 : # define open _open
45 : #endif
46 :
47 :
48 : #include "bits.h"
49 : #include "debug.h"
50 : #include "printbuf.h"
51 : #include "json_object.h"
52 : #include "json_tokener.h"
53 : #include "json_util.h"
54 :
55 122 : struct json_object* json_object_from_file(char *filename)
56 : {
57 : struct printbuf *pb;
58 : struct json_object *obj;
59 : char buf[JSON_FILE_BUF_SIZE];
60 : int fd, ret;
61 :
62 122 : if((fd = open(filename, O_RDONLY)) < 0) {
63 : MC_ERROR("json_object_from_file: error reading file %s: %s\n",
64 : filename, strerror(errno));
65 8 : return (struct json_object*)error_ptr(-1);
66 : }
67 114 : if(!(pb = printbuf_new())) {
68 : MC_ERROR("json_object_from_file: printbuf_new failed\n");
69 0 : return (struct json_object*)error_ptr(-1);
70 : }
71 342 : while((ret = read(fd, buf, JSON_FILE_BUF_SIZE)) > 0) {
72 114 : printbuf_memappend(pb, buf, ret);
73 : }
74 114 : close(fd);
75 114 : if(ret < 0) {
76 : MC_ABORT("json_object_from_file: error reading file %s: %s\n",
77 : filename, strerror(errno));
78 0 : printbuf_free(pb);
79 0 : return (struct json_object*)error_ptr(-1);
80 : }
81 114 : obj = json_tokener_parse(pb->buf);
82 114 : printbuf_free(pb);
83 114 : return obj;
84 : }
85 :
86 19 : int json_object_to_file(char *filename, struct json_object *obj)
87 : {
88 : const char *json_str;
89 : int fd, ret;
90 : unsigned int wpos, wsize;
91 :
92 19 : if(!obj) {
93 : MC_ERROR("json_object_to_file: object is null\n");
94 0 : return -1;
95 : }
96 :
97 19 : if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
98 : MC_ERROR("json_object_to_file: error opening file %s: %s\n",
99 : filename, strerror(errno));
100 2 : return -1;
101 : }
102 :
103 17 : if(!(json_str = json_object_to_json_string(obj))) { return -1; }
104 :
105 :
106 17 : wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
107 17 : wpos = 0;
108 51 : while(wpos < wsize) {
109 17 : if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
110 0 : close(fd);
111 : MC_ERROR("json_object_to_file: error writing file %s: %s\n",
112 : filename, strerror(errno));
113 0 : return -1;
114 : }
115 :
116 : /* because of the above check for ret < 0, we can safely cast and add */
117 17 : wpos += (unsigned int)ret;
118 : }
119 :
120 17 : close(fd);
121 17 : return 0;
122 : }
|