Uma solução simples de cabeçalho único para analisar JSON em C e C ++.
O JSON é analisado em um buffer de alocação único e somente leitura.
Os compiladores suportados atuais são GCC, CLANG e MSVC.
As plataformas suportadas atuais são Windows, Mac OS e Linux.
Apenas #include "json.h" em seu código!
Analise uma corda json em um dom.
struct json_value_s * json_parse (
const void * src ,
size_t src_size );src - Uma string JSON UTF -8 para analisar.src_size - o tamanho do src em bytes. Retorna uma struct json_value_s* apontando a raiz do json dom.
A estrutura principal para interagir com um modelo de objeto de documentos JSON (DOM) analisado é o struct json_value_s .
struct json_value_s {
void * payload ;
size_t type ;
};payload - um ponteiro para o conteúdo do valor.type - o tipo de payload de estrutura de estruturas aponta, um dos json_type_e . Nota: Se o tipo for json_type_true , json_type_false ou json_type_null , a carga útil será nula.Pares estendido uma corda JSON em um 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 - Uma string JSON UTF -8 para analisar.src_size - o tamanho do src em bytes.flags_bitset - sinalizadores de análise extra, um bitset de sinalizadores especificados em enum json_parse_flags_e .alloc_func_ptr - uma função de retorno de chamada a ser usada para fazer a alocação única. Se nulo, malloc() é usado.user_data - os dados do usuário a serem passados como o primeiro argumento para alloc_func_ptr .result - o resultado da análise. Se ocorrer um erro de análise, isso conterá que tipo de erro e onde ocorreu na fonte. Pode ser nulo. Retorna uma struct json_value_s* apontando a raiz do json dom.
As bandeiras de análise extra que podem ser especificadas para json_parse_ex() são as seguintes:
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 - O padrão, nenhum comportamento especial está ativado.json_parse_flags_allow_trailing_comma - permita vírgulas à direita em objetos e matrizes. Por exemplo, tanto [true,] quanto {"a" : null,} seriam permitidos com esta opção.json_parse_flags_allow_unquoted_keys - Permita chaves não cotadas para objetos. Por exemplo, {a : null} seria permitido com esta opção.json_parse_flags_allow_global_object - permita um objeto global não embrulhado. Por exemplo, a : null, b : true, c : {} seria permitido com esta opção.json_parse_flags_allow_equals_in_object - permita que os objetos usem '=' e ':' entre pares de chave/valor. Por exemplo, {"a" = null, "b" : true} seria permitido com esta opção.json_parse_flags_allow_no_commas - Permita que os objetos não precisem ter separadores de vírgula entre pares de chave/valor. Por exemplo, {"a" : null "b" : true} seria permitido com esta opção.json_parse_flags_allow_c_style_comments - permita que comentários no estilo C ( // ou /* */ ) sejam ignorados no arquivo json de entrada.json_parse_flags_deprecated - uma opção depreciada.json_parse_flags_allow_location_information - permita que as informações de localização sejam rastreadas para onde os valores estão no json de entrada. Útil para alertar os usuários a erros com informações precisas de localização referentes à fonte original. Quando esta opção estiver ativada, todos json_value_s* podem ser lançados para json_value_ex_s* , e o json_string_s* de json_object_element_s* do membro do nome pode ser lançado para json_string_ex_s* para recuperar locais específicos em todos os valores e teclas. Nota Esta opção aumentará o orçamento de memória necessário para o DOM usado para gravar o JSON.json_parse_flags_allow_single_quoted_strings - permite que as strings estejam em 'single quotes' .json_parse_flags_allow_hexadecimal_numbers - permite que números hexadecimais sejam usados 0x42 .json_parse_flags_allow_leading_plus_sign - permite um sinal líder ' +' nos números +42 .json_parse_flags_allow_leading_or_trailing_decimal_point - permite que pontos decimais sejam chumentes ou arrastados por 0 dígitos .42 ou 42. ..json_parse_flags_allow_inf_and_nan - permite o uso de Identificadores do Infinito e Nan Infinity ou NaN .json_parse_flags_allow_multi_line_strings - permite que as strings abranjam várias linhas.json_parse_flags_allow_simplified_json - permita que o json simplificado seja analisado. O JSON simplificado é a possibilidade de um conjunto de outras opções de análise. Veja o blog Bitsquid apresentando isso aqui.json_parse_flags_allow_json5 - permita que o JSON5 seja analisado. O JSON5 é uma possibilidade de um conjunto de outras opções de análise. Veja o site definindo esta extensão aqui. json_parseDigamos que tivéssemos o json string '{"a": true, "b": [false, null, "foo"]}' . Para chegar a cada parte do JSON analisado, farí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 );Existem algumas funções que não servem a nenhum propósito senão torná -lo mais agradável para iterar através do JSON Dom produzido:
json_value_as_string - Retorna um valor como uma string ou nulo se não fosse uma string.json_value_as_number - retorna um valor como um número ou nulo se não fosse um número.json_value_as_object - retorna um valor como objeto ou nulo se não fosse um objeto.json_value_as_array - Retorna um valor como uma matriz ou NULL se não fosse uma matriz.json_value_is_true - Retorna diferente de zero é um valor foi verdadeiro, caso contrário, zero.json_value_is_false - Retorna diferente de zero é um valor foi falso, caso contrário, zero.json_value_is_null - Retorna diferente de zero é um valor foi nulo, zero caso contrário.Vamos olhar para o mesmo exemplo de cima, mas usando esses iteradores auxiliares:
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 você pode ver, isso torna o DOM um pouco mais agradável.
Se você deseja extrair um valor de um DOM para uma nova alocação, então json_extract_value e json_extract_value_ex são amigos. Essas funções permitem que você aceite qualquer valor e sua subárvore de um DOM e o clonam em uma nova alocação - um único malloc ou uma região de alocação fornecida pelo usuário.
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 );A função JSON_PARSE chama MaiC uma vez e, em seguida, corta essa alocação única para suportar todas as estruturas JSON estranhas e maravilhosas que você pode imaginar!
A estrutura dos dados é sempre o JSON Structs First (que codifica a estrutura do JSON original), seguido pelos dados.
Este é um software gratuito e não onerado lançado em domínio público.
Qualquer pessoa pode copiar, modificar, publicar, usar, compilar, vender ou distribuir este software, em forma de código-fonte ou como um binário compilado, para qualquer finalidade, comercial ou não comercial e por qualquer meio.
Nas jurisdições que reconhecem as leis de direitos autorais, o autor ou autores deste software dedica todo e qualquer interesse de direitos autorais no software ao domínio público. Fazemos essa dedicação para o benefício do público em geral e em detrimento de nossos herdeiros e sucessores. Pretendemos que essa dedicação seja um ato aberto de renúncia à perpetuidade de todos os direitos presentes e futuros deste software sob a lei de direitos autorais.
O software é fornecido "como está", sem garantia de qualquer tipo, expresso ou implícito, incluindo, entre outros, as garantias de comercialização, aptidão para uma finalidade específica e não innoculação. Em nenhum caso, os autores serão responsáveis por qualquer reclamação, danos ou outro passivo, seja em uma ação de contrato, delito ou de outra forma, decorrente de, de ou em conexão com o software ou o uso ou outras negociações no software.
Para mais informações, consulte http://unlicense.org/