Skip to content

Commit

Permalink
Merge pull request #46 from TeskaLabs/feature/export-as-string
Browse files Browse the repository at this point in the history
Add a C API capability to export parsed JSON as a string.
  • Loading branch information
ateska authored Jul 24, 2023
2 parents a45c185 + a8b9ae4 commit bd5b3b6
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 0 deletions.
13 changes: 13 additions & 0 deletions cysimdjson/cysimdjsonc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,16 @@ int cysimdjson_parser_test() {

return 0;
}


size_t cysimdjson_minify(void * e, char * buffer, size_t buffer_size) {
simdjson::dom::element * element = static_cast<simdjson::dom::element *>(e);
std::string json_string = simdjson::minify(*element);

if (json_string.size() < buffer_size) {
std::strcpy(buffer, json_string.c_str());
return json_string.size();
} else {
return 0; // The output JSON doesn't fit
}
}
4 changes: 4 additions & 0 deletions cysimdjson/cysimdjsonc.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ bool cysimdjson_element_get(const char * attrname, size_t attrlen, void * elemen

int cysimdjson_parser_test(void);

// Export element `e` as JSON into the "buffer" and returns the exported JSON size.
// If the "buffer_size" is too small, returns 0;
size_t cysimdjson_minify(void * element, char * buffer, size_t buffer_size);

#endif
57 changes: 57 additions & 0 deletions test/test_capi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ def setUp(self):
self.cysimdjsonapi.cysimdjson_element_get.restype = ctypes.c_bool
self.cysimdjsonapi.cysimdjson_element_get.argtypes = [ctypes.c_void_p, ctypes.c_size_t, ctypes.c_void_p, ctypes.c_void_p]

self.cysimdjsonapi.cysimdjson_minify.restype = ctypes.c_size_t
self.cysimdjsonapi.cysimdjson_minify.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_size_t]


def test_capi_01(self):
parser = self.cysimdjsonapi.cysimdjson_parser_new()
Expand Down Expand Up @@ -153,3 +156,57 @@ def test_capi_06(self):
cython_element = cysimdjson.addr_to_element(element_addr)
val = cython_element.at_pointer("/document/key4")
self.assertEqual(val, 40)


def test_capi_07(self):
'''
Export parsed JSON into a string
'''

parser = cysimdjson.JSONParser()

with open(os.path.join(THIS_DIR, 'test.json'), 'r') as fo:
json_parsed = parser.parse_string(fo.read())

# Transition into C API
element_addr = json_parsed.get_addr()
self.assertNotEqual(element_addr, 0)

buf_max_size = 16*1024
buf = ctypes.create_string_buffer(buf_max_size)

size = self.cysimdjsonapi.cysimdjson_minify(
element_addr,
buf,
buf_max_size
)
self.assertNotEqual(size, 0)

json_string = buf[:size].decode('utf-8')
self.assertEqual(json_string, r'''{"document":{"key1":1,"key2":"2","key3":"3","key4":40,"key5":"50"}}''')



def test_capi_08(self):
'''
Try to export parsed JSON into a string but the output buffer is too small
'''

parser = cysimdjson.JSONParser()

with open(os.path.join(THIS_DIR, 'test.json'), 'r') as fo:
json_parsed = parser.parse_string(fo.read())

# Transition into C API
element_addr = json_parsed.get_addr()
self.assertNotEqual(element_addr, 0)

buf_max_size = 3
buf = ctypes.create_string_buffer(buf_max_size)

size = self.cysimdjsonapi.cysimdjson_minify(
element_addr,
buf,
buf_max_size
)
self.assertEqual(size, 0)

0 comments on commit bd5b3b6

Please sign in to comment.