Una solución simple de encabezado único para analizar JSON en C y C ++.
JSON se analiza en un búfer de asignación única de solo lectura.
Los compiladores compatibles actuales son GCC, Clang y MSVC.
Las plataformas compatibles actuales son Windows, Mac OS y Linux.
¡Solo #include "json.h" en tu código!
Analice una cuerda JSON en un DOM.
struct json_value_s * json_parse (
const void * src ,
size_t src_size );src - Una cadena UTF -8 JSON para analizar.src_size - El tamaño de src en bytes. Devuelve una struct json_value_s* apuntando la raíz del JSON DOM.
La estructura principal para interactuar con un modelo de objeto de documento JSON analizado (DOM) es el struct json_value_s .
struct json_value_s {
void * payload ;
size_t type ;
};payload : un puntero al contenido del valor.type : el tipo de Struct payload señala, uno de json_type_e . Nota: Si el tipo es json_type_true , json_type_false o json_type_null , la carga útil será nula.Parse extendido una cadena JSON en un DOM.
struct json_value_s * json_parse_ex (
const void * src ,
size_t src_size ,
size_t flags_bitset ,
void * ( * alloc_func_ptr )( void * , size_t ),
void * user_data ,
struct json_parse_result_s * result );src - Una cadena UTF -8 JSON para analizar.src_size - El tamaño de src en bytes.flags_bitset : banderas de análisis adicionales, un bitset de banderas especificados en enum json_parse_flags_e .alloc_func_ptr : una función de devolución de llamada para usar para hacer la asignación única. Si es nulo, se usa malloc() .user_data : datos del usuario que se pasarán como el primer argumento a alloc_func_ptr .result : el resultado del análisis. Si ocurriera un error de análisis, esto contendrá qué tipo de error y en qué parte de la fuente ocurrió. Puede ser nulo. Devuelve una struct json_value_s* apuntando la raíz del JSON DOM.
Las banderas de análisis adicionales que se pueden especificar a json_parse_ex() son los siguientes:
enum json_parse_flags_e {
json_parse_flags_default = 0 ,
json_parse_flags_allow_trailing_comma = 0x1 ,
json_parse_flags_allow_unquoted_keys = 0x2 ,
json_parse_flags_allow_global_object = 0x4 ,
json_parse_flags_allow_equals_in_object = 0x8 ,
json_parse_flags_allow_no_commas = 0x10 ,
json_parse_flags_allow_c_style_comments = 0x20 ,
json_parse_flags_deprecated = 0x40 ,
json_parse_flags_allow_location_information = 0x80 ,
json_parse_flags_allow_single_quoted_strings = 0x100 ,
json_parse_flags_allow_hexadecimal_numbers = 0x200 ,
json_parse_flags_allow_leading_plus_sign = 0x400 ,
json_parse_flags_allow_leading_or_trailing_decimal_point = 0x800 ,
json_parse_flags_allow_inf_and_nan = 0x1000 ,
json_parse_flags_allow_multi_line_strings = 0x2000 ,
json_parse_flags_allow_simplified_json =
( json_parse_flags_allow_trailing_comma |
json_parse_flags_allow_unquoted_keys |
json_parse_flags_allow_global_object |
json_parse_flags_allow_equals_in_object |
json_parse_flags_allow_no_commas ),
json_parse_flags_allow_json5 =
( json_parse_flags_allow_trailing_comma |
json_parse_flags_allow_unquoted_keys |
json_parse_flags_allow_c_style_comments |
json_parse_flags_allow_single_quoted_strings |
json_parse_flags_allow_hexadecimal_numbers |
json_parse_flags_allow_leading_plus_sign |
json_parse_flags_allow_leading_or_trailing_decimal_point |
json_parse_flags_allow_inf_and_nan |
json_parse_flags_allow_multi_line_strings )
};json_parse_flags_default : el valor predeterminado, no se habilita ningún comportamiento especial.json_parse_flags_allow_trailing_comma - Permitir comas finales en objetos y matrices. Por ejemplo, tanto [true,] como {"a" : null,} se permitirían con esta opción encendida.json_parse_flags_allow_unquoted_keys - Permitir claves sin cotización para objetos. Por ejemplo, {a : null} se permitiría con esta opción encendida.json_parse_flags_allow_global_object - Permitir un objeto global desappsleted. Por ejemplo, a : null, b : true, c : {} se permitiría con esta opción encendida.json_parse_flags_allow_equals_in_object - Permitir los objetos para usar '=' así como ':' entre pares de clave/valor. Por ejemplo, {"a" = null, "b" : true} se permitiría con esta opción encendida.json_parse_flags_allow_no_commas - Permitir que los objetos no tengan que tener separadores de coma entre pares de clave/valor. Por ejemplo, {"a" : null "b" : true} se permitiría con esta opción encendida.json_parse_flags_allow_c_style_comments - Permitir comentarios de estilo C ( // o /* */ ) para ignorar en el archivo de entrada JSON.json_parse_flags_deprecated - Una opción desactivada.json_parse_flags_allow_location_information : permita que la información de ubicación se rastree para donde están los valores en la entrada JSON. Útil para alertar a los usuarios de errores con información de ubicación precisa relacionada con la fuente original. Cuando esta opción está habilitada, todos json_value_s* se pueden lanzar a json_value_ex_s* , y el miembro json_string_s* de json_object_element_s* El miembro del nombre se puede lanzar a json_string_ex_s* para recuperar ubicaciones específicas en todos los valores y teclas. Nota Esta opción aumentará el presupuesto de memoria requerido para el DOM utilizado para registrar el JSON.json_parse_flags_allow_single_quoted_strings - permite que las cadenas estén en 'single quotes' .json_parse_flags_allow_hexadecimal_numbers - Permite que los números hexadecimales se usen 0x42 .json_parse_flags_allow_leading_plus_sign - Permite un signo ' +' principal en los números +42 .json_parse_flags_allow_leading_or_trailing_decimal_point - Permite que los puntos decimales sigan o se sigan con 0 dígitos .42 o 42. .json_parse_flags_allow_inf_and_nan - Permite usar identificadores infinito y nan Infinity o NaN .json_parse_flags_allow_multi_line_strings - Permite que las cadenas abarcan múltiples líneas.json_parse_flags_allow_simplified_json - Permitir que JSON simplificado se analice. JSON simplificado es una habilitación de un conjunto de otras opciones de análisis. Vea el blog Bitsquid que presenta esto aquí.json_parse_flags_allow_json5 - Permitir que JSON5 se analice. JSON5 es una habilitación de un conjunto de otras opciones de análisis. Vea el sitio web que define esta extensión aquí. json_parseDigamos que tuvimos la cadena JSON '{"A": True, "B": [False, Null, "foo"]}' . Para llegar a cada parte del JSON analizado lo haríamos:
const char json [] = "{"a" : true, "b" : [false, null, "foo"]}" ;
struct json_value_s * root = json_parse ( json , strlen ( json ));
assert ( root -> type == json_type_object );
struct json_object_s * object = ( struct json_object_s * ) root -> payload ;
assert ( object -> length == 2 );
struct json_object_element_s * a = object -> start ;
struct json_string_s * a_name = a -> name ;
assert ( 0 == strcmp ( a_name -> string , "a" ));
assert ( a_name -> string_size == strlen ( "a" ));
struct json_value_s * a_value = a -> value ;
assert ( a_value -> type == json_type_true );
assert ( a_value -> payload == NULL );
struct json_object_element_s * b = a -> next ;
assert ( b -> next == NULL );
struct json_string_s * b_name = b -> name ;
assert ( 0 == strcmp ( b_name -> string , "b" ));
assert ( b_name -> string_size == strlen ( "b" ));
struct json_value_s * b_value = b -> value ;
assert ( b_value -> type == json_type_array );
struct json_array_s * array = ( struct json_array_s * ) b_value -> payload ;
assert ( array -> length == 3 );
struct json_array_element_s * b_1st = array -> start ;
struct json_value_s * b_1st_value = b_1st -> value ;
assert ( b_1st_value -> type == json_type_false );
assert ( b_1st_value -> payload == NULL );
struct json_array_element_s * b_2nd = b_1st -> next ;
struct json_value_s * b_2nd_value = b_2nd -> value ;
assert ( b_2nd_value -> type == json_type_null );
assert ( b_2nd_value -> payload == NULL );
struct json_array_element_s * b_3rd = b_2nd -> next ;
assert ( b_3rd -> next == NULL );
struct json_value_s * b_3rd_value = b_3rd -> value ;
assert ( b_3rd_value -> type == json_type_string );
struct json_string_s * string = ( struct json_string_s * ) b_3rd_value -> payload ;
assert ( 0 == strcmp ( string -> string , "foo" ));
assert ( string -> string_size == strlen ( "foo" ));
/* Don't forget to free the one allocation! */
free ( root );Hay algunas funciones que no sirven otro propósito que hacer que sea más agradable iterar a través del JSON DOM producido:
json_value_as_string : devuelve un valor como una cadena, o nulo si no era una cadena.json_value_as_number : devuelve un valor como un número, o nulo si no era un número.json_value_as_object : devuelve un valor como objeto, o nulo si no era un objeto.json_value_as_array : devuelve un valor como una matriz, o nulo si no fue una matriz.json_value_is_true - RETRESTURAS El valor cero es un valor que fue verdadero, cero de lo contrario.json_value_is_false - Returns Non -Zero es un valor fue falso, cero de lo contrario.json_value_is_null - Returns No Zero es un valor NULL, cero de lo contrario.Veamos el mismo ejemplo desde arriba, pero usando estos iteradores de ayuda: en su lugar:
const char json [] = "{"a" : true, "b" : [false, null, "foo"]}" ;
struct json_value_s * root = json_parse ( json , strlen ( json ));
struct json_object_s * object = json_value_as_object ( root );
assert ( object != NULL );
assert ( object -> length == 2 );
struct json_object_element_s * a = object -> start ;
struct json_string_s * a_name = a -> name ;
assert ( 0 == strcmp ( a_name -> string , "a" ));
assert ( a_name -> string_size == strlen ( "a" ));
struct json_value_s * a_value = a -> value ;
assert ( json_value_is_true ( a_value ));
struct json_object_element_s * b = a -> next ;
assert ( b -> next == NULL );
struct json_string_s * b_name = b -> name ;
assert ( 0 == strcmp ( b_name -> string , "b" ));
assert ( b_name -> string_size == strlen ( "b" ));
struct json_array_s * array = json_value_as_array ( b -> value );
assert ( array -> length == 3 );
struct json_array_element_s * b_1st = array -> start ;
struct json_value_s * b_1st_value = b_1st -> value ;
assert ( json_value_is_false ( b_1st_value ));
struct json_array_element_s * b_2nd = b_1st -> next ;
struct json_value_s * b_2nd_value = b_2nd -> value ;
assert ( json_value_is_null ( b_2nd_value ));
struct json_array_element_s * b_3rd = b_2nd -> next ;
assert ( b_3rd -> next == NULL );
struct json_string_s * string = json_value_as_string ( b_3rd -> value );
assert ( string != NULL );
assert ( 0 == strcmp ( string -> string , "foo" ));
assert ( string -> string_size == strlen ( "foo" ));
/* Don't forget to free the one allocation! */
free ( root );Como puede ver, hace que iterando a través del DOM sea un poco más agradable.
Si desea extraer un valor de un DOM a una nueva asignación, entonces json_extract_value y json_extract_value_ex ¿Ustedes son amigos? Estas funciones le permiten tomar cualquier valor y su subárbol de un DOM y clonarlo en una nueva asignación, ya sea un solo malloc o una región de asignación proporcionada por el usuario.
const char json [] = "{"foo" : { "bar" : [123, false, null, true], "haz" : "haha" }}" ;
struct json_value_s * root = json_parse ( json , strlen ( json ));
assert ( root );
struct json_value_s * foo = json_value_as_object ( root ) -> start -> value ;
assert ( foo );
struct json_value_s * extracted = json_extract_value ( foo );
/* We can free root now because we've got a new allocation for extracted! */
free ( root );
assert ( json_value_as_object ( extracted ));
/* Don't forget to free the one allocation! */
free ( extracted );¡La función JSON_PARSE llama a Malloc una vez, y luego corta esta asignación única para apoyar todas las estructuras JSON extrañas y maravillosas que puedas imaginar!
La estructura de los datos es siempre las estructuras JSON primero (que codifican la estructura del JSON original), seguido de los datos.
Este es un software gratuito y sin gravación lanzado en el dominio público.
Cualquier persona es libre de copiar, modificar, publicar, usar, compilar, vender o distribuir este software, ya sea en formulario de código fuente o como un binario compilado, para cualquier propósito, comercial o no comercial, y por cualquier medio.
En jurisdicciones que reconocen las leyes de derechos de autor, el autor o autores de este software dedican todos y cada uno de los intereses de los derechos de autor en el software al dominio público. Hacemos esta dedicación en beneficio del público en general y en detrimento de nuestros herederos y sucesores. Tenemos la intención de que esta dedicación sea un acto manifiesto de renuncia a perpetuidad de todos los derechos presentes y futuros de este software bajo la ley de derechos de autor.
El software se proporciona "tal cual", sin garantía de ningún tipo, expresa o implícita, incluidas, entre otros, las garantías de comerciabilidad, idoneidad para un propósito particular y no infracción. En ningún caso los autores serán responsables de ningún reclamo, daños u otra responsabilidad, ya sea en una acción de contrato, agravio o de otro modo, surgiendo, de o en relación con el software o el uso u otros tratos en el software.
Para obtener más información, consulte http://unlicense.org/