Browse Source

* Webassembly browser storage API

Michaël Van Canneyt 2 months ago
parent
commit
92eb7ba81f

+ 9 - 0
packages/wasm-utils/fpmake.pp

@@ -74,6 +74,15 @@ begin
       T.Dependencies.AddUnit('wasm.regexp.shared');
       T.Dependencies.AddUnit('wasm.regexp.shared');
       T.Dependencies.AddUnit('wasm.regexp.objects');
       T.Dependencies.AddUnit('wasm.regexp.objects');
     T:=P.Targets.AddUnit('wasm.exceptions.pas');
     T:=P.Targets.AddUnit('wasm.exceptions.pas');
+
+    // Storage
+    T:=P.Targets.AddUnit('wasm.storage.shared.pas');
+    T:=P.Targets.AddUnit('wasm.storage.api.pas');
+      T.Dependencies.AddUnit('wasm.storage.shared');
+    T:=P.Targets.AddUnit('wasm.storage.objects.pas');
+      T.Dependencies.AddUnit('wasm.storage.shared');
+      T.Dependencies.AddUnit('wasm.storage.api');
+    
 {$ifndef ALLPACKAGES}
 {$ifndef ALLPACKAGES}
     Run;
     Run;
     end;
     end;

+ 21 - 0
packages/wasm-utils/src/wasm.storage.api.pas

@@ -0,0 +1,21 @@
+unit wasm.storage.api;
+
+interface
+
+uses wasm.storage.shared;
+
+function __storage_get_item(aStorageKind : Longint; aKey : PAnsiChar; aKeyLen : Integer; aResult : PPansiChar; aResultLen : PLongint) : longint; external storageExportName name storageFN_GetItem;
+
+function __storage_key(aStorageKind : Longint; aKey : integer; aResult : PPAnsichar; aResultLen : PLongint) : longint; external storageExportName name storageFN_Key;
+
+function __storage_length(aStorageKind : Longint; aResult : PLongint) : longint;external storageExportName name storageFN_length;
+
+function __storage_set_item(aStorageKind : Longint; aKey : PAnsiChar; aKeyLen : Integer; aValue : PAnsiChar; aValueLen : Integer) : longint; external storageExportName name storageFN_SetItem;
+
+function __storage_remove_item(aStorageKind : Longint; aKey : PAnsiChar; aKeyLen : Integer) : longint; external storageExportName name storageFN_RemoveItem;
+
+function __storage_clear(aStorageKind : Longint) : longint; external storageExportName name storageFN_Clear;
+
+implementation
+
+end.

+ 155 - 0
packages/wasm-utils/src/wasm.storage.objects.pas

