Jump to content

wright

Members
  • Content Count

    37
  • Joined

  • Last visited

Posts posted by wright


  1. 1 hour ago, Brandon Staggs said:

    Does anyone have an insight on what keeps a company like Embarcadero using their own servers for this kind of stuff rather than something like AWS or Azure? (This is not me making a judgment, just genuine curiosity.) 

    Why would embarcadero use their competitor's servers?
    AWS   => AMAZON 
    Azure => Microsoft (MS Visual Studio) 

    • Confused 1

  2. How to fix => F2047 Circular unit reference to 'Ics.Fmx.OverbyteIcsWSocketS' ? when compiling the "D110InstallVclFmx" project it raised that error in "IcsLinuxD110".
    I thought that was due to the changes i did for porting it (ICS v9...) on Android platform, but that wasn't the case. it occured even for win32/64 bit platform too.
    I'm talking about the ICS V9.1


  3. On 11/12/2023 at 10:16 PM, wright said:

    but i faced a lot of errors when i target android platform and compiled, it gives me errors like:

    I fixed it. I have gone through all the implementations up to above the indexed function. All errors related to what i provided, were due to the compile directives that have encompassed "Compound statements" (begin...end) in function IcsGetLocalTimeZoneBias.
    I just added some android compile directives
    :
     

    //...
    {$IFDEF ANDROID}
    var
      TimeZone: TTimeZone;
    begin
      TimeZone := TTimeZone.Local;
      Result := -Round(TimeZone.GetUtcOffset(Now).TotalMinutes);
    end;
    {$ENDIF}

     

    On 11/14/2023 at 5:00 PM, Angus Robertson said:

    just comment out the offending functions like IcsIsValidAnsiCodePage which uses ICON and IcsGetFreeDiskSpace, which are fine for Posix not seemingly Android

    Yes! i noticed that.
    I'll list all changes after succeeded tests.


  4. 2 hours ago, Angus Robertson said:

    For ICS V10, just comment out the offending functions like IcsIsValidAnsiCodePage which uses ICON

    As per the recent updates, the iconv related functions and types have been removed and replaced with cross-platform RTL functions. That's how i managed to migrate the code... but needed to be tested.

    function IcsIsValidAnsiCodePage(const CP: LongWord): Boolean;
    {$IFDEF MSWINDOWS}
    begin
        Result := IsValidCodePage(CP);
    end;
    {$ENDIF}
    {$IFDEF POSIX}
    var
      Encoding: TEncoding;
      CodePageStr: AnsiString;
      I: Integer;
    begin
      Result := (CP <> 1200) and (CP <> 1201) and (CP <> 12000) and (CP <> 12001);
      if Result then
      begin
        // Find the corresponding character encoding for the code page
        for I := Low(IconvCodepageMapping) to High(IconvCodepageMapping) do
        begin
          if IconvCodepageMapping[I].C = CP then
          begin
            CodePageStr := IconvCodepageMapping[I].A;
            Break;
          end;
        end;
    
        // Try to get the encoding for the code page
        try
          Encoding := TEncoding.GetEncoding(AnsiString(CodePageStr));
          Result := Assigned(Encoding);
        except
          on E: EEncodingError do
            Result := False;
        end;
      end;
    end;
    {$ENDIF}

    However, codes for posix should work with android platform, but we can use the TEncoding.GetEncoding method to attempt to get an encoding for the given code page. 
     

    {$IFDEF ANDROID}
    var
      Encoding: TEncoding;
    begin
      Result := (CP <> 1200) and (CP <> 1201) and (CP <> 12000) and (CP <> 12001);
      if Result then
      begin
        try
          // Attempt to get the encoding for the code page
          Encoding := TEncoding.GetEncoding(CP);
          Result := Assigned(Encoding);
        except
          // Handle encoding error
          on E: EEncodingError do
            Result := False;
        end;
      end;
    end;
    {$ENDIF}

     

    • Like 1

  5. 1 hour ago, FPiette said:

    By the way, which platform do you use? Android or Apple?

    For the moment: Android (32-64 bit)

    1 hour ago, FPiette said:

    This is very clear: FList is not defined in TIcsIntegerList. So look FList at your class declaration, it is missing. Why ? I don't know because I don't have your modified code.

    FList is declared, as i posted it in the first post.⬇️

    23 hours ago, wright said:

    type

         TIcsIntegerList = class(TObject)
         private
               FList : TList<Integer>;    // Use TList<Integer> instead of TList
               function GetCount: Integer;

    1 hour ago, FPiette said:

    Don't take offense, but if you can solve such a simple error, I doubt you can port ICS to mobile platform.

    The fact is that, i thought tha was simple, why the IDE kept showing error and compiler failed where everything was declared.
    i also tried to reorder the constructor and functions to see if it causes compile errors but nothing solved. I also checked Doc wiki for Constructor overriding, if there is something to do with mobile platform.


  6. 38 minutes ago, FPiette said:

    publish the code around the error you get.

    - E2023 Function needs result type and E2003 Undeclared identifier: 'FList'

    function TIcsIntegerList.Add(Item: Integer): Integer;
    begin
        Result := FList.Add(Pointer(Item));
    end;

    - E2004 Identifier redeclared: 'TIcsIntegerList', E2003 Undeclared identifier: 'FList'

    procedure TIcsIntegerList.Clear;
    begin
        FList.Clear;
    end;

    - E2037 Declaration of 'TIcsIntegerList' differs from previous declaration.

    constructor TIcsIntegerList.Create;
    begin
        FList := TList.Create;
    end;

    - E2004 Identifier redeclared: 'TIcsIntegerList', E2003 Undeclared identifier: 'FList', E2003 Undeclared identifier: 'Index'

    procedure TIcsIntegerList.Delete(Index: Integer);
    begin
        FList.Delete(Index);
    end;

    - E2003 Undeclared identifier: 'iconv_t',  E2003 Undeclared identifier: 'iconv_open'E2003 Undeclared identifier: 'iconv_close' and E2029 Declaration expected but 'IF' found

    {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
    function IcsIsValidAnsiCodePage(const CP: LongWord): Boolean;
    {$IFDEF MSWINDOWS}
    begin
        Result := IsValidCodePage(CP);
    end;
    {$ENDIF}
    {$IFDEF POSIX}
    {$IFDEF MACOS}
    begin
        Result := CFLocaleGetIdentifier(CP);
    end;
    {$ENDIF}
    var
        Ctx: iconv_t;
    begin
        Result := (CP <> 1200) and (CP <> 1201) and (CP <> 12000) and (CP <> 12001);
        if Result then
        begin
            Ctx := iconv_open(PAnsiChar(IcsIconvNameFromCodePage(CP)), ICONV_UNICODE);
            if Ctx = iconv_t(-1) then
                Result := False
            else begin
                iconv_close(Ctx);
                Result := True;
            end;
        end;
    end;
    {$ENDIF}

    E2003 Undeclared identifier: '_statvfs', E2003 Undeclared identifier: 'statvfs', W1023 Comparing signed and unsigned types - widened both operands, E2029 ')' expected but identifier 'f_bfree' found

    function IcsGetFreeDiskSpace(const APath: String): Int64;
    {$IFDEF MSWINDOWS}
    var
        TotalSpace, FreeSpace : Int64;
    begin
        if GetDiskFreeSpaceEx (PChar(APath), FreeSpace, TotalSpace, nil) then
            Result := FreeSpace
        else
            Result := -1;
    {$ENDIF}
    {$IFDEF POSIX}
    var
        FN  : RawByteString; // Path or file name
        Buf : _statvfs;
    begin
        FN := UnicodeToAnsi(APath, CP_UTF8);
        if statvfs(PAnsiChar(FN), Buf) = 0 then
            Result := Int64(Buf.f_bfree) * Int64(Buf.f_frsize)  { V8.65 }
        else
            Result := -1;
    {$ENDIF}
    end;

    E2034 Too many actual parameters, with variable "LBOMSize" when compiling on Android platform.

    function  IcsGetBufferCodepage(Buf: PAnsiChar; ByteCount: Integer): LongWord; { V8.07 }
    var
      LBOMSize: Integer;
    begin
      Result := IcsGetBufferCodepage(Buf, ByteCount, LBOMSize);
    end;

    - - The TIcsFileStreamW class is a Unicode version of the TFileStream class throws errors. It is a custom file stream class defined. On Android, file handling is done differently, i am still looking for a work around. 

    • E2003 Undeclared identifier: 'TIcsFileStreamW'
    • E2029 '=' expected but ';' found
    • E2029 '=' expected but ')' found
    • E2075 This form of method call only allowed in methods of derived types
    • E2003 Undeclared identifier: 'FFileName'
    • E2037 Declaration of 'TIcsFileStreamW' differs from previous declaration
    { TIcsFileStreamW }
    
    {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
    constructor TIcsFileStreamW.Create(const FileName: UnicodeString; Mode: Word);
    begin
    {$IFDEF COMPILER12_UP}
        inherited Create(FileName, Mode);
        FFileName := FileName;
    {$ELSE}
        Create(Filename, Mode, 0);
    {$ENDIF}
    end;
    
    
    {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
    constructor TIcsFileStreamW.Create(const FileName: UnicodeString; Mode: Word;
      Rights: Cardinal);
    begin
    {$IFDEF COMPILER12_UP}
        inherited Create(FileName, Mode, Rights);
        FFileName := FileName;
    {$ELSE}
        if Mode = fmCreate then
        begin
            inherited Create(IcsFileCreateW(FileName));
            if Cardinal(FHandle) = INVALID_HANDLE_VALUE then
            {$IFDEF COMPILER12_UP}
                raise Exception.CreateResFmt(@SFCreateErrorEx,
                                    [ExpandFileName(FileName),
                                    SysErrorMessage(GetLastError)]);
            {$ELSE}
                raise Exception.CreateResFmt(@SFCreateErrorEx,
                                    [IcsExpandFileNameW(FileName),
                                    SysErrorMessage(GetLastError)]);
            {$ENDIF}
    
        end
        else begin
            inherited Create(IcsFileOpenW(FileName, Mode));
            if Cardinal(FHandle) = INVALID_HANDLE_VALUE then
            {$IFDEF COMPILER12_UP}
                raise Exception.CreateResFmt(@SFCreateErrorEx,
                                    [ExpandFileName(FileName),
                                    SysErrorMessage(GetLastError)]);
            {$ELSE}
                raise Exception.CreateResFmt(@SFCreateErrorEx,
                                    [IcsExpandFileNameW(FileName),
                                    SysErrorMessage(GetLastError)]);
            {$ENDIF}
        end;
        FFileName := FileName;
    {$ENDIF}
    end;
    
    {* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *}
    constructor TIcsFileStreamW.Create(const Utf8FileName: UTF8String;
      Mode: Word);
    begin
    {$IFDEF COMPILER12_UP}
        FFileName := Utf8FileName;
        inherited Create(FFileName, Mode);
    {$ELSE}
        Create(AnsiToUnicode(Utf8FileName, CP_UTF8), Mode, 0);
    {$ENDIF}
    end;

     


  7. Really interesting! My main purpose is to have the WebSocket/Ssl modules working on my projects which target Android platform. I know that porting ICS V9.0 to Android is likely to be a more complex and time-consuming task. And by initially focusing on ICS V10, i can make quicker progress and gain valuable experience with the newer codebase but I would like to use / port "TSslWebSocketCli" with Ssl.


  8. 5 minutes ago, FPiette said:

    IMO, you don't need to change TIcsIntegerList to work on another platform. TList exists on all platforms, isn't it?

    TList exist on all platforms, yes! I followed instructions from Migrating_Delphi_Code_to_Mobile_from_Desktop and embarcadero Delphi recommends the use of TList<...>, in our case: TList<Integer> to make it Cros-platform. as in ref: Generics_Collections_TList, stackoverflow: explication of - Remy Lebeau

    2 hours ago, FPiette said:

    You should publish what you have on the lines around the error because we don't necessarily have the exact same source code as you have

    from the original file, these errors are on these lines (5912 to 5940) :

    [DCC Error] OverbyteIcsUtils.pas(5912): E2023 Function needs result type
    [DCC Error] OverbyteIcsUtils.pas(5914): E2003 Undeclared identifier: 'FList'
    [DCC Error] OverbyteIcsUtils.pas(5914): E2003 Undeclared identifier: 'Item'
    [DCC Error] OverbyteIcsUtils.pas(5919): E2004 Identifier redeclared: 'TIcsIntegerList'
    [DCC Error] OverbyteIcsUtils.pas(5921): E2003 Undeclared identifier: 'FList'
    [DCC Error] OverbyteIcsUtils.pas(5926): E2037 Declaration of 'TIcsIntegerList' differs from previous declaration
    [DCC Error] OverbyteIcsUtils.pas(5928): E2003 Undeclared identifier: 'FList'
    [DCC Error] OverbyteIcsUtils.pas(5933): E2004 Identifier redeclared: 'TIcsIntegerList'
    [DCC Error] OverbyteIcsUtils.pas(5935): E2003 Undeclared identifier: 'FList'
    [DCC Error] OverbyteIcsUtils.pas(5935): E2003 Undeclared identifier: 'Index'
    [DCC Error] OverbyteIcsUtils.pas(5940): E2037 Declaration of 'TIcsIntegerList' differs from previous declaration

     

    2 hours ago, FPiette said:

    Probably the code I wrote for Linux will help you as mobile platforms (Android, iOS share most of Linux API)

    Yes, you've done the bulk of the work, thank you for that! but there are many Types / classes which don't compile on Android/mobile platform such as: "TIcsFileStreamW" in "OverbyteIcsUtils.pas", "iconv"..."iconv_open"..., "_statvfs" (the way we get free space on disk for linux doesn't work for android, i planned to add it), "IcsGetBufferCodepage" (the way to get buffer of codepage for mobile platform need to be implemented, i 'll post mine later). As i sais i'll focus on "TIcsIntegerList" first.

    ics v9 tlist err.png


  9. HI there i just made a try, i started there!

    To work on the Android platform using compile directives, i needed to make some modifications to the code in several files. Lets focus on 'svn.overbyte.be/svn/icsv9/Source/OverbyteIcsUtils.pas'.The classTIcsIntegerList is essentially a wrapper around the TList class, since this code was designed for use in a Windows platform target, on a different platform, i needed to make some adjustments.
     

    type
        TIcsIntegerList = class(TObject)
        private
            FList     : TList<Integer>; // Use TList<Integer> instead of TList
            function  GetCount: Integer;
            function  GetFirst: Integer;
            function  GetLast: Integer;
            function  GetItem(Index: Integer): Integer;
            procedure SetItem(Index: Integer; const Value: Integer);
        public
            constructor Create; virtual;
            destructor  Destroy; override;
            function    IndexOf(Item: Integer): Integer;
            function    Add(Item: Integer): Integer; virtual;
            procedure   Assign(Source: TIcsIntegerList); virtual;
            procedure   Clear; virtual;
            procedure   Delete(Index: Integer); virtual;
            property    Count: Integer read GetCount;
            property    First: Integer read GetFirst;
            property    Last : Integer read GetLast;
            property    Items[Index: Integer] : Integer read  GetItem
                                                        write SetItem; default;
        end;
    
    // ... other codes
    
    { TIcsIntegerList }
    
    function TIcsIntegerList.Add(Item: Integer): Integer;
    begin
        Result := FList.Add(Item); // No need to typecast Item to Pointer
    end;
    
    procedure TIcsIntegerList.Clear;
    begin
        FList.Clear;
    end;
    
    constructor TIcsIntegerList.Create;
    begin
        FList := TList<Integer>.Create; // Use TList<Integer> instead of TList
    end;
    
    procedure TIcsIntegerList.Delete(Index: Integer);
    begin
        FList.Delete(Index);
    end;
    
    destructor TIcsIntegerList.Destroy;
    begin
        FList.Free;
        inherited;
    end;
    
    function TIcsIntegerList.GetCount: Integer;
    begin
        Result := FList.Count;
    end;
    
    function TIcsIntegerList.GetFirst: Integer;
    begin
        Result := FList.First; // No need to typecast FList.First to Integer
    end;
    
    function TIcsIntegerList.GetLast: Integer;
    begin
        Result := FList.Last; // No need to typecast FList.Last to Integer
    end;
    
    // ... other codes

    but i faced a lot of errors when i target android platform and compiled, it gives me errors like:
     

    [DCC Error] OverbyteIcsUtils.pas(5931): E2023 Function needs result type
    [DCC Error] OverbyteIcsUtils.pas(5933): E2003 Undeclared identifier: 'FList'
    [DCC Error] OverbyteIcsUtils.pas(5933): E2003 Undeclared identifier: 'Item'
    [DCC Error] OverbyteIcsUtils.pas(5938): E2004 Identifier redeclared: 'TIcsIntegerList'
    [DCC Error] OverbyteIcsUtils.pas(5940): E2003 Undeclared identifier: 'FList'
    [DCC Error] OverbyteIcsUtils.pas(5945): E2037 Declaration of 'TIcsIntegerList' differs from previous declaration

    ...:
    So how to fix it? Or can anyone point me to the right direction?


  10. Got it Works but in a different way than the official sample. I'm not satisfied with my procedure, i think there is a better way to do iteration  without MongoDB.

    what i changed:

     

    ...
    ListView1.Items.BeginUpdate;
      try
        LStreamReader := TStreamReader.Create('../../resto.json', TEncoding.UTF8, True);
        LJsonTextReader := TJsonTextReader.Create(LStreamReader);
        oIter := TJSONIterator.Create(LJsonTextReader);
    
        while oIter.Next() do
        begin
          oItem := ListView1.Items.Add;
          for i := 1 to ListView1.Columns.Count - 1 do
            oItem.SubItems.Add('');
    
          if oIter.&Type in [TJsonToken.StartObject, TJsonToken.StartArray] then
          begin
            oIter.Recurse;
            if oIter.Next('address') then
            begin
              oIter.Recurse;
              oIter.Next('building');
              oItem.SubItems[2] := oIter.AsString;
              oIter.Next('street');
              oItem.SubItems[1] := oIter.AsString;
              oIter.Return
            end;
            oIter.Next('borough');
            oItem.SubItems[3] := oIter.AsValue.ToString;
            oIter.Next('cuisine');
            oItem.SubItems[0] := oIter.AsValue.ToString;
            oIter.Next('name');
            oItem.Caption := oIter.AsValue.ToString;
          end;
    
          if oIter.InRecurse then
            oIter.Return
          else
            Break;
        end;
      finally
        ListView1.Items.EndUpdate;
      end;
    ...

    Result:

     

    Screenshot 2022-12-27 105039.png


  11. It seems that TJSONIterator.Path doesn't read the values at all! 

    i tried this and i still figure issues:

    cuisine doens't load.

    ............
    ListView1.Items.BeginUpdate;
      try
        LStreamReader := TStreamReader.Create('../../resto.json', TEncoding.UTF8, True);
        LJsonTextReader := TJsonTextReader.Create(LStreamReader);
        oIter := TJSONIterator.Create(LJsonTextReader);
    
        while oIter.Next() do
        begin
          oItem := ListView1.Items.Add;
          for i := 1 to ListView1.Columns.Count - 1 do
            oItem.SubItems.Add('');
    
          if oIter.&Type in [TJsonToken.StartObject, TJsonToken.StartArray] then
          begin
            oIter.Recurse;
            oIter.Next('name');
            oItem.Caption := oIter.AsValue.ToString;
            oIter.Next('cuisine');
            oItem.SubItems[0] := oIter.AsValue.ToString;
          end
          .........
          .........

     

    Screenshot 2022-12-27 105039.png

×