1414#ifndef PHP_SIMDJSON_H
1515#define PHP_SIMDJSON_H
1616
17+ /*
18+ * Error constant implementation notes:
19+ *
20+ * - 0 always means success, and non-0 is a failure condition.
21+ * - Prefix these with SIMDJSON_PHP_ERR_ to distinguish them from other values.
22+ * - The error codes (value or labels) belonging to the C simdjson project may change in the future.
23+ *
24+ * Maybe these should be exposed as extern const once there's a project that needs the other values.
25+ * For now, they're also exposed as `REGISTER_LONG_CONSTANT("SIMDJSON_ERR_" #errcode, (val), CONST_PERSISTENT)`
26+ */
27+ #define SIMDJSON_PHP_ERR_SUCCESS 0
28+ #define SIMDJSON_PHP_ERR_INVALID_PHP_PROPERTY 255
29+ #define SIMDJSON_PHP_ERR_KEY_COUNT_NOT_COUNTABLE 254
30+
1731/*
1832 * Put all of the publicly visible functionality and macros into the same header file
1933 * (On windows, the include paths used by the c compiler may be different)
2034 */
2135#include "Zend/zend.h"
2236#include "Zend/zend_portability.h"
2337
24- // All code in this header file should be changed to go within BEGIN_EXTERN_C/END_EXTERN_C macros (both header definitions, and C++ declarations, including function implementations),
25- // so that pecls written in C can use this functionality without separate C++ files to load bindings.h.
26- // BEGIN_EXTERN_C is needed for symbols to be mangled using C rules instead of C++ rules in all includers.
27- // When I add ZEND_API to declarations and possibly definitions, I get linker errors.
38+ /*
39+ * All code in this header file should be changed to go within BEGIN_EXTERN_C/END_EXTERN_C macros
40+ * (both header definitions, and C++ declarations, including function implementations),
41+ * so that pecls written in C can use this functionality without separate C++ files to load bindings.h.
42+ *
43+ * This header file deliberately does not depend on other header files in this project,
44+ * to make including this header file easier for other PECLs (avoid include path issues)
45+ *
46+ * BEGIN_EXTERN_C is needed for symbols to be mangled using C rules instead of C++ rules in all includers.
47+ * (This macro can be used from both C and C++ source files)
48+ */
2849BEGIN_EXTERN_C ()
2950
3051extern zend_module_entry simdjson_module_entry ;
3152#define phpext_simdjson_ptr &simdjson_module_entry
3253
3354#define PHP_SIMDJSON_VERSION "2.2.0dev"
3455#define SIMDJSON_SUPPORT_URL "https://github.com/crazyxman/simdjson_php"
35- #define SIMDJSON_PARSE_FAIL 0
36- #define SIMDJSON_PARSE_SUCCESS 1
37- #define SIMDJSON_PARSE_KEY_EXISTS 2
38- #define SIMDJSON_PARSE_KEY_NOEXISTS 3
3956
4057#define SIMDJSON_PARSE_DEFAULT_DEPTH 512
4158
@@ -51,6 +68,8 @@ ZEND_BEGIN_MODULE_GLOBALS(simdjson)
5168 * php::simdjson::parser pointer, constructed on first use with request-scope lifetime.
5269 * Note that in ZTS builds, the thread for each request will deliberately have different instances for each concurrently running request.
5370 * (The simdjson library is not thread safe)
71+ *
72+ * This is similar to php-src's ext/session session data storage.
5473 */
5574 struct simdjson_php_parser * parser ;
5675ZEND_END_MODULE_GLOBALS (simdjson )
@@ -67,9 +86,7 @@ ZEND_TSRMLS_CACHE_EXTERN()
6786#endif
6887#endif
6988
70- /*
71- * This module defines utilities and helper functions used elsewhere in simdjson.
72- */
89+ /* Only the functions and variables defined with PHP_SIMDJSON_API can be loaded by other PECLs */
7390#ifdef PHP_WIN32
7491# define PHP_SIMDJSON_API __declspec(dllexport)
7592#elif defined(__GNUC__ ) && __GNUC__ >= 4
@@ -78,27 +95,90 @@ ZEND_TSRMLS_CACHE_EXTERN()
7895# define PHP_SIMDJSON_API /* nothing special */
7996#endif
8097
98+ /** Defines 'class SimdJsonException' */
8199extern PHP_SIMDJSON_API zend_class_entry * simdjson_exception_ce ;
100+ extern PHP_SIMDJSON_API zend_class_entry * simdjson_value_error_ce ;
82101
83- // NOTE: Namespaces and references(&) are C++ only functionality.
84- // To expose this functionality to other C PECLs,
85- // switch to a forward class declaration of a class that only wraps simdjson::dom::parser
102+ /**
103+ * NOTE: Namespaces and references(&) and classes (instead of structs) are C++ only functionality.
104+ *
105+ * To expose this functionality to other C PECLs,
106+ * switch to a forward class declaration of a class that only wraps simdjson::dom::parser
107+ */
86108typedef uint8_t simdjson_php_error_code ;
87109
88110/* NOTE: Callers should check if len is greater than 4GB - simdjson will always return a non zero error code for those */
89111
90- /* FIXME add cplus_simdjson_get_default_singleton_parser api */
91- /* FIXME add cplus_simdjson_decode_with_default_singleton_parser(return_value, json, len, bool assoc) */
92-
93- PHP_SIMDJSON_API const char * cplus_simdjson_error_msg (simdjson_php_error_code );
94- PHP_SIMDJSON_API void cplus_simdjson_throw_jsonexception (simdjson_php_error_code );
95- PHP_SIMDJSON_API struct simdjson_php_parser * cplus_simdjson_create_parser (void );
96- PHP_SIMDJSON_API void cplus_simdjson_free_parser (struct simdjson_php_parser * parser );
97- PHP_SIMDJSON_API bool cplus_simdjson_is_valid (struct simdjson_php_parser * parser , const char * json , size_t len , size_t depth );
98- PHP_SIMDJSON_API simdjson_php_error_code cplus_simdjson_parse (struct simdjson_php_parser * parser , const char * json , size_t len , zval * return_value , bool assoc , size_t depth );
99- PHP_SIMDJSON_API simdjson_php_error_code cplus_simdjson_key_value (struct simdjson_php_parser * parser , const char * json , size_t len , const char * key , zval * return_value , bool assoc , size_t depth );
100- PHP_SIMDJSON_API u_short cplus_simdjson_key_exists (struct simdjson_php_parser * parser , const char * json , size_t len , const char * key , size_t depth );
101- PHP_SIMDJSON_API simdjson_php_error_code cplus_simdjson_key_count (struct simdjson_php_parser * parser , const char * json , size_t len , const char * key , zval * return_value , size_t depth );
112+ /* FIXME add php_simdjson_get_default_singleton_parser api */
113+ /* FIXME add php_simdjson_decode_with_default_singleton_parser(return_value, json, len, bool assoc) */
114+
115+ /**
116+ * Returns the error message corresponding to a given error code returned by a call to simdjson_php.
117+ */
118+ PHP_SIMDJSON_API const char * php_simdjson_error_msg (simdjson_php_error_code code );
119+ /**
120+ * Throw a SimdJsonException with the provided error code and the corresponding error message.
121+ */
122+ PHP_SIMDJSON_API void php_simdjson_throw_jsonexception (simdjson_php_error_code code );
123+ /**
124+ * Create a brand new parser instance.
125+ *
126+ * The caller must free it with php_simdjson_free_parser once it is no longer used.
127+ *
128+ * Callers may use this instead of the shared singleton parser when memory usage is a concern
129+ * (e.g. the PECLs are likely to be used load a string that's megabytes long in a long-lived php process)
130+ */
131+ PHP_SIMDJSON_API struct simdjson_php_parser * php_simdjson_create_parser (void );
132+ /**
133+ * Release a parser **constructed by php_simdjson_create_parser** and all associated buffers.
134+ */
135+ PHP_SIMDJSON_API void php_simdjson_free_parser (struct simdjson_php_parser * parser );
136+ /**
137+ * Returns true if the given json string is valid
138+ */
139+ PHP_SIMDJSON_API bool php_simdjson_is_valid (struct simdjson_php_parser * parser , const char * json , size_t len , size_t depth );
140+ /**
141+ * Parses the given string into a return code.
142+ *
143+ * If the returned error code is 0, then return_value contains the parsed value.
144+ * If the returned error code is non-0, then return_value will not be initialized.
145+ */
146+ PHP_SIMDJSON_API simdjson_php_error_code php_simdjson_parse (struct simdjson_php_parser * parser , const char * json , size_t len , zval * return_value , bool assoc , size_t depth );
147+ /**
148+ * Parses the part of the given string at the json pointer 'key' into a PHP value at return_value
149+ *
150+ * If the returned error code is 0, then return_value contains the parsed value (or null).
151+ * If the returned error code is non-0, then return_value will not be initialized.
152+ *
153+ * - SIMDJSON_ERR_NO_SUCH_FIELD is returned if the json pointer 'key' is not found
154+ * - Other errors are returned for invalid json, etc.
155+ *
156+ * @see https://www.rfc-editor.org/rfc/rfc6901.html
157+ */
158+ PHP_SIMDJSON_API simdjson_php_error_code php_simdjson_key_value (struct simdjson_php_parser * parser , const char * json , size_t len , const char * key , zval * return_value , bool assoc , size_t depth );
159+ /**
160+ * Checks if the json pointer 'key' exists in the given json string.
161+ *
162+ * - 0 if the key exists
163+ * - NO_SUCH_FIELD if a field does not exist in an object
164+ * - INDEX_OUT_OF_BOUNDS if an array index is larger than an array length
165+ * - INCORRECT_TYPE if a non-integer is used to access an array
166+ * - INVALID_JSON_POINTER if the JSON pointer is invalid and cannot be parsed
167+ *
168+ * @see https://www.rfc-editor.org/rfc/rfc6901.html
169+ */
170+ PHP_SIMDJSON_API uint8_t php_simdjson_key_exists (struct simdjson_php_parser * parser , const char * json , size_t len , const char * key , size_t depth );
171+ /**
172+ * Count the keys of the given array/object at json pointer 'key' exists in the given json string.
173+ *
174+ * If the returned error code is 0, then the zval in return_value is overwritten with the key count using ZVAL_LONG.
175+ * - For arrays, this is the array size
176+ * - For objects, this is the object size
177+ * - For other values, this is 0 (when fail_if_uncountable is false)
178+ *
179+ * @see https://www.rfc-editor.org/rfc/rfc6901.html
180+ */
181+ PHP_SIMDJSON_API simdjson_php_error_code php_simdjson_key_count (struct simdjson_php_parser * parser , const char * json , size_t len , const char * key , zval * return_value , size_t depth , bool fail_if_uncountable );
102182
103183END_EXTERN_C ()
104184
0 commit comments