Skip to content

Commit

Permalink
Add InternetSocket
Browse files Browse the repository at this point in the history
  • Loading branch information
ollydev committed Dec 3, 2023
1 parent 9d49b88 commit 9bef7a4
Show file tree
Hide file tree
Showing 4 changed files with 256 additions and 3 deletions.
6 changes: 5 additions & 1 deletion Source/Simba.lpi
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@
<PackageName Value="LCL"/>
</Item5>
</RequiredPackages>
<Units Count="168">
<Units Count="169">
<Unit0>
<Filename Value="Simba.lpr"/>
<IsPartOfProject Value="True"/>
Expand Down Expand Up @@ -1110,6 +1110,10 @@
<Filename Value="simba.ide_mainmenubar.pas"/>
<IsPartOfProject Value="True"/>
</Unit167>
<Unit168>
<Filename Value="simba.internetsocket.pas"/>
<IsPartOfProject Value="True"/>
</Unit168>
</Units>
</ProjectOptions>
<CompilerOptions>
Expand Down
1 change: 0 additions & 1 deletion Source/forms/simba.main.pas
Original file line number Diff line number Diff line change
Expand Up @@ -985,7 +985,6 @@ procedure TSimbaForm.SetupDocking;

procedure TSimbaForm.SetupCompleted;
begin
WriteLn('Setup completed');
if SimbaSettings.FirstLaunch then
MenuItemAssociateScripts.Click();

Expand Down
73 changes: 72 additions & 1 deletion Source/script/imports/simba.import_web.pas
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ implementation
uses
lptypes, ffi,
fphttpclient,
simba.nativeinterface, simba.httpclient;
simba.nativeinterface, simba.httpclient, simba.internetsocket;

