SDK Multiplataforma en C logo

SDK Multiplataforma en C

JSON

❮ Anterior
Siguiente ❯

Funciones

type*json_read (...)
voidjson_write (...)
voidjson_destroy (...)
voidjson_destopt (...)

JSON JavaScript Object Notation, es un formato de datos en modo texto que permite representar de manera sencilla tipos básicos, objetos y arrays. Aunque su uso se ha popularizado en el ámbito Web puede utilizarse también para otros fines, como por ejemplo, archivos de configuración o intercambio local. Su sintaxis es fácil de entender para los humanos y sencilla de procesar para las máquinas. En (Listado 1) reproducimos un pequeño fragmento de la respuesta JSON de un servicio Web de ejemplo:

Listado 1: Fragmento JSON devuelto por un Web Service.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
{
    "code":0,
    "size":80,
    "data":[
    {"id":0,
    "code":"i7-8700K",
    "description":"Intel BX80684I78700K 8th Gen Core i7-8700K Processor",
    type":0,
    "price":374.8899999999999863575794734060764312744140625,
    "image":"cpu_00.jpg",
    "image64":"\/9j\/4AAQSkZJRgABAQ....
    },
    ...
    ]
}

En su estructura podemos encontrar estos tipos de datos:

  • Booleanos: Representados por las constantes true o false.
  • Números: Utiliza la notación exponencial de C para valores en coma flotante: 23, .76, -0.54 o 5.6e12 son ejemplos válidos de valores numéricos. JSON no distingue entre enteros, negativos o reales.
  • Cadenas: Cualquier texto entre comillas se considera una cadena. Admite cualquier carácter Unicode en UTF-8 o mediante la secuencia de escape \uXXXX para indicar el codepoint.
  • Objetos: Están delimitados por llaves y compuestos por varios campos separados por comas. Cada campo lo forman un identificador (cadena) seguido del carácter dos puntos y un valor que puede ser cualquier tipo simple, objeto u array (Listado 2).
  • Listado 2: Objeto JSON
    1
    2
    3
    4
    5
    6
    7
    
    {
        "field1" : true,
        "field2" : 24.67,
        "field3" : "Hello Pibe",
        "field4" : [1, 2, 4, 8.4],
        "field5" : { "x" : 34.32, "y" : -6.19 }
    }
    
  • Arrays: Listas de valores delimitados por cochetes [ ... ] y separados por comas. Los valores no tienen porqué ser del mismo tipo como suele ocurrir en algunos lenguajes de programación (Listado 3).
  • Listado 3: Array JSON
    1
    2
    3
    
    [
        18, "Hello Pibe", true, { "x" : 34.32, "y" : -6.19 }
    ]
    
  • null: Indica la ausencia de valor.
  • Binarios: JSON no soporta datos binarios por lo que objetos opacos (imágenes, por ejemplo) deben ser codificados en texto y transmitidos como un valor de tipo cadena. El formato más extendido y soportado globalmente es el Base64 donde cada carácter representa 6 bits de información.
El parser JSON de NAppGUI transforma automáticamente los objetos Image a Base64 y viceversa, lo que permite incrustar imágenes como campos de datos.

1. Obtener datos JSON

Lo primero que debemos hacer es conectar con el servicio Web mediante HTTP para realizar la consulta y obtener el JSON de respuesta (Listado 4). También podemos leer el contenido de un JSON desde un archivo local o cualquier otro origen de datos.

Listado 4: Obtener un stream JSON desde un servicio Web o desde disco.
1
2
Stream *stm = http_dget("http://serv.nappgui.com/dproducts.php", NULL, NULL);
Stream *stm = hfile_stream("/home/fran/appdata/config.json", NULL);

2. Convertir JSON en objetos

Si todo ha ido bien, tendremos en Stream *stm un bloque de texto en formato JSON. El siguiente paso será "parsearlo" para convertir la secuencia de caracteres en objetos binarios para su uso desde la aplicación (Listado 5).

Listado 5: Traducir un JSON a un objeto C.
1
2
PJson *json = json_read(stm, NULL, PJson);
stm_close(&stm);

Para que esta llamada tenga éxito, previamente hemos debido crear las estructuras equivalentes y registrarlas en la base de datos interna de la aplicación (Listado 6). Consulta Data binding para saber más sobre la vinculación automática de datos.

Listado 6: Estructuras C que albergarán el contenido del JSON.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
typedef struct _product_t Product;
typedef struct _pjson_t PJson;

struct _product_t
{
    uint32_t type;
    String *code;
    String *description;
    Image *image64;
    real32_t price;
};

struct _pjson_t
{
    int32_t code;
    uint32_t size;
    ArrPt(Product) *data;
};

dbind(Product, uint32_t, type);
dbind(Product, String*, code);
dbind(Product, String*, description);
dbind(Product, Image*, image64);
dbind(Product, real32_t, price);
dbind(PJson, int32_t, code);
dbind(PJson, uint32_t, size);
dbind(PJson, ArrPt(Product)*, data);

3. Convertir objetos en JSON

El proceso inverso también es muy sencillo de realizar gracias a DBind. Imaginemos que hemos realizado cambios en el objeto PJson del apartado anterior y queremos guardar una copia en formato JSON (Listado 7).

Listado 7: Traducir un objeto C a JSON.
1
2
3
4
5
6
7
PJson *json = ...;

Stream *stm = stm_to_file("/home/fran/appdata/config.json", NULL);
json_write(stm, json, NULL, PJson);

stm_close(&stm);
json_destroy(&json, PJson);

json_read ()

Procesa un script JSON. Transformará texto JSON en un objeto binario.

type*
json_read(Stream *stm,
          const JsonOpts *opts,
          type);
stm

Entrada de datos en formato JSON.

opts

Opciones.

type

Tipo de datos.

Retorna

Objeto resultado.

Observaciones

Ver Convertir JSON en objetos.


json_write ()

Guarda un objeto binario en formato JSON.

void
json_write(Stream *stm,
           type *data,
           const JsonOpts *opts,
           type);
stm

Salida de datos en formato JSON.

data

Objeto.

opts

Opciones.

type

Tipo de datos.

Observaciones

Ver Convertir objetos en JSON.


json_destroy ()

Destruye un objeto JSON.

void
json_destroy(type **data,
             type);
data

Objeto.

type

Tipo de datos.


json_destopt ()

Destruye un objeto JSON, si este no es NULL.

void
json_destopt(type **data,
             type);
data

Objeto.

type

Tipo de datos.

❮ Anterior
Siguiente ❯