Jump to content

mytbo

Members
  • Content Count

    21
  • Joined

  • Last visited

Posts posted by mytbo


  1. With this data structure for the VST, it would be easier to use a class as a record for the tree data. The VST should better not hold the data, but only display it. This article shows how easy it is to map a data structure in VST. Here is the translation into English with Google Translator. The result is not perfect (rather not so good), also some formatting is destroyed, but it is readable.

     

    With best regards

    Thomas

     


  2. 3 hours ago, Thonwelling said:

    Download HTML from server, save it as a file and execute the following:Download HTML from server, save it as a file and execute the following:How can i succed with this ??? 

    Download HTML from server, save it as a file and execute the following:

    procedure TfrmMain.FormShow(Sender: TObject);
    begin
      EdgeBrowser.CreateWebView;
    end;
    
    procedure TfrmMain.EdgeBrowserCreateWebViewCompleted(Sender: TCustomEdgeBrowser; AResult: HRESULT);
    begin
      btnLoadHtml.Enabled := (AResult = 0);
    end;
    
    procedure TfrmMain.btnLoadHtmlClick(Sender: TObject);
    begin
      // ... download HTML from server, save it as a file
      EdgeBrowser.Navigate('file:///C:/Ambar/Temp/loginRetorno.html');
    end;

    With best regards

    Thomas


  3. 7 hours ago, bzwirs said:

    I need to collect all tubes data.  At this stage, specifically the coin_unit and coin_count fields.

    With mORMot it can be solved as follows (all tubes for all records, or tubes for record with index):

    uses
      mormot.core.base,
      mormot.core.text,
      mormot.core.os,
      mormot.core.variants,
      mormot.db.rad.ui;
    
    function ShowTubesForRecordIndex(pmGrid: TDBGrid; const pmcDBFileName: TFileName; pmDBRecIdx: Integer): Boolean;
    var
      docDB: TDocVariantData;
    begin
      Result := False;
      if pmGrid = Nil then Exit; //=>
    
      FreeAndNil(pmGrid.DataSource);
      if docDB.InitJsonFromFile(pmcDBFileName, JSON_FAST_FLOAT) then
      begin
        pmGrid.DataSource := TDataSource.Create(pmGrid);
        var docPath: PDocVariantData := docDB.A['records']._[pmDBRecIdx].O['coin_mech'].A['tubes'];
        pmGrid.DataSource.DataSet := DocVariantToDataSet(pmGrid.DataSource, Variant(docPath^));
        Result := (pmGrid.DataSource.DataSet <> Nil);
      end;
    end;
    
    function ShowTubesOfAllRecords(pmGrid: TDBGrid; const pmcDBFileName: TFileName): Boolean;
    var
      docDB: TDocVariantData;
      tubes: TVariantDynArray;
    begin
      Result := False;
      if pmGrid = Nil then Exit; //=>
    
      FreeAndNil(pmGrid.DataSource);
      if docDB.InitJsonFromFile(pmcDBFileName, JSON_FAST_FLOAT) then
      begin
        var docTubesPath: PDocVariantData;
        var docRecordsPath: PDocVariantData := docDB.A['records'];
        for var i: Integer := 0 to docRecordsPath.Count - 1 do
        begin
          docTubesPath := docRecordsPath._[i].O['coin_mech'].A['tubes'];
          for var n: Integer := 0 to docTubesPath.Count - 1 do
          begin
            SetLength(tubes, Length(tubes) + 1);
            tubes[High(tubes)] := Variant(docTubesPath._[n]^);
          end;
        end;
    
        if Length(tubes) > 0 then
        begin
          pmGrid.DataSource := TDataSource.Create(pmGrid);
          pmGrid.DataSource.DataSet := VariantsToDataSet(pmGrid.DataSource, tubes, Length(tubes), [], []);
          Result := (pmGrid.DataSource.DataSet <> Nil);
        end;
      end;
    end;

    Used as follows:

    var fileName: TFileName := MakePath([Executable.ProgramFilePath, 'DocDB.json']);
    ShowTubesForRecordIndex(DBGrid, fileName, 0);
    // ShowTubesOfAllRecords(DBGrid, fileName);

    I have published an article on topic mORMot DocVariant here (forum Delphi-PRAXIS). Here is the translation into English with Google Translator. The result is not perfect (rather not so good), also some formatting is destroyed, but it is readable.

     

    With best regards
    Thomas


  4. 1 hour ago, Bob Devine said:

    It was the best library when I tested a couple years back for handling nested objects...

    What problems did you have with nested objects? mORMot can serialize almost anything to JSON. And if you use class TSynAutoCreateFields, you don't have to create or destroy the child object(s) yourself. It is enough to write the following:

    type
      {$M+}
      TSubItem = class(TObject)
      private
        FSubValue: RawUtf8;
      published
        property SubValue: RawUtf8
          read FSubValue write FSubValue;
      end;
      {$M-}
    
      TItem = class(TSynAutoCreateFields)
      private
        FValue: RawUtf8;
        FSubItem: TSubItem;
      published
        property Value: RawUtf8
          read FValue write FValue;
        property SubItem: TSubItem
          read FSubItem;
      end;
    
    var
      item: TItem;
      list: TObjectList;
    begin
      list := TObjectList.Create;
      try
        for var i: Integer := 0 to 1000 do
        begin
          item := TItem.Create;
          item.Value := StringToUtf8('value' + i.ToString);
          item.SubItem.SubValue := StringToUtf8('subValue' + i.ToString);
          list.Add(item);
        end;
    
        ObjectToJsonFile(list, '_listData.json');
      finally
        list.Free;
      end;

    With best regards
    Thomas


  5. 18 hours ago, chkaufmann said:

    Can somebody recommend me another library?

    In mORMot there are many ways to process JSON. mORMot is at least factor 5 faster than your current solution and more than 20 times faster than Delphi's own classes. A few of several possibilities are:

    var
      v: Variant;
    begin
      v := _JsonFast('{"splash.annually": "normal"}');
      ShowMessage(v.Value('splash.annually'));
    
    var
      doc: TDocVariantData;
    begin
      doc.InitJson('{"splash.annually": "normal"}');
      ShowMessage(doc.S['splash.annually']);

    I have published an article on this topic here (forum Delphi-PRAXIS). Here is the translation into English with Google Translator. The result is not perfect (rather not so good), also some formatting is destroyed, but it is readable.

     

    With best regards
    Thomas


  6. 20 hours ago, RaelB said:

    I'm considering to use the filesystem for this purpose, as apposed to using a database e.g. sqlite.

    With your requirements I would prefer a SQLite database. There is an article with sample source code on this topic in the DP forum (German part). Here is the translation into English with Google Translator. The result is not perfect, also some formatting is destroyed, but it is readable.


    With best regards
    Thomas


  7. 11 hours ago, Bart Verbakel said:

    Why am I missing the array 'Int' in this JSON string?

    The problem is simple. The way you have defined the field in the record, no Rtti information is created. This can be illustrated with the following:

    var rttiType: TRttiType := TRttiContext.Create.GetType(TypeInfo(TMyRecord));
    if rttiType <> Nil then
    begin
      var recFieldType: TRttiType;
      for var field: TRttiField in rttiType.GetFields do
      begin
        recFieldType := field.FieldType;
        if recFieldType <> Nil then
          ShowMessage(recFieldType.ClassType.ClassName)
        else
          ShowMessage('Nil');
      end;
    end;

    Solution: Explicitly define your own type or use dynamic arrays.

    type
      TInt3Array = array[1..3] of Integer;

    With best regards

    Thomas

    • Like 1

  8. 30 minutes ago, Stefan Glienke said:

    Actually, it's way simpler:

    
    function BuildDigits(_Digits: UInt16; _Invalids: UInt8): UInt16;
    begin
      _Digits := UInt16((_Digits - 2048) * 11);
      _Digits := (_Digits and $FFFC) or (_Invalids and $03);
      Result := Swap(_Digits);
    end;

    IIRC a smaller than register size unsigned ordinal type will not cause an overflow when it wraps around 0 so it's not necessary to turn it into a signed to avoid that. The CPU uses 32bit register math anyway. The UInt16 of the multiplication is necessary though.

    You are right. Thanks for the explanation. I didn't realize how easy it is to bypass range-checking.

     

    With best regards

    Thomas


  9. 7 hours ago, grantful said:

    How can i drill down to

    With mORMot you can do it very easy.

    uses
      mormot.core.base,
      mormot.core.json,
      mormot.net.client;
      
    type
      TDataRec = packed record
        Count: Integer;
        Message: RawUtf8;
        SearchCriteria: RawUtf8;
        Results: array of record
          Value: RawUtf8;
          ValueId: Integer;
          Variable: RawUtf8;
          VariableId: Integer;
        end;
      end;
      
    var url: RawUtf8 := 'https://vpic.nhtsa.dot.gov/api/vehicles/decodevin/1G1BE5SM8J7207504?format=json&amp;modelyear';
    var content: RawByteString := HttpGet(url);
    if content <> '' then
    begin
      var dataRec: TDataRec;
      if RecordLoadJson(dataRec, content, TypeInfo(TDataRec)) then
      begin
        ShowMessage(dataRec.Count.ToString);
        ShowMessage(Length(dataRec.Results).ToString);
        for var i: Integer := 0 to High(dataRec.Results) do
        begin
          if dataRec.Results[i].Variable = 'Crash Imminent Braking (CIB)' then
            ShowMessage(dataRec.Results[i].VariableId.ToString);
        end;
      end;
    end;

    Additional information can be found in this article in Delphi-PRAXIS forum. Here is the translation into English with Google Translator. The result is not perfect (rather not so good), also some formatting is destroyed, but it is readable.

     

    With best regards

    Thomas


  10. 5 hours ago, David Schwartz said:

    So far, there are solutions I've found on one end that offer member management that have REST APIs but cannot be used to save a few additional user-specific data items that aren't visible to users; and on the other end there are platforms that let me save whatever I want (they're a general DB) but I'd need to build all of the member management, auth, payment processing, and security stuff into it.

    You wrote a long text but probably didn't spend a second to follow my links. If you did, what are you missing? I'm happy to take suggestions for further articles.

     

    With best regards

    Thomas


  11. I can't answer your question for ICS. I use Curl because it supports FTP/FTPS/SFTP. You can find all the information on how to use it in this forum thread.

     

    An example of a download function:

    function FTPDownloadFile(const pmcUrl, pmcUserName, pmcPassword: RawUtf8; var pmvContent: RawByteString): TCurlResult;
    var
      hnd: TCurl;
    begin
      Result := crFailedInit;
      if not CurlIsAvailable then Exit; //=>
    
      hnd := curl.easy_init;
      if hnd <> Nil then
      begin
        curl.easy_setopt(hnd, coURL, Pointer(pmcUrl));
        curl.easy_setopt(hnd, coUserName, Pointer(pmcUserName));
        curl.easy_setopt(hnd, coPassword, Pointer(pmcPassword));
        curl.easy_setopt(hnd, coWriteFunction, @CurlWriteRawByteString);
        curl.easy_setopt(hnd, coWriteData, @pmvContent);
        Result := curl.easy_perform(hnd);
        if Result <> crOk then
          pmvContent := '';
    
        curl.easy_cleanup(hnd);
      end;
    end;

    Use it like this (for an SFTP server):

    uses
      mormot.core.base,
      mormot.core.text,
      mormot.core.os,
      mormot.lib.curl;
    
    var
      url: RawUtf8;
      buffer: RawByteString;
    begin
      url := 'sftp://test.rebex.net:22/pub/example/readme.txt';
      if FTPDownloadFile(url, 'demo', 'password', buffer) = crOk then
      begin
        FileFromString(buffer, MakePath([Executable.ProgramFilePath, 'readme.txt']));
        ShowMessage(Format('Download completed: %s', [KB(Length(buffer))]));
      end;
    end;

    With best regards

    Thomas


  12. 1 hour ago, xorpas said:

    I download a latest version but the same problem

    No, you are using the wrong libcurl DLL. Please download the file only from the official site and do not use any other source. Here is the link to the Windows download. The file for curl for 32-bit has the name curl-7.87.0_4-win32-mingw.zip and SHA256: ef8730e31245ef138aba1e3f02ae02e3fce435ec89177d7c8b05de5ce3c07891. The libcurl DLL has the modification date: Wednesday, December 21, 2022, 07:05:38. File size is 4,405,320 bytes.

     

    With best regards

    Thomas

    • Like 2

  13. The all-purpose solution is Curl. The curl.exe program is part of current Windows versions. Links: GitHub, Download, Manual, libcurl C API and libcurl C examples. An encapsulation for libcurl DLL can be found in the mORMot unit mormot.lib.curl. The mORMot library does not need to be installed. Download the current commit and the static binaries from the last tag directory. Set the appropriate library and search paths in Delphi. This pattern helps to create them:

    // Simply replace the colons with the save path
    ..\src;..\src\app;..\src\core;..\src\crypt;..\src\db;..\src\lib;..\src\misc;..\src\net;..\src\orm;..\src\rest;..\src\script;..\src\soa;..\src\tools\ecc;..\src\ui;

    For many use cases you can find a template in the libcurl C examples. The following Delphi example shows the implementation for a download:

    uses
      mormot.core.base,
      mormot.core.text,
      mormot.core.os,
      mormot.lib.curl;
    
    var
      hnd: TCurl;
      url: RawUtf8;
      res: TCurlResult;
      buffer: RawByteString;
      responseSize: Int64;
    begin
      if not CurlIsAvailable then Exit; //=>
    
      hnd := curl.easy_init;
      if hnd <> Nil then
      begin
        url := 'https://icons8.com/icons/set/home.html';
        curl.easy_setopt(hnd, coURL, Pointer(url));
        curl.easy_setopt(hnd, coSSLVerifyPeer, 0);
        curl.easy_setopt(hnd, coSSLVerifyHost, 0);
        curl.easy_setopt(hnd, coWriteFunction, @CurlWriteRawByteString);
        curl.easy_setopt(hnd, coWriteData, @buffer);
        res := curl.easy_perform(hnd);
        if res = crOk then
        begin
          FileFromString(buffer, MakePath([Executable.ProgramFilePath, 'home.html']));
          
          curl.easy_getinfo(hnd, ciSizeDownloadT, responseSize);
          ShowMessage(Format('Download completed: %s', [KB(responseSize)]));
        end
        else
          ShowMessage(Format('Curl told us %d (%s)', [Ord(res), curl.easy_strerror(res)]));
    
        curl.easy_cleanup(hnd);
      end;
    end;

    An example to study is also the class TCurlHttp from the unit mormot.net.client.

     

    With best regards

    Thomas

    • Thanks 1

  14. With mORMot you can write it as follows:

    ShowMessage(Utf8ToString(VariantSaveJson(
      _Obj(['registration_ids', _Arr(['crX7c-...']), 'notification', _Obj(['title', 'Hi', 'body', 'Notification test'])]))));

    The function _Obj() uses name-value pairs. The description of _Obj() can be found in the help here and for _Arr() here. Information about TDocVariant documents can be found here.

     

    With best regards

    Thomas

×