Browse Source

introduce json_object_new_string_noalloc()

On some low memory systems, calling malloc (by the use of strdup) causes
memory fragmentation which eventually results in out of memory
situation. using json_object_new_string_noalloc helps to solve this
issue.

also add basic test for json_object_new_string_noalloc
pull/476/head
Mehmet Akif TASOVA 6 years ago
parent
commit
7f3850e6bc
6 changed files with 81 additions and 0 deletions
  1. +17
    -0
      json_object.c
  2. +13
    -0
      json_object.h
  3. +1
    -0
      tests/Makefile.am
  4. +48
    -0
      tests/test_string_noalloc.c
  5. +1
    -0
      tests/test_string_noalloc.expected
  6. +1
    -0
      tests/test_string_noalloc.test

+ 17
- 0
json_object.c View File

@@ -1015,6 +1015,23 @@ static void json_object_string_delete(struct json_object* jso)
json_object_generic_delete(jso);
}

struct json_object* json_object_new_string_noalloc(char *s)
{
struct json_object *jso = json_object_new(json_type_string);
if (!jso)
return NULL;
jso->_delete = &json_object_string_delete;
jso->_to_json_string = &json_object_string_to_json_string;
jso->o.c_string.len = strlen(s);
if(jso->o.c_string.len < LEN_DIRECT_STRING_DATA) {
memcpy(jso->o.c_string.str.data, s, jso->o.c_string.len);
free(s);
} else {
jso->o.c_string.str.ptr = s;
}
return jso;
}

struct json_object* json_object_new_string(const char *s)
{
struct json_object *jso = json_object_new(json_type_string);


+ 13
- 0
json_object.h View File

@@ -893,6 +893,19 @@ JSON_EXPORT int json_object_set_double(struct json_object *obj,double new_value)

/* string type methods */

/** Create a new empty json_object of type json_type_string
*
* Use given string as is, do not call malloc if given string is longer
* than internal buffer size. Ownership of s will be transferred to
* json_object and s will be freed when json_object_put decided to free
* memory of json_object.
*
* @param s the string, must be heap alloacted and must not be freed.
* @returns a json_object of type json_type_string
* @see json_object_new_string_len()
*/
JSON_EXPORT struct json_object* json_object_new_string_noalloc(char *s);

/** Create a new empty json_object of type json_type_string
*
* A copy of the string is made and the memory is managed by the json_object


+ 1
- 0
tests/Makefile.am View File

@@ -27,6 +27,7 @@ TESTS+= test_set_value.test
TESTS+= test_visit.test
TESTS+= test_json_pointer.test
TESTS+= test_int_add.test
TESTS+= test_string_noalloc.test

check_PROGRAMS=
check_PROGRAMS += $(TESTS:.test=)


+ 48
- 0
tests/test_string_noalloc.c View File

@@ -0,0 +1,48 @@
/*
* Tests if binary strings are supported.
*/

#include <stdio.h>
#include <string.h>
#include <string.h>
#include "config.h"

#include "json_inttypes.h"
#include "json_object.h"
#include "json_tokener.h"

int main(void)
{
/* this test has a space after the null character. check that it's still included */
char *str1 = strdup("This string should be longer than 32 characters");
char *str2 = strdup("this string is short");
struct json_object *jso_str = NULL;

if (!str1 || !str2)
{
puts("FAIL: strdup() returned NULL");
return 1;
}

jso_str = json_object_new_string_noalloc(str1);
if (!jso_str)
{
puts("FAIL: json_object_new_string_noalloc(str1) returned NULL");
return 2;
}

json_object_put(jso_str);
jso_str = NULL;

jso_str = json_object_new_string_noalloc(str2);
if (!jso_str)
{
puts("FAIL: json_object_new_string_noalloc(str2) returned NULL");
return 3;
}

json_object_put(jso_str);

puts("PASS");
return 0;
}

+ 1
- 0
tests/test_string_noalloc.expected View File

@@ -0,0 +1 @@
PASS

+ 1
- 0
tests/test_string_noalloc.test View File

@@ -0,0 +1 @@
test_basic.test

Loading…
Cancel
Save