Something went wrong. Try again.
javascript for 🐜's, a tiny runtime with big ambitions antjs.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179#include <stdlib.h>#include <string.h>#include <uthash.h>
#include "ant.h"#include "errors.h"#include "runtime.h"#include "internal.h"#include "descriptors.h"
#include "modules/symbol.h"#include "modules/sessionstorage.h"
typedef struct storage_entry { char *key; char *value; UT_hash_handle hh;} storage_entry_t;
static storage_entry_t *session_storage = NULL;
static void storage_set_item(const char *key, size_t key_len, const char *value, size_t value_len) { storage_entry_t *entry = NULL; HASH_FIND(hh, session_storage, key, key_len, entry); if (entry) { HASH_DEL(session_storage, entry); free(entry); } entry = ant_calloc(sizeof(storage_entry_t) + key_len + 1 + value_len + 1); if (!entry) return; entry->key = (char *)(entry + 1); entry->value = entry->key + key_len + 1; memcpy(entry->key, key, key_len); entry->key[key_len] = '\0'; memcpy(entry->value, value, value_len); entry->value[value_len] = '\0'; HASH_ADD_KEYPTR(hh, session_storage, entry->key, key_len, entry);}
static char *storage_get_item(const char *key, size_t key_len) { storage_entry_t *entry = NULL; HASH_FIND(hh, session_storage, key, key_len, entry); return entry ? entry->value : NULL;}
static void storage_remove_item(const char *key, size_t key_len) { storage_entry_t *entry = NULL; HASH_FIND(hh, session_storage, key, key_len, entry); if (entry) { HASH_DEL(session_storage, entry); free(entry); }}
static void storage_clear(void) { storage_entry_t *entry, *tmp; HASH_ITER(hh, session_storage, entry, tmp) { HASH_DEL(session_storage, entry); free(entry); }}
static size_t storage_length(void) { return HASH_COUNT(session_storage);}
static char *storage_key(size_t index) { storage_entry_t *entry; size_t i = 0; for (entry = session_storage; entry != NULL; entry = entry->hh.next) { if (i == index) return entry->key; i++; } return NULL;}
// sessionStorage.setItem(key, value)static ant_value_t js_sessionstorage_setItem(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 2) { return js_mkerr(js, "Failed to execute 'setItem' on 'Storage': 2 arguments required"); } size_t key_len, value_len; char *key = js_getstr(js, args[0], &key_len); char *value = js_getstr(js, js_tostring_val(js, args[1]), &value_len); storage_set_item(key, key_len, value, value_len); return js_mkundef();}
// sessionStorage.getItem(key)static ant_value_t js_sessionstorage_getItem(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) { return js_mkerr(js, "Failed to execute 'getItem' on 'Storage': 1 argument required"); } size_t key_len; char *key = js_getstr(js, args[0], &key_len); char *value = storage_get_item(key, key_len); if (!value) return js_mknull(); return js_mkstr(js, value, strlen(value));}
// sessionStorage.removeItem(key)static ant_value_t js_sessionstorage_removeItem(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) { return js_mkerr(js, "Failed to execute 'removeItem' on 'Storage': 1 argument required"); } size_t key_len; char *key = js_getstr(js, args[0], &key_len); storage_remove_item(key, key_len); return js_mkundef();}
// sessionStorage.clear()static ant_value_t js_sessionstorage_clear(ant_params_t) { storage_clear(); return js_mkundef();}
// sessionStorage.key(index)static ant_value_t js_sessionstorage_key(ant_t *js, ant_value_t *args, int nargs) { if (nargs < 1) { return js_mkerr(js, "Failed to execute 'key' on 'Storage': 1 argument required"); } if (vtype(args[0]) != T_NUM) { return js_mknull(); } double idx = js_getnum(args[0]); if (idx < 0) return js_mknull(); size_t index = (size_t)idx; char *key = storage_key(index); if (!key) return js_mknull(); return js_mkstr(js, key, strlen(key));}
// sessionStorage.lengthstatic ant_value_t js_sessionstorage_length(ant_params_t) { return js_mknum((double)storage_length());}
void init_sessionstorage_module(void) { ant_t *js = rt->js; ant_value_t glob = js_glob(js); ant_value_t storage_obj = js_mkobj(js); js_set(js, storage_obj, "setItem", js_mkfun(js_sessionstorage_setItem)); js_set(js, storage_obj, "getItem", js_mkfun(js_sessionstorage_getItem)); js_set(js, storage_obj, "removeItem", js_mkfun(js_sessionstorage_removeItem)); js_set(js, storage_obj, "clear", js_mkfun(js_sessionstorage_clear)); js_set(js, storage_obj, "key", js_mkfun(js_sessionstorage_key)); ant_value_t length_getter = js_mkfun(js_sessionstorage_length); js_set_getter_desc(js, storage_obj, "length", 6, length_getter, JS_DESC_E); js_set_sym(js, storage_obj, get_toStringTag_sym(), ANT_STRING("Storage")); js_set(js, glob, "sessionStorage", storage_obj);}