@@ -0,0 +1,155 @@
+unit wasm.storage.objects;
+
+{$mode objfpc}
+{$h+}
+
+interface
+
+uses 
+  {$IFDEF FPC_DOTTEDUNITS}
+  System.SysUtils,
+  {$ELSE}
+  SysUtils,
+  {$ENDIF}
+  wasm.storage.shared, 
+  wasm.storage.api;
+  
+Type
+  EWasmStorage = class(Exception);
+
+  { TWasmStorage }
+
+  TWasmStorage = class(TObject)
+  private
+    FUseExceptions: Boolean;
+    function CheckRes(aRes: integer; const aOperation: String): boolean;
+  protected
+    Class function Kind : Integer; virtual; abstract;
+    function GetAndReleaseString(aValue: PAnsiChar; aValueLen: Integer): UTF8String;
+    function GetKey(aKey : Integer) : UTF8String;
+    function GetItem(const aKey : UTF8String) : UTF8String;
+    procedure SetItem(const aKey : UTF8String; const aValue : UTF8String);
+  Public  
+    function Count : Integer;
+    procedure Remove(const aKey : UTF8String);
+    procedure Clear;
+    property Items[aKey : UTF8String] : UTF8String read GetItem write SetItem;
+    property Keys[aKey : Integer] : UTF8String Read GetKey;
+    property UseExceptions : Boolean Read FUseExceptions Write FUseExceptions;
+  end;  
+  
+  TWasmLocalStorage = class(TWasmStorage)
+  protected
+    class function kind : integer; override;
+  end;  
+
+  TWasmSessionStorage = class(TWasmStorage)
+  protected
+    class function kind : integer; override;
+  end;  
+  
+implementation
+
+function TWasmStorage.CheckRes(aRes : integer; const aOperation : String) : boolean;
+
+begin
+  Result:=aRes=ESTORAGE_SUCCESS;
+  if not Result and UseExceptions then
+    Raise EWasmStorage.CreateFmt('Storage error %d for operation "%s"',[aRes,aOperation]);
+end;
+
+function TWasmStorage.GetAndReleaseString(aValue : PAnsiChar; aValueLen : Integer) : UTF8String;
+
+begin
+  Result:='';
+  if (aValue=Nil) or (aValueLen=0) then
+    exit;
+  SetLength(Result,aValueLen);
+  Move(aValue^,Result[1],aValueLen);
+  FreeMem(aValue);
+end;
+
+function TWasmStorage.GetKey(aKey : Integer) : UTF8String;
+
+var
+  lRes: longint;
+  lKeyName : PAnsiChar;
+  lKeyNameLen : Longint;
+
+begin
+  Result:='';
+  lRes:=__storage_key(kind,aKey,@lKeyName,@lKeyNameLen);
+  if not CheckRes(lRes,'GetKey') then
+    exit;
+  Result:=GetAndReleaseString(lKeyName,lKeyNameLen);
+end;
+
+function TWasmStorage.GetItem(const aKey: UTF8String): UTF8String;
+
+var
+  lRes: longint;
+  lValue : PAnsiChar;
+  lValueLen : Longint;
+
+begin
+  Result:='';
+  lRes:=__storage_get_item(kind,PAnsiChar(aKey),Length(aKey),@lValue,@lValueLen);
+  if not CheckRes(lRes,'GetItem') then
+    exit;
+  Result:=GetAndReleaseString(lValue,lValueLen);
+end;
+
+procedure TWasmStorage.SetItem(const aKey: UTF8String; const aValue: UTF8String);
+
+var
+  lRes: longint;
+  lValue : PAnsiChar;
+  lValueLen : Longint;
+
+begin
+  lRes:=__storage_set_item(kind,PAnsiChar(aKey),Length(aKey),PAnsiChar(aValue),Length(aValue));
+  CheckRes(lRes,'SetItem');
+end;
+
+function TWasmStorage.Count : Integer;
+
+var
+  lRes,lCount : Longint;
+
+begin
+  lCount:=0;
+  lRes:=__storage_length(kind,@lCount);
+  if not CheckRes(lRes,'Count') then
+    exit;
+  Result:=lCount;
+end;
+
+procedure TWasmStorage.Remove(const aKey: UTF8String);
+var
+  lRes : Longint;
+begin
+  lRes:=__storage_remove_item(kind,PAnsiChar(aKey),Length(aKey));
+  CheckRes(lRes,'Remove');
+end;
+
+procedure TWasmStorage.Clear;
+
+var
+  lRes : Longint;
+begin
+  lRes:=__storage_clear(kind);
+  CheckRes(lRes,'Remove');
+end;
+
+class function TWasmLocalStorage.kind : integer; 
+begin
+  Result:=STORAGE_LOCAL;
+end;
+
+class function TWasmSessionStorage.kind : integer; 
+begin
+  Result:=STORAGE_SESSION;
+end;
+
+end.
+  

+ 26 - 0
packages/wasm-utils/src/wasm.storage.shared.pas

@@ -0,0 +1,26 @@
+unit wasm.storage.shared;
+
+{$mode ObjFPC}
+
+interface
+
+const
+  STORAGE_LOCAL   = 0;
+  STORAGE_SESSION = 1;
+
+  ESTORAGE_SUCCESS     = 0;
+  ESTORAGE_INVALIDKIND = -1;
+
+  storageExportName    = 'storage';
+  storageFN_GetItem    = 'storage_get_item';
+  storageFN_Key        = 'storage_key';
+  storageFN_length     = 'storage_length';
+  storageFN_SetItem    = 'storage_set_item';
+  storageFN_RemoveItem = 'storage_remove_item';
+  storageFN_Clear      = 'storage_clear';
+
+
+implementation
+
+end.
+