MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

sessionStorage

+288 -1
+84
examples/spec/sessionstorage.js
··· 1 + import { test, summary } from './helpers.js'; 2 + 3 + console.log('sessionStorage Tests\n'); 4 + 5 + test('sessionStorage exists', typeof sessionStorage, 'object'); 6 + 7 + sessionStorage.setItem('key1', 'value1'); 8 + test('setItem/getItem basic', sessionStorage.getItem('key1'), 'value1'); 9 + 10 + sessionStorage.setItem('key1', 'newValue'); 11 + test('setItem overwrites', sessionStorage.getItem('key1'), 'newValue'); 12 + 13 + test('getItem non-existent', sessionStorage.getItem('nonExistent'), null); 14 + 15 + sessionStorage.clear(); 16 + test('length after clear', sessionStorage.length, 0); 17 + 18 + sessionStorage.setItem('a', '1'); 19 + test('length after 1 item', sessionStorage.length, 1); 20 + 21 + sessionStorage.setItem('b', '2'); 22 + test('length after 2 items', sessionStorage.length, 2); 23 + 24 + sessionStorage.setItem('c', '3'); 25 + test('length after 3 items', sessionStorage.length, 3); 26 + 27 + let keys = []; 28 + for (let i = 0; i < sessionStorage.length; i++) { 29 + keys.push(sessionStorage.key(i)); 30 + } 31 + test('key() returns keys', keys.length, 3); 32 + test('key() includes a', keys.includes('a'), true); 33 + test('key() includes b', keys.includes('b'), true); 34 + test('key() includes c', keys.includes('c'), true); 35 + 36 + test('key() out of bounds', sessionStorage.key(100), null); 37 + test('key() negative index', sessionStorage.key(-1), null); 38 + 39 + sessionStorage.removeItem('b'); 40 + test('removeItem decreases length', sessionStorage.length, 2); 41 + test('removeItem removes key', sessionStorage.getItem('b'), null); 42 + test('removeItem keeps others', sessionStorage.getItem('a'), '1'); 43 + 44 + sessionStorage.removeItem('nonExistent'); 45 + test('removeItem non-existent key', sessionStorage.length, 2); 46 + 47 + sessionStorage.clear(); 48 + test('clear removes all', sessionStorage.length, 0); 49 + test('clear removes a', sessionStorage.getItem('a'), null); 50 + test('clear removes c', sessionStorage.getItem('c'), null); 51 + 52 + sessionStorage.setItem('number', '42'); 53 + test('store number string', sessionStorage.getItem('number'), '42'); 54 + 55 + sessionStorage.setItem('bool', 'true'); 56 + test('store bool string', sessionStorage.getItem('bool'), 'true'); 57 + 58 + sessionStorage.setItem('empty', ''); 59 + test('store empty string', sessionStorage.getItem('empty'), ''); 60 + 61 + sessionStorage.setItem('key-with-dash', 'dash'); 62 + test('key with dash', sessionStorage.getItem('key-with-dash'), 'dash'); 63 + 64 + sessionStorage.setItem('key_with_underscore', 'underscore'); 65 + test('key with underscore', sessionStorage.getItem('key_with_underscore'), 'underscore'); 66 + 67 + sessionStorage.setItem('key.with.dot', 'dot'); 68 + test('key with dot', sessionStorage.getItem('key.with.dot'), 'dot'); 69 + 70 + sessionStorage.setItem('special', 'hello\nworld'); 71 + test('value with newline', sessionStorage.getItem('special'), 'hello\nworld'); 72 + 73 + sessionStorage.setItem('unicode', 'Hello'); 74 + test('value with unicode', sessionStorage.getItem('unicode'), 'Hello'); 75 + 76 + const obj = { name: 'John', age: 30 }; 77 + sessionStorage.setItem('user', JSON.stringify(obj)); 78 + const retrieved = JSON.parse(sessionStorage.getItem('user')); 79 + test('JSON storage name', retrieved.name, 'John'); 80 + test('JSON storage age', retrieved.age, 30); 81 + 82 + sessionStorage.clear(); 83 + 84 + summary();
+6
include/modules/sessionstorage.h
··· 1 + #ifndef SESSIONSTORAGE_H 2 + #define SESSIONSTORAGE_H 3 + 4 + void init_sessionstorage_module(void); 5 + 6 + #endif
+1 -1
meson.build
··· 75 75 build_date = run_command('date', '+%Y-%m-%d', check: true).stdout().strip() 76 76 77 77 version_conf = configuration_data() 78 - version_conf.set('ANT_VERSION', '0.2.0.9') 78 + version_conf.set('ANT_VERSION', '0.2.0.10') 79 79 version_conf.set('ANT_GIT_HASH', git_hash) 80 80 version_conf.set('ANT_BUILD_DATE', build_date) 81 81
+2
src/main.c
··· 36 36 #include "modules/reflect.h" 37 37 #include "modules/symbol.h" 38 38 #include "modules/textcodec.h" 39 + #include "modules/sessionstorage.h" 39 40 40 41 int js_result = EXIT_SUCCESS; 41 42 ··· 206 207 init_url_module(); 207 208 init_reflect_module(); 208 209 init_textcodec_module(); 210 + init_sessionstorage_module(); 209 211 210 212 ant_register_library(shell_library, "ant:shell", NULL); 211 213 ant_register_library(ffi_library, "ant:ffi", NULL);
+195
src/modules/sessionstorage.c
··· 1 + #include <stdlib.h> 2 + #include <string.h> 3 + #include <uthash.h> 4 + 5 + #include "runtime.h" 6 + #include "modules/sessionstorage.h" 7 + #include "modules/symbol.h" 8 + 9 + typedef struct storage_entry { 10 + char *key; 11 + char *value; 12 + UT_hash_handle hh; 13 + } storage_entry_t; 14 + 15 + static storage_entry_t *session_storage = NULL; 16 + 17 + static void storage_clear(void) { 18 + storage_entry_t *entry, *tmp; 19 + HASH_ITER(hh, session_storage, entry, tmp) { 20 + HASH_DEL(session_storage, entry); 21 + free(entry->key); 22 + free(entry->value); 23 + free(entry); 24 + } 25 + } 26 + 27 + static void storage_set_item(const char *key, size_t key_len, const char *value, size_t value_len) { 28 + storage_entry_t *entry = NULL; 29 + 30 + HASH_FIND(hh, session_storage, key, key_len, entry); 31 + 32 + if (entry) { 33 + free(entry->value); 34 + entry->value = malloc(value_len + 1); 35 + if (entry->value) { 36 + memcpy(entry->value, value, value_len); 37 + entry->value[value_len] = '\0'; 38 + } 39 + } else { 40 + entry = malloc(sizeof(storage_entry_t)); 41 + if (!entry) return; 42 + 43 + entry->key = malloc(key_len + 1); 44 + entry->value = malloc(value_len + 1); 45 + 46 + if (!entry->key || !entry->value) { 47 + free(entry->key); 48 + free(entry->value); 49 + free(entry); 50 + return; 51 + } 52 + 53 + memcpy(entry->key, key, key_len); 54 + entry->key[key_len] = '\0'; 55 + memcpy(entry->value, value, value_len); 56 + entry->value[value_len] = '\0'; 57 + 58 + HASH_ADD_KEYPTR(hh, session_storage, entry->key, key_len, entry); 59 + } 60 + } 61 + 62 + static char *storage_get_item(const char *key, size_t key_len) { 63 + storage_entry_t *entry = NULL; 64 + HASH_FIND(hh, session_storage, key, key_len, entry); 65 + return entry ? entry->value : NULL; 66 + } 67 + 68 + static void storage_remove_item(const char *key, size_t key_len) { 69 + storage_entry_t *entry = NULL; 70 + HASH_FIND(hh, session_storage, key, key_len, entry); 71 + 72 + if (entry) { 73 + HASH_DEL(session_storage, entry); 74 + free(entry->key); 75 + free(entry->value); 76 + free(entry); 77 + } 78 + } 79 + 80 + static size_t storage_length(void) { 81 + return HASH_COUNT(session_storage); 82 + } 83 + 84 + static char *storage_key(size_t index) { 85 + storage_entry_t *entry; 86 + size_t i = 0; 87 + 88 + for (entry = session_storage; entry != NULL; entry = entry->hh.next) { 89 + if (i == index) return entry->key; 90 + i++; 91 + } 92 + 93 + return NULL; 94 + } 95 + 96 + // sessionStorage.setItem(key, value) 97 + static jsval_t js_sessionstorage_setItem(struct js *js, jsval_t *args, int nargs) { 98 + if (nargs < 2) { 99 + return js_mkerr(js, "Failed to execute 'setItem' on 'Storage': 2 arguments required"); 100 + } 101 + 102 + size_t key_len, value_len; 103 + char *key = js_getstr(js, args[0], &key_len); 104 + char *value = js_getstr(js, args[1], &value_len); 105 + 106 + storage_set_item(key, key_len, value, value_len); 107 + 108 + return js_mkundef(); 109 + } 110 + 111 + // sessionStorage.getItem(key) 112 + static jsval_t js_sessionstorage_getItem(struct js *js, jsval_t *args, int nargs) { 113 + if (nargs < 1) { 114 + return js_mkerr(js, "Failed to execute 'getItem' on 'Storage': 1 argument required"); 115 + } 116 + 117 + size_t key_len; 118 + char *key = js_getstr(js, args[0], &key_len); 119 + char *value = storage_get_item(key, key_len); 120 + 121 + if (!value) return js_mknull(); 122 + 123 + return js_mkstr(js, value, strlen(value)); 124 + } 125 + 126 + // sessionStorage.removeItem(key) 127 + static jsval_t js_sessionstorage_removeItem(struct js *js, jsval_t *args, int nargs) { 128 + if (nargs < 1) { 129 + return js_mkerr(js, "Failed to execute 'removeItem' on 'Storage': 1 argument required"); 130 + } 131 + 132 + size_t key_len; 133 + char *key = js_getstr(js, args[0], &key_len); 134 + storage_remove_item(key, key_len); 135 + 136 + return js_mkundef(); 137 + } 138 + 139 + // sessionStorage.clear() 140 + static jsval_t js_sessionstorage_clear(struct js *js, jsval_t *args, int nargs) { 141 + (void)js; (void)args; (void)nargs; 142 + storage_clear(); 143 + return js_mkundef(); 144 + } 145 + 146 + // sessionStorage.key(index) 147 + static jsval_t js_sessionstorage_key(struct js *js, jsval_t *args, int nargs) { 148 + if (nargs < 1) { 149 + return js_mkerr(js, "Failed to execute 'key' on 'Storage': 1 argument required"); 150 + } 151 + 152 + if (js_type(args[0]) != JS_NUM) { 153 + return js_mknull(); 154 + } 155 + 156 + double idx = js_getnum(args[0]); 157 + if (idx < 0) return js_mknull(); 158 + 159 + size_t index = (size_t)idx; 160 + char *key = storage_key(index); 161 + 162 + if (!key) return js_mknull(); 163 + 164 + return js_mkstr(js, key, strlen(key)); 165 + } 166 + 167 + // sessionStorage.length 168 + static jsval_t js_sessionstorage_length(struct js *js, jsval_t *args, int nargs) { 169 + (void)js; (void)args; (void)nargs; 170 + return js_mknum((double)storage_length()); 171 + } 172 + 173 + void init_sessionstorage_module(void) { 174 + struct js *js = rt->js; 175 + jsval_t glob = js_glob(js); 176 + 177 + jsval_t storage_obj = js_mkobj(js); 178 + 179 + js_set(js, storage_obj, "setItem", js_mkfun(js_sessionstorage_setItem)); 180 + js_set(js, storage_obj, "getItem", js_mkfun(js_sessionstorage_getItem)); 181 + js_set(js, storage_obj, "removeItem", js_mkfun(js_sessionstorage_removeItem)); 182 + js_set(js, storage_obj, "clear", js_mkfun(js_sessionstorage_clear)); 183 + js_set(js, storage_obj, "key", js_mkfun(js_sessionstorage_key)); 184 + 185 + jsval_t length_getter = js_mkfun(js_sessionstorage_length); 186 + jsval_t desc = js_mkobj(js); 187 + js_set(js, desc, "get", length_getter); 188 + js_set(js, desc, "enumerable", js_mktrue()); 189 + js_set(js, desc, "configurable", js_mkfalse()); 190 + js_set(js, storage_obj, "__desc_length", desc); 191 + js_set(js, storage_obj, "__getter", js_mktrue()); 192 + 193 + js_set(js, storage_obj, get_toStringTag_sym_key(), js_mkstr(js, "Storage", 7)); 194 + js_set(js, glob, "sessionStorage", storage_obj); 195 + }