* Replaced fphttpclient with indy10.
* Added compression support
@@ -103,6 +103,9 @@ Once the first none-empty line is unrecognized (no command found), the parser wi
|
||||
This can be repeated multiple times but will only be used when Method == POST.
|
||||
The Content-Type header is set automatically too.
|
||||
|
||||
`Compress[ed]`
|
||||
: Adds support for gzip,deflate compression to the connection.
|
||||
|
||||
`Call <URL>`
|
||||
: This prepares the actual call by providing the URL to be called.
|
||||
Variables in the form of `@<variablename>` are replaced accordingly.
|
||||
|
||||
@@ -24,11 +24,25 @@ interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, CustApp,
|
||||
IniFiles, fphttpclient, jsonparser, JTemplate,
|
||||
UFilter;
|
||||
IniFiles, jsonparser, JTemplate,
|
||||
UFilter, IdHTTP, IdMultipartFormData;
|
||||
|
||||
type
|
||||
|
||||
{ TRestHTTP }
|
||||
|
||||
TRestHTTP = class(TIdHTTP)
|
||||
public
|
||||
procedure Perform(AMethod, AURL: String; ARequest, AResponse: TStream);
|
||||
end;
|
||||
|
||||
{ TRestRequest }
|
||||
|
||||
TRestRequest = class(TIdHTTPRequest)
|
||||
public
|
||||
procedure Prepare;
|
||||
end;
|
||||
|
||||
{ TRestemplateApplication }
|
||||
|
||||
TRestemplateApplication = class(TCustomApplication)
|
||||
@@ -38,9 +52,10 @@ type
|
||||
FSessionIni: TIniFile;
|
||||
FTemplateName: String;
|
||||
FParser: TJTemplateParser;
|
||||
FHttp: TFPHTTPClient;
|
||||
FHttp: TRestHTTP;
|
||||
FRequest: TRestRequest;
|
||||
FContent: TStringList;
|
||||
FFormFields: TStringList;
|
||||
FFormFields: TIdMultiPartFormDataStream;
|
||||
FFilters: TFilterList;
|
||||
FBeautify: Boolean;
|
||||
FURL: String;
|
||||
@@ -67,7 +82,8 @@ type
|
||||
implementation
|
||||
|
||||
uses
|
||||
strutils, crt, UCRTHelper, fpjson, DOM, XMLRead, XMLWrite, vinfo;
|
||||
strutils, crt, UCRTHelper, fpjson, DOM, XMLRead, XMLWrite, vinfo,
|
||||
IdCompressorZLib;
|
||||
|
||||
type
|
||||
TContentType = (ctOther, ctJSON, ctXML);
|
||||
@@ -84,6 +100,22 @@ begin
|
||||
Result := (ContentType <> ctOther);
|
||||
end;
|
||||
|
||||
{ TRestRequest }
|
||||
|
||||
procedure TRestRequest.Prepare;
|
||||
begin
|
||||
//Parse RawHeaders, since they have precendence and should not be overridden!
|
||||
ProcessHeaders;
|
||||
end;
|
||||
|
||||
{ TRestHTTP }
|
||||
|
||||
procedure TRestHTTP.Perform(AMethod, AURL: String; ARequest, AResponse: TStream
|
||||
);
|
||||
begin
|
||||
DoRequest(AMethod, AURL, ARequest, AResponse, []);
|
||||
end;
|
||||
|
||||
{ TRestemplateApplication }
|
||||
|
||||
procedure TRestemplateApplication.DoRun;
|
||||
@@ -199,6 +231,11 @@ begin
|
||||
Result := True;
|
||||
CmdFormField(Copy(ALine, 11, Length(ALine)));
|
||||
end else
|
||||
if AnsiStartsStr('Compress', ALine) then
|
||||
begin
|
||||
Result := True;
|
||||
FHttp.Compressor := TIdCompressorZLib.Create(FHttp);
|
||||
end else
|
||||
if AnsiStartsStr('Call ', ALine) then
|
||||
begin
|
||||
Result := True;
|
||||
@@ -255,7 +292,11 @@ begin
|
||||
varName := Trim(Copy(AHeader, 1, i - 1));
|
||||
varValue := Trim(Copy(AHeader, i + 1, Length(AHeader)));
|
||||
|
||||
FHttp.AddHeader(varName, varValue);
|
||||
//Special handling is required for Indy
|
||||
{if SameText(varName, 'Accept-Encoding') then
|
||||
FHttp.Request.AcceptEncoding := varValue
|
||||
else}
|
||||
FRequest.RawHeaders.AddValue(varName, varValue);
|
||||
end;
|
||||
|
||||
procedure TRestemplateApplication.CmdBasicAuth(AData: String);
|
||||
@@ -268,8 +309,9 @@ begin
|
||||
while (i < Length(AData)) and (AData[i] <> separator) do
|
||||
Inc(i);
|
||||
|
||||
FHttp.UserName := Copy(AData, 2, i - 2);
|
||||
FHttp.Password := Copy(AData, i + 1, Length(AData));
|
||||
FRequest.Username := Copy(AData, 2, i - 2);
|
||||
FRequest.Password := Copy(AData, i + 1, Length(AData));
|
||||
FRequest.BasicAuthentication := True;
|
||||
end;
|
||||
|
||||
procedure TRestemplateApplication.CmdHighlight(AData: String);
|
||||
@@ -278,10 +320,18 @@ begin
|
||||
end;
|
||||
|
||||
procedure TRestemplateApplication.CmdFormField(AData: String);
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
i := 1;
|
||||
FParser.Content := AData;
|
||||
FParser.Replace;
|
||||
FFormFields.Add(FParser.Content);
|
||||
AData := FParser.Content;
|
||||
|
||||
while (i < Length(AData)) and (AData[i] <> '=') do
|
||||
Inc(i);
|
||||
|
||||
FFormFields.AddFormField(Copy(AData, 1, i - 1), Copy(AData, i + 1, Length(AData)));
|
||||
end;
|
||||
|
||||
procedure TRestemplateApplication.ProcessCall(AURL: String);
|
||||
@@ -304,23 +354,24 @@ begin
|
||||
if FContent.Count > 0 then
|
||||
begin
|
||||
request := TMemoryStream.Create;
|
||||
|
||||
// Variable replacement
|
||||
FParser.Content := FContent.Text;
|
||||
FParser.Replace;
|
||||
FContent.Text := FParser.Content;
|
||||
|
||||
FContent.SaveToStream(request);
|
||||
request.Position := 0;
|
||||
FHttp.RequestBody := request;
|
||||
end;
|
||||
|
||||
try
|
||||
//Special handling for formdata
|
||||
if SameText('POST', FMethod) and (FFormFields.Count > 0) then
|
||||
FHttp.FormPost(AURL, FFormFields, response)
|
||||
else
|
||||
FHttp.HTTPMethod(FMethod, AURL, response, []);
|
||||
FRequest.Prepare;
|
||||
FHttp.Request := FRequest;
|
||||
FHttp.HTTPOptions := FHttp.HTTPOptions + [hoNoProtocolErrorException];
|
||||
if FFormFields.Size > 0 then
|
||||
begin
|
||||
FHttp.Request.ContentType := FFormFields.RequestContentType;
|
||||
FHttp.Perform(FMethod, AURL, FFormFields, response);
|
||||
end else
|
||||
FHttp.Perform(FMethod, AURL, request, response);
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
@@ -331,16 +382,16 @@ begin
|
||||
end;
|
||||
|
||||
writeln;
|
||||
writeln('Status: ', FHttp.ResponseStatusCode, ' (', FHttp.ResponseStatusText, ')');
|
||||
writeln('Status: ', FHttp.ResponseCode, ' (', FHttp.ResponseText, ')');
|
||||
writeln;
|
||||
writeln('Headers:');
|
||||
for s in FHttp.ResponseHeaders do
|
||||
for s in FHttp.Response.RawHeaders do
|
||||
writeln(' ', s);
|
||||
writeln;
|
||||
|
||||
response.Position := 0;
|
||||
|
||||
if FBeautify and IdentifyContentType(FHttp.GetHeader(FHttp.ResponseHeaders, 'Content-Type'), contentType) then
|
||||
if FBeautify and IdentifyContentType(FHttp.Response.ContentType, contentType) then
|
||||
begin
|
||||
case contentType of
|
||||
ctJSON:
|
||||
@@ -474,8 +525,10 @@ begin
|
||||
|
||||
FSessionIni := TIniFile.Create(FConfigDir + 'session.ini');
|
||||
FContent := TStringList.Create;
|
||||
FFormFields := TStringList.Create;
|
||||
FHttp := TFPHTTPClient.Create(Self);
|
||||
FFormFields := TIdMultiPartFormDataStream.Create;
|
||||
FHttp := TRestHTTP.Create(nil);
|
||||
FRequest := TRestRequest.Create(FHttp);
|
||||
FRequest.RawHeaders.AddValue('User-Agent', 'Mozilla/4.0 (compatible; restemplate ' + VersionInfo.GetProductVersionString + ')');
|
||||
FFilters := TFilterList.Create;
|
||||
FParser := TJTemplateParser.Create;
|
||||
end;
|
||||
@@ -486,6 +539,7 @@ begin
|
||||
FContent.Free;
|
||||
FFormFields.Free;
|
||||
FHttp.Free;
|
||||
//TODO Owned? FRequest.Free;
|
||||
FFilters.Free;
|
||||
FParser.Free;
|
||||
inherited Destroy;
|
||||
|
||||
BIN
indy/Core/AboutBackground.bmp
Normal file
|
After Width: | Height: | Size: 546 KiB |
BIN
indy/Core/AboutIndyNET.resources
Normal file
BIN
indy/Core/AboutProg.res
Normal file
BIN
indy/Core/IconsDotNet/TIdAntiFreeze.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdCmdTCPClient.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdCmdTCPServer.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdConnectionIntercept.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdICMPClient.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdIOHandlerStack.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdIOHandlerStream.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdIPMCastClient.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdIPMCastServer.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdInterceptSimLog.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdInterceptThrottler.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdLogDebug.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdLogEvent.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdLogFile.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdLogStream.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdSchedulerOfThreadDefault.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdSchedulerOfThreadPool.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdServerIOHandlerStack.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdSimpleServer.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdSocksInfo.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdTCPClient.bmp
Normal file
|
After Width: | Height: | Size: 822 B |
BIN
indy/Core/IconsDotNet/TIdTCPServer.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdThreadComponent.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdTraceRoute.bmp
Normal file
|
After Width: | Height: | Size: 822 B |
BIN
indy/Core/IconsDotNet/TIdUDPClient.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IconsDotNet/TIdUDPServer.bmp
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
indy/Core/IdAbout.TWinForm.resources
Normal file
BIN
indy/Core/IdAbout.TfrmAbout.resources
Normal file
37
indy/Core/IdAbout.pas
Normal file
@@ -0,0 +1,37 @@
|
||||
unit IdAbout;
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
uses
|
||||
{$IFDEF DOTNET}
|
||||
IdAboutDotNET;
|
||||
{$ELSE}
|
||||
IdAboutVCL;
|
||||
{$ENDIF}
|
||||
|
||||
//we have a procedure for providing a product name and version in case
|
||||
//we ever want to make another product.
|
||||
procedure ShowAboutBox(const AProductName, AProductName2, AProductVersion : String);
|
||||
procedure ShowDlg;
|
||||
|
||||
implementation
|
||||
|
||||
{$IFDEF DOTNET}
|
||||
//for some reason, the Winforms designer doesn't like this in the same unit
|
||||
//as the class it's for
|
||||
{$R 'IdAboutDotNET.TfrmAbout.resources' 'IdAboutDotNET.resx'}
|
||||
{$ENDIF}
|
||||
|
||||
procedure ShowAboutBox(const AProductName, AProductName2, AProductVersion : String);
|
||||
begin
|
||||
TfrmAbout.ShowAboutBox(AProductName, AProductName2, AProductVersion);
|
||||
end;
|
||||
|
||||
procedure ShowDlg;
|
||||
begin
|
||||
TfrmAbout.ShowDlg;
|
||||
end;
|
||||
|
||||
end.
|
||||
BIN
indy/Core/IdAbout.resources
Normal file
184
indy/Core/IdAbout.resx
Normal file
@@ -0,0 +1,184 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used forserialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="imgLogo.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="imgLogo.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblName.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblName.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblName2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblName2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblVersion.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblVersion.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblCopyright.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblCopyright.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblBuiltFor.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblBuiltFor.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblLicense.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblLicense.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblPleaseVisitUs.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblPleaseVisitUs.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblURL.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblURL.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="bbtnOk.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="bbtnOk.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
</root>
|
||||
BIN
indy/Core/IdAboutDotNET.TfrmAbout.resources
Normal file
332
indy/Core/IdAboutDotNET.pas
Normal file
@@ -0,0 +1,332 @@
|
||||
unit IdAboutDotNET;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
System.Drawing, System.Collections, System.ComponentModel,
|
||||
System.Windows.Forms, System.Data;
|
||||
|
||||
type
|
||||
TfrmAbout = class(System.Windows.Forms.Form)
|
||||
{$REGION 'Designer Managed Code'}
|
||||
strict private
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
Components: System.ComponentModel.Container;
|
||||
imgLogo: System.Windows.Forms.PictureBox;
|
||||
bbtnOk: System.Windows.Forms.Button;
|
||||
lblName: System.Windows.Forms.Label;
|
||||
lblName2: System.Windows.Forms.Label;
|
||||
lblVersion: System.Windows.Forms.Label;
|
||||
lblCopyright: System.Windows.Forms.Label;
|
||||
lblBuiltFor: System.Windows.Forms.Label;
|
||||
lblLicense: System.Windows.Forms.Label;
|
||||
lblPleaseVisitUs: System.Windows.Forms.Label;
|
||||
lblURL: System.Windows.Forms.LinkLabel;
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
procedure InitializeComponent;
|
||||
procedure lblURL_LinkClicked(sender: System.Object; e: System.Windows.Forms.LinkLabelLinkClickedEventArgs);
|
||||
{$ENDREGION}
|
||||
strict protected
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
procedure Dispose(Disposing: Boolean); override;
|
||||
protected
|
||||
{ Private Declarations }
|
||||
function GetProductName: string;
|
||||
procedure SetProductName(const AValue: string);
|
||||
function GetProductName2: string;
|
||||
procedure SetProductName2(const AValue: string);
|
||||
function GetVersion: string;
|
||||
procedure SetVersion(const AValue: string);
|
||||
function LoadBitmap(AResName: string): Bitmap;
|
||||
public
|
||||
constructor Create;
|
||||
//we have a method for providing a product name and version in case
|
||||
//we ever want to make another product.
|
||||
class Procedure ShowAboutBox(const AProductName, AProductName2, AProductVersion : String);
|
||||
class Procedure ShowDlg;
|
||||
property ProductName : String read GetProductName write SetProductName;
|
||||
property ProductName2 : String read GetProductName2 write SetProductName2;
|
||||
property Version : String read GetVersion write SetVersion;
|
||||
|
||||
end;
|
||||
|
||||
[assembly: RuntimeRequiredAttribute(TypeOf(TfrmAbout))]
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
IdDsnCoreResourceStrings, System.Diagnostics,
|
||||
IdGlobal, System.Reflection, System.Resources, SysUtils;
|
||||
|
||||
const
|
||||
ResourceBaseName = 'IdAboutNET';
|
||||
{$R 'AboutIndyNET.resources'}
|
||||
|
||||
{$AUTOBOX ON}
|
||||
|
||||
{$REGION 'Windows Form Designer generated code'}
|
||||
/// <summary>
|
||||
/// Required method for Designer support -- do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
procedure TfrmAbout.InitializeComponent;
|
||||
begin
|
||||
Self.imgLogo := System.Windows.Forms.PictureBox.Create;
|
||||
Self.bbtnOk := System.Windows.Forms.Button.Create;
|
||||
Self.lblName := System.Windows.Forms.Label.Create;
|
||||
Self.lblName2 := System.Windows.Forms.Label.Create;
|
||||
Self.lblVersion := System.Windows.Forms.Label.Create;
|
||||
Self.lblCopyright := System.Windows.Forms.Label.Create;
|
||||
Self.lblBuiltFor := System.Windows.Forms.Label.Create;
|
||||
Self.lblLicense := System.Windows.Forms.Label.Create;
|
||||
Self.lblPleaseVisitUs := System.Windows.Forms.Label.Create;
|
||||
Self.lblURL := System.Windows.Forms.LinkLabel.Create;
|
||||
Self.SuspendLayout;
|
||||
//
|
||||
// imgLogo
|
||||
//
|
||||
Self.imgLogo.Location := System.Drawing.Point.Create(0, 0);
|
||||
Self.imgLogo.Name := 'imgLogo';
|
||||
Self.imgLogo.Size := System.Drawing.Size.Create(388, 240);
|
||||
Self.imgLogo.TabIndex := 0;
|
||||
Self.imgLogo.TabStop := False;
|
||||
//
|
||||
// bbtnOk
|
||||
//
|
||||
Self.bbtnOk.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Bottom
|
||||
or System.Windows.Forms.AnchorStyles.Right)));
|
||||
Self.bbtnOk.DialogResult := System.Windows.Forms.DialogResult.Cancel;
|
||||
Self.bbtnOk.Location := System.Drawing.Point.Create(475, 302);
|
||||
Self.bbtnOk.Name := 'bbtnOk';
|
||||
Self.bbtnOk.TabIndex := 0;
|
||||
Self.bbtnOk.Text := 'Button1';
|
||||
//
|
||||
// lblName
|
||||
//
|
||||
Self.lblName.Font := System.Drawing.Font.Create('Arial Black', 14.25, System.Drawing.FontStyle.Regular,
|
||||
System.Drawing.GraphicsUnit.Point, (Byte(0)));
|
||||
Self.lblName.Location := System.Drawing.Point.Create(51, 28);
|
||||
Self.lblName.Name := 'lblName';
|
||||
Self.lblName.Size := System.Drawing.Size.Create(200, 101);
|
||||
Self.lblName.TabIndex := 1;
|
||||
Self.lblName.Text := 'Label1';
|
||||
Self.lblName.TextAlign := System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// lblName2
|
||||
//
|
||||
Self.lblName.Font := System.Drawing.Font.Create('Arial', 14.25, System.Drawing.FontStyle.Regular,
|
||||
System.Drawing.GraphicsUnit.Point, (Byte(0)));
|
||||
Self.lblName.Location := System.Drawing.Point.Create(54, 110);
|
||||
Self.lblName.Name := 'lblName';
|
||||
Self.lblName.Size := System.Drawing.Size.Create(192, 35);
|
||||
Self.lblName.TabIndex := 2;
|
||||
Self.lblName.Text := 'Label2';
|
||||
Self.lblName.TextAlign := System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// lblVersion
|
||||
//
|
||||
Self.lblVersion.Font := System.Drawing.Font.Create('Arial', 14.25,
|
||||
System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, (Byte(0)));
|
||||
Self.lblVersion.Location := System.Drawing.Point.Create(300, 170);
|
||||
Self.lblVersion.Name := 'lblVersion';
|
||||
Self.lblVersion.Size := System.Drawing.Size.Create(200, 17);
|
||||
Self.lblVersion.TabIndex := 3;
|
||||
Self.lblVersion.Text := 'Label3';
|
||||
Self.lblVersion.TextAlign := System.Drawing.ContentAlignment.TopRight;
|
||||
//
|
||||
// lblCopyright
|
||||
//
|
||||
Self.lblCopyright.Font := System.Drawing.Font.Create('Arial', 14.25,
|
||||
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (Byte(0)));
|
||||
Self.lblCopyright.Location := System.Drawing.Point.Create(58, 171);
|
||||
Self.lblCopyright.Name := 'lblCopyright';
|
||||
Self.lblCopyright.Size := System.Drawing.Size.Create(138, 15);
|
||||
Self.lblCopyright.TabIndex := 6;
|
||||
Self.lblCopyright.Text := 'Label6';
|
||||
Self.lblCopyright.TextAlign := System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// lblBuiltFor
|
||||
//
|
||||
Self.lblBuiltFor.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Top
|
||||
or System.Windows.Forms.AnchorStyles.Right)));
|
||||
Self.lblBuiltFor.Font := System.Drawing.Font.Create('Arial', 14.25,
|
||||
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (Byte(0)));
|
||||
Self.lblBuiltFor.Location := System.Drawing.Point.Create(300, 188);
|
||||
Self.lblBuiltFor.Name := 'lblBuiltFor';
|
||||
Self.lblBuiltFor.Size := System.Drawing.Size.Create(200, 17);
|
||||
Self.lblBuiltFor.TabIndex := 4;
|
||||
Self.lblBuiltFor.Text := 'Label4';
|
||||
Self.lblBuiltFor.TextAlign := System.Drawing.ContentAlignment.TopRight;
|
||||
//
|
||||
// lblLicense
|
||||
//
|
||||
Self.lblLicense.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Top
|
||||
or System.Windows.Forms.AnchorStyles.Right)));
|
||||
Self.lblLicense.Font := System.Drawing.Font.Create('Arial', 14.25,
|
||||
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (Byte(0)));
|
||||
Self.lblLicense.Location := System.Drawing.Point.Create(300, 227);
|
||||
Self.lblLicense.Name := 'lblLicense';
|
||||
Self.lblLicense.Size := System.Drawing.Size.Create(200, 45);
|
||||
Self.lblLicense.TabIndex := 5;
|
||||
Self.lblLicense.Text := 'Label5';
|
||||
Self.lblBuiltFor.TextAlign := System.Drawing.ContentAlignment.TopRight;
|
||||
//
|
||||
// lblPleaseVisitUs
|
||||
//
|
||||
Self.lblPleaseVisitUs.Font := System.Drawing.Font.Create('Arial', 14.25,
|
||||
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (Byte(0)));
|
||||
Self.lblPleaseVisitUs.Location := System.Drawing.Point.Create(58, 278);
|
||||
Self.lblPleaseVisitUs.Name := 'lblPleaseVisitUs';
|
||||
Self.lblPleaseVisitUs.Size := System.Drawing.Size.Create(276, 15);
|
||||
Self.lblPleaseVisitUs.TabIndex := 7;
|
||||
Self.lblPleaseVisitUs.Text := 'Label7';
|
||||
Self.lblPleaseVisitUs.TextAlign := System.Drawing.ContentAlignment.TopCenter;
|
||||
//
|
||||
// lblURL
|
||||
//
|
||||
Self.lblCopyright.Font := System.Drawing.Font.Create('Arial', 14.25,
|
||||
System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, (Byte(0)));
|
||||
Self.lblURL.Location := System.Drawing.Point.Create(58, 292);
|
||||
Self.lblURL.Name := 'lblURL';
|
||||
Self.lblURL.Size := System.Drawing.Size.Create(141, 15);
|
||||
Self.lblURL.TabIndex := 8;
|
||||
Self.lblURL.TabStop := True;
|
||||
Self.lblURL.Text := 'LinkLabel8';
|
||||
Self.lblURL.TextAlign := System.Drawing.ContentAlignment.TopCenter;
|
||||
Include(Self.lblURL.LinkClicked, Self.lblURL_LinkClicked);
|
||||
//
|
||||
// TfrmAbout
|
||||
//
|
||||
Self.AcceptButton := Self.bbtnOk;
|
||||
Self.AutoScaleBaseSize := System.Drawing.Size.Create(5, 13);
|
||||
Self.CancelButton := Self.bbtnOk;
|
||||
Self.ClientSize := System.Drawing.Size.Create(336, 554);
|
||||
Self.Controls.Add(Self.lblURL);
|
||||
Self.Controls.Add(Self.lblPleaseVisitUs);
|
||||
Self.Controls.Add(Self.lblCopyright);
|
||||
Self.Controls.Add(Self.lblVersion);
|
||||
Self.Controls.Add(Self.lblName);
|
||||
Self.Controls.Add(Self.lblName2);
|
||||
Self.Controls.Add(Self.lblBuiltFor);
|
||||
Self.Controls.Add(Self.lblLicense);
|
||||
Self.Controls.Add(Self.bbtnOk);
|
||||
Self.Controls.Add(Self.imgLogo);
|
||||
Self.FormBorderStyle := System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
Self.MaximizeBox := False;
|
||||
Self.MinimizeBox := False;
|
||||
Self.Name := 'TfrmAbout';
|
||||
Self.ShowInTaskbar := False;
|
||||
Self.StartPosition := System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
Self.Text := 'WinForm';
|
||||
Self.ResumeLayout(False);
|
||||
end;
|
||||
{$ENDREGION}
|
||||
|
||||
procedure TfrmAbout.Dispose(Disposing: Boolean);
|
||||
begin
|
||||
if Disposing then
|
||||
begin
|
||||
if Components <> nil then
|
||||
Components.Dispose();
|
||||
end;
|
||||
inherited Dispose(Disposing);
|
||||
end;
|
||||
|
||||
constructor TfrmAbout.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent;
|
||||
//
|
||||
// TODO: Add any constructor code after InitializeComponent call
|
||||
//
|
||||
Self.Text := RSAAboutFormCaption;
|
||||
lblName.Text := RSAAboutBoxTitle1;
|
||||
lblName2.Text := RSAAboutBoxTitle2;
|
||||
lblBuiltFor.Text := IndyFormat(RSAAboutBoxBuiltFor, ['DotNET']);
|
||||
lblLicense.Text := RSAAboutBoxLicences;
|
||||
lblCopyright.Text := RSAAboutBoxCopyright;
|
||||
lblPleaseVisitUs.Text := RSAAboutBoxPleaseVisit;
|
||||
lblURL.Text := RSAAboutBoxIndyWebsite;
|
||||
lblURL.Links.Add(0, Length(RSAABoutBoxIndyWebsite), RSAAboutBoxIndyWebsite);
|
||||
bbtnOk.Text := RSOk;
|
||||
imgLogo.Image := LoadBitmap('AboutBackground.bmp');
|
||||
end;
|
||||
|
||||
procedure TfrmAbout.SetProductName(const AValue : String);
|
||||
begin
|
||||
Self.lblName.Text := AValue;
|
||||
end;
|
||||
|
||||
procedure TfrmAbout.SetProductName2(const AValue : String);
|
||||
begin
|
||||
Self.lblName2.Text := AValue;
|
||||
end;
|
||||
|
||||
procedure TfrmAbout.SetVersion(const AValue: string);
|
||||
begin
|
||||
Self.lblVersion.Text := AValue;
|
||||
end;
|
||||
|
||||
function TfrmAbout.GetVersion: string;
|
||||
begin
|
||||
Result := Self.lblVersion.Text;
|
||||
end;
|
||||
|
||||
function TfrmAbout.GetProductName: string;
|
||||
begin
|
||||
Result := Self.lblName.Text;
|
||||
end;
|
||||
|
||||
function TfrmAbout.GetProductName2: string;
|
||||
begin
|
||||
Result := Self.lblName2.Text;
|
||||
end;
|
||||
|
||||
class procedure TfrmAbout.ShowAboutBox(const AProductName, AProductName2,
|
||||
AProductVersion: String);
|
||||
begin
|
||||
with TfrmAbout.Create do
|
||||
try
|
||||
Version := IndyFormat(RSAAboutBoxVersion, [AProductVersion]);
|
||||
ProductName := AProductName;
|
||||
ProductName2 := AProductName2;
|
||||
Text := AProductName;
|
||||
ShowDialog;
|
||||
finally
|
||||
Dispose;
|
||||
end;
|
||||
end;
|
||||
|
||||
class procedure TfrmAbout.ShowDlg;
|
||||
begin
|
||||
ShowAboutBox(RSAAboutBoxTitle1, RSAAboutBoxTitle2, gsIdVersion);
|
||||
end;
|
||||
|
||||
procedure TfrmAbout.lblURL_LinkClicked(sender: System.Object; e: System.Windows.Forms.LinkLabelLinkClickedEventArgs);
|
||||
var
|
||||
LDest : String;
|
||||
begin
|
||||
LDest := e.Link.LinkData as string;
|
||||
System.Diagnostics.Process.Start(LDest);
|
||||
e.Link.Visited := True;
|
||||
end;
|
||||
|
||||
function TfrmAbout.LoadBitmap(AResName: string): Bitmap;
|
||||
var
|
||||
LR: System.Resources.ResourceManager;
|
||||
begin
|
||||
LR := System.Resources.ResourceManager.Create('AboutIndyNET', System.Reflection.Assembly.GetExecutingAssembly);
|
||||
Result := (Bitmap(LR.GetObject(AResName)));
|
||||
end;
|
||||
|
||||
end.
|
||||
BIN
indy/Core/IdAboutDotNET.resources
Normal file
184
indy/Core/IdAboutDotNET.resx
Normal file
@@ -0,0 +1,184 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used forserialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="imgLogo.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="imgLogo.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="bbtnOk.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="bbtnOk.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblName.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblName.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblName2.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblName2.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblVersion.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblVersion.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblCopyright.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblCopyright.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblBuiltFor.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblBuiltFor.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblLicense.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblLicense.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblPleaseVisitUs.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblPleaseVisitUs.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblURL.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblURL.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
</root>
|
||||
BIN
indy/Core/IdAboutNET.resources
Normal file
BIN
indy/Core/IdAboutVCL.RES
Normal file
5438
indy/Core/IdAboutVCL.lrs
Normal file
420
indy/Core/IdAboutVCL.pas
Normal file
@@ -0,0 +1,420 @@
|
||||
unit IdAboutVCL;
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
uses
|
||||
{$IFDEF WIDGET_KYLIX}
|
||||
QStdCtrls, QForms, QExtCtrls, QControls, QComCtrls, QGraphics, Qt,
|
||||
{$ENDIF}
|
||||
{$IFDEF WIDGET_VCL_LIKE}
|
||||
StdCtrls, Buttons, ExtCtrls, Graphics, Controls, ComCtrls, Forms,
|
||||
{$ENDIF}
|
||||
{$IFDEF HAS_UNIT_Types}
|
||||
Types,
|
||||
{$ENDIF}
|
||||
{$IFDEF WIDGET_LCL}
|
||||
LResources,
|
||||
{$ENDIF}
|
||||
Classes, SysUtils;
|
||||
|
||||
type
|
||||
TfrmAbout = class(TForm)
|
||||
protected
|
||||
FimLogo : TImage;
|
||||
FlblCopyRight : TLabel;
|
||||
FlblName : TLabel;
|
||||
FlblName2 : TLabel;
|
||||
FlblVersion : TLabel;
|
||||
FlblBuiltFor : TLabel;
|
||||
FlblLicense : TLabel;
|
||||
FlblPleaseVisitUs : TLabel;
|
||||
FlblURL : TLabel;
|
||||
//for LCL, we use a TBitBtn to be consistant with some GUI interfaces
|
||||
//and the Lazarus IDE.
|
||||
{$IFDEF USE_TBitBtn}
|
||||
FbbtnOk : TBitBtn;
|
||||
{$ELSE}
|
||||
FbbtnOk : TButton;
|
||||
{$ENDIF}
|
||||
procedure lblURLClick(Sender: TObject);
|
||||
function GetProductName: String;
|
||||
procedure SetProductName(const AValue: String);
|
||||
function GetProductName2: String;
|
||||
procedure SetProductName2(const AValue: String);
|
||||
function GetVersion: String;
|
||||
procedure SetVersion(const AValue: String);
|
||||
public
|
||||
//we have a method for providing a product name and version in case
|
||||
//we ever want to make another product.
|
||||
class procedure ShowDlg;
|
||||
class procedure ShowAboutBox(const AProductName, AProductName2, AProductVersion: String);
|
||||
constructor Create(AOwner : TComponent); overload; override;
|
||||
constructor Create; reintroduce; overload;
|
||||
property ProductName : String read GetProductName write SetProductName;
|
||||
property ProductName2 : String read GetProductName2 write SetProductName2;
|
||||
property Version : String read GetVersion write SetVersion;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{$IFNDEF WIDGET_LCL}
|
||||
{$IFDEF WIN32_OR_WIN64}
|
||||
{$R IdAboutVCL.RES}
|
||||
{$ENDIF}
|
||||
{$IFDEF KYLIX}
|
||||
{$R IdAboutVCL.RES}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
uses
|
||||
{$IFDEF WIN32_OR_WIN64}ShellApi, {$ENDIF}
|
||||
{$IFNDEF WIDGET_LCL}
|
||||
//done this way because we reference HInstance in Delphi for loading
|
||||
//resources. Lazarus does something different.
|
||||
{$IFDEF WIN32_OR_WIN64}
|
||||
Windows,
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
IdDsnCoreResourceStrings,
|
||||
IdGlobal;
|
||||
|
||||
{$IFNDEF WIDGET_LCL}
|
||||
function RGBToColor(R, G, B: Byte): TColor;
|
||||
begin
|
||||
Result := RGB(R, G, B);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{ TfrmAbout }
|
||||
|
||||
constructor TfrmAbout.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited CreateNew(AOwner,0);
|
||||
|
||||
FimLogo := TImage.Create(Self);
|
||||
FlblCopyRight := TLabel.Create(Self);
|
||||
FlblName := TLabel.Create(Self);
|
||||
FlblName2 := TLabel.Create(Self);
|
||||
FlblVersion := TLabel.Create(Self);
|
||||
FlblBuiltFor := TLabel.Create(Self);
|
||||
FlblLicense := TLabel.Create(Self);
|
||||
FlblPleaseVisitUs := TLabel.Create(Self);
|
||||
FlblURL := TLabel.Create(Self);
|
||||
{$IFDEF USE_TBitBtn}
|
||||
FbbtnOk := TBitBtn.Create(Self);
|
||||
{$ELSE}
|
||||
FbbtnOk := TButton.Create(Self);
|
||||
{$ENDIF}
|
||||
|
||||
Name := 'formAbout';
|
||||
Left := 0;
|
||||
Top := 0;
|
||||
Anchors := [];//[akLeft, akTop, akRight,akBottom];
|
||||
BorderIcons := [biSystemMenu];
|
||||
BorderStyle := bsDialog;
|
||||
|
||||
Caption := RSAAboutFormCaption;
|
||||
ClientHeight := 336;
|
||||
ClientWidth := 554;
|
||||
Color := 2520226; // RGBToColor(38, 116, 162)
|
||||
|
||||
Font.Color := 16776138; // RGBToColor(202, 251, 255)
|
||||
Font.Height := -12;
|
||||
Font.Size := 9;
|
||||
Font.Name := 'Arial';
|
||||
Font.Style := [];
|
||||
Position := poScreenCenter;
|
||||
{$IFDEF WIDGET_VCL}
|
||||
Scaled := True;
|
||||
{$ENDIF}
|
||||
Constraints.MinHeight := Height;
|
||||
Constraints.MinWidth := Width;
|
||||
// PixelsPerInch := 96;
|
||||
|
||||
FimLogo.Name := 'imLogo';
|
||||
FimLogo.Parent := Self;
|
||||
FimLogo.Left := 0;
|
||||
FimLogo.Top := 0;
|
||||
FimLogo.Width := 388;
|
||||
FimLogo.Height := 240;
|
||||
|
||||
{$IFDEF WIDGET_LCL}
|
||||
FimLogo.Picture.Pixmap.LoadFromLazarusResource('IndyAboutBkgnd'); //this is XPM format, so Pixmap is used
|
||||
FimLogo.Align := alClient;
|
||||
FimLogo.Stretch := True;
|
||||
{$ELSE} // Because Lazarus is also WIDGET_VCL_LIKE_OR_KYLIX
|
||||
{$IFDEF WIDGET_VCL_LIKE_OR_KYLIX}
|
||||
FimLogo.Picture.Bitmap.LoadFromResourceName(HInstance, 'INDY_ABOUT_BACKGROUND'); {Do not Localize}
|
||||
FimLogo.Align := alClient;
|
||||
FimLogo.Stretch := True;
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
FlblName.Name := 'lblName';
|
||||
FlblName.Parent := Self;
|
||||
FlblName.Left := 51;
|
||||
FlblName.Top := 28;
|
||||
FlblName.Width := 200;
|
||||
FlblName.Height := 101;
|
||||
FlblName.Anchors := [akLeft, akTop];
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblName.Font.Charset := DEFAULT_CHARSET;
|
||||
FlblName.Transparent := True;
|
||||
{$ENDIF}
|
||||
FlblName.Font.Color := clWhite;
|
||||
FlblName.Font.Height := -72;
|
||||
FlblName.Font.Name := 'Arial Black';
|
||||
FlblName.Font.Style := [];
|
||||
FlblName.ParentFont := False;
|
||||
FlblName.WordWrap := False;
|
||||
FlblName.Caption := RSAAboutBoxTitle1;
|
||||
|
||||
FlblName2.Name := 'lblName2';
|
||||
FlblName2.Parent := Self;
|
||||
FlblName2.Left := 54;
|
||||
FlblName2.Top := 110;
|
||||
FlblName2.Width := 192;
|
||||
FlblName2.Height := 35;
|
||||
FlblName2.Anchors := [akLeft, akTop];
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblName2.Font.Charset := DEFAULT_CHARSET;
|
||||
FlblName2.Transparent := True;
|
||||
{$ENDIF}
|
||||
FlblName2.Font.Color := clWhite;
|
||||
FlblName2.Font.Height := -31;
|
||||
FlblName2.Font.Name := 'Arial';
|
||||
FlblName2.Font.Style := [];
|
||||
FlblName2.ParentFont := False;
|
||||
FlblName2.WordWrap := False;
|
||||
FlblName2.Caption := RSAAboutBoxTitle2;
|
||||
|
||||
FlblVersion.Name := 'lblVersion';
|
||||
FlblVersion.Parent := Self;
|
||||
FlblVersion.Left := 300;
|
||||
FlblVersion.Top := 170;
|
||||
FlblVersion.Width := 200;
|
||||
FlblVersion.Height := 17;
|
||||
FlblVersion.Alignment := taRightJustify;
|
||||
FlblVersion.AutoSize := False;
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblVersion.Font.Charset := DEFAULT_CHARSET;
|
||||
FlblVersion.Transparent := True;
|
||||
{$ENDIF}
|
||||
FlblVersion.Font.Color := 16776138; // RGBToColor(202, 251, 255)
|
||||
FlblVersion.Font.Height := -15;
|
||||
FlblVersion.Font.Name := 'Arial';
|
||||
FlblVersion.Font.Style := [fsBold];
|
||||
FlblVersion.ParentFont := False;
|
||||
FlblVersion.Anchors := [akTop, akRight];
|
||||
|
||||
FlblBuiltFor.Name := 'lblBuiltFor';
|
||||
FlblBuiltFor.Parent := Self;
|
||||
FlblBuiltFor.Left := 300;
|
||||
FlblBuiltFor.Top := 188;
|
||||
FlblBuiltFor.Width := 200;
|
||||
FlblBuiltFor.Height := 17;
|
||||
FlblBuiltFor.Alignment := taRightJustify;
|
||||
FlblBuiltFor.AutoSize := False;
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblBuiltFor.Font.Charset := DEFAULT_CHARSET;
|
||||
FlblBuiltFor.Transparent := True;
|
||||
{$ENDIF}
|
||||
FlblBuiltFor.Font.Color := 16776138; // RGBToColor(202, 251, 255)
|
||||
FlblBuiltFor.Font.Height := -14;
|
||||
FlblBuiltFor.Font.Name := 'Arial';
|
||||
FlblBuiltFor.Font.Style := [];
|
||||
FlblBuiltFor.ParentFont := False;
|
||||
FlblBuiltFor.Anchors := [akTop, akRight];
|
||||
|
||||
// RLebeau: not using resouce strings for the product names because:
|
||||
// 1. the names are pretty specific and not likely to change with localization;
|
||||
// 2. we are trying to avoid using IFDEFs in resource units, per Embarcadero's request;
|
||||
// 3. I don't want to create more product-specific resource units unless we really need them;
|
||||
{$IFDEF WIDGET_KYLIX}
|
||||
FlblBuiltFor.Caption := IndyFormat(RSAAboutBoxBuiltFor, ['Kylix']);
|
||||
{$ELSE}
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblBuiltFor.Caption := IndyFormat(RSAAboutBoxBuiltFor, ['VCL']);
|
||||
{$ELSE}
|
||||
{$IFDEF WIDGET_LCL}
|
||||
FlblBuiltFor.Caption := IndyFormat(RSAAboutBoxBuiltFor, ['Lazarus']);
|
||||
{$ELSE}
|
||||
FlblBuiltFor.Caption := IndyFormat(RSAAboutBoxBuiltFor, ['Unknown']);
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
FlblLicense.Name := 'lblLicense';
|
||||
FlblLicense.Parent := Self;
|
||||
FlblLicense.Left := 300;
|
||||
FlblLicense.Top := 227;
|
||||
FlblLicense.Width := 200;
|
||||
FlblLicense.Height := 45;
|
||||
FlblLicense.Alignment := taRightJustify;
|
||||
FlblLicense.AutoSize := False;
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblLicense.Font.Charset := DEFAULT_CHARSET;
|
||||
FlblLicense.Transparent := True;
|
||||
{$ENDIF}
|
||||
FlblLicense.Font.Color := 16776138; // RGBToColor(202, 251, 255)
|
||||
FlblLicense.Font.Height := -12;
|
||||
FlblLicense.Font.Name := 'Arial';
|
||||
FlblLicense.Font.Style := [];
|
||||
FlblLicense.ParentFont := False;
|
||||
FlblLicense.WordWrap := True;
|
||||
FlblLicense.Anchors := [akTop, akRight];
|
||||
FlblLicense.Caption := RSAAboutBoxLicences;
|
||||
|
||||
FlblCopyRight.Name := 'lblCopyRight';
|
||||
FlblCopyRight.Parent := Self;
|
||||
FlblCopyRight.Left := 58;
|
||||
FlblCopyRight.Top := 171;
|
||||
FlblCopyRight.Width := 138;
|
||||
FlblCopyRight.Height := 15;
|
||||
FlblCopyRight.Caption := RSAAboutBoxCopyright;
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblCopyRight.Font.Charset := DEFAULT_CHARSET;
|
||||
FlblCopyRight.Transparent := True;
|
||||
{$ENDIF}
|
||||
FlblCopyRight.Font.Color := 16776138; // RGBToColor(202, 251, 255)
|
||||
FlblCopyRight.Font.Height := -12;
|
||||
FlblCopyRight.Font.Name := 'Arial';
|
||||
FlblCopyRight.Font.Style := [];
|
||||
FlblCopyRight.ParentFont := False;
|
||||
FlblCopyRight.WordWrap := True;
|
||||
|
||||
FlblPleaseVisitUs.Name := 'lblPleaseVisitUs';
|
||||
FlblPleaseVisitUs.Parent := Self;
|
||||
FlblPleaseVisitUs.Left := 58;
|
||||
FlblPleaseVisitUs.Top := 278;
|
||||
FlblPleaseVisitUs.Width := 276;
|
||||
FlblPleaseVisitUs.Height := 15;
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblPleaseVisitUs.Font.Charset := DEFAULT_CHARSET;
|
||||
FlblPleaseVisitUs.Transparent := True;
|
||||
{$ENDIF}
|
||||
FlblPleaseVisitUs.Font.Color := 16776138; // RGBToColor(202, 251, 255)
|
||||
FlblPleaseVisitUs.Font.Height := -12;
|
||||
FlblPleaseVisitUs.Font.Name := 'Arial';
|
||||
FlblPleaseVisitUs.ParentFont := False;
|
||||
FlblPleaseVisitUs.Caption := RSAAboutBoxPleaseVisit;
|
||||
FlblPleaseVisitUs.Anchors := [akLeft, akTop];
|
||||
|
||||
FlblURL.Name := 'lblURL';
|
||||
FlblURL.Left := 58;
|
||||
FlblURL.Top := 292;
|
||||
FlblURL.Width := 141;
|
||||
FlblURL.Height := 15;
|
||||
FlblURL.Cursor := crHandPoint;
|
||||
{$IFDEF WIDGET_VCL}
|
||||
FlblURL.Font.Charset := DEFAULT_CHARSET;
|
||||
FlblURL.Transparent := True;
|
||||
{$ENDIF}
|
||||
FlblURL.Font.Color := 16776138; // RGBToColor(202, 251, 255)
|
||||
FlblURL.Font.Height := -12;
|
||||
FlblURL.Font.Name := 'Arial';
|
||||
FlblURL.ParentFont := False;
|
||||
FlblURL.OnClick := lblURLClick;
|
||||
FlblURL.Caption := RSAAboutBoxIndyWebsite;
|
||||
FlblURL.Anchors := [akLeft, akTop];
|
||||
FlblURL.Parent := Self;
|
||||
|
||||
FbbtnOk.Name := 'bbtnOk';
|
||||
FbbtnOk.Left := 475;
|
||||
{$IFDEF USE_TBitBtn}
|
||||
FbbtnOk.Top := 297;
|
||||
{$ELSE}
|
||||
FbbtnOk.Top := 302;
|
||||
FbbtnOk.Height := 25;
|
||||
{$ENDIF}
|
||||
FbbtnOk.Width := 75;
|
||||
FbbtnOk.Anchors := [akRight, akBottom];
|
||||
{$IFDEF USE_TBitBtn}
|
||||
FbbtnOk.Font.Color := clBlack;
|
||||
FbbtnOk.ParentFont := False;
|
||||
FbbtnOk.Kind := bkOk;
|
||||
{$ELSE}
|
||||
FbbtnOk.Caption := RSOk;
|
||||
{$ENDIF}
|
||||
FbbtnOk.Cancel := True;
|
||||
FbbtnOk.Default := True;
|
||||
FbbtnOk.ModalResult := 1;
|
||||
FbbtnOk.TabOrder := 0;
|
||||
FbbtnOk.Anchors := [akLeft, akTop, akRight];
|
||||
FbbtnOk.Parent := Self;
|
||||
end;
|
||||
|
||||
function TfrmAbout.GetVersion: String;
|
||||
begin
|
||||
Result := FlblVersion.Caption;
|
||||
end;
|
||||
|
||||
function TfrmAbout.GetProductName: String;
|
||||
begin
|
||||
Result := FlblName.Caption;
|
||||
end;
|
||||
|
||||
function TfrmAbout.GetProductName2: String;
|
||||
begin
|
||||
Result := FlblName2.Caption;
|
||||
end;
|
||||
|
||||
procedure TfrmAbout.lblURLClick(Sender: TObject);
|
||||
begin
|
||||
{$IFDEF WIN32_OR_WIN64}
|
||||
ShellAPI.ShellExecute(Handle, nil, PChar(FlblURL.Caption), nil, nil, 0); {Do not Localize}
|
||||
FlblURL.Font.Color := clPurple;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TfrmAbout.SetVersion(const AValue: String);
|
||||
begin
|
||||
FlblVersion.Caption := AValue;
|
||||
end;
|
||||
|
||||
procedure TfrmAbout.SetProductName(const AValue: String);
|
||||
begin
|
||||
FlblName.Caption := AValue;
|
||||
end;
|
||||
|
||||
procedure TfrmAbout.SetProductName2(const AValue: String);
|
||||
begin
|
||||
FlblName2.Caption := AValue;
|
||||
end;
|
||||
|
||||
class procedure TfrmAbout.ShowAboutBox(const AProductName, AProductName2, AProductVersion: String);
|
||||
var
|
||||
LFrm: TfrmAbout;
|
||||
begin
|
||||
LFrm := TfrmAbout.Create;
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
try
|
||||
{$ENDIF}
|
||||
LFrm.Version := IndyFormat(RSAAboutBoxVersion, [AProductVersion]);
|
||||
LFrm.ProductName := AProductName;
|
||||
LFrm.ProductName2 := AProductName2;
|
||||
LFrm.ShowModal;
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
finally
|
||||
LFrm.Free;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
class procedure TfrmAbout.ShowDlg;
|
||||
begin
|
||||
ShowAboutBox(RSAAboutBoxTitle1, RSAAboutBoxTitle2, gsIdVersion);
|
||||
end;
|
||||
|
||||
constructor TfrmAbout.Create;
|
||||
begin
|
||||
Create(nil);
|
||||
end;
|
||||
|
||||
{$IFDEF WIDGET_LCL}
|
||||
initialization
|
||||
{$i IdAboutVCL.lrs}
|
||||
{$ENDIF}
|
||||
end.
|
||||
1
indy/Core/IdAboutVCL.rc
Normal file
@@ -0,0 +1 @@
|
||||
INDY_ABOUT_BACKGROUND BITMAP AboutBackground.bmp
|
||||
1469
indy/Core/IdAboutVCL.xpm
Normal file
161
indy/Core/IdAntiFreeze.pas
Normal file
@@ -0,0 +1,161 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.6 2004.02.03 4:16:42 PM czhower
|
||||
For unit name changes.
|
||||
|
||||
Rev 1.5 2004.01.01 3:13:32 PM czhower
|
||||
Updated comment.
|
||||
|
||||
Rev 1.4 2003.12.31 10:30:24 PM czhower
|
||||
Comment update.
|
||||
|
||||
Rev 1.3 2003.12.31 7:25:14 PM czhower
|
||||
Now works in .net
|
||||
|
||||
Rev 1.2 10/4/2003 9:52:08 AM GGrieve
|
||||
add IdCoreGlobal to uses list
|
||||
|
||||
Rev 1.1 2003.10.01 1:12:30 AM czhower
|
||||
.Net
|
||||
|
||||
Rev 1.0 11/13/2002 08:37:36 AM JPMugaas
|
||||
}
|
||||
|
||||
unit IdAntiFreeze;
|
||||
|
||||
{
|
||||
NOTE - This unit must NOT appear in any Indy uses clauses. This is a ONE way
|
||||
relationship and is linked in IF the user uses this component. This is done to
|
||||
preserve the isolation from the massive FORMS unit.
|
||||
|
||||
Because it links to Forms:
|
||||
|
||||
- The Application.ProcessMessages cannot be done in IdCoreGlobal as an OS
|
||||
independent function, and thus this unit is allowed to violate the IFDEF
|
||||
restriction.
|
||||
}
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
uses
|
||||
Classes,
|
||||
IdAntiFreezeBase,
|
||||
IdBaseComponent;
|
||||
|
||||
{ Directive needed for C++Builder HPP and OBJ files for this that will force it
|
||||
to be statically compiled into the code }
|
||||
|
||||
{$IFDEF HAS_DIRECTIVE_HPPEMIT_LINKUNIT}
|
||||
{$HPPEMIT LINKUNIT}
|
||||
{$ELSE}
|
||||
{$IFDEF WINDOWS}
|
||||
{$HPPEMIT '#pragma link "IdAntiFreeze"'} {Do not Localize}
|
||||
{$ENDIF}
|
||||
{$IFDEF UNIX}
|
||||
{$HPPEMIT '#pragma link "IdAntiFreeze.o"'} {Do not Localize}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
type
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute}
|
||||
[ComponentPlatformsAttribute(
|
||||
pidWin32
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_Win32} or pidWin32{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_Win64} or pidWin64{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_OSX32} or pidOSX32{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_iOS_Simulator} or pidiOSSimulator{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_Android} or pidAndroid{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_Linux32} or pidLinux32{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_iOS_Device32} or pidiOSDevice32{$ELSE}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_iOS_Device} or pidiOSDevice{$ENDIF}{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_WinNX32} or pidWinNX32{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_Linux64} or pidLinux64{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_WinIoT32} or pidWinIoT32{$ENDIF}
|
||||
{$IFDEF HAS_ComponentPlatformsAttribute_iOS_Device64} or pidiOSDevice64{$ENDIF}
|
||||
)]
|
||||
{$ENDIF}
|
||||
TIdAntiFreeze = class(TIdAntiFreezeBase)
|
||||
public
|
||||
procedure Process; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
{$IFDEF WIDGET_KYLIX}
|
||||
QForms,
|
||||
{$ENDIF}
|
||||
{$IFDEF WIDGET_VCL_LIKE}
|
||||
Forms,
|
||||
{$ENDIF}
|
||||
{$IFDEF WINDOWS}
|
||||
{$IFNDEF FMX}
|
||||
Messages,
|
||||
Windows,
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFDEF WIDGET_WINFORMS}
|
||||
System.Windows.Forms,
|
||||
{$ENDIF}
|
||||
IdGlobal;
|
||||
|
||||
{$IFDEF UNIX}
|
||||
procedure TIdAntiFreeze.Process;
|
||||
begin
|
||||
//TODO: Handle ApplicationHasPriority
|
||||
Application.ProcessMessages;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF WINDOWS}
|
||||
|
||||
{$IFNDEF FMX}
|
||||
procedure TIdAntiFreeze.Process;
|
||||
var
|
||||
LMsg: TMsg;
|
||||
begin
|
||||
if ApplicationHasPriority then begin
|
||||
Application.ProcessMessages;
|
||||
end else begin
|
||||
// This guarantees it will not ever call Application.Idle
|
||||
if PeekMessage(LMsg, 0, 0, 0, PM_NOREMOVE) then begin
|
||||
Application.HandleMessage;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{$ELSE}
|
||||
procedure TIdAntiFreeze.Process;
|
||||
begin
|
||||
//TODO: Handle ApplicationHasPriority
|
||||
Application.ProcessMessages;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
{$ENDIF}
|
||||
|
||||
{$IFDEF WIDGET_WINFORMS}
|
||||
procedure TIdAntiFreeze.Process;
|
||||
begin
|
||||
//TODO: Handle ApplicationHasPriority
|
||||
Application.DoEvents;
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
end.
|
||||
1948
indy/Core/IdAssignedNumbers.pas
Normal file
1030
indy/Core/IdBuffer.pas
Normal file
305
indy/Core/IdCmdTCPClient.pas
Normal file
@@ -0,0 +1,305 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.18 2/8/05 5:24:48 PM RLebeau
|
||||
Updated Disconnect() to not wait for the listening thread to terminate until
|
||||
after the inherited Disconnect() is called, so that the socket is actually
|
||||
disconnected and the thread can terminate properly.
|
||||
|
||||
Rev 1.17 2/1/05 12:38:30 AM RLebeau
|
||||
Removed unused CommandHandlersEnabled property
|
||||
|
||||
Rev 1.16 6/11/2004 8:48:16 AM DSiders
|
||||
Added "Do not Localize" comments.
|
||||
|
||||
Rev 1.15 5/18/04 9:12:26 AM RLebeau
|
||||
Bug fix for SetExceptionReply() property setter
|
||||
|
||||
Rev 1.14 5/16/04 5:18:04 PM RLebeau
|
||||
Added setter method to ExceptionReply property
|
||||
|
||||
Rev 1.13 5/10/2004 6:10:38 PM DSiders
|
||||
Removed unused member var FCommandHandlersInitialized.
|
||||
|
||||
Rev 1.12 2004.03.06 1:33:00 PM czhower
|
||||
-Change to disconnect
|
||||
-Addition of DisconnectNotifyPeer
|
||||
-WriteHeader now write bufers
|
||||
|
||||
Rev 1.11 2004.03.01 5:12:24 PM czhower
|
||||
-Bug fix for shutdown of servers when connections still existed (AV)
|
||||
-Implicit HELP support in CMDserver
|
||||
-Several command handler bugs
|
||||
-Additional command handler functionality.
|
||||
|
||||
Rev 1.10 2004.02.03 4:17:10 PM czhower
|
||||
For unit name changes.
|
||||
|
||||
Rev 1.9 2004.01.20 10:03:22 PM czhower
|
||||
InitComponent
|
||||
|
||||
Rev 1.8 1/4/04 8:46:16 PM RLebeau
|
||||
Added OnBeforeCommandHandler and OnAfterCommandHandler events
|
||||
|
||||
Rev 1.7 11/4/2003 10:25:40 PM DSiders
|
||||
Removed duplicate FReplyClass member in TIdCmdTCPClient (See
|
||||
TIdTCPConnection).
|
||||
|
||||
Rev 1.6 10/21/2003 10:54:20 AM JPMugaas
|
||||
Fix for new API change.
|
||||
|
||||
Rev 1.5 2003.10.18 9:33:24 PM czhower
|
||||
Boatload of bug fixes to command handlers.
|
||||
|
||||
Rev 1.4 2003.10.02 10:16:26 AM czhower
|
||||
.Net
|
||||
|
||||
Rev 1.3 2003.09.19 11:54:26 AM czhower
|
||||
-Completed more features necessary for servers
|
||||
-Fixed some bugs
|
||||
|
||||
Rev 1.2 7/9/2003 10:55:24 PM BGooijen
|
||||
Restored all features
|
||||
|
||||
Rev 1.1 7/9/2003 04:36:06 PM JPMugaas
|
||||
You now can override the TIdReply with your own type. This should illiminate
|
||||
some warnings about some serious issues. TIdReply is ONLY a base class with
|
||||
virtual methods.
|
||||
|
||||
Rev 1.0 7/7/2003 7:06:40 PM SPerry
|
||||
Component that uses command handlers
|
||||
|
||||
Rev 1.0 7/6/2003 4:47:26 PM SPerry
|
||||
Units that use Command handlers
|
||||
}
|
||||
|
||||
unit IdCmdTCPClient;
|
||||
|
||||
{
|
||||
Original author: Sergio Perry
|
||||
Description: TCP client that uses CommandHandlers
|
||||
}
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
uses
|
||||
IdContext,
|
||||
IdException,
|
||||
IdGlobal,
|
||||
IdReply,
|
||||
IdResourceStringsCore,
|
||||
IdThread,
|
||||
IdTCPClient,
|
||||
IdCommandHandlers;
|
||||
|
||||
type
|
||||
TIdCmdTCPClient = class;
|
||||
|
||||
{ Events }
|
||||
TIdCmdTCPClientAfterCommandHandlerEvent = procedure(ASender: TIdCmdTCPClient;
|
||||
AContext: TIdContext) of object;
|
||||
TIdCmdTCPClientBeforeCommandHandlerEvent = procedure(ASender: TIdCmdTCPClient;
|
||||
var AData: string; AContext: TIdContext) of object;
|
||||
|
||||
{ Listening Thread }
|
||||
|
||||
TIdCmdClientContext = class(TIdContext)
|
||||
protected
|
||||
FClient: TIdCmdTCPClient;
|
||||
public
|
||||
property Client: TIdCmdTCPClient read FClient;
|
||||
end;
|
||||
|
||||
TIdCmdTCPClientListeningThread = class(TIdThread)
|
||||
protected
|
||||
FContext: TIdCmdClientContext;
|
||||
FClient: TIdCmdTCPClient;
|
||||
FRecvData: String;
|
||||
//
|
||||
procedure Run; override;
|
||||
public
|
||||
constructor Create(AClient: TIdCmdTCPClient); reintroduce;
|
||||
destructor Destroy; override;
|
||||
//
|
||||
property Client: TIdCmdTCPClient read FClient;
|
||||
property RecvData: String read FRecvData write FRecvData;
|
||||
end;
|
||||
|
||||
{ TIdCmdTCPClient }
|
||||
TIdCmdTCPClient = class(TIdTCPClient)
|
||||
protected
|
||||
FExceptionReply: TIdReply;
|
||||
FListeningThread: TIdCmdTCPClientListeningThread;
|
||||
FCommandHandlers: TIdCommandHandlers;
|
||||
FOnAfterCommandHandler: TIdCmdTCPClientAfterCommandHandlerEvent;
|
||||
FOnBeforeCommandHandler: TIdCmdTCPClientBeforeCommandHandlerEvent;
|
||||
//
|
||||
procedure DoAfterCommandHandler(ASender: TIdCommandHandlers; AContext: TIdContext);
|
||||
procedure DoBeforeCommandHandler(ASender: TIdCommandHandlers; var AData: string;
|
||||
AContext: TIdContext);
|
||||
procedure DoReplyUnknownCommand(AContext: TIdContext; ALine: string); virtual;
|
||||
function GetCmdHandlerClass: TIdCommandHandlerClass; virtual;
|
||||
procedure InitComponent; override;
|
||||
procedure SetCommandHandlers(AValue: TIdCommandHandlers);
|
||||
procedure SetExceptionReply(AValue: TIdReply);
|
||||
public
|
||||
procedure Connect; override;
|
||||
destructor Destroy; override;
|
||||
procedure Disconnect(ANotifyPeer: Boolean); override;
|
||||
published
|
||||
property CommandHandlers: TIdCommandHandlers read FCommandHandlers write SetCommandHandlers;
|
||||
property ExceptionReply: TIdReply read FExceptionReply write SetExceptionReply;
|
||||
//
|
||||
property OnAfterCommandHandler: TIdCmdTCPClientAfterCommandHandlerEvent
|
||||
read FOnAfterCommandHandler write FOnAfterCommandHandler;
|
||||
property OnBeforeCommandHandler: TIdCmdTCPClientBeforeCommandHandlerEvent
|
||||
read FOnBeforeCommandHandler write FOnBeforeCommandHandler;
|
||||
end;
|
||||
|
||||
EIdCmdTCPClientError = class(EIdException);
|
||||
EIdCmdTCPClientConnectError = class(EIdCmdTCPClientError);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
IdReplyRFC, SysUtils;
|
||||
|
||||
type
|
||||
TIdCmdClientContextAccess = class(TIdCmdClientContext)
|
||||
end;
|
||||
|
||||
{ Listening Thread }
|
||||
|
||||
constructor TIdCmdTCPClientListeningThread.Create(AClient: TIdCmdTCPClient);
|
||||
begin
|
||||
FClient := AClient;
|
||||
FContext := TIdCmdClientContext.Create(AClient, nil, nil);
|
||||
FContext.FClient := AClient;
|
||||
TIdCmdClientContextAccess(FContext).FOwnsConnection := False;
|
||||
//
|
||||
inherited Create(False);
|
||||
end;
|
||||
|
||||
destructor TIdCmdTCPClientListeningThread.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
FreeAndNil(FContext);
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClientListeningThread.Run;
|
||||
begin
|
||||
FRecvData := FClient.IOHandler.ReadLn;
|
||||
if not FClient.CommandHandlers.HandleCommand(FContext, FRecvData) then begin
|
||||
FClient.DoReplyUnknownCommand(FContext, FRecvData);
|
||||
end;
|
||||
//Synchronize(?);
|
||||
if not Terminated then begin
|
||||
FClient.IOHandler.CheckForDisconnect;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TIdCmdTCPClient }
|
||||
|
||||
destructor TIdCmdTCPClient.Destroy;
|
||||
begin
|
||||
Disconnect;
|
||||
FreeAndNil(FExceptionReply);
|
||||
FreeAndNil(FCommandHandlers);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClient.Connect;
|
||||
begin
|
||||
inherited Connect;
|
||||
//
|
||||
try
|
||||
FListeningThread := TIdCmdTCPClientListeningThread.Create(Self);
|
||||
except
|
||||
Disconnect(True);
|
||||
IndyRaiseOuterException(EIdCmdTCPClientConnectError.Create(RSNoCreateListeningThread));
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClient.Disconnect(ANotifyPeer: Boolean);
|
||||
begin
|
||||
if Assigned(FListeningThread) then begin
|
||||
FListeningThread.Terminate;
|
||||
end;
|
||||
try
|
||||
inherited Disconnect(ANotifyPeer);
|
||||
finally
|
||||
if Assigned(FListeningThread) and not IsCurrentThread(FListeningThread) then begin
|
||||
FListeningThread.WaitFor;
|
||||
FreeAndNil(FListeningThread);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClient.DoAfterCommandHandler(ASender: TIdCommandHandlers;
|
||||
AContext: TIdContext);
|
||||
begin
|
||||
if Assigned(OnAfterCommandHandler) then begin
|
||||
OnAfterCommandHandler(Self, AContext);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClient.DoBeforeCommandHandler(ASender: TIdCommandHandlers;
|
||||
var AData: string; AContext: TIdContext);
|
||||
begin
|
||||
if Assigned(OnBeforeCommandHandler) then begin
|
||||
OnBeforeCommandHandler(Self, AData, AContext);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClient.DoReplyUnknownCommand(AContext: TIdContext; ALine: string);
|
||||
begin
|
||||
end;
|
||||
|
||||
function TIdCmdTCPClient.GetCmdHandlerClass: TIdCommandHandlerClass;
|
||||
begin
|
||||
Result := TIdCommandHandler;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClient.InitComponent;
|
||||
var
|
||||
LHandlerClass: TIdCommandHandlerClass;
|
||||
begin
|
||||
inherited InitComponent;
|
||||
|
||||
FExceptionReply := FReplyClass.Create(nil);
|
||||
ExceptionReply.SetReply(500, 'Unknown Internal Error'); {do not localize}
|
||||
|
||||
LHandlerClass := GetCmdHandlerClass;
|
||||
FCommandHandlers := TIdCommandHandlers.Create(Self, FReplyClass, nil, ExceptionReply, LHandlerClass);
|
||||
FCommandHandlers.OnAfterCommandHandler := DoAfterCommandHandler;
|
||||
FCommandHandlers.OnBeforeCommandHandler := DoBeforeCommandHandler;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClient.SetCommandHandlers(AValue: TIdCommandHandlers);
|
||||
begin
|
||||
FCommandHandlers.Assign(AValue);
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPClient.SetExceptionReply(AValue: TIdReply);
|
||||
begin
|
||||
FExceptionReply.Assign(AValue);
|
||||
end;
|
||||
|
||||
end.
|
||||
535
indy/Core/IdCmdTCPServer.pas
Normal file
@@ -0,0 +1,535 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.42 2/1/05 12:36:36 AM RLebeau
|
||||
Removed CommandHandlersEnabled property, no longer used
|
||||
|
||||
Rev 1.41 12/2/2004 9:26:42 PM JPMugaas
|
||||
Bug fix.
|
||||
|
||||
Rev 1.40 2004.10.27 9:20:04 AM czhower
|
||||
For TIdStrings
|
||||
|
||||
Rev 1.39 10/26/2004 8:42:58 PM JPMugaas
|
||||
Should be more portable with new references to TIdStrings and TIdStringList.
|
||||
|
||||
Rev 1.38 6/21/04 10:07:14 PM RLebeau
|
||||
Updated .DoConnect() to make sure the connection is still connected before
|
||||
then sending the Greeting
|
||||
|
||||
Rev 1.37 6/20/2004 12:01:44 AM DSiders
|
||||
Added "Do Not Localize" comments.
|
||||
|
||||
Rev 1.36 6/16/04 12:37:06 PM RLebeau
|
||||
more compiler errors
|
||||
|
||||
Rev 1.35 6/16/04 12:30:32 PM RLebeau
|
||||
compiler errors
|
||||
|
||||
Rev 1.34 6/16/04 12:12:26 PM RLebeau
|
||||
Updated ExceptionReply, Greeting, HelpReply, MaxConnectionReply, and
|
||||
ReplyUnknownCommand properties to use getter methods that call virtual Create
|
||||
methods which descendants can override for class-specific initializations
|
||||
|
||||
Rev 1.33 5/16/04 5:16:52 PM RLebeau
|
||||
Added setter methods to ExceptionReply, HelpReply, and ReplyTexts properties
|
||||
|
||||
Rev 1.32 4/19/2004 5:39:58 PM BGooijen
|
||||
Added comment
|
||||
|
||||
Rev 1.31 4/18/2004 11:58:44 PM BGooijen
|
||||
Wasn't thread safe
|
||||
|
||||
Rev 1.30 3/3/2004 4:59:38 AM JPMugaas
|
||||
Updated for new properties.
|
||||
|
||||
Rev 1.29 2004.03.01 5:12:24 PM czhower
|
||||
-Bug fix for shutdown of servers when connections still existed (AV)
|
||||
-Implicit HELP support in CMDserver
|
||||
-Several command handler bugs
|
||||
-Additional command handler functionality.
|
||||
|
||||
Rev 1.28 2004.02.29 9:43:08 PM czhower
|
||||
Added ReadCommandLine.
|
||||
|
||||
Rev 1.27 2004.02.29 8:17:18 PM czhower
|
||||
Minor cosmetic changes to code.
|
||||
|
||||
Rev 1.26 2004.02.03 4:17:08 PM czhower
|
||||
For unit name changes.
|
||||
|
||||
Rev 1.25 03/02/2004 01:49:22 CCostelloe
|
||||
Added DoReplyUnknownCommand to allow TIdIMAP4Server set a correct reply for
|
||||
unknown commands
|
||||
|
||||
Rev 1.24 1/29/04 9:43:16 PM RLebeau
|
||||
Added setter methods to various TIdReply properties
|
||||
|
||||
Rev 1.23 2004.01.20 10:03:22 PM czhower
|
||||
InitComponent
|
||||
|
||||
Rev 1.22 1/5/2004 2:35:36 PM JPMugaas
|
||||
Removed of object in method declarations.
|
||||
|
||||
Rev 1.21 1/5/04 10:12:58 AM RLebeau
|
||||
Fixed Typos in OnBeforeCommandHandler and OnAfterCommandHandler events
|
||||
|
||||
Rev 1.20 1/4/04 8:45:34 PM RLebeau
|
||||
Added OnBeforeCommandHandler and OnAfterCommandHandler events
|
||||
|
||||
Rev 1.19 1/1/2004 9:33:22 PM BGooijen
|
||||
the abstract class TIdReply was created sometimes, fixed that
|
||||
|
||||
Rev 1.18 2003.10.18 9:33:26 PM czhower
|
||||
Boatload of bug fixes to command handlers.
|
||||
|
||||
Rev 1.17 2003.10.18 8:03:58 PM czhower
|
||||
Defaults for codes
|
||||
|
||||
Rev 1.16 8/31/2003 11:49:40 AM BGooijen
|
||||
removed FReplyClass, this was also in TIdTCPServer
|
||||
|
||||
Rev 1.15 7/9/2003 10:55:24 PM BGooijen
|
||||
Restored all features
|
||||
|
||||
Rev 1.14 7/9/2003 04:36:08 PM JPMugaas
|
||||
You now can override the TIdReply with your own type. This should illiminate
|
||||
some warnings about some serious issues. TIdReply is ONLY a base class with
|
||||
virtual methods.
|
||||
|
||||
Rev 1.13 2003.07.08 2:26:02 PM czhower
|
||||
Sergio's update
|
||||
|
||||
Rev 1.0 7/7/2003 7:06:44 PM SPerry
|
||||
Component that uses command handlers
|
||||
|
||||
Rev 1.0 7/6/2003 4:47:32 PM SPerry
|
||||
Units that use Command handlers
|
||||
|
||||
Adapted to IdCommandHandlers.pas SPerry
|
||||
|
||||
Rev 1.7 4/4/2003 8:08:00 PM BGooijen
|
||||
moved some consts from tidtcpserver here
|
||||
|
||||
Rev 1.6 3/23/2003 11:22:24 PM BGooijen
|
||||
Moved some code to HandleCommand
|
||||
|
||||
Rev 1.5 3/22/2003 1:46:36 PM BGooijen
|
||||
Removed unused variables
|
||||
|
||||
Rev 1.4 3/20/2003 12:18:30 PM BGooijen
|
||||
Moved ReplyExceptionCode from TIdTCPServer to TIdCmdTCPServer
|
||||
|
||||
Rev 1.3 3/20/2003 12:14:18 PM BGooijen
|
||||
Re-enabled Server.ReplyException
|
||||
|
||||
Rev 1.2 2/24/2003 07:21:50 PM JPMugaas
|
||||
Now compiles with new core code restructures.
|
||||
|
||||
Rev 1.1 1/23/2003 11:06:10 AM BGooijen
|
||||
|
||||
Rev 1.0 1/20/2003 12:48:40 PM BGooijen
|
||||
Tcpserver with command handlers, these were originally in TIdTcpServer, but
|
||||
are now moved here
|
||||
}
|
||||
|
||||
unit IdCmdTCPServer;
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
//Put FPC into Delphi mode
|
||||
|
||||
uses
|
||||
Classes,
|
||||
IdCommandHandlers,
|
||||
IdContext,
|
||||
IdIOHandler,
|
||||
IdReply,
|
||||
IdTCPServer,
|
||||
SysUtils;
|
||||
|
||||
type
|
||||
TIdCmdTCPServer = class;
|
||||
|
||||
{ Events }
|
||||
TIdCmdTCPServerAfterCommandHandlerEvent = procedure(ASender: TIdCmdTCPServer;
|
||||
AContext: TIdContext) of object;
|
||||
TIdCmdTCPServerBeforeCommandHandlerEvent = procedure(ASender: TIdCmdTCPServer;
|
||||
var AData: string; AContext: TIdContext) of object;
|
||||
|
||||
TIdCmdTCPServer = class(TIdTCPServer)
|
||||
protected
|
||||
FCommandHandlers: TIdCommandHandlers;
|
||||
FCommandHandlersInitialized: Boolean;
|
||||
FExceptionReply: TIdReply;
|
||||
FHelpReply: TIdReply;
|
||||
FGreeting: TIdReply;
|
||||
FMaxConnectionReply: TIdReply;
|
||||
FOnAfterCommandHandler: TIdCmdTCPServerAfterCommandHandlerEvent;
|
||||
FOnBeforeCommandHandler: TIdCmdTCPServerBeforeCommandHandlerEvent;
|
||||
FReplyClass: TIdReplyClass;
|
||||
FReplyTexts: TIdReplies;
|
||||
FReplyUnknownCommand: TIdReply;
|
||||
//
|
||||
procedure CheckOkToBeActive; override;
|
||||
function CreateExceptionReply: TIdReply; virtual;
|
||||
function CreateGreeting: TIdReply; virtual;
|
||||
function CreateHelpReply: TIdReply; virtual;
|
||||
function CreateMaxConnectionReply: TIdReply; virtual;
|
||||
function CreateReplyUnknownCommand: TIdReply; virtual;
|
||||
procedure DoAfterCommandHandler(ASender: TIdCommandHandlers; AContext: TIdContext);
|
||||
procedure DoBeforeCommandHandler(ASender: TIdCommandHandlers; var AData: string;
|
||||
AContext: TIdContext);
|
||||
procedure DoConnect(AContext: TIdContext); override;
|
||||
function DoExecute(AContext: TIdContext): Boolean; override;
|
||||
procedure DoMaxConnectionsExceeded(AIOHandler: TIdIOHandler); override;
|
||||
// This is here to allow servers to override this functionality, such as IMAP4 server
|
||||
procedure DoReplyUnknownCommand(AContext: TIdContext; ALine: string); virtual;
|
||||
function GetExceptionReply: TIdReply;
|
||||
function GetGreeting: TIdReply;
|
||||
function GetHelpReply: TIdReply;
|
||||
function GetMaxConnectionReply: TIdReply;
|
||||
function GetRepliesClass: TIdRepliesClass; virtual;
|
||||
function GetReplyClass: TIdReplyClass; virtual;
|
||||
function GetReplyUnknownCommand: TIdReply;
|
||||
procedure InitializeCommandHandlers; virtual;
|
||||
procedure InitComponent; override;
|
||||
// This is used by command handlers as the only input. This can be overriden to filter, modify,
|
||||
// or preparse the input.
|
||||
function ReadCommandLine(AContext: TIdContext): string; virtual;
|
||||
procedure Startup; override;
|
||||
procedure SetCommandHandlers(AValue: TIdCommandHandlers);
|
||||
procedure SetExceptionReply(AValue: TIdReply);
|
||||
procedure SetGreeting(AValue: TIdReply);
|
||||
procedure SetHelpReply(AValue: TIdReply);
|
||||
procedure SetMaxConnectionReply(AValue: TIdReply);
|
||||
procedure SetReplyUnknownCommand(AValue: TIdReply);
|
||||
procedure SetReplyTexts(AValue: TIdReplies);
|
||||
public
|
||||
destructor Destroy; override;
|
||||
published
|
||||
property CommandHandlers: TIdCommandHandlers read FCommandHandlers
|
||||
write SetCommandHandlers;
|
||||
property ExceptionReply: TIdReply read GetExceptionReply write SetExceptionReply;
|
||||
property Greeting: TIdReply read GetGreeting write SetGreeting;
|
||||
property HelpReply: TIdReply read GetHelpReply write SetHelpReply;
|
||||
property MaxConnectionReply: TIdReply read GetMaxConnectionReply
|
||||
write SetMaxConnectionReply;
|
||||
property ReplyTexts: TIdReplies read FReplyTexts write SetReplyTexts;
|
||||
property ReplyUnknownCommand: TIdReply read GetReplyUnknownCommand
|
||||
write SetReplyUnknownCommand;
|
||||
//
|
||||
property OnAfterCommandHandler: TIdCmdTCPServerAfterCommandHandlerEvent
|
||||
read FOnAfterCommandHandler write FOnAfterCommandHandler;
|
||||
property OnBeforeCommandHandler: TIdCmdTCPServerBeforeCommandHandlerEvent
|
||||
read FOnBeforeCommandHandler write FOnBeforeCommandHandler;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
IdGlobal,
|
||||
IdResourceStringsCore,
|
||||
IdReplyRFC;
|
||||
|
||||
function TIdCmdTCPServer.GetReplyClass: TIdReplyClass;
|
||||
begin
|
||||
Result := TIdReplyRFC;
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.GetRepliesClass: TIdRepliesClass;
|
||||
begin
|
||||
Result := TIdRepliesRFC;
|
||||
end;
|
||||
|
||||
destructor TIdCmdTCPServer.Destroy;
|
||||
begin
|
||||
inherited Destroy;
|
||||
FreeAndNil(FReplyUnknownCommand);
|
||||
FreeAndNil(FReplyTexts);
|
||||
FreeAndNil(FMaxConnectionReply);
|
||||
FreeAndNil(FHelpReply);
|
||||
FreeAndNil(FGreeting);
|
||||
FreeAndNil(FExceptionReply);
|
||||
FreeAndNil(FCommandHandlers);
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.DoAfterCommandHandler(ASender: TIdCommandHandlers;
|
||||
AContext: TIdContext);
|
||||
begin
|
||||
if Assigned(OnAfterCommandHandler) then begin
|
||||
OnAfterCommandHandler(Self, AContext);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.DoBeforeCommandHandler(ASender: TIdCommandHandlers;
|
||||
var AData: string; AContext: TIdContext);
|
||||
begin
|
||||
if Assigned(OnBeforeCommandHandler) then begin
|
||||
OnBeforeCommandHandler(Self, AData, AContext);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.DoExecute(AContext: TIdContext): Boolean;
|
||||
var
|
||||
LLine: string;
|
||||
begin
|
||||
if CommandHandlers.Count > 0 then begin
|
||||
Result := True;
|
||||
if AContext.Connection.Connected then begin
|
||||
LLine := ReadCommandLine(AContext);
|
||||
// OLX sends blank lines during reset groups (NNTP) and expects no response.
|
||||
// Not sure what the RFCs say about blank lines.
|
||||
// I telnetted to some newsservers, and they dont respond to blank lines.
|
||||
// This unit is core and not NNTP, but we should be consistent.
|
||||
if LLine <> '' then begin
|
||||
if not FCommandHandlers.HandleCommand(AContext, LLine) then begin
|
||||
DoReplyUnknownCommand(AContext, LLine);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
Result := inherited DoExecute(AContext);
|
||||
end;
|
||||
if Result and Assigned(AContext.Connection) then begin
|
||||
Result := AContext.Connection.Connected;
|
||||
end;
|
||||
// the return value is used to determine if the DoExecute needs to be called again by the thread
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.DoReplyUnknownCommand(AContext: TIdContext; ALine: string);
|
||||
var
|
||||
LReply: TIdReply;
|
||||
begin
|
||||
if CommandHandlers.PerformReplies then begin
|
||||
LReply := FReplyClass.CreateWithReplyTexts(nil, ReplyTexts); try
|
||||
LReply.Assign(ReplyUnknownCommand);
|
||||
LReply.Text.Add(ALine);
|
||||
AContext.Connection.IOHandler.Write(LReply.FormattedReply);
|
||||
finally
|
||||
FreeAndNil(LReply);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.InitializeCommandHandlers;
|
||||
begin
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.DoConnect(AContext: TIdContext);
|
||||
var
|
||||
LGreeting: TIdReply;
|
||||
begin
|
||||
inherited DoConnect(AContext);
|
||||
// RLebeau - check the connection first in case the application
|
||||
// chose to disconnect the connection in the OnConnect event handler.
|
||||
if AContext.Connection.Connected then begin
|
||||
if Greeting.ReplyExists then begin
|
||||
ReplyTexts.UpdateText(Greeting);
|
||||
LGreeting := FReplyClass.Create(nil); try // SendGreeting calls TIdReply.GetFormattedReply
|
||||
LGreeting.Assign(Greeting); // and that changes the reply object, so we have to
|
||||
SendGreeting(AContext, LGreeting); // clone it to make it thread-safe
|
||||
finally
|
||||
FreeAndNil(LGreeting);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.DoMaxConnectionsExceeded(AIOHandler: TIdIOHandler);
|
||||
begin
|
||||
inherited DoMaxConnectionsExceeded(AIOHandler);
|
||||
//Do not UpdateText here - in thread. Is done in constructor
|
||||
AIOHandler.Write(MaxConnectionReply.FormattedReply);
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.Startup;
|
||||
var
|
||||
i, j: Integer;
|
||||
LDescr: TStrings;
|
||||
LHelpList: TStringList;
|
||||
LHandler, LAddedHandler: TIdCommandHandler;
|
||||
begin
|
||||
inherited Startup;
|
||||
if not FCommandHandlersInitialized then begin
|
||||
// InitializeCommandHandlers must be called only at runtime, and only after streaming
|
||||
// has occured. This used to be in .Loaded and that worked for forms. It failed
|
||||
// for dynamically created instances and also for descendant classes.
|
||||
FCommandHandlersInitialized := True;
|
||||
InitializeCommandHandlers;
|
||||
if HelpReply.Code <> '' then begin
|
||||
LAddedHandler := CommandHandlers.Add;
|
||||
LAddedHandler.Command := 'Help'; {do not localize}
|
||||
LAddedHandler.Description.Text := 'Displays commands that the servers supports.'; {do not localize}
|
||||
LAddedHandler.NormalReply.Assign(HelpReply);
|
||||
LHelpList := TStringList.Create;
|
||||
try
|
||||
for i := 0 to CommandHandlers.Count - 1 do begin
|
||||
LHandler := CommandHandlers.Items[i];
|
||||
if LHandler.HelpVisible then begin
|
||||
LHelpList.AddObject(LHandler.Command+LHandler.HelpSuperScript, LHandler);
|
||||
end;
|
||||
end;
|
||||
LHelpList.Sort;
|
||||
for i := 0 to LHelpList.Count - 1 do begin
|
||||
LAddedHandler.Response.Add(LHelpList[i]);
|
||||
LDescr := TIdCommandHandler(LHelpList.Objects[i]).Description;
|
||||
for j := 0 to LDescr.Count - 1 do begin
|
||||
LAddedHandler.Response.Add(' ' + LDescr[j]); {do not localize}
|
||||
end;
|
||||
LAddedHandler.Response.Add(''); {do not localize}
|
||||
end;
|
||||
finally
|
||||
FreeAndNil(LHelpList);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.SetCommandHandlers(AValue: TIdCommandHandlers);
|
||||
begin
|
||||
FCommandHandlers.Assign(AValue);
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.CreateExceptionReply: TIdReply;
|
||||
begin
|
||||
Result := FReplyClass.CreateWithReplyTexts(nil, ReplyTexts);
|
||||
Result.SetReply(500, 'Unknown Internal Error'); {do not localize}
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.GetExceptionReply: TIdReply;
|
||||
begin
|
||||
if FExceptionReply = nil then begin
|
||||
FExceptionReply := CreateExceptionReply;
|
||||
end;
|
||||
Result := FExceptionReply;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.SetExceptionReply(AValue: TIdReply);
|
||||
begin
|
||||
ExceptionReply.Assign(AValue);
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.CreateGreeting: TIdReply;
|
||||
begin
|
||||
Result := FReplyClass.CreateWithReplyTexts(nil, ReplyTexts);
|
||||
Result.SetReply(200, 'Welcome'); {do not localize}
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.GetGreeting: TIdReply;
|
||||
begin
|
||||
if FGreeting = nil then begin
|
||||
FGreeting := CreateGreeting;
|
||||
end;
|
||||
Result := FGreeting;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.SetGreeting(AValue: TIdReply);
|
||||
begin
|
||||
Greeting.Assign(AValue);
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.CreateHelpReply: TIdReply;
|
||||
begin
|
||||
Result := FReplyClass.CreateWithReplyTexts(nil, ReplyTexts);
|
||||
Result.SetReply(100, 'Help follows'); {do not localize}
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.GetHelpReply: TIdReply;
|
||||
begin
|
||||
if FHelpReply = nil then begin
|
||||
FHelpReply := CreateHelpReply;
|
||||
end;
|
||||
Result := FHelpReply;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.SetHelpReply(AValue: TIdReply);
|
||||
begin
|
||||
HelpReply.Assign(AValue);
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.CreateMaxConnectionReply: TIdReply;
|
||||
begin
|
||||
Result := FReplyClass.CreateWithReplyTexts(nil, ReplyTexts);
|
||||
Result.SetReply(300, 'Too many connections. Try again later.'); {do not localize}
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.GetMaxConnectionReply: TIdReply;
|
||||
begin
|
||||
if FMaxConnectionReply = nil then begin
|
||||
FMaxConnectionReply := CreateMaxConnectionReply;
|
||||
end;
|
||||
Result := FMaxConnectionReply;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.SetMaxConnectionReply(AValue: TIdReply);
|
||||
begin
|
||||
MaxConnectionReply.Assign(AValue);
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.CreateReplyUnknownCommand: TIdReply;
|
||||
begin
|
||||
Result := FReplyClass.CreateWithReplyTexts(nil, ReplyTexts);
|
||||
Result.SetReply(400, 'Unknown Command'); {do not localize}
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.GetReplyUnknownCommand: TIdReply;
|
||||
begin
|
||||
if FReplyUnknownCommand = nil then begin
|
||||
FReplyUnknownCommand := CreateReplyUnknownCommand;
|
||||
end;
|
||||
Result := FReplyUnknownCommand;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.SetReplyUnknownCommand(AValue: TIdReply);
|
||||
begin
|
||||
ReplyUnknownCommand.Assign(AValue);
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.SetReplyTexts(AValue: TIdReplies);
|
||||
begin
|
||||
FReplyTexts.Assign(AValue);
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.InitComponent;
|
||||
begin
|
||||
inherited InitComponent;
|
||||
FReplyClass := GetReplyClass;
|
||||
|
||||
// Before Command handlers as they need FReplyTexts, but after FReplyClass is set
|
||||
FReplyTexts := GetRepliesClass.Create(Self, FReplyClass);
|
||||
|
||||
FCommandHandlers := TIdCommandHandlers.Create(Self, FReplyClass, ReplyTexts, ExceptionReply);
|
||||
FCommandHandlers.OnAfterCommandHandler := DoAfterCommandHandler;
|
||||
FCommandHandlers.OnBeforeCommandHandler := DoBeforeCommandHandler;
|
||||
end;
|
||||
|
||||
function TIdCmdTCPServer.ReadCommandLine(AContext: TIdContext): string;
|
||||
begin
|
||||
Result := AContext.Connection.IOHandler.ReadLn;
|
||||
end;
|
||||
|
||||
procedure TIdCmdTCPServer.CheckOkToBeActive;
|
||||
begin
|
||||
if (CommandHandlers.Count = 0) and FCommandHandlersInitialized then begin
|
||||
inherited CheckOkToBeActive;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
682
indy/Core/IdCommandHandlers.pas
Normal file
@@ -0,0 +1,682 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.36 2/1/05 12:37:48 AM RLebeau
|
||||
Removed IdCommandHandlersEnabledDefault variable, no longer used.
|
||||
|
||||
Rev 1.35 1/3/05 4:43:20 PM RLebeau
|
||||
Changed use of AnsiSameText() to use TextIsSame() instead
|
||||
|
||||
Rev 1.34 12/17/04 12:54:04 PM RLebeau
|
||||
Updated TIdCommandHandler.Check() to not match misspelled commands when a
|
||||
CmdDelimiter is specified.
|
||||
|
||||
Rev 1.33 12/10/04 1:48:04 PM RLebeau
|
||||
Bug fix for TIdCommandHandler.DoCommand()
|
||||
|
||||
Rev 1.32 10/26/2004 8:42:58 PM JPMugaas
|
||||
Should be more portable with new references to TIdStrings and TIdStringList.
|
||||
|
||||
Rev 1.31 6/17/2004 2:19:50 AM JPMugaas
|
||||
Problem with unparsed parameters. The initial deliniator between the command
|
||||
and reply was being added to Unparsed Params leading some strange results and
|
||||
command failures.
|
||||
|
||||
Rev 1.30 6/6/2004 11:44:34 AM JPMugaas
|
||||
Removed a temporary workaround for a Telnet Sequences issue in the
|
||||
TIdFTPServer. That workaround is no longer needed as we fixed the issue
|
||||
another way.
|
||||
|
||||
Rev 1.29 5/16/04 5:20:22 PM RLebeau
|
||||
Removed local variable from TIdCommandHandler constructor, no longer used
|
||||
|
||||
Rev 1.28 2004.03.03 3:19:52 PM czhower
|
||||
sorted
|
||||
|
||||
Rev 1.27 3/3/2004 4:59:40 AM JPMugaas
|
||||
Updated for new properties.
|
||||
|
||||
Rev 1.26 3/2/2004 8:10:36 AM JPMugaas
|
||||
HelpHide renamed to HelpVisable.
|
||||
|
||||
Rev 1.25 3/2/2004 6:37:36 AM JPMugaas
|
||||
Updated with properties for more comprehensive help systems.
|
||||
|
||||
Rev 1.24 2004.03.01 7:13:40 PM czhower
|
||||
Comaptibilty fix.
|
||||
|
||||
Rev 1.23 2004.03.01 5:12:26 PM czhower
|
||||
-Bug fix for shutdown of servers when connections still existed (AV)
|
||||
-Implicit HELP support in CMDserver
|
||||
-Several command handler bugs
|
||||
-Additional command handler functionality.
|
||||
|
||||
Rev 1.22 2004.02.29 9:49:06 PM czhower
|
||||
Bug fix, and now responses are also write buffered.
|
||||
|
||||
Rev 1.21 2004.02.03 4:17:10 PM czhower
|
||||
For unit name changes.
|
||||
|
||||
Rev 1.20 1/29/04 10:00:40 PM RLebeau
|
||||
Added setter methods to various TIdReply properties
|
||||
|
||||
Rev 1.19 2003.12.31 7:31:58 PM czhower
|
||||
AnsiSameText --> TextIsSame
|
||||
|
||||
Rev 1.18 10/19/2003 11:36:52 AM DSiders
|
||||
Added localization comments where setting response codes.
|
||||
|
||||
Rev 1.17 2003.10.18 9:33:26 PM czhower
|
||||
Boatload of bug fixes to command handlers.
|
||||
|
||||
Rev 1.16 2003.10.18 8:07:12 PM czhower
|
||||
Fixed bug with defaults.
|
||||
|
||||
Rev 1.15 2003.10.18 8:03:58 PM czhower
|
||||
Defaults for codes
|
||||
|
||||
Rev 1.14 10/5/2003 03:06:18 AM JPMugaas
|
||||
Should compile.
|
||||
|
||||
Rev 1.13 8/9/2003 3:52:44 PM BGooijen
|
||||
TIdCommandHandlers can now create any TIdCommandHandler descendant. this
|
||||
makes it possible to override TIdCommandHandler.check and check for the
|
||||
command a different way ( binary commands, protocols where the string doesn't
|
||||
start with the command )
|
||||
|
||||
Rev 1.12 8/2/2003 2:22:54 PM SPerry
|
||||
Fixed OnCommandHandlersException problem
|
||||
|
||||
Rev 1.11 8/2/2003 1:43:08 PM SPerry
|
||||
Modifications to get command handlers to work
|
||||
|
||||
Rev 1.9 7/30/2003 10:18:30 PM SPerry
|
||||
Fixed AV when creating commandhandler (again) -- for some reason the bug
|
||||
fixed in Rev. 1.7 was still there.
|
||||
|
||||
Rev 1.8 7/30/2003 8:31:58 PM SPerry
|
||||
Fixed AV with LFReplyClass.
|
||||
|
||||
Rev 1.4 7/9/2003 10:55:26 PM BGooijen
|
||||
Restored all features
|
||||
|
||||
Rev 1.3 7/9/2003 04:36:10 PM JPMugaas
|
||||
You now can override the TIdReply with your own type. This should illiminate
|
||||
some warnings about some serious issues. TIdReply is ONLY a base class with
|
||||
virtual methods.
|
||||
|
||||
Rev 1.2 7/9/2003 01:43:22 PM JPMugaas
|
||||
Should now compile.
|
||||
|
||||
Rev 1.1 7/9/2003 2:56:44 PM SPerry
|
||||
Added OnException event
|
||||
|
||||
|
||||
Rev 1.0 7/6/2003 4:47:38 PM SPerry
|
||||
Units that use Command handlers
|
||||
}
|
||||
unit IdCommandHandlers;
|
||||
|
||||
{
|
||||
Original author: Chad Z. Hower
|
||||
Separate Unit : Sergio Perry
|
||||
}
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
//Put FPC into Delphi mode
|
||||
|
||||
uses
|
||||
Classes,
|
||||
IdBaseComponent, IdComponent, IdReply, IdGlobal,
|
||||
IdContext, IdReplyRFC;
|
||||
|
||||
const
|
||||
IdEnabledDefault = True;
|
||||
// DO NOT change this default (ParseParams). Many servers rely on this
|
||||
IdParseParamsDefault = True;
|
||||
IdHelpVisibleDef = True;
|
||||
type
|
||||
TIdCommandHandlers = class;
|
||||
TIdCommandHandler = class;
|
||||
TIdCommand = class;
|
||||
|
||||
{ Events }
|
||||
TIdCommandEvent = procedure(ASender: TIdCommand) of object;
|
||||
TIdAfterCommandHandlerEvent = procedure(ASender: TIdCommandHandlers;
|
||||
AContext: TIdContext) of object;
|
||||
TIdBeforeCommandHandlerEvent = procedure(ASender: TIdCommandHandlers;
|
||||
var AData: string; AContext: TIdContext) of object;
|
||||
TIdCommandHandlersExceptionEvent = procedure(ACommand: String; AContext: TIdContext) of object;
|
||||
|
||||
{ TIdCommandHandler }
|
||||
TIdCommandHandler = class(TCollectionItem)
|
||||
protected
|
||||
FCmdDelimiter: Char;
|
||||
FCommand: string;
|
||||
{$IFDEF USE_OBJECT_ARC}
|
||||
// When ARC is enabled, object references MUST be valid objects.
|
||||
// It is common for users to store non-object values, though, so
|
||||
// we will provide separate properties for those purposes
|
||||
//
|
||||
// TODO; use TValue instead of separating them
|
||||
//
|
||||
FDataObject: TObject;
|
||||
FDataValue: PtrInt;
|
||||
{$ELSE}
|
||||
FData: TObject;
|
||||
{$ENDIF}
|
||||
FDescription: TStrings;
|
||||
FDisconnect: boolean;
|
||||
FEnabled: boolean;
|
||||
FExceptionReply: TIdReply;
|
||||
FHelpSuperScript : String; //may be something like * or + which should appear in help
|
||||
FHelpVisible : Boolean;
|
||||
FName: string;
|
||||
FNormalReply: TIdReply;
|
||||
FOnCommand: TIdCommandEvent;
|
||||
FParamDelimiter: Char;
|
||||
FParseParams: Boolean;
|
||||
FReplyClass : TIdReplyClass;
|
||||
FResponse: TStrings;
|
||||
FTag: integer;
|
||||
//
|
||||
function GetDisplayName: string; override;
|
||||
procedure SetDescription(AValue: TStrings);
|
||||
procedure SetExceptionReply(AValue: TIdReply);
|
||||
procedure SetNormalReply(AValue: TIdReply);
|
||||
procedure SetResponse(AValue: TStrings);
|
||||
public
|
||||
function Check(const AData: string; AContext: TIdContext): boolean; virtual;
|
||||
procedure DoCommand(const AData: string; AContext: TIdContext; AUnparsedParams: string); virtual;
|
||||
procedure DoParseParams(AUnparsedParams: string; AParams: TStrings); virtual;
|
||||
constructor Create(ACollection: TCollection); override;
|
||||
destructor Destroy; override;
|
||||
// function GetNamePath: string; override;
|
||||
function NameIs(const ACommand: string): Boolean;
|
||||
//
|
||||
{$IFDEF USE_OBJECT_ARC}
|
||||
property DataObject: TObject read FDataObject write FDataObject;
|
||||
property DataValue: PtrInt read FDataValue write FDataValue;
|
||||
{$ELSE}
|
||||
property Data: TObject read FData write FData;
|
||||
{$ENDIF}
|
||||
published
|
||||
property CmdDelimiter: Char read FCmdDelimiter write FCmdDelimiter;
|
||||
property Command: string read FCommand write FCommand;
|
||||
property Description: TStrings read FDescription write SetDescription;
|
||||
property Disconnect: boolean read FDisconnect write FDisconnect;
|
||||
property Enabled: boolean read FEnabled write FEnabled default IdEnabledDefault;
|
||||
property ExceptionReply: TIdReply read FExceptionReply write SetExceptionReply;
|
||||
property Name: string read FName write FName;
|
||||
property NormalReply: TIdReply read FNormalReply write SetNormalReply;
|
||||
property ParamDelimiter: Char read FParamDelimiter write FParamDelimiter;
|
||||
property ParseParams: Boolean read FParseParams write FParseParams;
|
||||
property Response: TStrings read FResponse write SetResponse;
|
||||
property Tag: Integer read FTag write FTag;
|
||||
//
|
||||
property HelpSuperScript : String read FHelpSuperScript write FHelpSuperScript; //may be something like * or + which should appear in help
|
||||
property HelpVisible : Boolean read FHelpVisible write FHelpVisible default IdHelpVisibleDef;
|
||||
|
||||
property OnCommand: TIdCommandEvent read FOnCommand write FOnCommand;
|
||||
end;
|
||||
|
||||
TIdCommandHandlerClass = class of TIdCommandHandler;
|
||||
|
||||
{ TIdCommandHandlers }
|
||||
TIdCommandHandlers = class(TOwnedCollection)
|
||||
protected
|
||||
FBase: TIdComponent;
|
||||
FExceptionReply: TIdReply;
|
||||
FOnAfterCommandHandler: TIdAfterCommandHandlerEvent;
|
||||
FOnBeforeCommandHandler: TIdBeforeCommandHandlerEvent;
|
||||
FOnCommandHandlersException: TIdCommandHandlersExceptionEvent;
|
||||
FParseParamsDef: Boolean;
|
||||
FPerformReplies: Boolean;
|
||||
FReplyClass: TIdReplyClass;
|
||||
FReplyTexts: TIdReplies;
|
||||
//
|
||||
procedure DoAfterCommandHandler(AContext: TIdContext);
|
||||
procedure DoBeforeCommandHandler(AContext: TIdContext; var VLine: string);
|
||||
procedure DoOnCommandHandlersException(const ACommand: String; AContext: TIdContext);
|
||||
function GetItem(AIndex: Integer): TIdCommandHandler;
|
||||
// This is used instead of the OwnedBy property directly calling GetOwner because
|
||||
// D5 dies with internal errors and crashes
|
||||
// function GetOwnedBy: TIdPersistent;
|
||||
procedure SetItem(AIndex: Integer; const AValue: TIdCommandHandler);
|
||||
public
|
||||
function Add: TIdCommandHandler;
|
||||
constructor Create(
|
||||
ABase: TIdComponent;
|
||||
AReplyClass: TIdReplyClass;
|
||||
AReplyTexts: TIdReplies;
|
||||
AExceptionReply: TIdReply = nil;
|
||||
ACommandHandlerClass: TIdCommandHandlerClass = nil
|
||||
); reintroduce;
|
||||
function HandleCommand(AContext: TIdContext; var VCommand: string): Boolean; virtual;
|
||||
//
|
||||
property Base: TIdComponent read FBase;
|
||||
property Items[AIndex: Integer]: TIdCommandHandler read GetItem write SetItem;
|
||||
// OwnedBy is used so as not to conflict with Owner in D6
|
||||
//property OwnedBy: TIdPersistent read GetOwnedBy;
|
||||
property ParseParamsDefault: Boolean read FParseParamsDef write FParseParamsDef;
|
||||
property PerformReplies: Boolean read FPerformReplies write FPerformReplies;
|
||||
property ReplyClass: TIdReplyClass read FReplyClass;
|
||||
property ReplyTexts: TIdReplies read FReplyTexts;
|
||||
//
|
||||
property OnAfterCommandHandler: TIdAfterCommandHandlerEvent read FOnAfterCommandHandler
|
||||
write FOnAfterCommandHandler;
|
||||
// Occurs in the context of the peer thread
|
||||
property OnBeforeCommandHandler: TIdBeforeCommandHandlerEvent read FOnBeforeCommandHandler
|
||||
write FOnBeforeCommandHandler;
|
||||
property OnCommandHandlersException: TIdCommandHandlersExceptionEvent read FOnCommandHandlersException
|
||||
write FOnCommandHandlersException;
|
||||
end;
|
||||
|
||||
{ TIdCommand }
|
||||
TIdCommand = class(TObject)
|
||||
protected
|
||||
FCommandHandler: TIdCommandHandler;
|
||||
FDisconnect: Boolean;
|
||||
FParams: TStrings;
|
||||
FPerformReply: Boolean;
|
||||
FRawLine: string;
|
||||
FReply: TIdReply;
|
||||
FResponse: TStrings;
|
||||
FContext: TIdContext;
|
||||
FUnparsedParams: string;
|
||||
FSendEmptyResponse: Boolean;
|
||||
//
|
||||
procedure DoCommand; virtual;
|
||||
procedure SetReply(AValue: TIdReply);
|
||||
procedure SetResponse(AValue: TStrings);
|
||||
public
|
||||
constructor Create(AOwner: TIdCommandHandler); virtual;
|
||||
destructor Destroy; override;
|
||||
procedure SendReply;
|
||||
//
|
||||
property CommandHandler: TIdCommandHandler read FCommandHandler;
|
||||
property Disconnect: Boolean read FDisconnect write FDisconnect;
|
||||
property PerformReply: Boolean read FPerformReply write FPerformReply;
|
||||
property Params: TStrings read FParams;
|
||||
property RawLine: string read FRawLine;
|
||||
property Reply: TIdReply read FReply write SetReply;
|
||||
property Response: TStrings read FResponse write SetResponse;
|
||||
property Context: TIdContext read FContext;
|
||||
property UnparsedParams: string read FUnparsedParams;
|
||||
property SendEmptyResponse: Boolean read FSendEmptyResponse write FSendEmptyResponse;
|
||||
end;//TIdCommand
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
SysUtils;
|
||||
|
||||
{ TIdCommandHandlers }
|
||||
|
||||
constructor TIdCommandHandlers.Create(
|
||||
ABase: TIdComponent;
|
||||
AReplyClass: TIdReplyClass;
|
||||
AReplyTexts: TIdReplies;
|
||||
AExceptionReply: TIdReply = nil;
|
||||
ACommandHandlerClass: TIdCommandHandlerClass = nil
|
||||
);
|
||||
begin
|
||||
if ACommandHandlerClass = nil then begin
|
||||
ACommandHandlerClass := TIdCommandHandler;
|
||||
end;
|
||||
inherited Create(ABase, ACommandHandlerClass);
|
||||
FBase := ABase;
|
||||
FExceptionReply := AExceptionReply;
|
||||
FParseParamsDef := IdParseParamsDefault;
|
||||
FPerformReplies := True; // RLebeau: default to legacy behavior
|
||||
FReplyClass := AReplyClass;
|
||||
FReplyTexts := AReplyTexts;
|
||||
end;
|
||||
|
||||
function TIdCommandHandlers.Add: TIdCommandHandler;
|
||||
begin
|
||||
Result := TIdCommandHandler(inherited Add);
|
||||
end;
|
||||
|
||||
function TIdCommandHandlers.HandleCommand(AContext: TIdContext;
|
||||
var VCommand: string): Boolean;
|
||||
var
|
||||
i, j: Integer;
|
||||
begin
|
||||
j := Count - 1;
|
||||
Result := False;
|
||||
DoBeforeCommandHandler(AContext, VCommand); try
|
||||
i := 0;
|
||||
while i <= j do begin
|
||||
if Items[i].Enabled then begin
|
||||
Result := Items[i].Check(VCommand, AContext);
|
||||
if Result then begin
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
Inc(i);
|
||||
end;
|
||||
finally DoAfterCommandHandler(AContext); end;
|
||||
end;
|
||||
|
||||
procedure TIdCommandHandlers.DoAfterCommandHandler(AContext: TIdContext);
|
||||
begin
|
||||
if Assigned(OnAfterCommandHandler) then begin
|
||||
OnAfterCommandHandler(Self, AContext);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCommandHandlers.DoBeforeCommandHandler(AContext: TIdContext;
|
||||
var VLine: string);
|
||||
begin
|
||||
if Assigned(OnBeforeCommandHandler) then begin
|
||||
OnBeforeCommandHandler(Self, VLine, AContext);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCommandHandlers.DoOnCommandHandlersException(const ACommand: String;
|
||||
AContext: TIdContext);
|
||||
begin
|
||||
if Assigned(FOnCommandHandlersException) then begin
|
||||
OnCommandHandlersException(ACommand, AContext);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdCommandHandlers.GetItem(AIndex: Integer): TIdCommandHandler;
|
||||
begin
|
||||
Result := TIdCommandHandler(inherited Items[AIndex]);
|
||||
end;
|
||||
|
||||
{
|
||||
function TIdCommandHandlers.GetOwnedBy: TIdPersistent;
|
||||
begin
|
||||
Result := GetOwner;
|
||||
end;
|
||||
}
|
||||
|
||||
procedure TIdCommandHandlers.SetItem(AIndex: Integer; const AValue: TIdCommandHandler);
|
||||
begin
|
||||
inherited SetItem(AIndex, AValue);
|
||||
end;
|
||||
|
||||
{ TIdCommandHandler }
|
||||
|
||||
procedure TIdCommandHandler.DoCommand(const AData: string; AContext: TIdContext; AUnparsedParams: string);
|
||||
var
|
||||
LCommand: TIdCommand;
|
||||
begin
|
||||
LCommand := TIdCommand.Create(Self);
|
||||
try
|
||||
LCommand.FRawLine := AData;
|
||||
LCommand.FContext := AContext;
|
||||
LCommand.FUnparsedParams := AUnparsedParams;
|
||||
|
||||
if ParseParams then begin
|
||||
DoParseParams(AUnparsedParams, LCommand.Params);
|
||||
end;
|
||||
|
||||
// RLebeau 2/21/08: for the IRC protocol, RFC 2812 section 2.4 says that
|
||||
// clients are not allowed to issue numeric replies for server-issued
|
||||
// commands. Added the PerformReplies property so TIdIRC can specify
|
||||
// that behavior.
|
||||
if Collection is TIdCommandHandlers then begin
|
||||
LCommand.PerformReply := TIdCommandHandlers(Collection).PerformReplies;
|
||||
end;
|
||||
|
||||
try
|
||||
if (LCommand.Reply.Code = '') and (NormalReply.Code <> '') then begin
|
||||
LCommand.Reply.Assign(NormalReply);
|
||||
end;
|
||||
|
||||
//if code<>'' before DoCommand, then it breaks exception handling
|
||||
Assert(LCommand.Reply.Code <> '');
|
||||
LCommand.DoCommand;
|
||||
|
||||
if LCommand.Reply.Code = '' then begin
|
||||
LCommand.Reply.Assign(NormalReply);
|
||||
end;
|
||||
// UpdateText here in case user wants to add to it. SendReply also gets it in case
|
||||
// a different reply is sent (ie exception, etc), or the user changes the code in the event
|
||||
LCommand.Reply.UpdateText;
|
||||
except
|
||||
on E: Exception do begin
|
||||
// If there is an unhandled exception, we override all replies
|
||||
// If nothing specified to override with, we throw the exception again.
|
||||
// If the user wants a custom value on exception other, its their responsibility
|
||||
// to catch it before it reaches us
|
||||
LCommand.Reply.Clear;
|
||||
if LCommand.PerformReply then begin
|
||||
// Try from command handler first
|
||||
if ExceptionReply.Code <> '' then begin
|
||||
LCommand.Reply.Assign(ExceptionReply);
|
||||
// If still no go, from server
|
||||
// Can be nil though. Typically only servers pass it in
|
||||
end else if (Collection is TIdCommandHandlers) and (TIdCommandHandlers(Collection).FExceptionReply <> nil) then begin
|
||||
LCommand.Reply.Assign(TIdCommandHandlers(Collection).FExceptionReply);
|
||||
end;
|
||||
if LCommand.Reply.Code <> '' then begin
|
||||
//done this way in case an exception message has more than one line.
|
||||
//otherwise you could get something like this:
|
||||
//
|
||||
// 550 System Error. Code: 2
|
||||
// The system cannot find the file specified
|
||||
//
|
||||
//and the second line would throw off some clients.
|
||||
LCommand.Reply.Text.Text := E.Message;
|
||||
//Reply.Text.Add(E.Message);
|
||||
LCommand.SendReply;
|
||||
end else begin
|
||||
raise;
|
||||
end;
|
||||
end else begin
|
||||
raise;
|
||||
end;
|
||||
end else begin
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
|
||||
if LCommand.PerformReply then begin
|
||||
LCommand.SendReply;
|
||||
end;
|
||||
|
||||
if (LCommand.Response.Count > 0) or LCommand.SendEmptyResponse then begin
|
||||
AContext.Connection.WriteRFCStrings(LCommand.Response);
|
||||
end else if Response.Count > 0 then begin
|
||||
AContext.Connection.WriteRFCStrings(Response);
|
||||
end;
|
||||
finally
|
||||
try
|
||||
if LCommand.Disconnect then begin
|
||||
AContext.Connection.Disconnect;
|
||||
end;
|
||||
finally
|
||||
LCommand.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCommandHandler.DoParseParams(AUnparsedParams: string; AParams: TStrings);
|
||||
// AUnparsedParams is not preparsed and is completely left up to the command handler. This will
|
||||
// allow for future expansion such as multiple delimiters etc, and allow the logic to properly
|
||||
// remain in each of the command handler implementations. In the future there may be a base type
|
||||
// and multiple descendants
|
||||
begin
|
||||
AParams.Clear;
|
||||
SplitDelimitedString(AUnparsedParams, AParams, FParamDelimiter <> #32, FParamDelimiter);
|
||||
end;
|
||||
|
||||
function TIdCommandHandler.Check(const AData: string; AContext: TIdContext): boolean;
|
||||
// AData is not preparsed and is completely left up to the command handler. This will allow for
|
||||
// future expansion such as wild cards etc, and allow the logic to properly remain in each of the
|
||||
// command handler implementations. In the future there may be a base type and multiple descendants
|
||||
var
|
||||
LUnparsedParams: string;
|
||||
begin
|
||||
LUnparsedParams := '';
|
||||
Result := TextIsSame(AData, Command); // Command by itself
|
||||
|
||||
if not Result then begin
|
||||
if CmdDelimiter <> #0 then begin
|
||||
Result := TextStartsWith(AData, Command + CmdDelimiter);
|
||||
if Result then begin
|
||||
LUnparsedParams := Copy(AData, Length(Command) + 2, MaxInt);
|
||||
end;
|
||||
end else begin
|
||||
// Dont strip any part of the params out.. - just remove the command purely on length and
|
||||
// no delim
|
||||
Result := TextStartsWith(AData, Command);
|
||||
if Result then begin
|
||||
LUnparsedParams := Copy(AData, Length(Command) + 1, MaxInt);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if Result then begin
|
||||
DoCommand(AData, AContext, LUnparsedParams);
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TIdCommandHandler.Create(ACollection: TCollection);
|
||||
begin
|
||||
inherited Create(ACollection);
|
||||
|
||||
FReplyClass := TIdCommandHandlers(ACollection).ReplyClass;
|
||||
if FReplyClass = nil then begin
|
||||
FReplyClass := TIdReplyRFC;
|
||||
end;
|
||||
|
||||
FCmdDelimiter := #32;
|
||||
FEnabled := IdEnabledDefault;
|
||||
FName := ClassName + IntToStr(ID);
|
||||
FParamDelimiter := #32;
|
||||
FParseParams := TIdCommandHandlers(ACollection).ParseParamsDefault;
|
||||
FResponse := TStringList.Create;
|
||||
FDescription := TStringList.Create;
|
||||
|
||||
FNormalReply := FReplyClass.CreateWithReplyTexts(nil, TIdCommandHandlers(ACollection).ReplyTexts);
|
||||
if FNormalReply is TIdReplyRFC then begin
|
||||
FNormalReply.Code := '200'; {do not localize}
|
||||
end;
|
||||
FHelpVisible := IdHelpVisibleDef;
|
||||
// Dont initialize, pulls from CmdTCPServer for defaults
|
||||
FExceptionReply := FReplyClass.CreateWithReplyTexts(nil, TIdCommandHandlers(ACollection).ReplyTexts);
|
||||
end;
|
||||
|
||||
destructor TIdCommandHandler.Destroy;
|
||||
begin
|
||||
FreeAndNil(FResponse);
|
||||
FreeAndNil(FNormalReply);
|
||||
FreeAndNil(FDescription);
|
||||
FreeAndNil(FExceptionReply);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TIdCommandHandler.GetDisplayName: string;
|
||||
begin
|
||||
if Command = '' then begin
|
||||
Result := Name;
|
||||
end else begin
|
||||
Result := Command;
|
||||
end;
|
||||
end;
|
||||
|
||||
{
|
||||
function TIdCommandHandler.GetNamePath: string;
|
||||
begin
|
||||
if Collection <> nil then begin
|
||||
// OwnedBy is used because D4/D5 dont expose Owner on TOwnedCollection but D6 does
|
||||
Result := TIdCommandHandlers(Collection).OwnedBy.GetNamePath + '.' + Name;
|
||||
end else begin
|
||||
Result := inherited GetNamePath;
|
||||
end;
|
||||
end;
|
||||
}
|
||||
|
||||
function TIdCommandHandler.NameIs(const ACommand: string): Boolean;
|
||||
begin
|
||||
Result := TextIsSame(ACommand, FName);
|
||||
end;
|
||||
|
||||
procedure TIdCommandHandler.SetExceptionReply(AValue: TIdReply);
|
||||
begin
|
||||
FExceptionReply.Assign(AValue);
|
||||
end;
|
||||
|
||||
procedure TIdCommandHandler.SetNormalReply(AValue: TIdReply);
|
||||
begin
|
||||
FNormalReply.Assign(AValue);
|
||||
end;
|
||||
|
||||
procedure TIdCommandHandler.SetResponse(AValue: TStrings);
|
||||
begin
|
||||
FResponse.Assign(AValue);
|
||||
end;
|
||||
|
||||
procedure TIdCommandHandler.SetDescription(AValue: TStrings);
|
||||
begin
|
||||
FDescription.Assign(AValue);
|
||||
end;
|
||||
|
||||
{ TIdCommand }
|
||||
|
||||
constructor TIdCommand.Create(AOwner: TIdCommandHandler);
|
||||
begin
|
||||
inherited Create;
|
||||
FParams := TStringList.Create;
|
||||
FReply := AOwner.FReplyClass.CreateWithReplyTexts(nil, TIdCommandHandlers(AOwner.Collection).ReplyTexts);
|
||||
FResponse := TStringList.Create;
|
||||
FCommandHandler := AOwner;
|
||||
FDisconnect := AOwner.Disconnect;
|
||||
end;
|
||||
|
||||
destructor TIdCommand.Destroy;
|
||||
begin
|
||||
FreeAndNil(FReply);
|
||||
FreeAndNil(FResponse);
|
||||
FreeAndNil(FParams);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TIdCommand.DoCommand;
|
||||
begin
|
||||
if Assigned(CommandHandler.OnCommand) then begin
|
||||
CommandHandler.OnCommand(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCommand.SendReply;
|
||||
begin
|
||||
PerformReply := False;
|
||||
Reply.UpdateText;
|
||||
Context.Connection.IOHandler.Write(Reply.FormattedReply);
|
||||
end;
|
||||
|
||||
procedure TIdCommand.SetReply(AValue: TIdReply);
|
||||
begin
|
||||
FReply.Assign(AValue);
|
||||
end;
|
||||
|
||||
procedure TIdCommand.SetResponse(AValue: TStrings);
|
||||
begin
|
||||
FResponse.Assign(AValue);
|
||||
end;
|
||||
|
||||
end.
|
||||
1687
indy/Core/IdCompilerDefines.inc
Normal file
220
indy/Core/IdContext.pas
Normal file
@@ -0,0 +1,220 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.14 6/16/2004 2:08:48 PM JPMugaas
|
||||
Binding made public for the FTP Server.
|
||||
|
||||
Rev 1.13 6/4/2004 1:34:24 PM DSiders
|
||||
Removed unused TIdContextDoRun, TIdContextMethod types.
|
||||
|
||||
Rev 1.12 2004.02.03 4:17:08 PM czhower
|
||||
For unit name changes.
|
||||
|
||||
Rev 1.11 21.1.2004 ã. 12:31:04 DBondzhev
|
||||
Fix for Indy source. Workaround for dccil bug
|
||||
now it can be compiled using Compile instead of build
|
||||
|
||||
Rev 1.10 2003.10.21 12:18:58 AM czhower
|
||||
TIdTask support and fiber bug fixes.
|
||||
|
||||
Rev 1.9 2003.10.11 5:47:18 PM czhower
|
||||
-VCL fixes for servers
|
||||
-Chain suport for servers (Super core)
|
||||
-Scheduler upgrades
|
||||
-Full yarn support
|
||||
|
||||
Rev 1.8 2003.09.19 11:54:28 AM czhower
|
||||
-Completed more features necessary for servers
|
||||
-Fixed some bugs
|
||||
|
||||
Rev 1.7 3/22/2003 09:45:26 PM JPMugaas
|
||||
Now should compile under D4.
|
||||
|
||||
Rev 1.6 3/13/2003 10:18:38 AM BGooijen
|
||||
Server side fibers, bug fixes
|
||||
|
||||
Rev 1.5 1/31/2003 7:24:18 PM BGooijen
|
||||
Added a .Binding function
|
||||
|
||||
Rev 1.4 1/23/2003 8:33:20 PM BGooijen
|
||||
|
||||
Rev 1.3 1/23/2003 11:06:06 AM BGooijen
|
||||
|
||||
|
||||
Rev 1.2 1-17-2003 23:58:30 BGooijen
|
||||
removed OnCreate/OnDestroy again, they had no use
|
||||
|
||||
Rev 1.0 1-17-2003 22:28:58 BGooijen
|
||||
}
|
||||
|
||||
unit IdContext;
|
||||
|
||||
interface
|
||||
|
||||
{$i IdCompilerDefines.inc}
|
||||
|
||||
uses
|
||||
Classes,
|
||||
IdSocketHandle, IdTCPConnection, IdTask, IdYarn, IdThreadSafe,
|
||||
{$IFDEF HAS_GENERICS_TThreadList}
|
||||
System.Generics.Collections,
|
||||
{$ENDIF}
|
||||
SysUtils;
|
||||
|
||||
type
|
||||
TIdContext = class;
|
||||
TIdContextClass = class of TIdContext;
|
||||
TIdContextRun = function(AContext: TIdContext): Boolean of object;
|
||||
TIdContextEvent = procedure(AContext: TIdContext) of object;
|
||||
TIdContextExceptionEvent = procedure(AContext: TIdContext; AException: Exception) of object;
|
||||
|
||||
{$IFDEF HAS_GENERICS_TThreadList}
|
||||
TIdContextThreadList = TIdThreadSafeObjectList<TIdContext>;
|
||||
TIdContextList = TList<TIdContext>;
|
||||
{$ELSE}
|
||||
// TODO: flesh out to match TThreadList<TIdContext> and TList<TIdContext> for non-Generics compilers
|
||||
TIdContextThreadList = TIdThreadSafeObjectList;
|
||||
TIdContextList = TList;
|
||||
{$ENDIF}
|
||||
|
||||
TIdContext = class(TIdTask)
|
||||
protected
|
||||
// A list in which this context is registered, this can be nil, and should
|
||||
// therefore not be used
|
||||
FContextList: TIdContextThreadList;
|
||||
FConnection: TIdTCPConnection; // TODO: should this be [Weak] on ARC systems?
|
||||
FOwnsConnection: Boolean;
|
||||
FOnRun: TIdContextRun;
|
||||
FOnBeforeRun: TIdContextEvent;
|
||||
FOnAfterRun: TIdContextEvent;
|
||||
FOnException: TIdContextExceptionEvent;
|
||||
//
|
||||
procedure BeforeRun; override;
|
||||
function Run: Boolean; override;
|
||||
procedure AfterRun; override;
|
||||
procedure HandleException(AException: Exception); override;
|
||||
function GetBinding: TIdSocketHandle;
|
||||
public
|
||||
constructor Create(
|
||||
AConnection: TIdTCPConnection;
|
||||
AYarn: TIdYarn;
|
||||
AList: TIdContextThreadList = nil
|
||||
); reintroduce; virtual;
|
||||
destructor Destroy; override;
|
||||
procedure RemoveFromList;
|
||||
//
|
||||
property Binding: TIdSocketHandle read GetBinding;
|
||||
property Connection: TIdTCPConnection read FConnection;
|
||||
//
|
||||
property OnAfterRun: TIdContextEvent read FOnAfterRun write FOnAfterRun;
|
||||
property OnBeforeRun: TIdContextEvent read FOnBeforeRun write FOnBeforeRun;
|
||||
property OnRun: TIdContextRun read FOnRun write FOnRun;
|
||||
property OnException: TIdContextExceptionEvent read FOnException write FOnException;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
{ TIdContext }
|
||||
|
||||
uses
|
||||
{$IFDEF VCL_XE3_OR_ABOVE}
|
||||
System.Types,
|
||||
{$ENDIF}
|
||||
IdGlobal,
|
||||
IdIOHandlerSocket;
|
||||
|
||||
constructor TIdContext.Create(AConnection: TIdTCPConnection; AYarn: TIdYarn;
|
||||
AList: TIdContextThreadList = nil);
|
||||
begin
|
||||
inherited Create(AYarn);
|
||||
FConnection := AConnection;
|
||||
FOwnsConnection := True;
|
||||
FContextList := AList;
|
||||
end;
|
||||
|
||||
destructor TIdContext.Destroy;
|
||||
begin
|
||||
if Assigned(FContextList) then begin
|
||||
FContextList.Remove(Self);
|
||||
end;
|
||||
|
||||
if FOwnsConnection then begin
|
||||
IdDisposeAndNil(FConnection);
|
||||
end;
|
||||
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TIdContext.RemoveFromList;
|
||||
begin
|
||||
FContextList := nil;
|
||||
end;
|
||||
|
||||
procedure TIdContext.BeforeRun;
|
||||
begin
|
||||
//Context must be added to ContextList outside of create. This avoids
|
||||
//the possibility of another thread accessing a context (specifically
|
||||
//a subclass) that is still creating. similar logic for remove/destroy.
|
||||
if Assigned(FContextList) then begin
|
||||
FContextList.Add(Self);
|
||||
end;
|
||||
|
||||
if Assigned(OnBeforeRun) then begin
|
||||
OnBeforeRun(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdContext.Run: Boolean;
|
||||
begin
|
||||
if Assigned(OnRun) then begin
|
||||
Result := OnRun(Self);
|
||||
end else begin
|
||||
Result := True;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdContext.AfterRun;
|
||||
begin
|
||||
if Assigned(OnAfterRun) then begin
|
||||
OnAfterRun(Self);
|
||||
end;
|
||||
|
||||
if FContextList <> nil then begin
|
||||
FContextList.Remove(Self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdContext.HandleException(AException: Exception);
|
||||
begin
|
||||
if Assigned(OnException) then begin
|
||||
OnException(Self, AException);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdContext.GetBinding: TIdSocketHandle;
|
||||
begin
|
||||
Result := nil;
|
||||
if Connection <> nil then begin
|
||||
if Connection.Socket <> nil then begin
|
||||
Result := Connection.Socket.Binding;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
12
indy/Core/IdCore90ASM90.inc
Normal file
@@ -0,0 +1,12 @@
|
||||
[assembly: AssemblyDescription('Internet Direct (Indy) 10.6.2 Core Run-Time Package for Borland Developer Studio')]
|
||||
[assembly: AssemblyConfiguration('')]
|
||||
[assembly: AssemblyCompany('Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')]
|
||||
[assembly: AssemblyProduct('Indy for Microsoft .NET Framework')]
|
||||
[assembly: AssemblyCopyright('Copyright © 1993 - 2015 Chad Z. Hower a.k.a Kudzu and the Indy Pit Crew')]
|
||||
[assembly: AssemblyTrademark('')]
|
||||
[assembly: AssemblyCulture('')]
|
||||
[assembly: AssemblyTitle('Indy .NET Core Run-Time Package')]
|
||||
[assembly: AssemblyVersion('10.6.2.*')]
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyKeyFile('')]
|
||||
[assembly: AssemblyKeyName('')]
|
||||
244
indy/Core/IdCoreDsnRegister.pas
Normal file
@@ -0,0 +1,244 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.4 12/10/2004 15:36:40 HHariri
|
||||
Fix so it works with D8 too
|
||||
|
||||
Rev 1.3 9/5/2004 2:08:14 PM JPMugaas
|
||||
Should work in D9 NET.
|
||||
|
||||
Rev 1.2 2/3/2004 11:42:52 AM JPMugaas
|
||||
Fixed for new design.
|
||||
|
||||
Rev 1.1 2/1/2004 2:44:20 AM JPMugaas
|
||||
Bindings editor should be fully functional including IPv6 support.
|
||||
|
||||
Rev 1.0 11/13/2002 08:41:18 AM JPMugaas
|
||||
}
|
||||
|
||||
unit IdCoreDsnRegister;
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
uses
|
||||
{$IFDEF DOTNET}
|
||||
Borland.Vcl.Design.DesignIntF,
|
||||
Borland.Vcl.Design.DesignEditors
|
||||
{$ELSE}
|
||||
{$IFDEF FPC}
|
||||
PropEdits,
|
||||
ComponentEditors
|
||||
{$ELSE}
|
||||
{$IFDEF VCL_6_OR_ABOVE}
|
||||
DesignIntf,
|
||||
DesignEditors
|
||||
{$ELSE}
|
||||
Dsgnintf
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
;
|
||||
|
||||
type
|
||||
{$IFDEF FPC}
|
||||
TIdBaseComponentEditor = class(TDefaultComponentEditor)
|
||||
{$ELSE}
|
||||
TIdBaseComponentEditor = class(TDefaultEditor)
|
||||
{$ENDIF}
|
||||
public
|
||||
procedure ExecuteVerb(Index: Integer); override;
|
||||
function GetVerb(Index: Integer): string; override;
|
||||
function GetVerbCount: Integer; override;
|
||||
end;
|
||||
|
||||
{$IFDEF FPC}
|
||||
TIdPropEdBinding = class(TPropertyEditor)
|
||||
protected
|
||||
FValue : String;
|
||||
property Value : String read FValue write FValue;
|
||||
{$ELSE}
|
||||
TIdPropEdBinding = class(TClassProperty)
|
||||
{$ENDIF}
|
||||
public
|
||||
procedure Edit; override;
|
||||
function GetAttributes: TPropertyAttributes; override;
|
||||
function GetValue: string; override;
|
||||
procedure SetValue(const Value: string); override;
|
||||
end;
|
||||
|
||||
// Procs
|
||||
procedure Register;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
Classes,
|
||||
{$IFDEF WIDGET_WINFORMS}
|
||||
IdDsnPropEdBindingNET,
|
||||
IdAboutDotNET,
|
||||
{$ELSE}
|
||||
IdDsnPropEdBindingVCL,
|
||||
IdAboutVCL,
|
||||
{$ENDIF}
|
||||
IdDsnCoreResourceStrings,
|
||||
IdBaseComponent,
|
||||
IdComponent,
|
||||
IdGlobal,
|
||||
IdStack,
|
||||
IdSocketHandle;
|
||||
|
||||
{
|
||||
Design Note: It turns out that in DotNET, there are no services file functions and
|
||||
IdPorts does not work as expected in DotNET. It is probably possible to read the
|
||||
services file ourselves but that creates some portability problems as the placement
|
||||
is different in every operating system.
|
||||
|
||||
e.g.
|
||||
|
||||
Linux and Unix-like systems - /etc
|
||||
Windows 95, 98, and ME - c:\windows
|
||||
Windows NT systems - c:\winnt\system32\drivers\etc
|
||||
|
||||
Thus, it will undercut whatever benefit we could get with DotNET.
|
||||
|
||||
About the best I could think of is to use an edit control because
|
||||
we can't offer anything from the services file in DotNET.
|
||||
|
||||
TODO: Maybe there might be a way to find the location in a more elegant
|
||||
manner than what I described.
|
||||
}
|
||||
|
||||
type
|
||||
{$IFDEF WIDGET_WINFORMS}
|
||||
TIdPropEdBindingEntry = TIdDsnPropEdBindingNET;
|
||||
{$ELSE}
|
||||
TIdPropEdBindingEntry = TIdDsnPropEdBindingVCL;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TIdPropEdBinding.Edit;
|
||||
var
|
||||
pSockets: TIdSocketHandles;
|
||||
pEntry: TIdPropEdBindingEntry;
|
||||
begin
|
||||
inherited Edit;
|
||||
|
||||
{$IFNDEF DOTNET}
|
||||
pSockets := TIdSocketHandles(
|
||||
{$IFDEF CPU64}
|
||||
GetInt64Value
|
||||
{$ELSE}
|
||||
GetOrdValue
|
||||
{$ENDIF}
|
||||
);
|
||||
{$ELSE}
|
||||
pSockets := GetObjValue as TIdSocketHandles;
|
||||
{$ENDIF}
|
||||
|
||||
pEntry := TIdPropEdBindingEntry.Create;
|
||||
try
|
||||
pEntry.Caption := TComponent(GetComponent(0)).Name;
|
||||
pEntry.DefaultPort := pSockets.DefaultPort;
|
||||
Value := GetListValues(pSockets);
|
||||
pEntry.SetList(Value);
|
||||
if pEntry.Execute then
|
||||
begin
|
||||
Value := pEntry.GetList;
|
||||
FillHandleList(Value, pSockets);
|
||||
end;
|
||||
finally
|
||||
pEntry.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdPropEdBinding.GetAttributes: TPropertyAttributes;
|
||||
begin
|
||||
Result := inherited GetAttributes + [paDialog];
|
||||
end;
|
||||
|
||||
function TIdPropEdBinding.GetValue: string;
|
||||
var
|
||||
pSockets: TIdSocketHandles;
|
||||
begin
|
||||
{$IFNDEF DOTNET}
|
||||
pSockets := TIdSocketHandles(
|
||||
{$IFDEF CPU64}
|
||||
GetInt64Value
|
||||
{$ELSE}
|
||||
GetOrdValue
|
||||
{$ENDIF}
|
||||
);
|
||||
{$ELSE}
|
||||
pSockets := GetObjValue as TIdSocketHandles;
|
||||
{$ENDIF}
|
||||
Result := GetListValues(pSockets);
|
||||
end;
|
||||
|
||||
procedure TIdPropEdBinding.SetValue(const Value: string);
|
||||
var
|
||||
pSockets: TIdSocketHandles;
|
||||
begin
|
||||
inherited SetValue(Value);
|
||||
{$IFNDEF DOTNET}
|
||||
pSockets := TIdSocketHandles(
|
||||
{$IFDEF CPU64}
|
||||
GetInt64Value
|
||||
{$ELSE}
|
||||
GetOrdValue
|
||||
{$ENDIF}
|
||||
);
|
||||
{$ELSE}
|
||||
pSockets := GetObjValue as TIdSocketHandles;
|
||||
{$ENDIF}
|
||||
pSockets.BeginUpdate;
|
||||
try
|
||||
FillHandleList(Value, pSockets);
|
||||
finally
|
||||
pSockets.EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TIdBaseComponentEditor }
|
||||
|
||||
procedure TIdBaseComponentEditor.ExecuteVerb(Index: Integer);
|
||||
begin
|
||||
case Index of
|
||||
0 : TfrmAbout.ShowDlg;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdBaseComponentEditor.GetVerb(Index: Integer): string;
|
||||
begin
|
||||
case Index of
|
||||
0: Result := IndyFormat(RSAAboutMenuItemName, [gsIdVersion]);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdBaseComponentEditor.GetVerbCount: Integer;
|
||||
begin
|
||||
Result := 1;
|
||||
end;
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterPropertyEditor(TypeInfo(TIdSocketHandles), nil, '', TIdPropEdBinding); {Do not Localize}
|
||||
RegisterComponentEditor(TIdBaseComponent, TIdBaseComponentEditor);
|
||||
end;
|
||||
|
||||
end.
|
||||
BIN
indy/Core/IdCoreRegister.dcr
Normal file
BIN
indy/Core/IdCoreRegisterCool.dcr
Normal file
BIN
indy/Core/IdCreditsBitmap.res
Normal file
BIN
indy/Core/IdCreditsBitmap.resources
Normal file
1138
indy/Core/IdCustomTCPServer.pas
Normal file
253
indy/Core/IdCustomTransparentProxy.pas
Normal file
@@ -0,0 +1,253 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.10 11/12/2004 11:30:16 AM JPMugaas
|
||||
Expansions for IPv6.
|
||||
|
||||
Rev 1.9 11/11/2004 10:25:22 PM JPMugaas
|
||||
Added OpenProxy and CloseProxy so you can do RecvFrom and SendTo functions
|
||||
from the UDP client with SOCKS. You must call OpenProxy before using
|
||||
RecvFrom or SendTo. When you are finished, you must use CloseProxy to close
|
||||
any connection to the Proxy. Connect and disconnect also call OpenProxy and
|
||||
CloseProxy.
|
||||
|
||||
Rev 1.8 11/11/2004 3:42:52 AM JPMugaas
|
||||
Moved strings into RS. Socks will now raise an exception if you attempt to
|
||||
use SOCKS4 and SOCKS4A with UDP. Those protocol versions do not support UDP
|
||||
at all.
|
||||
|
||||
Rev 1.7 11/9/2004 8:18:00 PM JPMugaas
|
||||
Attempt to add SOCKS support in UDP.
|
||||
|
||||
Rev 1.6 6/6/2004 11:51:56 AM JPMugaas
|
||||
Fixed TODO with an exception
|
||||
|
||||
Rev 1.5 2004.02.03 4:17:04 PM czhower
|
||||
For unit name changes.
|
||||
|
||||
Rev 1.4 10/15/2003 10:59:06 PM DSiders
|
||||
Corrected spelling error in resource string name.
|
||||
Added resource string for circular links exception in transparent proxy.
|
||||
|
||||
Rev 1.3 10/15/2003 10:10:18 PM DSiders
|
||||
Added localization comments.
|
||||
|
||||
Rev 1.2 5/16/2003 9:22:38 AM BGooijen
|
||||
Added Listen(...)
|
||||
|
||||
Rev 1.1 5/14/2003 6:41:00 PM BGooijen
|
||||
Added Bind(...)
|
||||
|
||||
Rev 1.0 12/2/2002 05:01:26 PM JPMugaas
|
||||
Rechecked in due to file corruption.
|
||||
}
|
||||
|
||||
unit IdCustomTransparentProxy;
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
//we need to put this in Delphi mode to work
|
||||
|
||||
uses
|
||||
Classes,
|
||||
IdComponent,
|
||||
IdException,
|
||||
IdGlobal,
|
||||
IdIOHandler,
|
||||
IdSocketHandle,
|
||||
IdBaseComponent;
|
||||
|
||||
type
|
||||
EIdTransparentProxyCircularLink = class(EIdException);
|
||||
EIdTransparentProxyUDPNotSupported = class(EIdException);
|
||||
|
||||
TIdCustomTransparentProxyClass = class of TIdCustomTransparentProxy;
|
||||
|
||||
TIdCustomTransparentProxy = class(TIdComponent)
|
||||
protected
|
||||
FHost: String;
|
||||
FPassword: String;
|
||||
FPort: TIdPort;
|
||||
FIPVersion : TIdIPVersion;
|
||||
FUsername: String;
|
||||
{$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FChainedProxy: TIdCustomTransparentProxy;
|
||||
//
|
||||
function GetEnabled: Boolean; virtual; abstract;
|
||||
procedure SetEnabled(AValue: Boolean); virtual;
|
||||
procedure MakeConnection(AIOHandler: TIdIOHandler; const AHost: string; const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual; abstract;
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||||
{$ENDIF}
|
||||
procedure SetChainedProxy(const AValue: TIdCustomTransparentProxy);
|
||||
public
|
||||
procedure Assign(ASource: TPersistent); override;
|
||||
procedure OpenUDP(AHandle : TIdSocketHandle; const AHost: string = ''; const APort: TIdPort = 0; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION); virtual;
|
||||
procedure CloseUDP(AHandle: TIdSocketHandle); virtual;
|
||||
function RecvFromUDP(AHandle: TIdSocketHandle; var ABuffer : TIdBytes;
|
||||
var VPeerIP: string; var VPeerPort: TIdPort; var VIPVersion: TIdIPVersion;
|
||||
AMSec: Integer = IdTimeoutDefault): Integer; virtual;
|
||||
procedure SendToUDP(AHandle: TIdSocketHandle;
|
||||
const AHost: string; const APort: TIdPort; const AIPVersion: TIdIPVersion;
|
||||
const ABuffer : TIdBytes); virtual;
|
||||
procedure Connect(AIOHandler: TIdIOHandler; const AHost: string; const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION);
|
||||
//
|
||||
procedure Bind(AIOHandler: TIdIOHandler; const AHost: string; const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION);overload;virtual;
|
||||
procedure Bind(AIOHandler: TIdIOHandler; const APort: TIdPort); overload;
|
||||
function Listen(AIOHandler: TIdIOHandler; const ATimeOut: Integer): Boolean; virtual;
|
||||
//
|
||||
property Enabled: Boolean read GetEnabled write SetEnabled;
|
||||
property Host: String read FHost write FHost;
|
||||
property Password: String read FPassword write FPassword;
|
||||
property Port: TIdPort read FPort write FPort;
|
||||
property IPVersion : TIdIPVersion read FIPVersion write FIPVersion default ID_DEFAULT_IP_VERSION;
|
||||
property Username: String read FUsername write FUsername;
|
||||
property ChainedProxy: TIdCustomTransparentProxy read FChainedProxy write SetChainedProxy;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
IdResourceStringsCore, IdExceptionCore;
|
||||
|
||||
{ TIdCustomTransparentProxy }
|
||||
|
||||
procedure TIdCustomTransparentProxy.Assign(ASource: TPersistent);
|
||||
var
|
||||
LSource: TIdCustomTransparentProxy;
|
||||
Begin
|
||||
if ASource is TIdCustomTransparentProxy then begin
|
||||
LSource := TIdCustomTransparentProxy(ASource);
|
||||
FHost := LSource.Host;
|
||||
FPassword := LSource.Password;
|
||||
FPort := LSource.Port;
|
||||
FIPVersion := LSource.IPVersion;
|
||||
FUsername := LSource.Username;
|
||||
end else begin
|
||||
inherited Assign(ASource);
|
||||
end;
|
||||
End;//
|
||||
|
||||
procedure TIdCustomTransparentProxy.Connect(AIOHandler: TIdIOHandler; const AHost: string; const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION);
|
||||
var
|
||||
// under ARC, convert a weak reference to a strong reference before working with it
|
||||
LChainedProxy: TIdCustomTransparentProxy;
|
||||
begin
|
||||
LChainedProxy := FChainedProxy;
|
||||
if Assigned(LChainedProxy) and LChainedProxy.Enabled then begin
|
||||
MakeConnection(AIOHandler, LChainedProxy.Host, LChainedProxy.Port);
|
||||
LChainedProxy.Connect(AIOHandler, AHost, APort, AIPVersion);
|
||||
end else begin
|
||||
MakeConnection(AIOHandler, AHost, APort, AIPVersion);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdCustomTransparentProxy.Listen(AIOHandler: TIdIOHandler; const ATimeOut: integer):boolean;
|
||||
begin
|
||||
raise EIdTransparentProxyCantBind.Create(RSTransparentProxyCannotBind);
|
||||
end;
|
||||
|
||||
procedure TIdCustomTransparentProxy.Bind(AIOHandler: TIdIOHandler; const AHost: string; const APort: TIdPort; const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION);
|
||||
begin
|
||||
raise EIdTransparentProxyCantBind.Create(RSTransparentProxyCannotBind);
|
||||
end;
|
||||
|
||||
procedure TIdCustomTransparentProxy.Bind(AIOHandler: TIdIOHandler; const APort: TIdPort);
|
||||
begin
|
||||
Bind(AIOHandler, '0.0.0.0', APort); {do not localize}
|
||||
end;
|
||||
|
||||
procedure TIdCustomTransparentProxy.SetEnabled(AValue: Boolean);
|
||||
Begin
|
||||
End;
|
||||
|
||||
// under ARC, all weak references to a freed object get nil'ed automatically
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
procedure TIdCustomTransparentProxy.Notification(AComponent: TComponent; Operation: TOperation);
|
||||
begin
|
||||
if (Operation = opRemove) and (AComponent = FChainedProxy) then begin
|
||||
FChainedProxy := nil;
|
||||
end;
|
||||
inherited Notification(AComponent,Operation);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
procedure TIdCustomTransparentProxy.SetChainedProxy(const AValue: TIdCustomTransparentProxy);
|
||||
var
|
||||
LNextValue: TIdCustomTransparentProxy;
|
||||
// under ARC, convert a weak reference to a strong reference before working with it
|
||||
LChainedProxy: TIdCustomTransparentProxy;
|
||||
begin
|
||||
LChainedProxy := FChainedProxy;
|
||||
|
||||
if LChainedProxy <> AValue then
|
||||
begin
|
||||
LNextValue := AValue;
|
||||
while Assigned(LNextValue) do begin
|
||||
if LNextValue = Self then begin
|
||||
raise EIdTransparentProxyCircularLink.CreateFmt(RSInterceptCircularLink, [ClassName]);// -> One EIDCircularLink exception
|
||||
end;
|
||||
LNextValue := LNextValue.ChainedProxy;
|
||||
end;
|
||||
|
||||
// under ARC, all weak references to a freed object get nil'ed automatically
|
||||
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
if Assigned(LChainedProxy) then begin
|
||||
LChainedProxy.RemoveFreeNotification(Self);
|
||||
end;
|
||||
{$ENDIF}
|
||||
|
||||
FChainedProxy := AValue;
|
||||
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
if Assigned(AValue) then begin
|
||||
AValue.FreeNotification(Self);
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdCustomTransparentProxy.CloseUDP(AHandle: TIdSocketHandle);
|
||||
begin
|
||||
raise EIdTransparentProxyUDPNotSupported.Create(RSTransparentProxyCanNotSupportUDP);
|
||||
end;
|
||||
|
||||
procedure TIdCustomTransparentProxy.OpenUDP(AHandle: TIdSocketHandle;
|
||||
const AHost: string = ''; const APort: TIdPort = 0;
|
||||
const AIPVersion: TIdIPVersion = ID_DEFAULT_IP_VERSION);
|
||||
begin
|
||||
raise EIdTransparentProxyUDPNotSupported.Create(RSTransparentProxyCanNotSupportUDP);
|
||||
end;
|
||||
|
||||
function TIdCustomTransparentProxy.RecvFromUDP(AHandle: TIdSocketHandle;
|
||||
var ABuffer : TIdBytes; var VPeerIP: string; var VPeerPort: TIdPort;
|
||||
var VIPVersion: TIdIPVersion; AMSec: Integer = IdTimeoutDefault): Integer;
|
||||
begin
|
||||
raise EIdTransparentProxyUDPNotSupported.Create(RSTransparentProxyCanNotSupportUDP);
|
||||
end;
|
||||
|
||||
procedure TIdCustomTransparentProxy.SendToUDP(AHandle: TIdSocketHandle;
|
||||
const AHost: string; const APort: TIdPort; const AIPVersion: TIdIPVersion;
|
||||
const ABuffer : TIdBytes);
|
||||
begin
|
||||
raise EIdTransparentProxyUDPNotSupported.Create(RSTransparentProxyCanNotSupportUDP);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
4
indy/Core/IdDeprecatedImplBugOff.inc
Normal file
@@ -0,0 +1,4 @@
|
||||
{$IFDEF DEPRECATED_IMPL_BUG}
|
||||
{$WARN SYMBOL_DEPRECATED OFF}
|
||||
{$ENDIF}
|
||||
|
||||
8
indy/Core/IdDeprecatedImplBugOn.inc
Normal file
@@ -0,0 +1,8 @@
|
||||
{$IFDEF DEPRECATED_IMPL_BUG}
|
||||
{$IFDEF HAS_DIRECTIVE_WARN_DEFAULT}
|
||||
{$WARN SYMBOL_DEPRECATED DEFAULT}
|
||||
{$ELSE}
|
||||
{$WARN SYMBOL_DEPRECATED ON}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
|
||||
94
indy/Core/IdDsnBaseCmpEdt.pas
Normal file
@@ -0,0 +1,94 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.2 9/5/2004 2:08:16 PM JPMugaas
|
||||
Should work in D9 NET.
|
||||
|
||||
Rev 1.1 2/3/2004 11:42:50 AM JPMugaas
|
||||
Fixed for new design.
|
||||
|
||||
Rev 1.0 11/13/2002 08:43:16 AM JPMugaas
|
||||
}
|
||||
|
||||
unit IdDsnBaseCmpEdt;
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
{$IFDEF DOTNET}
|
||||
Borland.Vcl.Design.DesignIntF,
|
||||
Borland.Vcl.Design.DesignEditors
|
||||
{$ELSE}
|
||||
{$IFDEF FPC}
|
||||
ComponentEditors
|
||||
{$ELSE}
|
||||
{$IFDEF VCL_6_OR_ABOVE}
|
||||
DesignIntf,
|
||||
DesignEditors
|
||||
{$ELSE}
|
||||
Dsgnintf
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
;
|
||||
|
||||
type
|
||||
{$IFDEF FPC}
|
||||
TIdBaseComponentEditor = class(TDefaultComponentEditor)
|
||||
{$ELSE}
|
||||
TIdBaseComponentEditor = class(TDefaultEditor)
|
||||
{$ENDIF}
|
||||
public
|
||||
procedure ExecuteVerb(Index: Integer); override;
|
||||
function GetVerb(Index: Integer): string; override;
|
||||
function GetVerbCount: Integer; override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
IdAbout,
|
||||
IdGlobal,
|
||||
IdDsnCoreResourceStrings,
|
||||
SysUtils;
|
||||
|
||||
{ TIdBaseComponentEditor }
|
||||
|
||||
procedure TIdBaseComponentEditor.ExecuteVerb(Index: Integer);
|
||||
begin
|
||||
case Index of
|
||||
0 : ShowAboutBox(RSAAboutBoxCompName, gsIdVersion);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdBaseComponentEditor.GetVerb(Index: Integer): string;
|
||||
begin
|
||||
case Index of
|
||||
0: Result := IndyFormat(RSAAboutMenuItemName, [gsIdVersion]);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdBaseComponentEditor.GetVerbCount: Integer;
|
||||
begin
|
||||
Result := 1;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
134
indy/Core/IdDsnCoreResourceStrings.pas
Normal file
@@ -0,0 +1,134 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.5 1/29/2004 8:54:30 AM JPMugaas
|
||||
Removed myself from the distribution Team Chairperson entry as I am resigning
|
||||
from that role.
|
||||
|
||||
Rev 1.4 10/15/2003 10:11:46 PM DSiders
|
||||
Added resource string for About box credits.
|
||||
Corrected spelling error in comments.
|
||||
|
||||
Rev 1.3 6/16/2003 12:01:44 PM JPMugaas
|
||||
Updated copyright to say 2003.
|
||||
|
||||
Rev 1.2 6/8/2003 05:46:58 AM JPMugaas
|
||||
The kitchen sink has now been implemented.
|
||||
|
||||
Rev 1.1 1/15/2003 08:03:56 AM JPMugaas
|
||||
Updated with new website address.
|
||||
|
||||
Rev 1.0 11/13/2002 08:43:24 AM JPMugaas
|
||||
}
|
||||
|
||||
unit IdDsnCoreResourceStrings;
|
||||
|
||||
{
|
||||
Note: This unit is for resource strings that are used in the Core Design-Time
|
||||
package and NOT any design-time packages. This is to prevent design-time
|
||||
resource strings from being linked into the Run-Time only package.
|
||||
}
|
||||
|
||||
interface
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
const
|
||||
IndyPitCrew = 'Kudzu (Chad Z. Hower)'#13#10
|
||||
+ 'and the Indy Pit Crew';
|
||||
|
||||
resourcestring
|
||||
{ About Box stuff }
|
||||
RSAAboutFormCaption = 'About';
|
||||
RSAAboutBoxCompName = 'Internet Direct (Indy)';
|
||||
RSAAboutMenuItemName = 'About Internet &Direct (Indy) %s...';
|
||||
|
||||
RSAAboutBoxVersion = 'Version %s';
|
||||
RSAAboutBoxCopyright = 'Copyright (c) 1993 - 2015'#13#10
|
||||
+ IndyPitCrew;
|
||||
RSAAboutBoxTitle1 = 'INDY';
|
||||
RSAAboutBoxTitle2 = 'Internet Direct';
|
||||
RSAAboutBoxLicences = 'Indy Modified BSD License'+#13#10+'Indy MPL License';
|
||||
RSAAboutBoxBuiltFor = 'Indy.Sockets (%s)';
|
||||
|
||||
RSAAboutBoxPleaseVisit = 'For the latest updates and information please visit:';
|
||||
RSAAboutBoxIndyWebsite = 'http://www.indyproject.org/'; {Do not Localize}
|
||||
|
||||
RSAAboutCreditsCoordinator = 'Project Coordinator';
|
||||
RSAAboutCreditsCoCordinator = 'Project Co-Coordinator';
|
||||
RSAAboutCreditsDocumentation = 'Documentation Coordinator';
|
||||
RSAAboutCreditsDemos = 'Demos Coordinator';
|
||||
RSAAboutCreditsRetiredPast = 'Retired/Past Contributors';
|
||||
RSAAboutCreditsIndyCrew = 'The Indy Pit Crew';
|
||||
|
||||
RSAAboutKitchenSink = IndyPitCrew+#10#13+'present the'#10#13'Kitchen Sink';
|
||||
|
||||
{Binding Editor stuff}
|
||||
{
|
||||
Note to translators - Please Read!!!
|
||||
|
||||
For all the constants except RSBindingFormCaption, there may be an
|
||||
& symbol before a letter or number. This is rendered as that character being
|
||||
underlined. In addition, the character after the & symbol along with the ALT
|
||||
key enables a user to move to that control. Since these are on one form, be
|
||||
careful to ensure that the same letter or number does not have a & before it
|
||||
in more than one string, otherwise an ALT key sequence will be broken.
|
||||
}
|
||||
RSBindingFormCaption = 'Binding Editor';
|
||||
RSBindingNewCaption = '&New';
|
||||
RSBindingDeleteCaption = '&Delete';
|
||||
//RSBindingAddCaption = '&Add';
|
||||
RSBindingRemoveCaption = '&Remove';
|
||||
RSBindingLabelBindings = '&Bindings';
|
||||
RSBindingHostnameLabel = '&IP Address';
|
||||
RSBindingPortLabel = '&Port';
|
||||
RSBindingIPVerLabel = 'IP &Version';
|
||||
RSBindingIPV4Item = 'IPv&4 (127.0.0.1)';
|
||||
RSBindingIPV6Item = 'IPv&6 (::1)';
|
||||
{Design time SASLList Hints}
|
||||
RSADlgSLMoveUp = 'Move Up';
|
||||
RSADlgSLMoveDown = 'Move Down';
|
||||
RSADlgSLAdd = 'Add';
|
||||
RSADlgSLRemove = 'Remove';
|
||||
//Caption that uses format with component name
|
||||
RSADlgSLCaption = 'Editing SASL List for %s';
|
||||
RSADlgSLAvailable = '&Available';
|
||||
RSADlgSLAssigned = 'A&ssigned (tried in order listed)';
|
||||
{Note that the Ampersand indicates an ALT keyboard sequence}
|
||||
RSADlgSLEditList = 'Edit &List';
|
||||
//Display item constants
|
||||
RSBindingAll = 'All'; //all IP addresses
|
||||
RSBindingAny = 'Any'; //any port
|
||||
|
||||
{Standard dialog stock strings}
|
||||
RSOk = 'OK';
|
||||
RSCancel = 'Cancel';
|
||||
RSHelp = '&Help';
|
||||
|
||||
// IdRegister
|
||||
RSRegIndyClients = 'Indy Clients';
|
||||
RSRegIndyServers = 'Indy Servers';
|
||||
RSRegIndyIntercepts = 'Indy Intercepts';
|
||||
RSRegIndyIOHandlers = 'Indy I/O Handlers';
|
||||
RSRegIndyMisc = 'Indy Misc';
|
||||
{$IFDEF FPC}
|
||||
CoreSuffix = ' - Core';
|
||||
{$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
143
indy/Core/IdDsnPropEdBinding.pas
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.9 10/26/2004 8:45:26 PM JPMugaas
|
||||
Should compile.
|
||||
|
||||
Rev 1.8 10/26/2004 8:42:58 PM JPMugaas
|
||||
Should be more portable with new references to TIdStrings and TIdStringList.
|
||||
|
||||
Rev 1.7 5/19/2004 10:44:28 PM DSiders
|
||||
Corrected spelling for TIdIPAddress.MakeAddressObject method.
|
||||
|
||||
Rev 1.6 2/3/2004 11:34:26 AM JPMugaas
|
||||
Should compile.
|
||||
|
||||
Rev 1.5.1.0 2/3/2004 11:32:26 AM JPMugaas
|
||||
Should compile.
|
||||
|
||||
Rev 1.5 2/1/2004 2:44:20 AM JPMugaas
|
||||
Bindings editor should be fully functional including IPv6 support.
|
||||
|
||||
Rev 1.4 2/1/2004 1:03:34 AM JPMugaas
|
||||
This now work properly in both Win32 and DotNET. The behavior had to change
|
||||
in DotNET because of some missing functionality and because implementing that
|
||||
functionality creates more problems than it would solve.
|
||||
|
||||
Rev 1.3 2003.12.31 10:42:22 PM czhower
|
||||
Warning removed
|
||||
|
||||
Rev 1.2 10/15/2003 10:12:32 PM DSiders
|
||||
Added localization comments.
|
||||
|
||||
Rev 1.1 2003.10.11 5:47:46 PM czhower
|
||||
-VCL fixes for servers
|
||||
-Chain suport for servers (Super core)
|
||||
-Scheduler upgrades
|
||||
-Full yarn support
|
||||
|
||||
Rev 1.0 11/13/2002 08:43:58 AM JPMugaas
|
||||
}
|
||||
|
||||
unit IdDsnPropEdBinding;
|
||||
|
||||
{
|
||||
Design Note: It turns out that in DotNET, there are no services file functions and
|
||||
IdPorts does not work as expected in DotNET. It is probably possible to read the
|
||||
services file ourselves but that creates some portability problems as the placement
|
||||
is different in every operating system.
|
||||
|
||||
e.g.
|
||||
|
||||
Linux and Unix-like systems - /etc
|
||||
Windows 95, 98, and ME - c:\windows
|
||||
Windows NT systems - c:\winnt\system32\drivers\etc
|
||||
|
||||
Thus, it will undercut whatever benefit we could get with DotNET.
|
||||
|
||||
About the best I could think of is to use an edit control because
|
||||
we can't offer anything from the services file in DotNET.
|
||||
|
||||
TODO: Maybe there might be a way to find the location in a more elegant
|
||||
manner than what I described.
|
||||
}
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
{$IFDEF WIDGET_WINFORMS}
|
||||
{$R 'IdDsnPropEdBindingNET.TIdDsnPropEdBindingNET.resources' 'IdDsnPropEdBindingNET.resx'}
|
||||
{$ENDIF}
|
||||
|
||||
uses
|
||||
Classes,
|
||||
IdSocketHandle;
|
||||
|
||||
{
|
||||
Design Note: It turns out that in DotNET, there are no services file functions and IdPorts
|
||||
does not work as expected in DotNET. It is probably possible to read the services
|
||||
file ourselves but that creates some portability problems as the placement is different
|
||||
in every operating system.
|
||||
|
||||
e.g.
|
||||
|
||||
Linux and Unix-like systems - /etc
|
||||
Windows 95, 98, and ME - c:\windows
|
||||
Windows NT systems - c:\winnt\system32\drivers\etc
|
||||
|
||||
Thus, it will undercut whatever benefit we could get with DotNET.
|
||||
|
||||
About the best I could think of is to use an edit control because
|
||||
we can't offer anything from the services file in DotNET.
|
||||
|
||||
TODO: Maybe there might be a way to find the location in a more eligant
|
||||
manner than what I described.
|
||||
}
|
||||
|
||||
procedure FillHandleList(const AList: string; ADest: TIdSocketHandles);
|
||||
function GetListValues(const ASocketHandles : TIdSocketHandles) : String;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
{$IFDEF WIDGET_WINFORMS}
|
||||
IdDsnPropEdBindingNET;
|
||||
{$ELSE}
|
||||
IdDsnPropEdBindingVCL;
|
||||
{$ENDIF}
|
||||
|
||||
procedure FillHandleList(const AList: string; ADest: TIdSocketHandles);
|
||||
begin
|
||||
{$IFDEF WIDGET_WINFORMS}
|
||||
IdDsnPropEdBindingNET.FillHandleList(AList,ADest);
|
||||
{$ELSE}
|
||||
IdDsnPropEdBindingVCL.FillHandleList(AList,ADest);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function GetListValues(const ASocketHandles : TIdSocketHandles) : String;
|
||||
begin
|
||||
{$IFDEF WIDGET_WINFORMS}
|
||||
Result := IdDsnPropEdBindingNET.GetListValues(ASocketHandles);
|
||||
{$ELSE}
|
||||
Result := IdDsnPropEdBindingVCL.GetListValues(ASocketHandles);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
end.
|
||||
BIN
indy/Core/IdDsnPropEdBindingNET.TIdDsnPropEdBindingNET.resources
Normal file
702
indy/Core/IdDsnPropEdBindingNET.pas
Normal file
@@ -0,0 +1,702 @@
|
||||
unit IdDsnPropEdBindingNET;
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes,
|
||||
System.Drawing, System.Collections, System.ComponentModel,
|
||||
System.Windows.Forms, System.Data, IdSocketHandle;
|
||||
|
||||
type
|
||||
TIdDsnPropEdBindingNET = class(System.Windows.Forms.Form)
|
||||
{$REGION 'Designer Managed Code'}
|
||||
strict private
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
Components: System.ComponentModel.Container;
|
||||
btnOk: System.Windows.Forms.Button;
|
||||
btnCancel: System.Windows.Forms.Button;
|
||||
lblBindings: System.Windows.Forms.Label;
|
||||
lbBindings: System.Windows.Forms.ListBox;
|
||||
btnNew: System.Windows.Forms.Button;
|
||||
btnDelete: System.Windows.Forms.Button;
|
||||
lblIPAddress: System.Windows.Forms.Label;
|
||||
edtIPAddress: System.Windows.Forms.ComboBox;
|
||||
lblPort: System.Windows.Forms.Label;
|
||||
edtPort: System.Windows.Forms.NumericUpDown;
|
||||
cboIPVersion: System.Windows.Forms.ComboBox;
|
||||
lblIPVersion: System.Windows.Forms.Label;
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
procedure InitializeComponent;
|
||||
procedure btnNew_Click(sender: System.Object; e: System.EventArgs);
|
||||
procedure btnDelete_Click(sender: System.Object; e: System.EventArgs);
|
||||
procedure edtPort_ValueChanged(sender: System.Object; e: System.EventArgs);
|
||||
procedure edtIPAddress_SelectedValueChanged(sender: System.Object; e: System.EventArgs);
|
||||
procedure cboIPVersion_SelectedValueChanged(sender: System.Object; e: System.EventArgs);
|
||||
procedure lbBindings_SelectedValueChanged(sender: System.Object; e: System.EventArgs);
|
||||
{$ENDREGION}
|
||||
strict protected
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
procedure Dispose(Disposing: Boolean); override;
|
||||
private
|
||||
FHandles : TIdSocketHandles;
|
||||
FDefaultPort : Integer;
|
||||
FIPv4Addresses : TStrings;
|
||||
FIPv6Addresses : TStrings;
|
||||
FCurrentHandle : TIdSocketHandle;
|
||||
|
||||
{ Private Declarations }
|
||||
procedure SetHandles(const Value: TIdSocketHandles);
|
||||
procedure SetIPv4Addresses(const Value: TStrings);
|
||||
procedure SetIPv6Addresses(const Value: TStrings);
|
||||
procedure UpdateBindingList;
|
||||
procedure UpdateEditControls;
|
||||
procedure FillComboBox(ACombo : System.Windows.Forms.ComboBox; AStrings :TStrings);
|
||||
procedure SetCaption(const AValue : String);
|
||||
function GetCaption : String;
|
||||
public
|
||||
constructor Create;
|
||||
function Execute : Boolean;
|
||||
function GetList: string;
|
||||
procedure SetList(const AList: string);
|
||||
property Handles : TIdSocketHandles read FHandles write SetHandles;
|
||||
property DefaultPort : Integer read FDefaultPort write FDefaultPort;
|
||||
property IPv4Addresses : TStrings read FIPv4Addresses write SetIPv4Addresses;
|
||||
property IPv6Addresses : TStrings read FIPv6Addresses write SetIPv6Addresses;
|
||||
property Caption : String read GetCaption write SetCaption;
|
||||
end;
|
||||
|
||||
[assembly: RuntimeRequiredAttribute(TypeOf(TIdDsnPropEdBindingNET))]
|
||||
|
||||
procedure FillHandleList(const AList: string; ADest: TIdSocketHandles);
|
||||
function GetListValues(const ASocketHandles : TIdSocketHandles) : String;
|
||||
|
||||
implementation
|
||||
uses
|
||||
IdGlobal,
|
||||
IdIPAddress,
|
||||
IdDsnCoreResourceStrings, IdStack, SysUtils;
|
||||
|
||||
const
|
||||
IPv6Wildcard1 = '::'; {do not localize}
|
||||
IPv6Wildcard2 = '0:0:0:0:0:0:0:0'; {do not localize}
|
||||
IPv6Loopback = '::1'; {do not localize}
|
||||
IPv4Wildcard = '0.0.0.0'; {do not localize}
|
||||
IPv4Loopback = '127.0.0.1'; {do not localize}
|
||||
|
||||
function IsValidIP(const AAddr : String): Boolean;
|
||||
var
|
||||
LIP: TIdIPAddress;
|
||||
begin
|
||||
LIP := TIdIPAddress.MakeAddressObject(AAddr);
|
||||
Result := Assigned(LIP);
|
||||
if Result then
|
||||
begin
|
||||
FreeAndNil(LIP);
|
||||
end;
|
||||
end;
|
||||
|
||||
function StripAndSymbol(s : String) : String;
|
||||
begin
|
||||
Result := '';
|
||||
repeat
|
||||
if s='' then
|
||||
begin
|
||||
Break;
|
||||
end;
|
||||
Result := Result + Fetch(s,'&');
|
||||
until False;
|
||||
end;
|
||||
|
||||
procedure FillHandleList(const AList: string; ADest: TIdSocketHandles);
|
||||
var
|
||||
LItems: TStringList;
|
||||
i: integer;
|
||||
LIPVersion: TIdIPVersion;
|
||||
LAddr, LText: string;
|
||||
LPort: integer;
|
||||
begin
|
||||
ADest.Clear;
|
||||
LItems := TStringList.Create;
|
||||
try
|
||||
LItems.CommaText := AList;
|
||||
for i := 0 to LItems.Count-1 do begin
|
||||
if Length(LItems[i]) > 0 then begin
|
||||
if TextStartsWith(LItems[i], '[') then begin
|
||||
// ipv6
|
||||
LIPVersion := Id_IPv6;
|
||||
LText := Copy(LItems[i], 2, MaxInt);
|
||||
LAddr := Fetch(LText, ']:');
|
||||
LPort := IndyStrToInt(LText, -1);
|
||||
end else begin
|
||||
// ipv4
|
||||
LIPVersion := Id_IPv4;
|
||||
LText := LItems[i];
|
||||
LAddr := Fetch(LText, ':');
|
||||
LPort := IndyStrToInt(LText, -1);
|
||||
//Note that 0 is legal and indicates the server binds to a random port
|
||||
end;
|
||||
if IsValidIP(LAddr) and (LPort > -1) and (LPort < 65536) then begin
|
||||
with ADest.Add do begin
|
||||
IPVersion := LIPVersion;
|
||||
IP := LAddr;
|
||||
Port := LPort;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
LItems.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function NumericOnly(const AText : String) : String;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := '';
|
||||
for i := 1 to Length(AText) do
|
||||
begin
|
||||
if IsNumeric(AText[i]) then
|
||||
begin
|
||||
Result := Result + AText[i];
|
||||
end
|
||||
else
|
||||
begin
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
if (Length(Result) = 0) then
|
||||
begin
|
||||
Result := '0';
|
||||
end;
|
||||
end;
|
||||
|
||||
function IndexOfNo(const ANo : Integer; AItems : System.Windows.Forms.ComboBox.ObjectCollection) : Integer;
|
||||
begin
|
||||
for Result := 0 to AItems.Count -1 do
|
||||
begin
|
||||
if ANo = IndyStrToInt( NumericOnly(AItems[Result].ToString )) then
|
||||
begin
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
function GetDisplayString(ASocketHandle: TIdSocketHandle): string;
|
||||
begin
|
||||
Result := '';
|
||||
case ASocketHandle.IPVersion of
|
||||
Id_IPv4 : Result := IndyFormat('%s:%d', [ASocketHandle.IP, ASocketHandle.Port]);
|
||||
Id_IPv6 : Result := IndyFormat('[%s]:%d', [ASocketHandle.IP, ASocketHandle.Port]);
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetListValues(const ASocketHandles : TIdSocketHandles) : String;
|
||||
var
|
||||
i: Integer;
|
||||
begin
|
||||
Result := '';
|
||||
for i := 0 to ASocketHandles.Count -1 do begin
|
||||
Result := Result + ',' + GetDisplayString(ASocketHandles[i]);
|
||||
end;
|
||||
Delete(Result,1,1);
|
||||
end;
|
||||
|
||||
{$AUTOBOX ON}
|
||||
|
||||
{$REGION 'Windows Form Designer generated code'}
|
||||
/// <summary>
|
||||
/// Required method for Designer support -- do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
procedure TIdDsnPropEdBindingNET.InitializeComponent;
|
||||
type
|
||||
TArrayOfInteger = array of Integer;
|
||||
begin
|
||||
Self.btnOk := System.Windows.Forms.Button.Create;
|
||||
Self.btnCancel := System.Windows.Forms.Button.Create;
|
||||
Self.lblBindings := System.Windows.Forms.Label.Create;
|
||||
Self.lbBindings := System.Windows.Forms.ListBox.Create;
|
||||
Self.btnNew := System.Windows.Forms.Button.Create;
|
||||
Self.btnDelete := System.Windows.Forms.Button.Create;
|
||||
Self.lblIPAddress := System.Windows.Forms.Label.Create;
|
||||
Self.edtIPAddress := System.Windows.Forms.ComboBox.Create;
|
||||
Self.lblPort := System.Windows.Forms.Label.Create;
|
||||
Self.edtPort := System.Windows.Forms.NumericUpDown.Create;
|
||||
Self.cboIPVersion := System.Windows.Forms.ComboBox.Create;
|
||||
Self.lblIPVersion := System.Windows.Forms.Label.Create;
|
||||
(System.ComponentModel.ISupportInitialize(Self.edtPort)).BeginInit;
|
||||
Self.SuspendLayout;
|
||||
//
|
||||
// btnOk
|
||||
//
|
||||
Self.btnOk.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Bottom
|
||||
or System.Windows.Forms.AnchorStyles.Right)));
|
||||
Self.btnOk.DialogResult := System.Windows.Forms.DialogResult.OK;
|
||||
Self.btnOk.Location := System.Drawing.Point.Create(312, 160);
|
||||
Self.btnOk.Name := 'btnOk';
|
||||
Self.btnOk.TabIndex := 0;
|
||||
//
|
||||
// btnCancel
|
||||
//
|
||||
Self.btnCancel.Anchor := (System.Windows.Forms.AnchorStyles((System.Windows.Forms.AnchorStyles.Bottom
|
||||
or System.Windows.Forms.AnchorStyles.Right)));
|
||||
Self.btnCancel.DialogResult := System.Windows.Forms.DialogResult.Cancel;
|
||||
Self.btnCancel.Location := System.Drawing.Point.Create(392, 160);
|
||||
Self.btnCancel.Name := 'btnCancel';
|
||||
Self.btnCancel.TabIndex := 1;
|
||||
//
|
||||
// lblBindings
|
||||
//
|
||||
Self.lblBindings.AutoSize := True;
|
||||
Self.lblBindings.Location := System.Drawing.Point.Create(8, 8);
|
||||
Self.lblBindings.Name := 'lblBindings';
|
||||
Self.lblBindings.Size := System.Drawing.Size.Create(42, 16);
|
||||
Self.lblBindings.TabIndex := 2;
|
||||
Self.lblBindings.Text := '&Binding';
|
||||
//
|
||||
// lbBindings
|
||||
//
|
||||
Self.lbBindings.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Top
|
||||
or System.Windows.Forms.AnchorStyles.Bottom) or System.Windows.Forms.AnchorStyles.Left)));
|
||||
Self.lbBindings.Location := System.Drawing.Point.Create(8, 24);
|
||||
Self.lbBindings.Name := 'lbBindings';
|
||||
Self.lbBindings.Size := System.Drawing.Size.Create(137, 121);
|
||||
Self.lbBindings.TabIndex := 3;
|
||||
Include(Self.lbBindings.SelectedValueChanged, Self.lbBindings_SelectedValueChanged);
|
||||
//
|
||||
// btnNew
|
||||
//
|
||||
Self.btnNew.Location := System.Drawing.Point.Create(152, 56);
|
||||
Self.btnNew.Name := 'btnNew';
|
||||
Self.btnNew.TabIndex := 4;
|
||||
Include(Self.btnNew.Click, Self.btnNew_Click);
|
||||
//
|
||||
// btnDelete
|
||||
//
|
||||
Self.btnDelete.Location := System.Drawing.Point.Create(152, 88);
|
||||
Self.btnDelete.Name := 'btnDelete';
|
||||
Self.btnDelete.TabIndex := 5;
|
||||
Include(Self.btnDelete.Click, Self.btnDelete_Click);
|
||||
//
|
||||
// lblIPAddress
|
||||
//
|
||||
Self.lblIPAddress.Location := System.Drawing.Point.Create(240, 8);
|
||||
Self.lblIPAddress.Name := 'lblIPAddress';
|
||||
Self.lblIPAddress.Size := System.Drawing.Size.Create(100, 16);
|
||||
Self.lblIPAddress.TabIndex := 6;
|
||||
Self.lblIPAddress.Text := 'Label1';
|
||||
//
|
||||
// edtIPAddress
|
||||
//
|
||||
Self.edtIPAddress.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Top
|
||||
or System.Windows.Forms.AnchorStyles.Left) or System.Windows.Forms.AnchorStyles.Right)));
|
||||
Self.edtIPAddress.Location := System.Drawing.Point.Create(240, 24);
|
||||
Self.edtIPAddress.Name := 'edtIPAddress';
|
||||
Self.edtIPAddress.Size := System.Drawing.Size.Create(224, 21);
|
||||
Self.edtIPAddress.TabIndex := 7;
|
||||
Include(Self.edtIPAddress.SelectedValueChanged, Self.edtIPAddress_SelectedValueChanged);
|
||||
//
|
||||
// lblPort
|
||||
//
|
||||
Self.lblPort.Location := System.Drawing.Point.Create(240, 58);
|
||||
Self.lblPort.Name := 'lblPort';
|
||||
Self.lblPort.Size := System.Drawing.Size.Create(100, 16);
|
||||
Self.lblPort.TabIndex := 8;
|
||||
Self.lblPort.Text := 'Label1';
|
||||
//
|
||||
// edtPort
|
||||
//
|
||||
Self.edtPort.Anchor := (System.Windows.Forms.AnchorStyles(((System.Windows.Forms.AnchorStyles.Top
|
||||
or System.Windows.Forms.AnchorStyles.Left) or System.Windows.Forms.AnchorStyles.Right)));
|
||||
Self.edtPort.Location := System.Drawing.Point.Create(240, 74);
|
||||
Self.edtPort.Maximum := System.Decimal.Create(TArrayOfInteger.Create(65535,
|
||||
0, 0, 0));
|
||||
Self.edtPort.Name := 'edtPort';
|
||||
Self.edtPort.Size := System.Drawing.Size.Create(224, 20);
|
||||
Self.edtPort.TabIndex := 9;
|
||||
Include(Self.edtPort.ValueChanged, Self.edtPort_ValueChanged);
|
||||
//
|
||||
// cboIPVersion
|
||||
//
|
||||
Self.cboIPVersion.DropDownStyle := System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
Self.cboIPVersion.Location := System.Drawing.Point.Create(240, 124);
|
||||
Self.cboIPVersion.Name := 'cboIPVersion';
|
||||
Self.cboIPVersion.Size := System.Drawing.Size.Create(224, 21);
|
||||
Self.cboIPVersion.TabIndex := 10;
|
||||
Include(Self.cboIPVersion.SelectedValueChanged, Self.cboIPVersion_SelectedValueChanged);
|
||||
//
|
||||
// lblIPVersion
|
||||
//
|
||||
Self.lblIPVersion.Location := System.Drawing.Point.Create(240, 108);
|
||||
Self.lblIPVersion.Name := 'lblIPVersion';
|
||||
Self.lblIPVersion.Size := System.Drawing.Size.Create(100, 16);
|
||||
Self.lblIPVersion.TabIndex := 11;
|
||||
Self.lblIPVersion.Text := 'Label1';
|
||||
//
|
||||
// TIdDsnPropEdBindingNET
|
||||
//
|
||||
Self.AcceptButton := Self.btnOk;
|
||||
Self.AutoScaleBaseSize := System.Drawing.Size.Create(5, 13);
|
||||
Self.CancelButton := Self.btnCancel;
|
||||
Self.ClientSize := System.Drawing.Size.Create(470, 189);
|
||||
Self.Controls.Add(Self.lblIPVersion);
|
||||
Self.Controls.Add(Self.cboIPVersion);
|
||||
Self.Controls.Add(Self.edtPort);
|
||||
Self.Controls.Add(Self.lblPort);
|
||||
Self.Controls.Add(Self.edtIPAddress);
|
||||
Self.Controls.Add(Self.lblIPAddress);
|
||||
Self.Controls.Add(Self.btnDelete);
|
||||
Self.Controls.Add(Self.btnNew);
|
||||
Self.Controls.Add(Self.lbBindings);
|
||||
Self.Controls.Add(Self.lblBindings);
|
||||
Self.Controls.Add(Self.btnCancel);
|
||||
Self.Controls.Add(Self.btnOk);
|
||||
Self.FormBorderStyle := System.Windows.Forms.FormBorderStyle.FixedDialog;
|
||||
Self.MaximizeBox := False;
|
||||
Self.MaximumSize := System.Drawing.Size.Create(480, 225);
|
||||
Self.MinimizeBox := False;
|
||||
Self.MinimumSize := System.Drawing.Size.Create(480, 225);
|
||||
Self.Name := 'TIdDsnPropEdBindingNET';
|
||||
Self.ShowInTaskbar := False;
|
||||
Self.StartPosition := System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
Self.Text := 'WinForm';
|
||||
(System.ComponentModel.ISupportInitialize(Self.edtPort)).EndInit;
|
||||
Self.ResumeLayout(False);
|
||||
end;
|
||||
{$ENDREGION}
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.Dispose(Disposing: Boolean);
|
||||
begin
|
||||
if Disposing then
|
||||
begin
|
||||
if Components <> nil then
|
||||
begin
|
||||
Components.Dispose();
|
||||
FreeAndNil(FHandles);
|
||||
|
||||
FreeAndNil(FIPv4Addresses);
|
||||
FreeAndNil(FIPv6Addresses);
|
||||
|
||||
//don't free FCurrentHandle; - it's in the handles collection
|
||||
TIdStack.DecUsage;
|
||||
end;
|
||||
end;
|
||||
inherited Dispose(Disposing);
|
||||
|
||||
end;
|
||||
|
||||
constructor TIdDsnPropEdBindingNET.Create;
|
||||
var
|
||||
i: Integer;
|
||||
LLocalAddresses: TIdStackLocalAddressList;
|
||||
begin
|
||||
inherited Create;
|
||||
//
|
||||
// Required for Windows Form Designer support
|
||||
//
|
||||
InitializeComponent;
|
||||
//
|
||||
// TODO: Add any constructor code after InitializeComponent call
|
||||
//
|
||||
FHandles := TIdSocketHandles.Create(nil);
|
||||
FIPv4Addresses := TStringList.Create;
|
||||
FIPv6Addresses := TStringList.Create;
|
||||
SetIPv4Addresses(nil);
|
||||
SetIPv6Addresses(nil);
|
||||
|
||||
TIdStack.IncUsage;
|
||||
try
|
||||
LLocalAddresses := TIdStackLocalAddressList.Create;
|
||||
try
|
||||
GStack.GetLocalAddressList(LLocalAddresses);
|
||||
for i := 0 to LLocalAddresses.Count-1 do
|
||||
begin
|
||||
case LLocalAddresses[i].IPVersion of
|
||||
Id_IPv4: FIPv4Addresses.Add(LLocalAddresses[i].IPAddress);
|
||||
Id_IPv6: FIPv6Addresses.Add(LLocalAddresses[i].IPAddress);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
LLocalAddresses.Free;
|
||||
end;
|
||||
finally
|
||||
TIdStack.DecUsage;
|
||||
end;
|
||||
|
||||
UpdateEditControls;
|
||||
//captions
|
||||
btnNew.Text := RSBindingNewCaption;
|
||||
btnDelete.Text := RSBindingDeleteCaption;
|
||||
lblIPAddress.Text := RSBindingHostnameLabel;
|
||||
lblPort.Text := RSBindingPortLabel;
|
||||
lblIPVersion.Text := RSBindingIPVerLabel;
|
||||
btnOk.Text := RSOk;
|
||||
btnCancel.Text := RSCancel;
|
||||
//IPVersion choices
|
||||
//we yhave to strip out the & symbol. In Win32, we use this
|
||||
//in a radio-box so a user could select by pressingg the 4 or 6
|
||||
//key. For this, we don't have a radio box and I'm too lazy
|
||||
//to use two Radio Buttons.
|
||||
cboIPVersion.Items.Add(StripAndSymbol(RSBindingIPV4Item));
|
||||
cboIPVersion.Items.Add(StripAndSymbol(RSBindingIPV6Item));
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.SetHandles(const Value: TIdSocketHandles);
|
||||
begin
|
||||
FHandles.Assign(Value);
|
||||
UpdateBindingList;
|
||||
end;
|
||||
|
||||
function TIdDsnPropEdBindingNET.GetList: string;
|
||||
begin
|
||||
Result := GetListValues(Handles);
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.SetIPv6Addresses(const Value: TStrings);
|
||||
begin
|
||||
if Assigned(Value) then begin
|
||||
FIPv6Addresses.Assign(Value);
|
||||
end;
|
||||
// Ensure that these two are always present
|
||||
if FIPv6Addresses.IndexOf(IPv6Loopback) = -1 then begin
|
||||
FIPv6Addresses.Insert(0, IPv6Loopback);
|
||||
end;
|
||||
if FIPv6Addresses.IndexOf(IPv6Wildcard1) = -1 then begin
|
||||
FIPv6Addresses.Insert(0, IPv6Wildcard1);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.SetIPv4Addresses(const Value: TStrings);
|
||||
begin
|
||||
if Assigned(Value) then begin
|
||||
FIPv4Addresses.Assign(Value);
|
||||
end;
|
||||
// Ensure that these two are always present
|
||||
if FIPv4Addresses.IndexOf(IPv6Loopback) = -1 then begin
|
||||
FIPv4Addresses.Insert(0, IPv4Loopback);
|
||||
end;
|
||||
if FIPv4Addresses.IndexOf(IPv4Wildcard) = -1 then begin
|
||||
FIPv4Addresses.Insert(0, IPv4Wildcard);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.SetList(const AList: string);
|
||||
begin
|
||||
FCurrentHandle := nil;
|
||||
FillHandleList(AList, Handles);
|
||||
UpdateBindingList;
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.lbBindings_SelectedValueChanged(sender: System.Object;
|
||||
e: System.EventArgs);
|
||||
begin
|
||||
if lbBindings.SelectedIndex >= 0 then begin
|
||||
btnDelete.Enabled := True;
|
||||
FCurrentHandle := FHandles[lbBindings.SelectedIndex];
|
||||
end else begin
|
||||
btnDelete.Enabled := False;
|
||||
FCurrentHandle := nil;
|
||||
end;
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.cboIPVersion_SelectedValueChanged(sender: System.Object;
|
||||
e: System.EventArgs);
|
||||
begin
|
||||
case cboIPVersion.SelectedIndex of
|
||||
0 :
|
||||
begin
|
||||
if FCurrentHandle.IPVersion <> Id_IPv4 then
|
||||
begin
|
||||
FCurrentHandle.IPVersion := Id_IPv4;
|
||||
FillComboBox(edtIPAddress,FIPv4Addresses);
|
||||
FCurrentHandle.IP := IPv4Wildcard;
|
||||
end;
|
||||
end;
|
||||
1 :
|
||||
begin
|
||||
if FCurrentHandle.IPVersion <> Id_IPv6 then
|
||||
begin
|
||||
FCurrentHandle.IPVersion := Id_IPv6;
|
||||
FillComboBox(edtIPAddress,FIPv6Addresses);
|
||||
FCurrentHandle.IP := IPv6Wildcard1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
UpdateEditControls;
|
||||
UpdateBindingList;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.edtIPAddress_SelectedValueChanged(sender: System.Object;
|
||||
e: System.EventArgs);
|
||||
begin
|
||||
FCurrentHandle.IP := edtIPAddress.SelectedItem.ToString;
|
||||
UpdateBindingList;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.edtPort_ValueChanged(sender: System.Object;
|
||||
e: System.EventArgs);
|
||||
begin
|
||||
if Assigned(FCurrentHandle) then begin
|
||||
FCurrentHandle.Port := edtPort.Value.ToInt16(edtPort.Value);
|
||||
end;
|
||||
UpdateBindingList;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.btnDelete_Click(sender: System.Object; e: System.EventArgs);
|
||||
var LSH : TIdSocketHandle;
|
||||
i : Integer;
|
||||
begin
|
||||
if lbBindings.SelectedIndex >= 0 then
|
||||
begin
|
||||
// Delete is not available in D4's collection classes
|
||||
// This should work just as well.
|
||||
i := lbBindings.get_SelectedIndex;
|
||||
LSH := Handles[i];
|
||||
FreeAndNil(LSH);
|
||||
lbBindings.Items.Remove(i);
|
||||
FCurrentHandle := nil;
|
||||
UpdateBindingList;
|
||||
end;
|
||||
lbBindings_SelectedValueChanged(nil, nil);
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.btnNew_Click(sender: System.Object; e: System.EventArgs);
|
||||
begin
|
||||
FCurrentHandle := FHandles.Add;
|
||||
FCurrentHandle.IP := IPv4Wildcard;
|
||||
FCurrentHandle.Port := FDefaultPort;
|
||||
UpdateBindingList;
|
||||
FillComboBox(edtIPAddress, FIPv4Addresses);
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.UpdateBindingList;
|
||||
var
|
||||
i: integer;
|
||||
selected: integer;
|
||||
s: string;
|
||||
begin
|
||||
selected := lbBindings.SelectedIndex;
|
||||
lbBindings.BeginUpdate;
|
||||
try
|
||||
if lbBindings.Items.Count = FHandles.Count then begin
|
||||
for i := 0 to FHandles.Count - 1 do begin
|
||||
s := GetDisplayString(FHandles[i]);
|
||||
if s <> lbBindings.Items[i].ToString then begin
|
||||
lbBindings.Items[i] := s;
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
lbBindings.Items.Clear;
|
||||
for i := 0 to FHandles.Count-1 do begin
|
||||
lbBindings.Items.Add(GetDisplayString(FHandles[i]));
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
lbBindings.EndUpdate;
|
||||
if Assigned(FCurrentHandle) then begin
|
||||
lbBindings.SelectedIndex := FCurrentHandle.Index;
|
||||
end else begin
|
||||
lbBindings.SelectedIndex := IndyMin(selected, lbBindings.Items.Count-1);
|
||||
end;
|
||||
end;
|
||||
{ selected := lbBindings.SelectedItem;
|
||||
lbBindings.Items.BeginUpdate;
|
||||
try
|
||||
if lbBindings.Items.Count = FHandles.Count then begin
|
||||
for i := 0 to FHandles.Count - 1 do begin
|
||||
s := GetDisplayString(FHandles[i]);
|
||||
if s <> lbBindings.Items[i] then begin
|
||||
lbBindings.Items[i] := s;
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
lbBindings.Items.Clear;
|
||||
for i := 0 to FHandles.Count-1 do begin
|
||||
lbBindings.Items.Add(GetDisplayString(FHandles[i]));
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
lbBindings.Items.EndUpdate;
|
||||
if Assigned(FCurrentHandle) then begin
|
||||
lbBindings.ItemIndex := FCurrentHandle.Index;
|
||||
end else begin
|
||||
lbBindings.ItemIndex := IndyMin(selected, lbBindings.Items.Count-1);
|
||||
end;
|
||||
end; }
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.UpdateEditControls;
|
||||
begin
|
||||
if Assigned(FCurrentHandle) then
|
||||
begin
|
||||
edtPort.Text := '';
|
||||
edtPort.Value := FCurrentHandle.Port;
|
||||
case FCurrentHandle.IPVersion of
|
||||
Id_IPv4 :
|
||||
begin
|
||||
FillComboBox(edtIPAddress, FIPv4Addresses);
|
||||
edtIPAddress.SelectedItem := edtIPAddress.Items[0];
|
||||
cboIPVersion.SelectedItem := cboIPVersion.Items[0];
|
||||
end;
|
||||
Id_IPv6 :
|
||||
begin
|
||||
FillComboBox(edtIPAddress, FIPv6Addresses);
|
||||
edtIPAddress.SelectedItem := edtIPAddress.Items[0];
|
||||
cboIPVersion.SelectedItem := cboIPVersion.Items[1];
|
||||
end;
|
||||
end;
|
||||
if edtIPAddress.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDown then begin
|
||||
edtIPAddress.Text := FCurrentHandle.IP;
|
||||
end else begin
|
||||
edtIPAddress.SelectedIndex := edtIPAddress.Items.IndexOf(FCurrentHandle.IP);
|
||||
end;
|
||||
end;
|
||||
|
||||
lblIPAddress.Enabled := Assigned(FCurrentHandle);
|
||||
edtIPAddress.Enabled := Assigned(FCurrentHandle);
|
||||
lblPort.Enabled := Assigned(FCurrentHandle);
|
||||
edtPort.Enabled := Assigned(FCurrentHandle);
|
||||
lblIPVersion.Enabled := Assigned(FCurrentHandle);
|
||||
cboIPVersion.Enabled := Assigned(FCurrentHandle);
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.FillComboBox(
|
||||
ACombo: System.Windows.Forms.ComboBox; AStrings: TStrings);
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
ACombo.Items.Clear;
|
||||
for i := 0 to AStrings.Count-1 do begin
|
||||
ACombo.Items.Add(AStrings[i]);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdDsnPropEdBindingNET.Execute: Boolean;
|
||||
begin
|
||||
Result := Self.ShowDialog = System.Windows.Forms.DialogResult.OK;
|
||||
end;
|
||||
|
||||
function TIdDsnPropEdBindingNET.GetCaption: String;
|
||||
begin
|
||||
Result := Text;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingNET.SetCaption(const AValue: String);
|
||||
begin
|
||||
Text := AValue;
|
||||
end;
|
||||
|
||||
end.
|
||||
196
indy/Core/IdDsnPropEdBindingNET.resx
Normal file
@@ -0,0 +1,196 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 1.3
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">1.3</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1">this is my long string</data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
[base64 mime encoded serialized .NET Framework object]
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
[base64 mime encoded string representing a byte array form of the .NET Framework object]
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used forserialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>1.3</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<data name="btnOk.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="btnOk.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="btnCancel.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="btnCancel.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblBindings.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblBindings.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lbBindings.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lbBindings.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="btnNew.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="btnNew.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="btnDelete.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="btnDelete.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblIPAddress.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblIPAddress.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="edtIPAddress.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="edtIPAddress.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblPort.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblPort.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="edtPort.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="edtPort.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="cboIPVersion.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="cboIPVersion.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="lblIPVersion.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="lblIPVersion.Modifiers" type="System.CodeDom.MemberAttributes, System, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>Private</value>
|
||||
</data>
|
||||
<data name="$this.Locked" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Language" type="System.Globalization.CultureInfo, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>(Default)</value>
|
||||
</data>
|
||||
<data name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.Localizable" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</data>
|
||||
<data name="$this.GridSize" type="System.Drawing.Size, System.Drawing, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>8, 8</value>
|
||||
</data>
|
||||
<data name="$this.DrawGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
<data name="$this.TrayHeight" type="System.Int32, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>80</value>
|
||||
</data>
|
||||
<data name="$this.SnapToGrid" type="System.Boolean, mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</data>
|
||||
</root>
|
||||
819
indy/Core/IdDsnPropEdBindingVCL.pas
Normal file
@@ -0,0 +1,819 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.9 10/26/2004 8:45:26 PM JPMugaas
|
||||
Should compile.
|
||||
|
||||
Rev 1.8 10/26/2004 8:42:58 PM JPMugaas
|
||||
Should be more portable with new references to TIdStrings and TIdStringList.
|
||||
|
||||
Rev 1.7 5/19/2004 10:44:28 PM DSiders
|
||||
Corrected spelling for TIdIPAddress.MakeAddressObject method.
|
||||
|
||||
Rev 1.6 2/3/2004 11:34:26 AM JPMugaas
|
||||
Should compile.
|
||||
|
||||
Rev 1.5.1.0 2/3/2004 11:32:26 AM JPMugaas
|
||||
Should compile.
|
||||
|
||||
Rev 1.5 2/1/2004 2:44:20 AM JPMugaas
|
||||
Bindings editor should be fully functional including IPv6 support.
|
||||
|
||||
Rev 1.4 2/1/2004 1:03:34 AM JPMugaas
|
||||
This now work properly in both Win32 and DotNET. The behavior had to change
|
||||
in DotNET because of some missing functionality and because implementing that
|
||||
functionality creates more problems than it would solve.
|
||||
|
||||
Rev 1.3 2003.12.31 10:42:22 PM czhower
|
||||
Warning removed
|
||||
|
||||
Rev 1.2 10/15/2003 10:12:32 PM DSiders
|
||||
Added localization comments.
|
||||
|
||||
Rev 1.1 2003.10.11 5:47:46 PM czhower
|
||||
-VCL fixes for servers
|
||||
-Chain suport for servers (Super core)
|
||||
-Scheduler upgrades
|
||||
-Full yarn support
|
||||
|
||||
Rev 1.0 11/13/2002 08:43:58 AM JPMugaas
|
||||
}
|
||||
|
||||
unit IdDsnPropEdBindingVCL;
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
uses
|
||||
Classes,
|
||||
{$IFDEF WIDGET_KYLIX}
|
||||
QActnList, QStdCtrls, QForms, QExtCtrls, QControls, QComCtrls, QGraphics, Qt,
|
||||
{$ENDIF}
|
||||
{$IFDEF WIDGET_VCL_LIKE}
|
||||
ActnList, StdCtrls, Buttons, ExtCtrls, Graphics, Controls, ComCtrls, Forms, Dialogs,
|
||||
{$ENDIF}
|
||||
{$IFDEF HAS_UNIT_Types}
|
||||
Types,
|
||||
{$ENDIF}
|
||||
{$IFDEF WINDOWS}
|
||||
Windows,
|
||||
{$ENDIF}
|
||||
{$IFDEF LCL}
|
||||
LResources,
|
||||
{$ENDIF}
|
||||
IdSocketHandle;
|
||||
{
|
||||
Design Note: It turns out that in DotNET, there are no services file functions and
|
||||
IdPorts does not work as expected in DotNET. It is probably possible to read the
|
||||
services file ourselves but that creates some portability problems as the placement
|
||||
is different in every operating system.
|
||||
|
||||
e.g.
|
||||
|
||||
Linux and Unix-like systems - /etc
|
||||
Windows 95, 98, and ME - c:\windows
|
||||
Windows NT systems - c:\winnt\system32\drivers\etc
|
||||
|
||||
Thus, it will undercut whatever benefit we could get with DotNET.
|
||||
|
||||
About the best I could think of is to use an edit control because
|
||||
we can't offer anything from the services file in DotNET.
|
||||
|
||||
TODO: Maybe there might be a way to find the location in a more elegant
|
||||
manner than what I described.
|
||||
}
|
||||
|
||||
type
|
||||
TIdDsnPropEdBindingVCL = class(TForm)
|
||||
{$IFDEF USE_TBitBtn}
|
||||
btnOk: TBitBtn;
|
||||
btnCancel: TBitBtn;
|
||||
{$ELSE}
|
||||
btnOk: TButton;
|
||||
btnCancel: TButton;
|
||||
{$ENDIF}
|
||||
lblBindings: TLabel;
|
||||
edtPort: TComboBox;
|
||||
rdoBindingType: TRadioGroup;
|
||||
lblIPAddress: TLabel;
|
||||
lblPort: TLabel;
|
||||
btnNew: TButton;
|
||||
btnDelete: TButton;
|
||||
ActionList1: TActionList;
|
||||
btnBindingsNew: TAction;
|
||||
btnBindingsDelete: TAction;
|
||||
edtIPAddress: TComboBox;
|
||||
lbBindings: TListBox;
|
||||
procedure btnBindingsNewExecute(Sender: TObject);
|
||||
procedure btnBindingsDeleteExecute(Sender: TObject);
|
||||
procedure btnBindingsDeleteUpdate(Sender: TObject);
|
||||
procedure edtPortKeyPress(Sender: TObject; var Key: Char);
|
||||
procedure edtIPAddressChange(Sender: TObject);
|
||||
procedure edtPortChange(Sender: TObject);
|
||||
procedure rdoBindingTypeClick(Sender: TObject);
|
||||
procedure lbBindingsClick(Sender: TObject);
|
||||
private
|
||||
procedure SetHandles(const Value: TIdSocketHandles);
|
||||
procedure SetIPv4Addresses(const Value: TStrings);
|
||||
procedure SetIPv6Addresses(const Value: TStrings);
|
||||
procedure UpdateBindingList;
|
||||
protected
|
||||
FInUpdateRoutine : Boolean;
|
||||
FHandles : TIdSocketHandles;
|
||||
FDefaultPort : Integer;
|
||||
FIPv4Addresses : TStrings;
|
||||
FIPv6Addresses : TStrings;
|
||||
fCreatedStack : Boolean;
|
||||
FCurrentHandle : TIdSocketHandle;
|
||||
procedure UpdateEditControls;
|
||||
function PortDescription(const PortNumber: integer): string;
|
||||
public
|
||||
Constructor Create(AOwner : TComponent); overload; override;
|
||||
constructor Create; reintroduce; overload;
|
||||
Destructor Destroy; override;
|
||||
function Execute : Boolean;
|
||||
function GetList: string;
|
||||
procedure SetList(const AList: string);
|
||||
property Handles : TIdSocketHandles read FHandles write SetHandles;
|
||||
property DefaultPort : Integer read FDefaultPort write FDefaultPort;
|
||||
property IPv4Addresses : TStrings read FIPv4Addresses write SetIPv4Addresses;
|
||||
property IPv6Addresses : TStrings read FIPv6Addresses write SetIPv6Addresses;
|
||||
end;
|
||||
|
||||
var
|
||||
IdPropEdBindingEntry: TIdDsnPropEdBindingVCL;
|
||||
|
||||
procedure FillHandleList(const AList: string; ADest: TIdSocketHandles);
|
||||
function GetListValues(const ASocketHandles : TIdSocketHandles) : String;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
IdGlobal,
|
||||
IdIPAddress,
|
||||
IdDsnCoreResourceStrings,
|
||||
IdStack,
|
||||
IdStackBSDBase,
|
||||
SysUtils;
|
||||
|
||||
const
|
||||
IPv6Wildcard1 = '::'; {do not localize}
|
||||
{CH IPv6Wildcard2 = '0:0:0:0:0:0:0:0'; } {do not localize}
|
||||
IPv6Loopback = '::1'; {do not localize}
|
||||
IPv4Wildcard = '0.0.0.0'; {do not localize}
|
||||
IPv4Loopback = '127.0.0.1'; {do not localize}
|
||||
|
||||
function IsValidIP(const AAddr : String): Boolean;
|
||||
var
|
||||
LIP : TIdIPAddress;
|
||||
begin
|
||||
LIP := TIdIPAddress.MakeAddressObject(AAddr);
|
||||
Result := Assigned(LIP);
|
||||
if Result then begin
|
||||
FreeAndNil(LIP);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure FillHandleList(const AList: string; ADest: TIdSocketHandles);
|
||||
var
|
||||
LItems: TStringList;
|
||||
i: integer;
|
||||
LIPVersion: TIdIPVersion;
|
||||
LAddr, LText: string;
|
||||
LPort: integer;
|
||||
LSocket: TIdSocketHandle;
|
||||
begin
|
||||
ADest.Clear;
|
||||
LItems := TStringList.Create;
|
||||
try
|
||||
LItems.CommaText := AList;
|
||||
for i := 0 to LItems.Count-1 do begin
|
||||
if Length(LItems[i]) > 0 then begin
|
||||
if TextStartsWith(LItems[i], '[') then begin
|
||||
// ipv6
|
||||
LIPVersion := Id_IPv6;
|
||||
LText := Copy(LItems[i], 2, MaxInt);
|
||||
LAddr := Fetch(LText, ']:');
|
||||
LPort := StrToIntDef(LText, -1);
|
||||
end else begin
|
||||
// ipv4
|
||||
LIPVersion := Id_IPv4;
|
||||
LText := LItems[i];
|
||||
LAddr := Fetch(LText, ':');
|
||||
LPort := StrToIntDef(LText, -1);
|
||||
//Note that 0 is legal and indicates the server binds to a random port
|
||||
end;
|
||||
if IsValidIP(LAddr) and (LPort > -1) and (LPort < 65536) then begin
|
||||
LSocket := ADest.Add;
|
||||
LSocket.IPVersion := LIPVersion;
|
||||
LSocket.IP := LAddr;
|
||||
LSocket.Port := LPort;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
LItems.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
{ TIdDsnPropEdBindingVCL }
|
||||
|
||||
function NumericOnly(const AText : String) : String;
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
Result := '';
|
||||
for i := 1 to Length(AText) do
|
||||
begin
|
||||
if IsNumeric(AText[i]) then begin
|
||||
Result := Result + AText[i];
|
||||
end else begin
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
if Length(Result) = 0 then begin
|
||||
Result := '0';
|
||||
end;
|
||||
end;
|
||||
|
||||
function IndexOfNo(const ANo : Integer; AStrings : TStrings) : Integer;
|
||||
begin
|
||||
for Result := 0 to AStrings.Count-1 do
|
||||
begin
|
||||
if ANo = IndyStrToInt(NumericOnly(AStrings[Result])) then begin
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
Result := -1;
|
||||
end;
|
||||
|
||||
function GetDisplayString(ASocketHandle: TIdSocketHandle): string;
|
||||
begin
|
||||
Result := '';
|
||||
case ASocketHandle.IPVersion of
|
||||
Id_IPv4 : Result := Format('%s:%d',[ASocketHandle.IP, ASocketHandle.Port]);
|
||||
Id_IPv6 : Result := Format('[%s]:%d',[ASocketHandle.IP, ASocketHandle.Port]);
|
||||
end;
|
||||
end;
|
||||
|
||||
function GetListValues(const ASocketHandles : TIdSocketHandles) : String;
|
||||
var i : Integer;
|
||||
begin
|
||||
Result := '';
|
||||
for i := 0 to ASocketHandles.Count -1 do begin
|
||||
Result := Result + ',' + GetDisplayString(ASocketHandles[i]);
|
||||
end;
|
||||
Delete(Result,1,1);
|
||||
end;
|
||||
|
||||
constructor TIdDsnPropEdBindingVCL.Create(AOwner: TComponent);
|
||||
var
|
||||
i : Integer;
|
||||
LLocalAddresses: TIdStackLocalAddressList;
|
||||
begin
|
||||
inherited CreateNew(AOwner, 0);
|
||||
{$IFNDEF WIDGET_KYLIX}
|
||||
Borderstyle := bsDialog;
|
||||
{$ENDIF}
|
||||
BorderIcons := [biSystemMenu];
|
||||
// Width := 480;
|
||||
// Height := 252;
|
||||
ClientWidth := 472;
|
||||
{$IFDEF USE_TBitBtn}
|
||||
ClientHeight := 230;
|
||||
{$ELSE}
|
||||
ClientHeight := 225;
|
||||
{$ENDIF}
|
||||
Constraints.MaxWidth := Width;
|
||||
Constraints.MaxHeight := Height;
|
||||
Constraints.MinWidth := Width;
|
||||
Constraints.MinHeight := Height;
|
||||
Position := poScreenCenter;
|
||||
lblBindings := TLabel.Create(Self);
|
||||
lbBindings := TListBox.Create(Self);
|
||||
ActionList1 := TActionList.Create(Self);
|
||||
btnBindingsNew := TAction.Create(Self);
|
||||
btnBindingsDelete := TAction.Create(Self);
|
||||
btnNew := TButton.Create(Self);
|
||||
btnDelete := TButton.Create(Self);
|
||||
lblIPAddress := TLabel.Create(Self);
|
||||
edtIPAddress := TComboBox.Create(Self);
|
||||
lblPort := TLabel.Create(Self);
|
||||
|
||||
edtPort := TComboBox.Create(Self);
|
||||
rdoBindingType := TRadioGroup.Create(Self);
|
||||
|
||||
{$IFDEF USE_TBitBtn}
|
||||
btnOk := TBitBtn.Create(Self);
|
||||
btnCancel := TBitBtn.Create(Self);
|
||||
{$ELSE}
|
||||
btnOk := TButton.Create(Self);
|
||||
btnCancel := TButton.Create(Self);
|
||||
{$ENDIF}
|
||||
|
||||
lblBindings.Name := 'lblBindings'; {do not localize}
|
||||
lblBindings.Parent := Self;
|
||||
lblBindings.Left := 8;
|
||||
lblBindings.Top := 8;
|
||||
lblBindings.Width := 35;
|
||||
lblBindings.Height := 13;
|
||||
lblBindings.Caption := '&Binding'; {do not localize}
|
||||
|
||||
lbBindings.Name := 'lbBindings'; {do not localize}
|
||||
lbBindings.Parent := Self;
|
||||
lbBindings.Left := 8;
|
||||
lbBindings.Top := 24;
|
||||
lbBindings.Width := 137;
|
||||
lbBindings.Height := 161;
|
||||
lbBindings.ItemHeight := 13;
|
||||
lbBindings.TabOrder := 8;
|
||||
lbBindings.OnClick := lbBindingsClick;
|
||||
|
||||
ActionList1.Name := 'ActionList1'; {do not localize}
|
||||
{
|
||||
ActionList1.Left := 152;
|
||||
ActionList1.Top := 32;
|
||||
}
|
||||
|
||||
btnBindingsNew.Name := 'btnBindingsNew'; {do not localize}
|
||||
btnBindingsNew.Caption := RSBindingNewCaption;
|
||||
btnBindingsNew.OnExecute := btnBindingsNewExecute;
|
||||
|
||||
btnBindingsDelete.Name := 'btnBindingsDelete'; {do not localize}
|
||||
btnBindingsDelete.Caption := RSBindingDeleteCaption;
|
||||
btnBindingsDelete.OnExecute := btnBindingsDeleteExecute;
|
||||
btnBindingsDelete.OnUpdate := btnBindingsDeleteUpdate;
|
||||
|
||||
btnNew.Name := 'btnNew'; {do not localize}
|
||||
btnNew.Parent := Self;
|
||||
btnNew.Left := 152;
|
||||
btnNew.Top := 72;
|
||||
btnNew.Width := 75;
|
||||
btnNew.Height := 25;
|
||||
btnNew.Action := btnBindingsNew;
|
||||
btnNew.TabOrder := 6;
|
||||
|
||||
btnDelete.Name := 'btnDelete'; {do not localize}
|
||||
btnDelete.Parent := Self;
|
||||
btnDelete.Left := 152;
|
||||
btnDelete.Top := 104;
|
||||
btnDelete.Width := 75;
|
||||
btnDelete.Height := 25;
|
||||
btnDelete.Action := btnBindingsDelete;
|
||||
btnDelete.TabOrder := 7;
|
||||
|
||||
lblIPAddress.Name := 'lblIPAddress'; {do not localize}
|
||||
lblIPAddress.Parent := Self;
|
||||
lblIPAddress.Left := 240;
|
||||
lblIPAddress.Top := 8;
|
||||
lblIPAddress.Width := 54;
|
||||
lblIPAddress.Height := 13;
|
||||
lblIPAddress.Caption := RSBindingHostnameLabel;
|
||||
lblIPAddress.Enabled := False;
|
||||
|
||||
edtIPAddress.Name := 'edtIPAddress'; {do not localize}
|
||||
edtIPAddress.Parent := Self;
|
||||
edtIPAddress.Left := 240;
|
||||
edtIPAddress.Top := 24;
|
||||
edtIPAddress.Width := 221;
|
||||
edtIPAddress.Height := 21;
|
||||
edtIPAddress.Enabled := False;
|
||||
edtIPAddress.ItemHeight := 13;
|
||||
edtIPAddress.TabOrder := 3;
|
||||
edtIPAddress.OnChange := edtIPAddressChange;
|
||||
|
||||
lblPort.Name := 'lblPort'; {do not localize}
|
||||
lblPort.Parent := Self;
|
||||
lblPort.Left := 240;
|
||||
lblPort.Top := 56;
|
||||
lblPort.Width := 22;
|
||||
lblPort.Height := 13;
|
||||
lblPort.Caption := RSBindingPortLabel;
|
||||
lblPort.Enabled := False;
|
||||
lblPort.FocusControl := edtPort;
|
||||
|
||||
edtPort.Name := 'edtPort'; {do not localize}
|
||||
edtPort.Parent := Self;
|
||||
edtPort.Left := 240;
|
||||
edtPort.Top := 72;
|
||||
edtPort.Width := 221;
|
||||
edtPort.Height := 21;
|
||||
edtPort.Enabled := False;
|
||||
edtPort.ItemHeight := 13;
|
||||
edtPort.TabOrder := 4;
|
||||
edtPort.OnChange := edtPortChange;
|
||||
edtPort.OnKeyPress := edtPortKeyPress;
|
||||
|
||||
rdoBindingType.Name := 'rdoBindingType'; {do not localize}
|
||||
rdoBindingType.Parent := Self;
|
||||
rdoBindingType.Left := 240;
|
||||
rdoBindingType.Top := 120;
|
||||
rdoBindingType.Width := 221;
|
||||
rdoBindingType.Height := 65;
|
||||
rdoBindingType.Caption := RSBindingIPVerLabel;
|
||||
rdoBindingType.Enabled := False;
|
||||
rdoBindingType.Items.Add(RSBindingIPV4Item);
|
||||
rdoBindingType.Items.Add(RSBindingIPV6Item);
|
||||
rdoBindingType.TabOrder := 5;
|
||||
rdoBindingType.OnClick := rdoBindingTypeClick;
|
||||
|
||||
btnOk.Name := 'btnOk'; {do not localize}
|
||||
btnOk.Parent := Self;
|
||||
btnOk.Anchors := [akRight, akBottom];
|
||||
btnOk.Left := 306;
|
||||
btnOk.Top := 193;
|
||||
btnOk.Width := 75;
|
||||
{$IFDEF USE_TBitBtn}
|
||||
btnOk.Height := 30;
|
||||
btnOk.Kind := bkOk;
|
||||
{$ELSE}
|
||||
btnOk.Height := 25;
|
||||
btnOk.Caption := RSOk;
|
||||
btnOk.Default := True;
|
||||
btnOk.ModalResult := 1;
|
||||
{$ENDIF}
|
||||
btnOk.TabOrder := 0;
|
||||
|
||||
btnCancel.Name := 'btnCancel'; {do not localize}
|
||||
btnCancel.Parent := Self;
|
||||
btnCancel.Anchors := [akRight, akBottom];
|
||||
btnCancel.Left := 386;
|
||||
btnCancel.Top := 193;
|
||||
btnCancel.Width := 75;
|
||||
{$IFDEF USE_TBitBtn}
|
||||
btnCancel.Height := 30;
|
||||
btnCancel.Kind := bkCancel;
|
||||
{$ELSE}
|
||||
btnCancel.Height := 25;
|
||||
btnCancel.Cancel := True;
|
||||
btnCancel.Caption := RSCancel;
|
||||
btnCancel.ModalResult := 2;
|
||||
{$ENDIF}
|
||||
btnCancel.Anchors := [akRight, akBottom];
|
||||
btnCancel.TabOrder := 1;
|
||||
|
||||
FHandles := TIdSocketHandles.Create(nil);
|
||||
FIPv4Addresses := TStringList.Create;
|
||||
FIPv6Addresses := TStringList.Create;
|
||||
SetIPv4Addresses(nil);
|
||||
SetIPv6Addresses(nil);
|
||||
|
||||
TIdStack.IncUsage;
|
||||
try
|
||||
LLocalAddresses := TIdStackLocalAddressList.Create;
|
||||
try
|
||||
GStack.GetLocalAddressList(LLocalAddresses);
|
||||
for i := 0 to LLocalAddresses.Count-1 do
|
||||
begin
|
||||
case LLocalAddresses[i].IPVersion of
|
||||
Id_IPv4: FIPv4Addresses.Add(LLocalAddresses[i].IPAddress);
|
||||
Id_IPv6: FIPv6Addresses.Add(LLocalAddresses[i].IPAddress);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
LLocalAddresses.Free;
|
||||
end;
|
||||
finally
|
||||
TIdStack.DecUsage;
|
||||
end;
|
||||
|
||||
edtPort.Items.BeginUpdate;
|
||||
try
|
||||
edtPort.Items.Add(PortDescription(0));
|
||||
for i := 0 to IdPorts.Count - 1 do begin
|
||||
edtPort.Items.Add(
|
||||
PortDescription(
|
||||
{$IFDEF HAS_GENERICS_TList}
|
||||
IdPorts[i]
|
||||
{$ELSE}
|
||||
PtrInt(IdPorts[i])
|
||||
{$ENDIF}
|
||||
)
|
||||
);
|
||||
end;
|
||||
finally
|
||||
edtPort.Items.EndUpdate;
|
||||
end;
|
||||
|
||||
AutoScroll := False;
|
||||
Caption := RSBindingFormCaption;
|
||||
{$IFDEF WIDGET_VCL}
|
||||
Scaled := False;
|
||||
{$ENDIF}
|
||||
Font.Color := clBtnText;
|
||||
Font.Height := -11;
|
||||
Font.Name := 'MS Sans Serif'; {Do not Localize}
|
||||
Font.Style := [];
|
||||
Position := poScreenCenter;
|
||||
PixelsPerInch := 96;
|
||||
FInUpdateRoutine := False;
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
destructor TIdDsnPropEdBindingVCL.Destroy;
|
||||
begin
|
||||
FreeAndNil(FIPv4Addresses);
|
||||
FreeAndNil(FIPv6Addresses);
|
||||
FreeAndNil(FHandles);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
function TIdDsnPropEdBindingVCL.PortDescription(const PortNumber: integer): string;
|
||||
var
|
||||
LList: TStringList;
|
||||
begin
|
||||
if PortNumber = 0 then begin
|
||||
Result := IndyFormat('%d: %s', [PortNumber, RSBindingAny]);
|
||||
end else begin
|
||||
Result := ''; {Do not Localize}
|
||||
LList := TStringList.Create;
|
||||
try
|
||||
GBSDStack.AddServByPortToList(PortNumber, LList);
|
||||
if LList.Count > 0 then begin
|
||||
Result := Format('%d: %s', [PortNumber, LList.CommaText]); {Do not Localize}
|
||||
end;
|
||||
finally
|
||||
LList.Free;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.SetHandles(const Value: TIdSocketHandles);
|
||||
begin
|
||||
FHandles.Assign(Value);
|
||||
UpdateBindingList;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.btnBindingsNewExecute(Sender: TObject);
|
||||
begin
|
||||
FCurrentHandle := FHandles.Add;
|
||||
FCurrentHandle.IP := IPv4Wildcard;
|
||||
FCurrentHandle.Port := FDefaultPort;
|
||||
UpdateBindingList;
|
||||
edtIPAddress.Items.Assign(FIPv4Addresses);
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.UpdateEditControls;
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
if Assigned(FCurrentHandle) then
|
||||
begin
|
||||
i := IndexOfNo(FCurrentHandle.Port,edtPort.Items);
|
||||
if i = -1 then begin
|
||||
edtPort.Text := IntToStr(FCurrentHandle.Port);
|
||||
end else begin
|
||||
edtPort.ItemIndex := i;
|
||||
end;
|
||||
|
||||
case FCurrentHandle.IPVersion of
|
||||
Id_IPv4 :
|
||||
begin
|
||||
rdoBindingType.ItemIndex := 0;
|
||||
edtIPAddress.Items.Assign(FIPv4Addresses);
|
||||
end;
|
||||
Id_IPv6 :
|
||||
begin
|
||||
rdoBindingType.ItemIndex := 1;
|
||||
edtIPAddress.Items.Assign(FIPv6Addresses);
|
||||
end;
|
||||
end;
|
||||
if edtIPAddress.Style = csDropDown then begin
|
||||
edtIPAddress.Text := FCurrentHandle.IP;
|
||||
end else begin
|
||||
edtIPAddress.ItemIndex := edtIPAddress.Items.IndexOf(FCurrentHandle.IP);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
edtIPAddress.Text := '';
|
||||
//in LCL, the line below caused an index out of range error.
|
||||
{$IFDEF WIDGET_VCL}
|
||||
edtPort.ItemIndex := -1; //-2;
|
||||
{$ENDIF}
|
||||
edtPort.Text := '';
|
||||
end;
|
||||
|
||||
lblIPAddress.Enabled := Assigned(FCurrentHandle);
|
||||
edtIPAddress.Enabled := Assigned(FCurrentHandle);
|
||||
lblPort.Enabled := Assigned(FCurrentHandle);
|
||||
edtPort.Enabled := Assigned(FCurrentHandle);
|
||||
rdoBindingType.Enabled := Assigned(FCurrentHandle);
|
||||
{$IFDEF WIDGET_KYLIX}
|
||||
//WOrkaround for CLX quirk that might be Kylix 1
|
||||
for i := 0 to rdoBindingType.ControlCount -1 do begin
|
||||
rdoBindingType.Controls[i].Enabled := Assigned(FCurrentHandle);
|
||||
end;
|
||||
{$ENDIF}
|
||||
{$IFDEF WIDGET_VCL_LIKE}
|
||||
//The Win32 VCL does not change the control background to a greyed look
|
||||
//when controls are disabled. This quirk is not present in CLX.
|
||||
if Assigned(FCurrentHandle) then
|
||||
begin
|
||||
edtIPAddress.Color := clWindow;
|
||||
edtPort.Color := clWindow;
|
||||
end else
|
||||
begin
|
||||
edtIPAddress.Color := clBtnFace;
|
||||
edtPort.Color := clBtnFace;
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.btnBindingsDeleteExecute(Sender: TObject);
|
||||
var
|
||||
LSH : TIdSocketHandle;
|
||||
begin
|
||||
if lbBindings.ItemIndex >= 0 then
|
||||
begin
|
||||
// Delete is not available in D4's collection classes
|
||||
// This should work just as well.
|
||||
LSH := Handles[lbBindings.ItemIndex];
|
||||
FreeAndNil(LSH);
|
||||
FCurrentHandle := nil;
|
||||
UpdateBindingList;
|
||||
end;
|
||||
lbBindingsClick(nil);
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.btnBindingsDeleteUpdate(Sender: TObject);
|
||||
begin
|
||||
btnBindingsDelete.Enabled := lbBindings.ItemIndex >= 0;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.SetIPv4Addresses(const Value: TStrings);
|
||||
begin
|
||||
if Assigned(Value) then begin
|
||||
FIPv4Addresses.Assign(Value);
|
||||
end;
|
||||
// Ensure that these two are always present
|
||||
if FIPv4Addresses.IndexOf(IPv6Loopback) = -1 then begin
|
||||
FIPv4Addresses.Insert(0, IPv4Loopback);
|
||||
end;
|
||||
if FIPv4Addresses.IndexOf(IPv4Wildcard) = -1 then begin
|
||||
FIPv4Addresses.Insert(0, IPv4Wildcard);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.SetIPv6Addresses(const Value: TStrings);
|
||||
begin
|
||||
if Assigned(Value) then begin
|
||||
FIPv6Addresses.Assign(Value);
|
||||
end;
|
||||
// Ensure that these two are always present
|
||||
if FIPv6Addresses.IndexOf(IPv6Loopback) = -1 then begin
|
||||
FIPv6Addresses.Insert(0, IPv6Loopback);
|
||||
end;
|
||||
if FIPv6Addresses.IndexOf(IPv6Wildcard1) = -1 then begin
|
||||
FIPv6Addresses.Insert(0, IPv6Wildcard1);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.edtPortKeyPress(Sender: TObject; var Key: Char);
|
||||
begin
|
||||
// RLebeau 1/7/09: using Char() for #128-#255 because in D2009, the compiler
|
||||
// may change characters >= #128 from their Ansi codepage value to their true
|
||||
// Unicode codepoint value, depending on the codepage used for the source code.
|
||||
// For instance, #128 may become #$20AC...
|
||||
|
||||
if (Key > Chr(31)) and (Key < Chr(128)) then begin
|
||||
if not IsNumeric(Key) then begin
|
||||
Key := #0;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.edtIPAddressChange(Sender: TObject);
|
||||
begin
|
||||
FCurrentHandle.IP := edtIPAddress.Text;
|
||||
UpdateBindingList;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.edtPortChange(Sender: TObject);
|
||||
begin
|
||||
if Assigned(FCurrentHandle) then begin
|
||||
FCurrentHandle.Port := IndyStrToInt(NumericOnly(edtPort.Text), 0);
|
||||
end;
|
||||
UpdateBindingList;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.rdoBindingTypeClick(Sender: TObject);
|
||||
begin
|
||||
case rdoBindingType.ItemIndex of
|
||||
0 :
|
||||
begin
|
||||
if FCurrentHandle.IPVersion <> Id_IPv4 then
|
||||
begin
|
||||
FCurrentHandle.IPVersion := Id_IPv4;
|
||||
edtIPAddress.Items.Assign(FIPv4Addresses);
|
||||
FCurrentHandle.IP := IPv4Wildcard;
|
||||
end;
|
||||
end;
|
||||
1 :
|
||||
begin
|
||||
if FCurrentHandle.IPVersion <> Id_IPv6 then
|
||||
begin
|
||||
FCurrentHandle.IPVersion := Id_IPv6;
|
||||
edtIPAddress.Items.Assign(FIPv6Addresses);
|
||||
FCurrentHandle.IP := IPv6Wildcard1;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
UpdateEditControls;
|
||||
UpdateBindingList;
|
||||
end;
|
||||
|
||||
function TIdDsnPropEdBindingVCL.GetList: string;
|
||||
begin
|
||||
Result := GetListValues(Handles);
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.lbBindingsClick(Sender: TObject);
|
||||
begin
|
||||
if lbBindings.ItemIndex >= 0 then begin
|
||||
FCurrentHandle := FHandles[lbBindings.ItemIndex];
|
||||
end else begin
|
||||
FCurrentHandle := nil;
|
||||
end;
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.SetList(const AList: string);
|
||||
begin
|
||||
FCurrentHandle := nil;
|
||||
FillHandleList(AList, Handles);
|
||||
UpdateBindingList;
|
||||
UpdateEditControls;
|
||||
end;
|
||||
|
||||
procedure TIdDsnPropEdBindingVCL.UpdateBindingList;
|
||||
var
|
||||
i: integer;
|
||||
selected: integer;
|
||||
s: string;
|
||||
begin
|
||||
//in Lazarus, for some odd reason, if you have more than one binding,
|
||||
//the routine is called while the items are updated
|
||||
if FInUpdateRoutine then begin
|
||||
Exit;
|
||||
end;
|
||||
FInUpdateRoutine := True;
|
||||
try
|
||||
selected := lbBindings.ItemIndex;
|
||||
lbBindings.Items.BeginUpdate;
|
||||
try
|
||||
if lbBindings.Items.Count = FHandles.Count then begin
|
||||
for i := 0 to FHandles.Count - 1 do begin
|
||||
s := GetDisplayString(FHandles[i]);
|
||||
if s <> lbBindings.Items[i] then begin
|
||||
lbBindings.Items[i] := s;
|
||||
end;
|
||||
end;
|
||||
end else begin
|
||||
lbBindings.Items.Clear;
|
||||
for i := 0 to FHandles.Count-1 do begin
|
||||
lbBindings.Items.Add(GetDisplayString(FHandles[i]));
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
lbBindings.Items.EndUpdate;
|
||||
if Assigned(FCurrentHandle) then begin
|
||||
lbBindings.ItemIndex := FCurrentHandle.Index;
|
||||
end else begin
|
||||
lbBindings.ItemIndex := IndyMin(selected, lbBindings.Items.Count-1);
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
FInUpdateRoutine := False;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdDsnPropEdBindingVCL.Execute: Boolean;
|
||||
begin
|
||||
Result := ShowModal = mrOk;
|
||||
end;
|
||||
|
||||
constructor TIdDsnPropEdBindingVCL.Create;
|
||||
begin
|
||||
Create(nil);
|
||||
end;
|
||||
|
||||
end.
|
||||
191
indy/Core/IdExceptionCore.pas
Normal file
@@ -0,0 +1,191 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.3 09/06/2004 09:52:34 CCostelloe
|
||||
Kylix 3 patch
|
||||
|
||||
Rev 1.2 6/4/2004 5:12:56 PM SGrobety
|
||||
added EIdMaxCaptureLineExceeded
|
||||
|
||||
Rev 1.1 2/10/2004 7:41:50 PM JPMugaas
|
||||
I had to move EWrapperException down to the system package because
|
||||
IdStackDotNET was using it and that would drage IdExceptionCore into the
|
||||
package. Borland changed some behavior so the warning is now an error.
|
||||
|
||||
Rev 1.0 2004.02.03 4:19:48 PM czhower
|
||||
Rename
|
||||
|
||||
Rev 1.15 11/4/2003 10:26:58 PM DSiders
|
||||
Added exceptions moved from IdIOHandler.pas and IdTCPConnection.pas.
|
||||
|
||||
Rev 1.14 2003.10.16 11:24:00 AM czhower
|
||||
Added IfAssigned
|
||||
|
||||
Rev 1.13 2003.10.11 5:47:58 PM czhower
|
||||
-VCL fixes for servers
|
||||
-Chain suport for servers (Super core)
|
||||
-Scheduler upgrades
|
||||
-Full yarn support
|
||||
|
||||
Rev 1.12 10/3/2003 11:38:36 PM GGrieve
|
||||
Add EIdWrapperException
|
||||
|
||||
Rev 1.11 9/29/2003 02:56:28 PM JPMugaas
|
||||
Added comment about why IdException.Create is virtual.
|
||||
|
||||
Rev 1.10 9/24/2003 11:42:50 PM JPMugaas
|
||||
Minor changes to help compile under NET
|
||||
|
||||
Rev 1.9 2003.09.19 10:10:02 PM czhower
|
||||
IfTrue, IfFalse
|
||||
|
||||
Rev 1.8 2003.09.19 11:54:28 AM czhower
|
||||
-Completed more features necessary for servers
|
||||
-Fixed some bugs
|
||||
|
||||
Rev 1.7 2003.07.17 4:57:04 PM czhower
|
||||
Added new exception type so it can be added to debugger list of ignored
|
||||
exceptions.
|
||||
|
||||
Rev 1.6 7/1/2003 8:33:02 PM BGooijen
|
||||
Added EIdFibersNotSupported
|
||||
|
||||
Rev 1.5 2003.06.05 10:08:50 AM czhower
|
||||
Extended reply mechanisms to the exception handling. Only base and RFC
|
||||
completed, handing off to J Peter.
|
||||
|
||||
Rev 1.4 5/14/2003 2:59:58 PM BGooijen
|
||||
Added exception for transparant proxy
|
||||
|
||||
Rev 1.3 2003.04.14 10:54:06 AM czhower
|
||||
Fiber specific exceptions
|
||||
|
||||
Rev 1.2 4/2/2003 7:18:38 PM BGooijen
|
||||
Added EIdHttpProxyError
|
||||
|
||||
Rev 1.1 1/17/2003 05:06:46 PM JPMugaas
|
||||
Exceptions for scheduler string.
|
||||
|
||||
Rev 1.0 11/13/2002 08:44:10 AM JPMugaas
|
||||
}
|
||||
|
||||
unit IdExceptionCore;
|
||||
|
||||
interface
|
||||
{$I IdCompilerDefines.inc}
|
||||
//needed to put FCP into Delphi mode
|
||||
uses
|
||||
IdException, IdStack;
|
||||
|
||||
type
|
||||
// IdFiber Exceptions
|
||||
EIdFiber = class(EIdException);
|
||||
EIdFiberFinished = class(EIdFiber);
|
||||
EIdFibersNotSupported = class(EIdFiber);
|
||||
|
||||
EIdAlreadyConnected = class(EIdException);
|
||||
|
||||
// EIdClosedSocket is raised if .Disconnect has been called and an operation is attempted
|
||||
// or Connect has not been called
|
||||
EIdClosedSocket = class(EIdException);
|
||||
EIdResponseError = class(EIdException);
|
||||
EIdReadTimeout = class(EIdException);
|
||||
EIdAcceptTimeout = class(EIdException);
|
||||
EIdReadLnMaxLineLengthExceeded = class(EIdException);
|
||||
EIdReadLnWaitMaxAttemptsExceeded = class(EIdException);
|
||||
|
||||
// TIdTCPConnection exceptions
|
||||
EIdPortRequired = class(EIdException);
|
||||
EIdHostRequired = class(EIdException);
|
||||
EIdTCPConnectionError = class(EIdException);
|
||||
EIdObjectTypeNotSupported = class(EIdTCPConnectionError);
|
||||
EIdInterceptPropIsNil = class(EIdTCPConnectionError);
|
||||
EIdInterceptPropInvalid = class(EIdTCPConnectionError);
|
||||
EIdIOHandlerPropInvalid = class(EIdTCPConnectionError);
|
||||
EIdNoDataToRead = class(EIdTCPConnectionError);
|
||||
EIdFileNotFound = class(EIdTCPConnectionError);
|
||||
|
||||
EIdNotConnected = class(EIdException);
|
||||
|
||||
EInvalidSyslogMessage = class(EIdException);
|
||||
EIdSSLProtocolReplyError = class(EIdException);
|
||||
EIdConnectTimeout = class(EIdException);
|
||||
EIdConnectException = class(EIdException);
|
||||
|
||||
EIdTransparentProxyCantBind = class(EIdException);
|
||||
|
||||
EIdHttpProxyError = class(EIdException);
|
||||
|
||||
EIdSocksError = class(EIdException);
|
||||
EIdSocksRequestFailed = class(EIdSocksError);
|
||||
EIdSocksRequestServerFailed = class(EIdSocksError);
|
||||
EIdSocksRequestIdentFailed = class(EIdSocksError);
|
||||
EIdSocksUnknownError = class(EIdSocksError);
|
||||
EIdSocksServerRespondError = class(EIdSocksError);
|
||||
EIdSocksAuthMethodError = class(EIdSocksError);
|
||||
EIdSocksAuthError = class(EIdSocksError);
|
||||
EIdSocksServerGeneralError = class(EIdSocksError);
|
||||
EIdSocksServerPermissionError = class (EIdSocksError);
|
||||
EIdSocksServerNetUnreachableError = class (EIdSocksError);
|
||||
EIdSocksServerHostUnreachableError = class (EIdSocksError);
|
||||
EIdSocksServerConnectionRefusedError = class (EIdSocksError);
|
||||
EIdSocksServerTTLExpiredError = class (EIdSocksError);
|
||||
EIdSocksServerCommandError = class (EIdSocksError);
|
||||
EIdSocksServerAddressError = class (EIdSocksError);
|
||||
|
||||
//IdIMAP4 Exception
|
||||
EIdConnectionStateError = class(EIdException);
|
||||
|
||||
// THE EDnsResolverError is used so the resolver can repond to only resolver execeptions.
|
||||
EIdDnsResolverError = Class(EIdException);
|
||||
|
||||
{Socket exceptions}
|
||||
EIdInvalidSocket = class(EIdException);
|
||||
|
||||
EIdThreadMgrError = class(EIdException);
|
||||
EIdThreadClassNotSpecified = class(EIdThreadMgrError);
|
||||
|
||||
{TIdTrivial FTP Exception }
|
||||
EIdTFTPException = class(EIdException);
|
||||
EIdTFTPFileNotFound = class(EIdTFTPException);
|
||||
EIdTFTPAccessViolation = class(EIdTFTPException);
|
||||
EIdTFTPAllocationExceeded = class(EIdTFTPException);
|
||||
EIdTFTPIllegalOperation = class(EIdTFTPException);
|
||||
EIdTFTPUnknownTransferID = class(EIdTFTPException);
|
||||
EIdTFTPFileAlreadyExists = class(EIdTFTPException);
|
||||
EIdTFTPNoSuchUser = class(EIdTFTPException);
|
||||
EIdTFTPOptionNegotiationFailed = class(EIdTFTPException); // RFC 1782
|
||||
|
||||
{Icmp exceptions}
|
||||
EIdIcmpException = class(EIdException);
|
||||
|
||||
EIdSetSizeExceeded = class(EIdException);
|
||||
|
||||
{IdMessage and things use this}
|
||||
EIdMessageException = class(EIdException);
|
||||
|
||||
//scheduler exception
|
||||
EIdSchedulerException = class(EIdException);
|
||||
EIdSchedulerMaxThreadsExceeded = class(EIdSchedulerException);
|
||||
|
||||
{ IdIOHandler }
|
||||
EIdMaxCaptureLineExceeded = class(EIdException); // S.G. 6/4/2004: triggered when a capture command exceeds the maximum number of line allowed
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
48
indy/Core/IdGlobalCore.pas
Normal file
@@ -0,0 +1,48 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.2 8/16/2004 1:08:46 PM JPMugaas
|
||||
Failed to compile in some IDE's.
|
||||
|
||||
Rev 1.1 2004.08.13 21:46:20 czhower
|
||||
Fix for .NET
|
||||
|
||||
Rev 1.0 2004.08.13 10:54:58 czhower
|
||||
Initial checkin
|
||||
}
|
||||
|
||||
unit IdGlobalCore;
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
uses
|
||||
Classes,
|
||||
IdGlobal;
|
||||
|
||||
const
|
||||
{$IFDEF UNIX}
|
||||
tpListener = tpNormal;
|
||||
{$ELSE}
|
||||
tpListener = tpHighest;
|
||||
{$ENDIF}
|
||||
|
||||
implementation
|
||||
|
||||
end.
|
||||
2695
indy/Core/IdIOHandler.pas
Normal file
575
indy/Core/IdIOHandlerSocket.pas
Normal file
@@ -0,0 +1,575 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.38 11/10/2004 8:25:54 AM JPMugaas
|
||||
Fix for AV caused by short-circut boolean evaluation.
|
||||
|
||||
Rev 1.37 27.08.2004 21:58:20 Andreas Hausladen
|
||||
Speed optimization ("const" for string parameters)
|
||||
|
||||
Rev 1.36 8/2/04 5:44:40 PM RLebeau
|
||||
Moved ConnectTimeout over from TIdIOHandlerStack
|
||||
|
||||
Rev 1.35 7/21/2004 12:22:32 PM BGooijen
|
||||
Fix to .connected
|
||||
|
||||
Rev 1.34 6/30/2004 12:31:34 PM BGooijen
|
||||
Added OnSocketAllocated
|
||||
|
||||
Rev 1.33 4/24/04 12:52:52 PM RLebeau
|
||||
Added setter method to UseNagle property
|
||||
|
||||
Rev 1.32 2004.04.18 12:52:02 AM czhower
|
||||
Big bug fix with server disconnect and several other bug fixed that I found
|
||||
along the way.
|
||||
|
||||
Rev 1.31 2004.02.03 4:16:46 PM czhower
|
||||
For unit name changes.
|
||||
|
||||
Rev 1.30 2/2/2004 11:46:46 AM BGooijen
|
||||
Dotnet and TransparentProxy
|
||||
|
||||
Rev 1.29 2/1/2004 9:44:00 PM JPMugaas
|
||||
Start on reenabling Transparant proxy.
|
||||
|
||||
Rev 1.28 2004.01.20 10:03:28 PM czhower
|
||||
InitComponent
|
||||
|
||||
Rev 1.27 1/2/2004 12:02:16 AM BGooijen
|
||||
added OnBeforeBind/OnAfterBind
|
||||
|
||||
Rev 1.26 12/31/2003 9:51:56 PM BGooijen
|
||||
Added IPv6 support
|
||||
|
||||
Rev 1.25 11/4/2003 10:37:40 PM BGooijen
|
||||
JP's patch to fix the bound port
|
||||
|
||||
Rev 1.24 10/19/2003 5:21:26 PM BGooijen
|
||||
SetSocketOption
|
||||
|
||||
Rev 1.23 10/18/2003 1:44:06 PM BGooijen
|
||||
Added include
|
||||
|
||||
Rev 1.22 2003.10.14 1:26:54 PM czhower
|
||||
Uupdates + Intercept support
|
||||
|
||||
Rev 1.21 10/9/2003 8:09:06 PM SPerry
|
||||
bug fixes
|
||||
|
||||
Rev 1.20 8/10/2003 2:05:50 PM SGrobety
|
||||
Dotnet
|
||||
|
||||
Rev 1.19 2003.10.07 10:18:26 PM czhower
|
||||
Uncommneted todo code that is now non dotnet.
|
||||
|
||||
Rev 1.18 2003.10.02 8:23:42 PM czhower
|
||||
DotNet Excludes
|
||||
|
||||
Rev 1.17 2003.10.01 9:11:18 PM czhower
|
||||
.Net
|
||||
|
||||
Rev 1.16 2003.10.01 5:05:12 PM czhower
|
||||
.Net
|
||||
|
||||
Rev 1.15 2003.10.01 2:46:38 PM czhower
|
||||
.Net
|
||||
|
||||
Rev 1.14 2003.10.01 11:16:32 AM czhower
|
||||
.Net
|
||||
|
||||
Rev 1.13 2003.09.30 1:22:58 PM czhower
|
||||
Stack split for DotNet
|
||||
|
||||
Rev 1.12 7/4/2003 08:26:44 AM JPMugaas
|
||||
Optimizations.
|
||||
|
||||
Rev 1.11 7/1/2003 03:39:44 PM JPMugaas
|
||||
Started numeric IP function API calls for more efficiency.
|
||||
|
||||
Rev 1.10 2003.06.30 5:41:56 PM czhower
|
||||
-Fixed AV that occurred sometimes when sockets were closed with chains
|
||||
-Consolidated code that was marked by a todo for merging as it no longer
|
||||
needed to be separate
|
||||
-Removed some older code that was no longer necessary
|
||||
|
||||
Passes bubble tests.
|
||||
|
||||
Rev 1.9 6/3/2003 11:45:58 PM BGooijen
|
||||
Added .Connected
|
||||
|
||||
Rev 1.8 2003.04.22 7:45:34 PM czhower
|
||||
|
||||
Rev 1.7 4/2/2003 3:24:56 PM BGooijen
|
||||
Moved transparantproxy from ..stack to ..socket
|
||||
|
||||
Rev 1.6 2/28/2003 9:51:56 PM BGooijen
|
||||
removed the field: FReadTimeout: Integer, it hided the one in TIdIOHandler
|
||||
|
||||
Rev 1.5 2/26/2003 1:15:38 PM BGooijen
|
||||
FBinding is now freed in IdIOHandlerSocket, instead of in IdIOHandlerStack
|
||||
|
||||
Rev 1.4 2003.02.25 1:36:08 AM czhower
|
||||
|
||||
Rev 1.3 2002.12.07 12:26:26 AM czhower
|
||||
|
||||
Rev 1.2 12-6-2002 20:09:14 BGooijen
|
||||
Changed SetDestination to search for the last ':', instead of the first
|
||||
|
||||
Rev 1.1 12-6-2002 18:54:14 BGooijen
|
||||
Added IPv6-support
|
||||
|
||||
Rev 1.0 11/13/2002 08:45:08 AM JPMugaas
|
||||
}
|
||||
|
||||
unit IdIOHandlerSocket;
|
||||
|
||||
interface
|
||||
|
||||
{$I IdCompilerDefines.inc}
|
||||
|
||||
uses
|
||||
Classes,
|
||||
IdCustomTransparentProxy,
|
||||
IdBaseComponent,
|
||||
IdGlobal,
|
||||
IdIOHandler,
|
||||
IdSocketHandle;
|
||||
|
||||
const
|
||||
IdDefTimeout = 0;
|
||||
IdBoundPortDefault = 0;
|
||||
|
||||
type
|
||||
{
|
||||
TIdIOHandlerSocket is the base class for socket IOHandlers that implement a
|
||||
binding.
|
||||
|
||||
Descendants
|
||||
-TIdIOHandlerStack
|
||||
-TIdIOHandlerChain
|
||||
}
|
||||
TIdIOHandlerSocket = class(TIdIOHandler)
|
||||
protected
|
||||
FBinding: TIdSocketHandle;
|
||||
FBoundIP: string;
|
||||
FBoundPort: TIdPort;
|
||||
FBoundPortMax: TIdPort;
|
||||
FBoundPortMin: TIdPort;
|
||||
FDefaultPort: TIdPort;
|
||||
FOnBeforeBind: TNotifyEvent;
|
||||
FOnAfterBind: TNotifyEvent;
|
||||
FOnSocketAllocated: TNotifyEvent;
|
||||
{$IFDEF USE_OBJECT_ARC}[Weak]{$ENDIF} FTransparentProxy: TIdCustomTransparentProxy;
|
||||
FImplicitTransparentProxy: Boolean;
|
||||
FUseNagle: Boolean;
|
||||
FReuseSocket: TIdReuseSocket;
|
||||
FIPVersion: TIdIPVersion;
|
||||
//
|
||||
procedure ConnectClient; virtual;
|
||||
procedure DoBeforeBind; virtual;
|
||||
procedure DoAfterBind; virtual;
|
||||
procedure DoSocketAllocated; virtual;
|
||||
procedure InitComponent; override;
|
||||
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
|
||||
function GetDestination: string; override;
|
||||
procedure SetDestination(const AValue: string); override;
|
||||
function GetReuseSocket: TIdReuseSocket;
|
||||
procedure SetReuseSocket(AValue: TIdReuseSocket);
|
||||
function GetTransparentProxy: TIdCustomTransparentProxy; virtual;
|
||||
procedure SetTransparentProxy(AProxy: TIdCustomTransparentProxy); virtual;
|
||||
function GetUseNagle: Boolean;
|
||||
procedure SetUseNagle(AValue: Boolean);
|
||||
//
|
||||
function SourceIsAvailable: Boolean; override;
|
||||
function CheckForError(ALastResult: Integer): Integer; override;
|
||||
procedure RaiseError(AError: Integer); override;
|
||||
public
|
||||
procedure AfterAccept; override;
|
||||
destructor Destroy; override;
|
||||
function BindingAllocated: Boolean;
|
||||
procedure Close; override;
|
||||
function Connected: Boolean; override;
|
||||
procedure Open; override;
|
||||
function WriteFile(const AFile: String; AEnableTransferFile: Boolean = False): Int64; override;
|
||||
//
|
||||
property Binding: TIdSocketHandle read FBinding;
|
||||
property BoundPortMax: TIdPort read FBoundPortMax write FBoundPortMax;
|
||||
property BoundPortMin: TIdPort read FBoundPortMin write FBoundPortMin;
|
||||
// events
|
||||
property OnBeforeBind: TNotifyEvent read FOnBeforeBind write FOnBeforeBind;
|
||||
property OnAfterBind: TNotifyEvent read FOnAfterBind write FOnAfterBind;
|
||||
property OnSocketAllocated: TNotifyEvent read FOnSocketAllocated write FOnSocketAllocated;
|
||||
published
|
||||
property BoundIP: string read FBoundIP write FBoundIP;
|
||||
property BoundPort: TIdPort read FBoundPort write FBoundPort default IdBoundPortDefault;
|
||||
property DefaultPort: TIdPort read FDefaultPort write FDefaultPort;
|
||||
property IPVersion: TIdIPVersion read FIPVersion write FIPVersion default ID_DEFAULT_IP_VERSION;
|
||||
property ReuseSocket: TIdReuseSocket read GetReuseSocket write SetReuseSocket default rsOSDependent;
|
||||
property TransparentProxy: TIdCustomTransparentProxy read GetTransparentProxy write SetTransparentProxy;
|
||||
property UseNagle: boolean read GetUseNagle write SetUseNagle default True;
|
||||
end;
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
//facilitate inlining only.
|
||||
{$IFDEF DOTNET}
|
||||
{$IFDEF USE_INLINE}
|
||||
System.IO,
|
||||
{$ENDIF}
|
||||
{$ENDIF}
|
||||
{$IFDEF WIN32_OR_WIN64 }
|
||||
Windows,
|
||||
{$ENDIF}
|
||||
SysUtils,
|
||||
IdStack,
|
||||
IdStackConsts,
|
||||
IdSocks;
|
||||
|
||||
{ TIdIOHandlerSocket }
|
||||
|
||||
procedure TIdIOHandlerSocket.AfterAccept;
|
||||
begin
|
||||
inherited AfterAccept;
|
||||
FIPVersion := FBinding.IPVersion;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.Close;
|
||||
begin
|
||||
if FBinding <> nil then begin
|
||||
FBinding.CloseSocket;
|
||||
end;
|
||||
inherited Close;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.ConnectClient;
|
||||
var
|
||||
LBinding: TIdSocketHandle;
|
||||
begin
|
||||
LBinding := Binding;
|
||||
DoBeforeBind;
|
||||
// Allocate the socket
|
||||
LBinding.IPVersion := FIPVersion;
|
||||
LBinding.AllocateSocket;
|
||||
DoSocketAllocated;
|
||||
// Bind the socket
|
||||
if BoundIP <> '' then begin
|
||||
LBinding.IP := BoundIP;
|
||||
end;
|
||||
LBinding.Port := BoundPort;
|
||||
LBinding.ClientPortMin := BoundPortMin;
|
||||
LBinding.ClientPortMax := BoundPortMax;
|
||||
LBinding.ReuseSocket := FReuseSocket;
|
||||
|
||||
// RLebeau 11/15/2014: Using the socket bind() function in a Mac OSX sandbox
|
||||
// causes the Apple store to reject an app with the following error if it
|
||||
// uses Indy client(s) and no Indy server(s):
|
||||
//
|
||||
// "This app uses one or more entitlements which do not have matching
|
||||
// functionality within the app. Apps should have only the minimum set of
|
||||
// entitlements necessary for the app to function properly. Please remove
|
||||
// all entitlements that are not needed by your app and submit an updated
|
||||
// binary for review, including the following:
|
||||
//
|
||||
// com.apple.security.network.server"
|
||||
//
|
||||
// Ideally, TIdSocketHandle.Bind() should not call TryBind() if the IP is
|
||||
// blank and the Port, ClientPortMin, and ClientPortMax are all 0. However,
|
||||
// TIdSocketHandle.Bind() is used for both clients and servers, and sometimes
|
||||
// a server needs to bind to port 0 to get a random ephemeral port, which it
|
||||
// can then report to clients. So lets do the check here instead, as this
|
||||
// method is only used for clients...
|
||||
|
||||
{$IFDEF DARWIN}
|
||||
// TODO: remove the DARWIN check and just skip the Bind() on all platforms?
|
||||
if (LBinding.IP <> '') or (LBinding.Port <> 0) or
|
||||
((LBinding.ClientPortMin <> 0) and (LBinding.ClientPortMax <> 0)) then
|
||||
begin
|
||||
LBinding.Bind;
|
||||
end;
|
||||
{$ELSE}
|
||||
LBinding.Bind;
|
||||
{$ENDIF}
|
||||
|
||||
// Turn off Nagle if specified
|
||||
LBinding.UseNagle := FUseNagle;
|
||||
DoAfterBind;
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.Connected: Boolean;
|
||||
begin
|
||||
Result := (BindingAllocated and inherited Connected) or (not InputBufferIsEmpty);
|
||||
end;
|
||||
|
||||
destructor TIdIOHandlerSocket.Destroy;
|
||||
begin
|
||||
SetTransparentProxy(nil);
|
||||
FreeAndNil(FBinding);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.DoBeforeBind;
|
||||
begin
|
||||
if Assigned(FOnBeforeBind) then begin
|
||||
FOnBeforeBind(self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.DoAfterBind;
|
||||
begin
|
||||
if Assigned(FOnAfterBind) then begin
|
||||
FOnAfterBind(self);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.DoSocketAllocated;
|
||||
begin
|
||||
if Assigned(FOnSocketAllocated) then begin
|
||||
FOnSocketAllocated(self);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.GetDestination: string;
|
||||
begin
|
||||
Result := Host;
|
||||
if (Port <> DefaultPort) and (Port > 0) then begin
|
||||
Result := Host + ':' + IntToStr(Port);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.Open;
|
||||
begin
|
||||
inherited Open;
|
||||
|
||||
if not Assigned(FBinding) then begin
|
||||
FBinding := TIdSocketHandle.Create(nil);
|
||||
end else begin
|
||||
FBinding.Reset(True);
|
||||
end;
|
||||
FBinding.ClientPortMin := BoundPortMin;
|
||||
FBinding.ClientPortMax := BoundPortMax;
|
||||
|
||||
//if the IOHandler is used to accept connections then port+host will be empty
|
||||
if (Host <> '') and (Port > 0) then begin
|
||||
ConnectClient;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.SetDestination(const AValue: string);
|
||||
var
|
||||
LPortStart: integer;
|
||||
begin
|
||||
// Bas Gooijen 06-Dec-2002: Changed to search the last ':', instead of the first:
|
||||
LPortStart := LastDelimiter(':', AValue);
|
||||
if LPortStart > 0 then begin
|
||||
Host := Copy(AValue, 1, LPortStart-1);
|
||||
Port := IndyStrToInt(Trim(Copy(AValue, LPortStart + 1, $FF)), DefaultPort);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.BindingAllocated: Boolean;
|
||||
begin
|
||||
Result := FBinding <> nil;
|
||||
if Result then begin
|
||||
Result := FBinding.HandleAllocated;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.WriteFile(const AFile: String;
|
||||
AEnableTransferFile: Boolean): Int64;
|
||||
{$IFDEF WIN32_OR_WIN64}
|
||||
var
|
||||
LOldErrorMode : Integer;
|
||||
{$ENDIF}
|
||||
begin
|
||||
Result := 0;
|
||||
{$IFDEF WIN32_OR_WIN64}
|
||||
LOldErrorMode := SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
try
|
||||
{$ENDIF}
|
||||
if FileExists(AFile) then begin
|
||||
if Assigned(GServeFileProc) and (not WriteBufferingActive)
|
||||
{and (Intercept = nil)} and AEnableTransferFile
|
||||
then begin
|
||||
Result := GServeFileProc(Binding.Handle, AFile);
|
||||
Exit;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result := inherited WriteFile(AFile, AEnableTransferFile);
|
||||
end;
|
||||
end;
|
||||
{$IFDEF WIN32_OR_WIN64}
|
||||
finally
|
||||
SetErrorMode(LOldErrorMode)
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.GetReuseSocket: TIdReuseSocket;
|
||||
begin
|
||||
if FBinding <> nil then begin
|
||||
Result := FBinding.ReuseSocket;
|
||||
end else begin
|
||||
Result := FReuseSocket;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.SetReuseSocket(AValue: TIdReuseSocket);
|
||||
begin
|
||||
FReuseSocket := AValue;
|
||||
if FBinding <> nil then begin
|
||||
FBinding.ReuseSocket := AValue;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.SetTransparentProxy(AProxy : TIdCustomTransparentProxy);
|
||||
var
|
||||
LClass: TIdCustomTransparentProxyClass;
|
||||
// under ARC, convert a weak reference to a strong reference before working with it
|
||||
LTransparentProxy: TIdCustomTransparentProxy;
|
||||
begin
|
||||
LTransparentProxy := FTransparentProxy;
|
||||
|
||||
if LTransparentProxy <> AProxy then
|
||||
begin
|
||||
// All this is to preserve the compatibility with old version
|
||||
// In the case when we have SocksInfo as object created in runtime without owner form it is treated as temporary object
|
||||
// In the case when the ASocks points to an object with owner it is treated as component on form.
|
||||
|
||||
// under ARC, all weak references to a freed object get nil'ed automatically
|
||||
|
||||
if Assigned(AProxy) then begin
|
||||
if not Assigned(AProxy.Owner) then begin
|
||||
if Assigned(LTransparentProxy) and (not FImplicitTransparentProxy) then begin
|
||||
FTransparentProxy := nil;
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
LTransparentProxy.RemoveFreeNotification(Self);
|
||||
{$ENDIF}
|
||||
end;
|
||||
LClass := TIdCustomTransparentProxyClass(AProxy.ClassType);
|
||||
if Assigned(LTransparentProxy) and (LTransparentProxy.ClassType <> LClass) then begin
|
||||
FTransparentProxy := nil;
|
||||
FImplicitTransparentProxy := False;
|
||||
IdDisposeAndNil(LTransparentProxy);
|
||||
end;
|
||||
if not Assigned(LTransparentProxy) then begin
|
||||
LTransparentProxy := LClass.Create(Self);
|
||||
FTransparentProxy := LTransparentProxy;
|
||||
FImplicitTransparentProxy := True;
|
||||
end;
|
||||
LTransparentProxy.Assign(AProxy);
|
||||
end else begin
|
||||
if Assigned(LTransparentProxy) then begin
|
||||
if FImplicitTransparentProxy then begin
|
||||
FTransparentProxy := nil;
|
||||
FImplicitTransparentProxy := False;
|
||||
IdDisposeAndNil(LTransparentProxy);
|
||||
end else begin
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
LTransparentProxy.RemoveFreeNotification(Self);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
FTransparentProxy := AProxy;
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
AProxy.FreeNotification(Self);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end
|
||||
else if Assigned(LTransparentProxy) then begin
|
||||
if FImplicitTransparentProxy then begin
|
||||
FTransparentProxy := nil;
|
||||
FImplicitTransparentProxy := False;
|
||||
IdDisposeAndNil(LTransparentProxy);
|
||||
end else begin
|
||||
FTransparentProxy := nil;
|
||||
{$IFNDEF USE_OBJECT_ARC}
|
||||
LTransparentProxy.RemoveFreeNotification(Self);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.GetTransparentProxy: TIdCustomTransparentProxy;
|
||||
var
|
||||
// under ARC, convert a weak reference to a strong reference before working with it
|
||||
LTransparentProxy: TIdCustomTransparentProxy;
|
||||
begin
|
||||
LTransparentProxy := FTransparentProxy;
|
||||
// Necessary at design time for Borland SOAP support
|
||||
if LTransparentProxy = nil then begin
|
||||
LTransparentProxy := TIdSocksInfo.Create(Self); //default
|
||||
FTransparentProxy := LTransparentProxy;
|
||||
FImplicitTransparentProxy := True;
|
||||
end;
|
||||
Result := LTransparentProxy;
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.GetUseNagle: Boolean;
|
||||
begin
|
||||
if FBinding <> nil then begin
|
||||
Result := FBinding.UseNagle;
|
||||
end else begin
|
||||
Result := FUseNagle;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.SetUseNagle(AValue: Boolean);
|
||||
begin
|
||||
FUseNagle := AValue;
|
||||
if FBinding <> nil then begin
|
||||
FBinding.UseNagle := AValue;
|
||||
end;
|
||||
end;
|
||||
|
||||
// under ARC, all weak references to a freed object get nil'ed automatically
|
||||
// so this is mostly redundant
|
||||
procedure TIdIOHandlerSocket.Notification(AComponent: TComponent; Operation: TOperation);
|
||||
begin
|
||||
if (Operation = opRemove) and (AComponent = FTransparentProxy) then begin
|
||||
FTransparentProxy := nil;
|
||||
FImplicitTransparentProxy := False;
|
||||
end;
|
||||
inherited Notification(AComponent, Operation);
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.InitComponent;
|
||||
begin
|
||||
inherited InitComponent;
|
||||
FUseNagle := True;
|
||||
FIPVersion := ID_DEFAULT_IP_VERSION;
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.SourceIsAvailable: Boolean;
|
||||
begin
|
||||
Result := BindingAllocated;
|
||||
end;
|
||||
|
||||
function TIdIOHandlerSocket.CheckForError(ALastResult: Integer): Integer;
|
||||
begin
|
||||
Result := GStack.CheckForSocketError(ALastResult, [Id_WSAESHUTDOWN, Id_WSAECONNABORTED, Id_WSAECONNRESET, Id_WSAETIMEDOUT]);
|
||||
end;
|
||||
|
||||
procedure TIdIOHandlerSocket.RaiseError(AError: Integer);
|
||||
begin
|
||||
GStack.RaiseSocketError(AError);
|
||||
end;
|
||||
|
||||
end.
|
||||
442
indy/Core/IdIOHandlerStack.pas
Normal file
@@ -0,0 +1,442 @@
|
||||
{
|
||||
$Project$
|
||||
$Workfile$
|
||||
$Revision$
|
||||
$DateUTC$
|
||||
$Id$
|
||||
|
||||
This file is part of the Indy (Internet Direct) project, and is offered
|
||||
under the dual-licensing agreement described on the Indy website.
|
||||
(http://www.indyproject.org/)
|
||||
|
||||
Copyright:
|
||||
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
|
||||
}
|
||||
{
|
||||
$Log$
|
||||
}
|
||||
{
|
||||
Rev 1.53 3/10/05 3:23:16 PM RLebeau
|
||||
Updated WriteDirect() to access the Intercept property directly.
|
||||
|
||||
Rev 1.52 11/12/2004 11:30:16 AM JPMugaas
|
||||
Expansions for IPv6.
|
||||
|
||||
Rev 1.51 11/11/04 12:03:46 PM RLebeau
|
||||
Updated DoConnectTimeout() to recognize IdTimeoutDefault
|
||||
|
||||
Rev 1.50 6/18/04 1:06:58 PM RLebeau
|
||||
Bug fix for ReadTimeout property
|
||||
|
||||
Rev 1.49 5/4/2004 9:57:34 AM JPMugaas
|
||||