[Pas2js] [feature request + ideas] Implementing TStream based classes (TBytesStream, TFileStream, TStringStream and so on)

silvioprog silvioprog at gmail.com
Tue Nov 13 16:21:40 CET 2018


On Sat, Nov 10, 2018 at 3:41 AM Mattias Gaertner via Pas2js <
pas2js at lists.freepascal.org> wrote:
[...]

> Yes, but that is async and interactive, so has little todo with
> SaveToFile. Correct?
>

It doesn't requires user interaction. And it can be easily written in a
sync way (I awalys prefer to use async ones, but ...). Consider the
following example (please notice it is just to check and test the idea, so
it is not cross-browser, but it could be improved using FileSaver.js ideas):

// growing buffer logic / error handling was omitted to make the example
clear
type
  TBytesStream = class
  private
    FBytes: TBytes;
  public
    constructor Create(const ABytes: TBytes); virtual;
    procedure SaveToFile(const AFileName: TFileName); virtual;
    property Bytes: TBytes read FBytes;
  end;

constructor TBytesStream.Create(const ABytes: TBytes);
begin
  inherited Create;
  FBytes := ABytes;
end;

procedure TBytesStream.SaveToFile(const AFileName: TFileName); assembler;
asm
    if (window.navigator.msSaveOrOpenBlob) // IE10+
        window.navigator.msSaveOrOpenBlob(file, filename);
    else { // Others
        if (!window.Blob)
            throw "The Blob API is not supported in this browser";
        var file = new Blob([this.FBytes], {type:
"application/octet-stream"});
        var url = (URL || webkitURL).createObjectURL(file);
        var a = document.createElement("a"),
                url = URL.createObjectURL(file);
        a.href = url;
        a.download = AFileName;
        document.body.appendChild(a);
        a.click();
        setTimeout(function() {
            document.body.removeChild(a);
            window.URL.revokeObjectURL(url);
        }, 0);
    }
end;

var
  b: TBytesStream;
begin
  b := TBytesStream.Create([65, 66, 67]);
  b.SaveToFile('filename.txt');
end.

Huh? Of course you still need TJSArrayBuffer for reading binary
> data and storing large data.
>

Do you want to make it for ES6+ only? I think something like this could be
used: {$IF ECMAScript>=6}TJSArrayBuffer{$ELSE}TBytes{$ENDIF}. So ugly, but
it is just to show that ES compatibility can be easily solved. Or, in an
another way:

procedure TBytesStream.Write(...);
begin
  CheckES6Plus; // raises something like 'Not implemented in this ES
edition'
...

procedure TBytesStream.SaveToFile(...);
begin
  CheckES6Plus;
...

I used it for the nodepas2js. Not so sure about if it is awesome. It
> seems to start a lot of threads and I missed fast functions for reading
> directories. I'm spoiled by fpc.
>

I would like to test it.


> Do you mean the -P parameters like -PECMAScript6?
> Works the same:
> {$IFDEF ECMAScript6} or {$IF ECMAScript>5}


Perfect! Now I checked it and worked like a charm. It will be very useful
in this work ...

--
Silvio Clécio
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/pas2js/attachments/20181113/504fe2b5/attachment.html>


More information about the Pas2js mailing list