]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
Issue #161: add a json_object_to_fd() function.
authorEric Haszlakiewicz <erh+git@nimenees.com>
Sun, 18 Jun 2017 18:44:45 +0000 (18:44 +0000)
committerEric Haszlakiewicz <erh+git@nimenees.com>
Sun, 18 Jun 2017 18:44:45 +0000 (18:44 +0000)
json_util.c
json_util.h
tests/test_util_file.c
tests/test_util_file.expected

index d7351dd6f98fe09096a5e90eeb355afb143bb4c4..9a2f9ff5b67eae5faf7cf6da57b8b73c15310d8c 100644 (file)
@@ -65,6 +65,8 @@ static int sscanf_is_broken = 0;
 static int sscanf_is_broken_testdone = 0;
 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] = "";
 
 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)
 {
-  const char *json_str;
-  int fd, ret;
-  unsigned int wpos, wsize;
+       int fd, ret;
+       int saved_errno;
 
-  if(!obj) {
-    _set_last_err("json_object_to_file: object is null\n");
-    return -1;
-  }
+       if (!obj) {
+               _set_last_err("json_object_to_file: object is null\n");
+               return -1;
+       }
 
-  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",
-            filename, strerror(errno));
-    return -1;
-  }
+       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",
+                             filename, strerror(errno));
+               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))) {
-    close(fd);
-    return -1;
-  }
+int json_object_to_fd(int fd, struct json_object *obj, int flags)
+{
+       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 */
-  wpos = 0;
-  while(wpos < wsize) {
-    if((ret = write(fd, json_str + wpos, wsize-wpos)) < 0) {
-      close(fd);
-      _set_last_err("json_object_to_file: error writing file %s: %s\n",
-            filename, strerror(errno));
-      return -1;
-    }
+       return _json_object_to_fd(fd, obj, flags, NULL);
+}
+static int _json_object_to_fd(int fd, struct json_object *obj, int flags, const char *filename)
+{
+       int ret;
+       const char *json_str;
+       unsigned int wpos, wsize;
 
-       /* because of the above check for ret < 0, we can safely cast and add */
-    wpos += (unsigned int)ret;
-  }
+       filename = filename ? filename : "(fd)";
 
-  close(fd);
-  return 0;
+       if (!(json_str = json_object_to_json_string_ext(obj,flags))) {
+               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
index a9132787bb0621e888e3888bed5ee59b0a78ab3f..d8926db9db09c128ff2869057202cc8a50b9c836 100644 (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);
 
 /**
- * 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.
  */
 const char *json_util_get_last_err(void);
index 1b4b066d89af79ba3468309743b85a6a6f2e167c..f98dce2e5c9e2fb75ddf51afc8ec5866c4d3c348 100644 (file)
@@ -49,6 +49,25 @@ static void test_write_to_file()
               (rv == 0) ? "OK" : "FAIL", outfile2, rv);
        if (rv == 0)
                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);
 }
 
index 09121b9959ae30bb6bb6ed423427d9d40276a062..f64a5a500dc12957969744f2fafb5373c60c2e6e 100644 (file)
@@ -19,3 +19,17 @@ file[json2.out], size=367, contents={
   "foo8":"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"}