wright 2 Posted November 12, 2023 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? Share this post Link to post
FPiette 383 Posted November 13, 2023 10 hours ago, wright said: 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. IMO, you don't need to change TIcsIntegerList to work on another platform. TList exists on all platforms, isn't it? 10 hours ago, wright said: [DCC Error] OverbyteIcsUtils.pas(5933😞 E2003 Undeclared identifier: 'FList' 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. Here on line 5933, I have the closing end of constructor TIcsFileStreamW.Create. The real difficulty in porting ICS to mobile platform is to replace Windows stuff that is used in ICS code. Mainly everything related to messages. ICS make heavily use of Windows messaging system (https://learn.microsoft.com/en-us/windows/win32/winmsg/windowing) which doesn't exists at all on the mobile platform and must be replaced by something else. Probably the code I wrote for Linux will help you as mobile platforms (Android, iOS share most of Linux API). Look at http://svn.overbyte.be/svn/icsv10/Source/ Share this post Link to post
wright 2 Posted November 13, 2023 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. Share this post Link to post
Angus Robertson 574 Posted November 13, 2023 ICS V9.0 will be very difficult to convert to Android, it should work on MacOS but has not been tested for a few years due to lack of hardware and volunteers. ICS V10 is currently a very small number of units that does work on Linux for simple sockets, no SSL. Over the next year or so I will be migrating the V9 code to V10, it's a massive job. I strongly recommend that initially you concentrate on adding Android support to V10 and making the two FMX samples work on Android. You will see results far faster than working with V9. Angus 1 Share this post Link to post
wright 2 Posted November 13, 2023 (edited) 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. Edited November 13, 2023 by wright Share this post Link to post
Angus Robertson 574 Posted November 13, 2023 The TsslWebSocketCli is a very new component, not heard of any using it yet (I use the websocket server for dynamic web pages). What are you using it for? It will need the HTTPRest component, but that will be one of the first to be converted. Adding SSL to V10 is likely to be the hardest part due to the low level changes. Angus Share this post Link to post
FPiette 383 Posted November 13, 2023 2 hours ago, wright said: from the original file, these errors are on these lines (5912 to 5940) : Those line numbers are useless for me. As I already said, publish the code around the error you get. 2 hours ago, wright said: but there are many Types / classes which don't compile on Android/mobile platform That's where you have to start. I gave the URL for TWSocket, but there are already a bunch of files. Did you had a look at everything? The last thing to do is to take the whole ICS and try to rebuilt it. You'll need YEARS to to that. Start with the basis: TWSocket and then higher level components. 2 hours ago, wright said: Embarcadero recommends the use of TList<...> Embarcadero wants you to use latest feature. Generics are wonderful, but don't spend time on converting perfectly working code. You'll do that at the last stage. 28 minutes ago, wright said: My main purpose is to have the WebSocket/Ssl modules working on my projects which target Android platform That is perfect. The path to the port is the inheritance chain for the components you need. At the lowest level, there is TWSocket. Start by TWSocket I made for Linux (Work in progress anyway) and write some basic application to test your code. This is a bottom to top way of programming. Share this post Link to post
wright 2 Posted November 13, 2023 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; Share this post Link to post
Angus Robertson 574 Posted November 13, 2023 Please don't post large chunks of code in this topic, few people need to look at it. Either attach to a short message as a text file or send it by private message to whoever has requested it. Angus Share this post Link to post
FPiette 383 Posted November 13, 2023 3 hours ago, wright said: - E2023 Function needs result type and E2003 Undeclared identifier: 'FList' function TIcsIntegerList.Add(Item: Integer): Integer; begin Result := FList.Add(Pointer(Item)); end; 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. Don't take offense, but if you can solve such a simple error, I doubt you can port ICS to mobile platform. 3 hours ago, wright said: - E2003 Undeclared identifier: '_statvfs', E2003 Undeclared identifier: 'statvfs', Those symbols are defined in Posix.SysStatvfs.pas unit. Check that. By the way, which platform do you use? Android or Apple? Share this post Link to post
wright 2 Posted November 13, 2023 (edited) 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. Edited November 13, 2023 by wright Share this post Link to post
FPiette 383 Posted November 14, 2023 12 hours ago, wright said: FList is declared, as i posted it in the first post. Maybe there is a conditional compilation ($IF...) which hide the declaration? When you Ctrl-Right-Click on the offending FList, the IDE should move the caret to FList declaration, if he can find it. The error about FList is not the first error. Maybe the compiler is confused by PREVIOUS error. Always resolve the errors in the order the compiler encounter them. Another check you can do: create a manifest syntax error in TIcsIntegerList = class(TObject) and recompile. If the error is not seen, that means the compiler don't see the declaration, probably because of some conditional compilation. Another check you can do: move all TIcsIntegerList class code to a new unit, use that unit in a trivial test program and compile. Share this post Link to post
Angus Robertson 574 Posted November 14, 2023 Don't worry about the compile errors with Android, I've just installed Android support for Delphi 12 and get a load of errors when building ICS 9.1 for Android (and a couple of Linux) which I will fix or suppress in the near future. For ICS V10, just comment out the offending functions like IcsIsValidAnsiCodePage which uses ICON and IcsGetFreeDiskSpace, which are fine for Posix not seemingly not Android, doubt any of this stuff is needed to get basic sockets working on Android. And avoid changes like using generics that are unnecessary to make ICS work on Android. Angus Share this post Link to post
wright 2 Posted November 14, 2023 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} 1 Share this post Link to post
Fr0sT.Brutal 900 Posted November 17, 2023 On 11/13/2023 at 5:14 PM, Angus Robertson said: Adding SSL to V10 is likely to be the hardest part due to the low level changes. If you plan to rewrite it anyway, probably you could make it in some pluggable manner to easily integrate another TLS engines? From the client app's view, not much TLS details are ever needed at all - just be able to connect to TLS server. Some could need to accept custom certs, provide user certs or select cyphers. That's all! Share this post Link to post
wright 2 Posted November 17, 2023 (edited) 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. Edited November 17, 2023 by wright Share this post Link to post
Angus Robertson 574 Posted November 17, 2023 Quote probably you could make it in some pluggable manner to easily integrate another TLS engines? That would be a massive amount of work, OpenSSL functions are buried in a lot of ICS functions at low level. I looked at your SChannel implementation for ICS when you initially wrote it. At the time the USP was no DLLs, but there are now two separate solutions that avoid distributing separate OpenSSL DLLs, so what do you now see as the benefit of SChannel? Angus Share this post Link to post
wright 2 Posted November 19, 2023 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 Share this post Link to post
Fr0sT.Brutal 900 Posted November 20, 2023 On 11/17/2023 at 7:09 PM, Angus Robertson said: At the time the USP was no DLLs, but there are now two separate solutions that avoid distributing separate OpenSSL DLLs, so what do you now see as the benefit of SChannel? What's the 2nd solution? I guess it's not free? Well, the benefit is native implementation, free from insane upgrade policy of OpenSSL; moreover, RTL socket/http uses it as well, and so does default cURL build. To add more, there are some OpenSSL forks/analogs now (WolfSSL, BoringSSL) which could be more suitable for some needs. Abstraction of TLS layer would be awesome. Extending the subject wider, I periodically dream of a universal handler stack in TWSocket to enable things like Socket.handlers := [ ThrottleHandler, TLSHandler, HTTPTunnelHandler, TLSHandler ] (enable throttling, connect via TLS to HTTP tunnel proxy and do TLS connection to remote server) that would provide a simple interface for any combination of protocols. That way TTLSSocket would be nothing more than TWSocket with auto-created TLSHandler. Want cascade of 5 TLS HTTP tunnel proxies? No problem! Want HTTP inside MsgPack inside Protobuf inside TLS-encryption? Easy. Want custom encrypted protocol? Just write handler. Please don't take this as criticism, I admire your efforts to keep ICS up-to-date. Share this post Link to post
Angus Robertson 574 Posted November 20, 2023 The second option to avoid distributing OpenSSL DLLs was added last week, embedding the DLLs in the application and extracting them when the application is first run to a common directory, this was discussed in the last OpenSSL update message. Other related changes will happen this week. I always saw the major downside of SChannel that Microsoft is slow to add new features, and they are only added to new Windows versions, even TLS/1.2 took several years to be added to Windows 8/Server 2012 and did not support EC certificates properly. So exactly the same update policy as OpenSSL, except you have to upgrade the entire OS instead of a couple of DLLs. Angus Share this post Link to post
Fr0sT.Brutal 900 Posted November 21, 2023 23 hours ago, Angus Robertson said: embedding the DLLs Ah, that one. Workaround in fact. 23 hours ago, Angus Robertson said: Microsoft is slow to add new features Well, you're right here - each approach has its pros and cons. So it's nice when you can choose Share this post Link to post
wright 2 Posted December 11, 2023 ICS V9.1 Done! Some improvement needed. Now i'm targeting V10. Share this post Link to post
FPiette 383 Posted December 12, 2023 10 hours ago, wright said: ICS V9.1 Done! What is done exactly? Share this post Link to post
Angus Robertson 574 Posted December 12, 2023 I've asked him to send me the changed units, I'll incorporate any safe Android changes I've not already made in the next couple of weeks, busy with low level SSL improvements. Angus Share this post Link to post