JSON e LSL (4 di 4)

Terminati gli aspetti essenziali di JSON per LSL nell’articolo precedente in questa quarta parte esamineremo le ultime tre funzioni riguardanti JSON ovvero:

  • llJsonValueType()
  • llList2Json()
  • llJson2List()

llJsonValueType()

Come abbiamo già detto nella prima parte JSON prevede uno specifico set di tipi di variabili, con questa funzione LSL cerca di determinare a quale tipo di variabile un dato elemento appartiene, fondamentalmente ci permette di discriminare tra oggetti, array, numeri, stringhe e boolean (i formati previsti dalle specifiche JSON)

La prima brutta notizia però è che la funzione restituisce sì una stringa, ma questa di fatto è composta da un solo carattere e che tale carattere, a prescindere dal responso, corrisponde ad un codice unicode privo di un specifico grafema (in pratica vedremo sempre e comunque il simbolo che il nostro SO utilizza per i codici unicode sconosciuti, tipicamente un rettangolino vuoto ( □ ). Questo implica che per sapere di cosa si tratta dovremo confrontarlo con il corrispondente carattere specifico per ogni responso, operazione un pò tediosa ma non possiamo farci molto.

La seconda brutta notizia, per così dire, è che quando llJsonValueType esamina un valore può accadere per varie ragioni, che il tipo di variabile non sia riconosciuto (ad esempio se sta esaminando un vector, che non appartiene al range previsto dalle specifiche ufficiali JSON) in casi come questo ci verrà ritornato un codice JSON_INVALID.

Questo codice aggiuntivo non è l’unico, JSON_NULL rappresenta una variabile nulla (cioè priva di valore, concetto che in LSL manca), ma il succo del discorso è che se vogliamo almeno tentare di desumere il tipo di variabile dobbiamo approntare una funzione ad hoc per controllare tutte le possibilità.

Un esempio (tratto dalla documentazione ufficiale) di una funzione atta a questo scopo potrebbe essere:

string typeName(string type) {
 if (type == JSON_NUMBER) return "JSON_NUMBER";
 if (type == JSON_INVALID) return "JSON_INVALID";
 if (type == JSON_OBJECT) return "JSON_OBJECT";
 if (type == JSON_ARRAY) return "JSON_ARRAY";
 if (type == JSON_TRUE) return "JSON_TRUE";
 if (type == JSON_FALSE) return "JSON_FALSE";
 if (type == JSON_STRING) return "JSON_STRING";
 if (type == JSON_NULL) return "JSON_NULL";
 return type;
}
default
{
 state_entry()
 {
  string myJsonArray1 = "[\"rosso\",11,3.14156,true,null,<123.5,56.7,23.0>]";

//esamina l'intera stringa e deduce che si tratta di un JSON Array
  llOwnerSay(typeName( llJsonValueType(myJsonArray1 , []) ) ); 

//una stringa
  llOwnerSay(typeName( llJsonValueType(myJsonArray1 , [0]) ) ); 

//un intero
  llOwnerSay(typeName( llJsonValueType(myJsonArray1 , [1]) ) ); 

//la funzione non fa distinzione tra integer e float restituendo sempre JSON_NUMBER
  llOwnerSay(typeName( llJsonValueType(myJsonArray1 , [2]) ) ); 

//questo 'true' booleano non ha nulla a che fare con il 'TRUE' di LSL
  llOwnerSay(typeName( llJsonValueType(myJsonArray1 , [3]) ) ); 

//'null' non ha senso in LSL, ma come elemento JSON viene correttamente 
  llOwnerSay(typeName( llJsonValueType(myJsonArray1 , [4]) ) ); 

//tipo vector, non riconosciuto nativamente da JSON
  llOwnerSay(typeName( llJsonValueType(myJsonArray1 , [5]) ) ); 

//restituisce JSON_NUM ma è un errore a causa del precedente vector memorizzato alla maniera di LSL e non come stringa
  llOwnerSay(typeName( llJsonValueType(myJsonArray1 , [6]) ) ); 
 }
}

È opportuno rimarcare il concetto che questa funzione controlla il tipo di variabile riferendosi alle specifiche JSON e non a quelle LSL, ragione per cui, ad esempio la costante TRUE di LSL non ha significato, per LSL infatti TRUE e 1 (intero) sono esattamente la stessa cosa e non è quindi sovrapponibile al valore booleano classico ‘vero’ ( ‘true’ ) che è quello effettivamente soppesato da llJsonValueType, stesso identico discorso per il valore booleano ‘falso’ ( ‘false’ ), o per le variabili nulle ( ‘null’ ) che in LSL non esistono nemmeno.

Inoltre, come avevamo già accennato, i tipi di variabili LSL non previsti dalle specifiche ufficiali JSON non vengono riconosciute, ragione per cui se volessimo memorizzare un vector dovremo gestirlo come se fosse una stringa pena altrimenti ricevere un JSON_INVALID e una serie di errori in coda ad esso.

 


llList2Json()

La seconda funzione da esaminare è llList2Json(), che come è intuibile dal nome si occupa di convertire un List in un JSON, funzione quindi molto comoda quando dobbiamo operare conversioni di questo genere. Le possibilità, essendo List monodimensionale, sono però limitate.

Possiamo convertire una list in un JSON_Array indicando il tipo di elemento JSON (array) e una lista di valori (in formato List):

list miaList2 = ["rosso", 11, 3.14156, TRUE, <123.5,56.7,23.0>];
string mioJsonArray2 = llList2Json( JSON_ARRAY, miaList1);
//la stringa mioJsonArray2 ora contiene:
// ["rosso",11,3.141560,1,"<123.500000, 56.700001, 23.000000>"]

Se invece avessimo una strided list dovremmo sensatamente utilizzare un JSON Object:

list miaList3 = ["colore","rosso", "età",11, "PiGreco",3.14156, "esito",TRUE, "posizione",<123.5,56.7,23.0>];
string mioJsonObject3 = llList2Json( JSON_OBJECT, miaLista3);
//la stringa mioJsonObject3 ora contiene:
// {"colore":"rosso","età":11,"PiGreco":3.141560,"esito":1,"posizione":"<123.500000, 56.700001, 23.000000>"}

In tutti i casi sarà cura della funzione stessa aggiungere apici ed effettuare le conversioni (es. da TRUE a 1) per generare un elemento JSON correttamente formattato.
Nei casi in cui questa ‘traduzione’ non fosse possibile allora la funzione restituirà un JSON_INVALID

 


llJson2List()

L’ultima funzione rappresenta il processo opposto, ovvero convertire un JSON in List, questa operazione però presenta maggiori complessità in quanto si potrebbero ad esempio incontrare boolean e null (non previsti da LSL) e/o elementi nidificati.

Nel caso di boolean e null la funzione semplicemente restituisce il carattere unicode corrispondente, nel caso di elementi nidificati tutti vengono fatti ‘collassare’ in stringhe, in modo che di fatto solo gli elementi root vengano riportati e i loro valori quindi, se formati da array o da oggetti, diventeranno una unica stringa ad essi associati (parentesi quadre o graffe incluse), di seguito alcuni esempi.

esempio: coversione di un JSON Array in una lista

string myJsonArray4 = "[\"rosso\",11,3.141560,true,\"<123.500000, 56.700001, 23.000000>\"]";
list myList4 = llJson2List(myJsonArray4 );
llOwnerSay( llList2CSV(myList4 ) );

La lista così ottenuta sarà formata da 5 valori: rosso, 11, 3.141560, □ , <123.500000, 56.700001, 23.000000>

Notare che il valore ‘true’ è stato convertito nel carattere unicode U+FDD6 che corrisponde al codice di JSON_TRUE.

esempio: conversione di un JSON Object in una lista

string myJsonObject5 = "{\"colore\":\"rosso\",\"età\":11,\"PiGreco\":3.141560,\"esito\":true,\"posizione\":\"<123.500000, 56.700001, 23.000000>\"}";
list myList5 = llJson2List(myJsonObject5 );
llOwnerSay( llList2CSV(myList5 ) );

La lista così ottenuta sarà formata da 10 valori, rispettando le accoppiate etichetta/valore come strided list: colore, rosso, età, 11, PiGreco, 3.141560, esito, , posizione, <123.500000, 56.700001, 23.000000>

esempio: conversione di un array JSON bidimensionale in una lista (monodimensionale):

string myJsonArray6 = "[[\"rosso\",11,3.141560,true],[\"<123.500000, 56.700001, 23.000000>\",999]";
list myList6 = llJson2List(myJsonArray6 );
llOwnerSay( llList2CSV( myList6 ) );

La lista così ottenuta sarà formata da 2 soli valori:
1° valore stringa con parentesi quadre incluse , 2° valore stringa con parentesi quadre incluse
[“rosso”,11,3.141560,true], [“<123.500000, 56.700001, 23.000000>”,999]


E con questo siamo giunti alla conclusione della nostra breve incursione di JSON nello scriping in SL, sperando, pur sapendo di non aver sviscerato tutto lo sviscerabile, di aver almeno fornito le basi per consentire di sperimentare con un minimo di confidenza questa espansione delle possibilità offerte da LSL.

 

Posted in LSL and tagged , , , , , .

Leave a Reply

Your email address will not be published.