Issue #161: add a json_object_to_fd() function.

This commit is contained in:
Eric Haszlakiewicz
2017-06-18 18:44:45 +00:00
parent 23e064ad29
commit e8e574fbe4
4 changed files with 96 additions and 31 deletions

View File

@@ -65,6 +65,8 @@ static int sscanf_is_broken = 0;
static int sscanf_is_broken_testdone = 0; static int sscanf_is_broken_testdone = 0;
static void sscanf_is_broken_test(void); static void sscanf_is_broken_test(void);
static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename);
static char _last_err[256] = ""; static char _last_err[256] = "";
const char *json_util_get_last_err() const char *json_util_get_last_err()
@@ -126,42 +128,61 @@ struct json_object* json_object_from_file(const char *filename)
int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags) int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags)
{ {
const char *json_str; int fd, ret;
int fd, ret; int saved_errno;
unsigned int wpos, wsize;
if(!obj) { if (!obj) {
_set_last_err("json_object_to_file: object is null\n"); _set_last_err("json_object_to_file: object is null\n");
return -1; return -1;
} }
if((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) { if ((fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, 0644)) < 0) {
_set_last_err("json_object_to_file: error opening file %s: %s\n", _set_last_err("json_object_to_file: error opening file %s: %s\n",
filename, strerror(errno)); filename, strerror(errno));
return -1; return -1;
} }
ret = _json_object_to_fd(fd, obj, flags, filename);
saved_errno = errno;
close(fd);
errno = saved_errno;
return ret;
}
if(!(json_str = json_object_to_json_string_ext(obj,flags))) { int json_object_to_fd(int fd, struct json_object *obj, int flags)
close(fd); {
return -1; if (!obj) {
} _set_last_err("json_object_to_fd: object is null\n");
return -1;
}
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */ return _json_object_to_fd(fd, obj, flags, NULL);
wpos = 0; }
while(wpos < wsize) { static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename)
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) { {
close(fd); int ret;
_set_last_err("json_object_to_file: error writing file %s: %s\n", const char *json_str;
filename, strerror(errno)); unsigned int wpos, wsize;
return -1;
}
/* because of the above check for ret < 0, we can safely cast and add */ filename = filename ? filename : "(fd)";
wpos += (unsigned int)ret;
}
close(fd); if (!(json_str = json_object_to_json_string_ext(obj,flags))) {
return 0; return -1;
}
wsize = (unsigned int)(strlen(json_str) & UINT_MAX); /* CAW: probably unnecessary, but the most 64bit safe */
wpos = 0;
while(wpos < wsize) {
if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
_set_last_err("json_object_to_file: error writing file %s: %s\n",
filename, strerror(errno));
return -1;
}
/* because of the above check for ret < 0, we can safely cast and add */
wpos += (unsigned int)ret;
}
return 0;
} }
// backwards compatible "format and write to file" function // backwards compatible "format and write to file" function

View File

@@ -67,7 +67,18 @@ extern int json_object_to_file(const char *filename, struct json_object *obj);
extern int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags); extern int json_object_to_file_ext(const char *filename, struct json_object *obj, int flags);
/** /**
* Return the last error from json_object_to_file{,_ext} or * Convert the json_object to a string and write it to the file descriptor.
* Handles partial writes and will keep writing until done, or an error
* occurs.
*
* @param flags flags to pass to json_object_to_json_string_ext()
* @return -1 if something fails. See json_util_get_last_err() for details.
*/
extern int json_object_to_fd(int fd, struct json_object *obj, int flags);
/**
* Return the last error from json_object_to_file{,_ext},
* json_object_to_fd() or
* json_object_from_{file,fd}, or NULL if there is none. * json_object_from_{file,fd}, or NULL if there is none.
*/ */
const char *json_util_get_last_err(void); const char *json_util_get_last_err(void);

View File

@@ -49,6 +49,25 @@ static void test_write_to_file()
(rv == 0) ? "OK" : "FAIL", outfile2, rv); (rv == 0) ? "OK" : "FAIL", outfile2, rv);
if (rv == 0) if (rv == 0)
stat_and_cat(outfile2); stat_and_cat(outfile2);
const char *outfile3 = "json3.out";
int d = open(outfile3, O_WRONLY|O_CREAT, 0600);
if (d < 0)
{
printf("FAIL: unable to open %s %s\n", outfile3, strerror(errno));
return;
}
rv = json_object_to_fd(d, jso, JSON_C_TO_STRING_PRETTY);
printf("%s: json_object_to_fd(%s, jso, JSON_C_TO_STRING_PRETTY)=%d\n",
(rv == 0) ? "OK" : "FAIL", outfile3, rv);
// Write the same object twice
rv = json_object_to_fd(d, jso, JSON_C_TO_STRING_PLAIN);
printf("%s: json_object_to_fd(%s, jso, JSON_C_TO_STRING_PLAIN)=%d\n",
(rv == 0) ? "OK" : "FAIL", outfile3, rv);
close(d);
if (rv == 0)
stat_and_cat(outfile3);
json_object_put(jso); json_object_put(jso);
} }

View File

@@ -19,3 +19,17 @@ file[json2.out], size=367, contents={
"foo8":"abcdefghijklmnopqrstuvwxyz", "foo8":"abcdefghijklmnopqrstuvwxyz",
"foo9":"abcdefghijklmnopqrstuvwxyz" "foo9":"abcdefghijklmnopqrstuvwxyz"
} }
OK: json_object_to_fd(json3.out, jso, JSON_C_TO_STRING_PRETTY)=0
OK: json_object_to_fd(json3.out, jso, JSON_C_TO_STRING_PLAIN)=0
file[json3.out], size=703, contents={
"foo":1234,
"foo1":"abcdefghijklmnopqrstuvwxyz",
"foo2":"abcdefghijklmnopqrstuvwxyz",
"foo3":"abcdefghijklmnopqrstuvwxyz",
"foo4":"abcdefghijklmnopqrstuvwxyz",
"foo5":"abcdefghijklmnopqrstuvwxyz",
"foo6":"abcdefghijklmnopqrstuvwxyz",
"foo7":"abcdefghijklmnopqrstuvwxyz",
"foo8":"abcdefghijklmnopqrstuvwxyz",
"foo9":"abcdefghijklmnopqrstuvwxyz"
}{"foo":1234,"foo1":"abcdefghijklmnopqrstuvwxyz","foo2":"abcdefghijklmnopqrstuvwxyz","foo3":"abcdefghijklmnopqrstuvwxyz","foo4":"abcdefghijklmnopqrstuvwxyz","foo5":"abcdefghijklmnopqrstuvwxyz","foo6":"abcdefghijklmnopqrstuvwxyz","foo7":"abcdefghijklmnopqrstuvwxyz","foo8":"abcdefghijklmnopqrstuvwxyz","foo9":"abcdefghijklmnopqrstuvwxyz"}