-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #20 from TeskaLabs/feature/c-api
Add a C API (initial version)
- Loading branch information
Showing
8 changed files
with
159 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
// We have to include "Python.h" b/c otherwise parser.parse() crashes | ||
// Assumption is that Python.h sets some definition that is used by `simdjson.h` | ||
// TODO: Find what `ifdef` is set and set that without `Python.h` | ||
#include "Python.h" | ||
|
||
#include "simdjson/simdjson.h" | ||
|
||
extern "C" { | ||
#include "cysimdjsonc.h" | ||
} | ||
|
||
void * cysimdjson_parser_new(void) { | ||
simdjson::dom::parser * parser = new simdjson::dom::parser(); | ||
void * p = static_cast<void*>(parser); | ||
return p; | ||
} | ||
|
||
void cysimdjson_parser_del(void * p) { | ||
assert(p != NULL); | ||
simdjson::dom::parser * parser = static_cast<simdjson::dom::parser *>(p); | ||
delete parser; | ||
} | ||
|
||
|
||
size_t cysimdjson_element_sizeof(void) { | ||
return sizeof(simdjson::dom::element); | ||
} | ||
|
||
|
||
bool cysimdjson_parser_parse(void * p, void * memory, const uint8_t * data, size_t datalen) { | ||
simdjson::dom::parser * parser = static_cast<simdjson::dom::parser *>(p); | ||
|
||
try { | ||
// Initialize the element at the memory provided by a caller | ||
// See: https://www.geeksforgeeks.org/placement-new-operator-cpp/ | ||
// `memory` is a pointer to a pre-allocated memory space with >= cysimdjson_element_sizeof() bytes | ||
simdjson::dom::element * element = new(memory) simdjson::dom::element(); | ||
|
||
// Parse the JSON | ||
auto err = parser->parse( | ||
data, datalen, | ||
true // Create a copy if needed (TODO: this may be optimized eventually to save data copy) | ||
).get(*element); | ||
|
||
if (err) { | ||
// Likely syntax error in JSON | ||
return true; | ||
} | ||
|
||
} catch (const std::bad_alloc& e) { | ||
// Error when allocating memory | ||
return true; | ||
} | ||
catch (...) { | ||
return true; | ||
} | ||
|
||
// No error | ||
return false; | ||
} | ||
|
||
|
||
bool cysimdjson_element_get_str(const char * attrname, size_t attrlen, void * e, const char ** output, size_t * outputlen) { | ||
simdjson::dom::element * element = static_cast<simdjson::dom::element *>(e); | ||
std::string_view pointer = std::string_view(attrname, attrlen); | ||
|
||
std::string_view result; | ||
auto err = element->at_pointer(pointer).get(result); | ||
if (err) { | ||
return true; | ||
} | ||
|
||
*output = result.data(); | ||
*outputlen = result.size(); | ||
return false; | ||
} | ||
|
||
|
||
// This is here for an unit test | ||
void cysimdjson_parser_test() { | ||
printf("cysimdjson_parser_test started ...\n"); | ||
|
||
simdjson::dom::parser parser; | ||
simdjson::dom::object object; | ||
|
||
const char * jsond = R"({"key":"value"} )"; | ||
const size_t jsond_len = std::strlen(jsond); | ||
|
||
auto error = parser.parse(jsond, jsond_len).get(object); | ||
|
||
printf("cysimdjson_parser_test OK!\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#ifndef CYSIMDJSONAPI_H | ||
#define CYSIMDJSONAPI_H | ||
|
||
// This is API for C (not C++) level | ||
// This header has to be C compliant | ||
|
||
#include <stddef.h> | ||
#include <stdint.h> | ||
#include <stdbool.h> | ||
|
||
void * cysimdjson_parser_new(void); | ||
void cysimdjson_parser_del(void * parser); | ||
|
||
size_t cysimdjson_element_sizeof(void); | ||
bool cysimdjson_parser_parse(void * parser, void * memory, const uint8_t * data, size_t datalen); | ||
|
||
bool cysimdjson_element_get_str(const char * attrname, size_t attrlen, void * element, const char ** output, size_t * outputlen); | ||
|
||
void cysimdjson_parser_test(void); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
from .test_array import * | ||
from .test_document import * | ||
from .test_capi import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import ctypes | ||
import unittest | ||
|
||
import cysimdjson | ||
|
||
|
||
class CySIMDJSONCAPITestCases(unittest.TestCase): | ||
|
||
|
||
def test_capi_01(self): | ||
|
||
ctypes.pythonapi.cysimdjson_parser_new.restype = ctypes.c_void_p | ||
ctypes.pythonapi.cysimdjson_parser_del.argtypes = [ctypes.c_void_p] | ||
|
||
parser = ctypes.pythonapi.cysimdjson_parser_new() | ||
|
||
ctypes.pythonapi.cysimdjson_parser_del(parser) | ||
|
||
|
||
def test_capi_02(self): | ||
ctypes.pythonapi.cysimdjson_parser_new.restype = ctypes.c_int | ||
element_sizeof = ctypes.pythonapi.cysimdjson_element_sizeof() | ||
print("element_sizeof:", element_sizeof) | ||
|
||
|
||
def test_capi_03(self): | ||
ctypes.pythonapi.cysimdjson_parser_test() |