Non è raro che un'estensione necessiti di memorizzare informazioni sul proprio stato, generalmente queste informazioni contengono le impostazioni come la dimensione dei caratteri utilizzati, colori ed altro.
Ci sono casi però che richiedono la memorizzazione di informazioni temporanee, informazioni che alla chiusura dell'applicazione possono tranquillamente andare perdute, i cosiddetti dati di sessione.
Mettere in piedi un meccanismo che legga/scriva su file e che lo elimini quando l'applicazione viene chiusa è semplice ma sicuramente noioso, per fortuna si ci si può avvalere di alcune interfacce XPCOM per fare tutto questo.
nsICacheService, non solo browser
L'interfaccia NsICacheService ci permette di utilizzare la cache dell'applicazione dal nostro codice.
Questa interfaccia non è presente solo sui browser (Firefox, SeaMonkey, Flock) che la usano come cache delle pagine ma in tutte le applicazioni basate su Gecko quindi anche Thunderbird, Komodo, Kompozer e così via.
Modalità di caching
Ci sono parecchie modalità per effettuare il caching dei dati, tra queste spicca quella che permette di creare oggetti in RAM distrutti al termine dell'applicazione, STORE_IN_MEMORY.
Se ne vedrà l'uso nell'esempio sottostante, per le altre modalità si faccia riferimento a nsICache.
Un esempio pratico, memorizzare oggetti javascript
L'esempio mostrato di seguito legge e scrive dalla cache oggetti Javascript, questo è reso semplice dall'utilizzo di un parser JSON che si occupa di codificare/decodificare l'oggetto in stringa.
I metodi principali sono getObjectFromCache e storeObjectInCache che prendono in ingresso due argomenti significativi per le API di caching:
- il clientId che altro non è che un identificativo univoco del chiamante (ad esempio il nome dell'estensione)
- la key che identifica all'interno del clientId la chiave da manipolare
Un utilizzo potrebbe essere quello di scrivere un oggetto JS point per poi rileggerlo
var point = {x : 10, y : 40};
storeObjectInCache("myCache", "point", point);
var cachedPoint = getObjectFromCache("myCache", "point")
alert(cachedPoint.x + " " + cachedPoint.y);
Di seguito è riportato il codice completo che per semplicità non contiene controlli sulle exception che si possono verificare
function getObjectFromCache(clientId, keyName) {
var cacheSession = createCacheSession(clientId);
var entry = cacheSession.openCacheEntry(keyName,
Components.interfaces.nsICache.ACCESS_READ, true);
var input = entry.openInputStream(0);
// Creo uno stream utilizzabile dagli script
var siStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
.createInstance(Components.interfaces.nsIScriptableInputStream);
siStream.init(input);
var str = siStream.read(-1);
return getJSON().parse(str);
}
function storeObjectInCache(clientId, keyName, object) {
var cacheSession = createCacheSession(clientId);
var entry = cacheSession.openCacheEntry(keyName,
Components.interfaces.nsICache.ACCESS_WRITE, true);
var output = entry.openOutputStream(0);
var str = getJSON().stringify(object);
output.write(str, str.length);
entry.markValid;
entry.close();
}
function createCacheSession(clientId) {
return Components.classes["@mozilla.org/network/cache-service;1"]
.getService(Components.interfaces.nsICacheService)
.createSession(clientId, Components.interfaces.nsICache.STORE_IN_MEMORY, true);
}
function getJSON() {
// test for Firefox 3.5
if (typeof(JSON) != "undefined") {
return JSON;
}
var json = Components.classes["@mozilla.org/dom/json;1"]
.createInstance(Components.interfaces.nsIJSON);
return { stringify : json.encode, parse : json.decode};
}