(*
Web
Expand Down Expand Up @@ -406,6 +406,66 @@ procedure _LapeSimbaHTTPClient_OnExtractProgress_Write(const Params: PParamArray
PSimbaHTTPClient(Params^[0])^.OnExtractProgress := TSimbaHTTPExtractingEvent(Params^[1]^);
end;

(*
TSimbaInternetSocket.Create
~~~~~~~~~~~~~~~~~~~~~~~~~~~
> function TSimbaInternetSocket.Create(AHost: String; APort: UInt16; UseSSL: Boolean): TSimbaInternetSocket; static;
*)
procedure _LapeSimbaInternetSocket_Create(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaInternetSocket(Result)^ := TSimbaInternetSocket.Create(PString(Params^[0])^, PUInt16(Params^[1])^, PBoolean(Params^[2])^);
end;

procedure _LapeSimbaInternetSocket_Connect(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaInternetSocket(Params^[0])^.Connect();
end;

procedure _LapeSimbaInternetSocket_HasData(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PBoolean(Result)^ := PSimbaInternetSocket(Params^[0])^.HasData();
end;

procedure _LapeSimbaInternetSocket_ReadString(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PString(Result)^ := PSimbaInternetSocket(Params^[0])^.ReadString(PInteger(Params^[1])^);
end;

procedure _LapeSimbaInternetSocket_ReadStringUntil(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PString(Result)^ := PSimbaInternetSocket(Params^[0])^.ReadStringUntil(PString(Params^[1])^, PInteger(Params^[2])^);
end;

procedure _LapeSimbaInternetSocket_WriteString(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PInteger(Result)^ := PSimbaInternetSocket(Params^[0])^.WriteString(PString(Params^[1])^);
end;

procedure _LapeSimbaInternetSocket_GetIOTimeout(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PInteger(Result)^ := PSimbaInternetSocket(Params^[0])^.IOTimeout;
end;

procedure _LapeSimbaInternetSocket_SetIOTimeout(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaInternetSocket(Params^[0])^.IOTimeout := PInteger(Params^[1])^;
end;

procedure _LapeSimbaInternetSocket_GetConnectTimeout(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PInteger(Result)^ := PSimbaInternetSocket(Params^[0])^.ConnectTimeout;
end;

procedure _LapeSimbaInternetSocket_SetConnectTimeout(const Params: PParamArray); LAPE_WRAPPER_CALLING_CONV
begin
PSimbaInternetSocket(Params^[0])^.ConnectTimeout := PInteger(Params^[1])^;
end;

procedure _LapeSimbaInternetSocket_LastError(const Params: PParamArray; const Result: Pointer); LAPE_WRAPPER_CALLING_CONV
begin
PInteger(Result)^ := PSimbaInternetSocket(Params^[0])^.LastError;
end;

procedure ImportWeb(Compiler: TSimbaScript_Compiler);
begin
with Compiler do
Expand Down Expand Up @@ -543,6 +603,17 @@ procedure ImportWeb(Compiler: TSimbaScript_Compiler);
TSimbaHTTPClient(Ptr^).FreeOnTerminate := True
end;

addClass('TInternetSocket');
addGlobalFunc('function TInternetSocket.Create(AHost: String; APort: UInt16; UseSSL: Boolean = False): TInternetSocket; static;', @_LapeSimbaInternetSocket_Create);
addGlobalFunc('procedure TInternetSocket.Connect;', @_LapeSimbaInternetSocket_Connect);
addGlobalFunc('function TInternetSocket.HasData: Boolean', @_LapeSimbaInternetSocket_HasData);
addGlobalFunc('function TInternetSocket.ReadString(MaxLen: Integer = 8192): String;', @_LapeSimbaInternetSocket_ReadString);
addGlobalFunc('function TInternetSocket.ReadStringUntil(Seq: String; Timeout: Integer): String;', @_LapeSimbaInternetSocket_ReadStringUntil);
addGlobalFunc('function TInternetSocket.WriteString(Str: String): Integer;', @_LapeSimbaInternetSocket_WriteString);
addGlobalFunc('function TInternetSocket.LastError: Integer;', @_LapeSimbaInternetSocket_LastError);
addClassVar('TInternetSocket', 'ConnectTimeout', 'Integer', @_LapeSimbaInternetSocket_GetConnectTimeout, @_LapeSimbaInternetSocket_SetConnectTimeout);
addClassVar('TInternetSocket', 'ReadWriteTimeout', 'Integer', @_LapeSimbaInternetSocket_GetIOTimeout, @_LapeSimbaInternetSocket_SetIOTimeout);

ImportingSection := '';
end;
end;
Expand Down
179 changes: 179 additions & 0 deletions Source/simba.internetsocket.pas
Original file line number Diff line number Diff line change
@@ -0,0 +1,179 @@
{
Author: Raymond van Venetië and Merlijn Wajer
Project: Simba (https://github.com/MerlijnWajer/Simba)
License: GNU General Public License (https://www.gnu.org/licenses/gpl-3.0)
Basic internet socket to connect to and read/write strings.
}
unit simba.internetsocket;

{$i simba.inc}

interface

uses
Classes, SysUtils, ssockets,
simba.mufasatypes, simba.baseclass;

type
PSimbaInternetSocket = ^TSimbaInternetSocket;
TSimbaInternetSocket = class(TSimbaBaseClass)
protected
FSocket: TInetSocket;
FHost: String;
FPort: UInt16;
FUseSSL: Boolean;

function GetLastError: Integer;
function GetConnectTimeout: Integer;
function GetIOTimeout: Integer;

procedure SetConnectTimeout(Value: Integer);
procedure SetIOTimeout(Value: Integer);
public
constructor Create(AHost: String; APort: UInt16; UseSSL: Boolean); reintroduce;
destructor Destroy; override;

procedure Connect;

function HasData: Boolean;

function ReadString(MaxLen: Integer = 8192): String;
function ReadStringUntil(Seq: String; Timeout: Integer): String;
function WriteString(Str: String): Integer;

property IOTimeout: Integer read GetIOTimeout Write SetIOTimeout;
property ConnectTimeout: Integer read GetConnectTimeout Write SetConnectTimeout;
property LastError: Integer read GetLastError;
end;

implementation

uses
{$ifdef unix}
BaseUnix,
{$endif}
{$ifdef windows}
WinSock2,
{$endif}
openssl, opensslsockets, sockets;

// is protected
type
TInetSocketHelper = class helper for TInetSocket
function SetSocketBlockingMode(ASocket: Integer; ABlockMode: TBlockingMode; AFDSPtr: Pointer): boolean;
end;

function TInetSocketHelper.SetSocketBlockingMode(ASocket: Integer; ABlockMode: TBlockingMode; AFDSPtr: Pointer): boolean;
begin
Result := inherited SetSocketBlockingMode(ASocket, ABlockMode, AFDSPtr);
end;

function TSimbaInternetSocket.GetLastError: Integer;
begin
Result := FSocket.LastError;
end;

function TSimbaInternetSocket.GetConnectTimeout: Integer;
begin
Result := FSocket.ConnectTimeout;
end;

function TSimbaInternetSocket.GetIOTimeout: Integer;
begin
Result := FSocket.IOTimeout;
end;

procedure TSimbaInternetSocket.SetConnectTimeout(Value: Integer);
begin
FSocket.ConnectTimeout := Value;
end;

procedure TSimbaInternetSocket.SetIOTimeout(Value: Integer);
begin
FSocket.IOTimeout := Value;
end;

constructor TSimbaInternetSocket.Create(AHost: String; APort: UInt16; UseSSL: Boolean);
begin
inherited Create();

FHost := AHost;
FPort := APort;
FUseSSL := UseSSL;

if FUseSSL then
FSocket := TInetSocket.Create(FHost, FPort, TOpenSSLSocketHandler.GetDefaultHandler())
else
FSocket := TInetSocket.Create(FHost, FPort, TSocketHandler.Create());
end;

destructor TSimbaInternetSocket.Destroy;
begin
if (FSocket <> nil) then
FreeAndNil(FSocket);

inherited Destroy;
end;

procedure TSimbaInternetSocket.Connect;
begin
if FUseSSL and (not IsSSLLoaded) then
InitSSLInterface();

FSocket.Connect();
end;

function TSimbaInternetSocket.HasData: Boolean;
var
FDS: TFDSet;
b: Byte;
begin
FSocket.SetSocketBlockingMode(FSocket.Handle, bmNonBlocking, @FDS);
FSocket.ReadFlags := MSG_PEEK;

try
Result := FSocket.Read(b, 1) > 0;
finally
FSocket.SetSocketBlockingMode(FSocket.Handle, bmBlocking, @FDS);
FSocket.ReadFlags := 0;
end;
end;

function TSimbaInternetSocket.WriteString(Str: String): Integer;
begin
if (Length(Str) > 0) then
Result := FSocket.Write(Str[1], Length(Str))
else
Result := 0;
end;

function TSimbaInternetSocket.ReadString(MaxLen: Integer): String;
begin
SetLength(Result, MaxLen);
SetLength(Result, FSocket.Read(Result[1], MaxLen));
end;

function TSimbaInternetSocket.ReadStringUntil(Seq: String; Timeout: Integer): String;
var
Read: String;
T: Integer;
begin
T := FSocket.IOTimeout;
FSocket.IOTimeout := Timeout;

Result := '';
while not Result.EndsWith(Seq) do
begin
Read := ReadString();
if (Length(Read) = 0) then
Break;

Result += Read;
end;

FSocket.IOTimeout := T;
end;

end.

0 comments on commit 9bef7a4

Please sign in to comment.