从http://code.google.com/p/mmz-asio4delphi/的svn上下载最新的代码。因为其代码是在不支持Unicode的Delphi版本运行,所以主要修改三个地方。
1.char改成ansichar,string改成ansistring
2.MessageBoxA替换MessageBox
3.Sock:Integer修改成Sock:TSocket
下面是粘贴了主要修改的UntsocketDxBaseClient.pas文件
{*******************************************************}
{ 单元名: Un_socket_control.pas }
{ 创建日期:2008-7-7 23:18:37 }
{ 创建者 马敏钊 }
{ 功能: 通讯对象单元 }
{ }
{*******************************************************}
unit UntsocketDxBaseClient;
interface
uses classes,
Windows,
Winsock;
// ONLY ENABLE THIS - IF YOU LICENSED OUR TLS-EDITION OF DXSOCK
// IT IS NOT FREE - IT IS NOT INCLUDED WITH WWS - IT'S AS A LEGAL ISSUE!
//
{.$DEFINE TLS_EDITION}
{.$DEFINE SUPPORT_DESIGNTIME_CLIENTS}
// ONLY ENABLE THIS - IF YOU LICENSED OUR CODE TRACER SUITE
{.$DEFINE CODE_TRACER}
// custom feature for SMTP Sender -> SMTP Relay -> track session ID
{$DEFINE SMTP_SESSION_FEATURE}
// THESE CAN BE CHANGED BY YOU:
{.$DEFINE FINALBUILD}
{.$DEFINE OCX_ONLY}// not done - will be in DXSock 4.0
{.$DEFINE OBJECTS_ONLY}
{$DEFINE ASM8086}
// LANGUAGE FILE FOR ERROR MESSAGE TEXT
{$DEFINE ENGLISH1}
{.$DEFINE FRENCH1}
{.$DEFINE GERMAN1}
{.$DEFINE ITALIAN1}
{.$DEFINE LOWMEM1}
{.$DEFINE PORTUGUESE1}
{.$DEFINE RUSSIAN1}
{.$DEFINE SPANISH1}
{.$DEFINE TURKISH1}
{$IFDEF VER90}
{$DEFINE VER100}
{$ENDIF}
{$IFDEF VER105}
{$DEFINE VER100}
{$ENDIF}
{$IFDEF FINALBUILD}
{$ALIGN ON}
{$ASSERTIONS OFF}
{$DEBUGINFO OFF}
{$DEFINITIONINFO OFF}
{$DESCRIPTION 'Uses Brain Patchwork DX, LLC. DXSock 4.0.0'}
{$EXTENDEDSYNTAX ON}
{$HINTS ON}
{$IMAGEBASE $2112CAFE}
{$IMPORTEDDATA ON}
{$IOCHECKS ON}
{$LOCALSYMBOLS OFF}
{$LONGansistringS ON}
{$OBJEXPORTALL ON}
{$OPTIMIZATION ON}
{$OVERFLOWCHECKS OFF}
{$RANGECHECKS OFF}
{$REALCOMPATIBILITY OFF}
{$REFERENCEINFO OFF}
{$RUNONLY OFF}
{$STACKFRAMES OFF}
{$VARansistringCHECKS ON}
{$WARNINGS ON}
{$ENDIF}
// END OF FILE //
const
INVALID_SOCKET = Winsock.INVALID_SOCKET;
SO_KeepAlive = Winsock.SO_KEEPALIVE;
WSAENOBUFS = Winsock.WSAENOBUFS;
WSAETIMEDOUT = Winsock.WSAETIMEDOUT;
WSAECONNABORTED = Winsock.WSAECONNABORTED;
Socket_Error = Winsock.SOCKET_ERROR;
// 7-27:
WSAEWOULDBLOCK = Winsock.WSAEWOULDBLOCK;
// 6-27:
WSAECONNRESET = Winsock.WSAECONNRESET;
{$IFDEF VER100}
type
in_addr = TInAddr;
{$ENDIF}
type
TDXBlockSizeFlags = (
bsfZero, // special meaning for TLS!
bsfRealSmall,
bsfSmall, bsfNormal,
bsfBigger,
bsfBiggest,
bsfHUGE);
{$J+} // 4.0
const
TDXHugeSize = 8192 * 2; // 16kb CHUNKS
TDXXferTimeout: Word = 50000; // if data loss then set to 50000
TDXMaxSocketBuffer: Word = TDXHugeSize; // Winsock Buffer Size
PeekBufferSize: Byte = 250; // do not go over 250!
{$J-}
var
{$IFDEF LINUX}
SizeOfInt: Cardinal = 4; // optimize compiling
{$ELSE}
SizeOfInt: Integer = 4; // optimize compiling
{$ENDIF}
type
Str1 = AnsiString;
{$IFDEF LINUX}
type
DWord = LongWord;
TThreadPriority = (tpIdle, tpLowest, tpLower, tpNormal, tpHigher, tpHighest, pTimeCritical);
{$ELSE}
type
PInteger = Windows.PInteger;
DWORD = Windows.DWord;
{$ENDIF}
type
TDXDataDirection = (ddAboutToWrite, ddAfterRead, ddCleanRead, ddFreePointer);
TDXFilterCallBack = procedure(DataDirection: TDXDataDirection; const InData: Pointer; var OutData: Pointer; const
InSize: Integer; var OutSize: Integer; var Handled: Boolean; xClientThread: TThread) of object;
TDXBSArray = array[0..65500] of ansichar;
TDXBSArray2 = array[0..250] of ansichar;
{$IFDEF LINUX}
TSockAddrIn = Libc.TSockAddrin;
TTimeVal = Libc.TTimeVal;
TFDSet = Libc.TFDSet;
{$ELSE}
TSockAddrIn = Winsock.TSockAddrIn;
TTimeVal = Winsock.TTimeVal;
TFDSet = Winsock.TFDSet;
{$ENDIF}
PNewConnect = ^TNewConnect;
TNewConnect = record
Port: Integer;
UseNAGLE: Boolean;
UseUDP: Boolean;
UseBlocking: Boolean;
ipAddress: ansistring;
end;
PNewListen = ^TNewListen;
TNewListen = record
Port: Integer;
WinsockQueue: Integer;
UseNAGLE: Boolean;
UseUDP: Boolean;
UseBlocking: Boolean;
ConnectionLess: Boolean;
end;
PWinsockInfo = ^TWinsockInfo; // 2.3 changed array from 0.. to 1..
TWinsockInfo = record
Major_Version: Byte; {current version}
Minor_Version: Byte; {current version}
Highest_Major_Version: Byte; {available on disk}
Highest_Minor_Version: Byte; {available on disk}
Description: array[1..256] of ansichar; // C++ ansichar Description[256];
SystemStatus: array[1..128] of ansichar; // C++ ansichar Description[128];
MaxSockets: Word; // C++ Unsigned short MaxSockets;
MaxUDPDatagramSize: Word; // C++ Unsigned short MaxUDPDatagramSize;
VendorInfo: Pansichar; // C++ ansichar FAR * VendorInfo;
end;
const
ConstSizeofTSockAddrIn = 16;
type
TDXSock = class(Tobject) // RC2
private
{$IFDEF CODE_TRACER}
CodeTracer: TDXCodeTracer;
{$ENDIF}
{$IFDEF TLS_EDITION}
tBuf: TBrkApart;
tStack: TMJBLIFO;
Straggler: ansistring;
{$ENDIF}
FClientThread: TThread;
FTLS: Boolean;
fChunkBuf: Pointer;
fbClientMode: Boolean;
fbIsUDP: Boolean;
fbIsKeepAlive: Boolean;
FsBindTo: ansistring;
FPeekBuffer: ^TDXBSArray2;
FReadTimeout: Boolean;
FUseBlocking: Boolean;
FBlockSizeFlags: TDXBlockSizeFlags;
FActualBlockSize: Integer;
FErrStatus: Integer;
fTooManyansicharacters: Integer;
feOnFilter: TDXFilterCallBack;
{$IFDEF TLS_EDITION}
feOnReadFilter: TDXFilterCallBack;
{$ENDIF}
GlobalPeerPort: Integer;
GlobalPeerIPAddress: ansistring;
// GlobalTimeout:TTimeVal;
VarConstSizeofTSockAddrIn: Integer;
// new 4.0 features
fTotalWBytes: Cardinal;
fTotalRBytes: Cardinal;
fCPSStart: TDateTime;
protected
function GetReleaseDate: ansistring;
procedure SetReleaseDate(value: ansistring);
function GetMyLocalPort: Integer;
function GetMyLocalIPAddr: ansistring;
function IsConnected: Boolean;
function IsValidSocket: Boolean;
function IsReadable: Boolean;
function IsWritable: Boolean;
function DidReadTimeout: Boolean;
procedure SetfBlockSizeFlags(Value: TDXBlockSizeFlags);
function CountmyWaiting: Integer;
public
SockAddr: TSockAddrIn;
{$IFDEF LINUX}
Sock: TFileDescriptor;
{$ELSE}
Sock: TSocket;
{$ENDIF}
{$IFNDEF OBJECTS_ONLY}
{$ENDIF}
constructor Create;
destructor Destroy; override;
function Connect(Parameters: PNewConnect): Boolean;
function Listen(Parameters: PNewListen): Boolean;
function Accept(var NewSock: TDXSock): Boolean;
procedure CloseGracefully;
procedure Disconnect; // Borland Friendly
procedure CloseNow;
function SendBuf(const Buf; Count: Integer): Integer; // Borland friendly
function ReceiveBuf(var Buf; Count: Integer): Integer; // Borland friendly
function Readbuffer(iBuf: pointer; Count: Integer): Integer; // Borland friendly
function CloseConn: Boolean;
function IsConning: Boolean;
function Writeansistring(const s: ansistring): Integer;
{$IFDEF VER100}
function BlockWrite(buf: Pointer; len: Integer): Integer;
function WriteCh(c: ansichar): Integer;
function Write(const s: ansistring): Integer;
{$ELSE}
function Write(c: ansichar): Integer; overload;
function Write(const s: ansistring): Integer; overload;
function Write(buf: Pointer; len: Integer): Integer; overload;
{$ENDIF}
function WriteLn(const s: ansistring): Integer;
function WriteResultCode(const Code: Integer; const Rslt: ansistring): Integer;
function WriteWithSize(S: ansistring): Boolean;
function WriteInteger(const n: integer): integer;
{$IFDEF VER100}
function SendFromStreamRange(Stream: TStream; Range: Integer): Boolean;
function SendFromStream(Stream: TStream): Boolean;
function SendFromWindowsFile(var Handle: Integer): boolean;
function SendFromBorlandFile(var Handle: file): boolean;
{$ELSE}
function SendFrom(Stream: TStream; Range: Integer): Boolean; overload;
function SendFrom(Stream: TStream): Boolean; overload;
function SendFrom(var Handle: Integer): boolean; overload;
function SendFrom(var Handle: file): boolean; overload;
{$ENDIF}
function SendFromStreamWithSize(Stream: TStream): Boolean;
{$IFDEF VER100}
function BlockRead(buf: Pointer; len: Integer): Integer;
function Read: ansichar;
{$ELSE}
function Read(buf: Pointer; len: Integer): Integer; overload;
function Read: ansichar; overload;
{$ENDIF}
function ReadInteger: integer;
function ReadStr(MaxLength: Integer): ansistring;
function Readansistring(MaxLength: Integer; iTimeout: Longword): ansistring;
function ReadLn(iTimeout: Longword = 100000): ansistring;
function ReadCRLF(iTimeout: Longword): ansistring;
function ReadToAnyDelimiter(iTimeout: Longword; Delimiter: ansistring): ansistring;
function ReadNull(Timeout: Longword): ansistring;
function ReadSpace(Timeout: Longword): ansistring;
function ReadWithSize: ansistring;
{$IFDEF VER100}
function SaveToStream(Stream: TStream; Timeout: Longword): Boolean;
function SaveToWindowsFile(var Handle: Integer; Timeout: Longword): boolean;
function SaveToBorlandFile(var Handle: file; Timeout: Longword): boolean;
{$ELSE}
function SaveTo(Stream: TStream; iTimeout: Longword): Boolean; overload;
function SaveTo(var Handle: Integer; iTimeout: Longword): boolean; overload;
function SaveTo(var Handle: file; iTimeout: Longword): boolean; overload;
{$ENDIF}
function SaveToStreamWithSize(Stream: TStream; iTimeout: Longword): Boolean;
function Getansichar: Str1;
function GetByte: Byte;
function FilterRead(const InBuf: Pointer; var OutBuf: Pointer; InSize: Integer; xClientThread: TThread): Integer;
function Peekansistring: ansistring;
function Peekansichar: ansichar;
function GetErrorStr: ansistring;
function GetMyErrorDesc(errorCode: Integer): ansistring;
procedure SetbNagle(TurnOn: Boolean);
procedure SetbBlocking(TurnOn: Boolean);
procedure WinsockVersion(var WinsockInfo: PWinsockInfo);
// made public for new TDXSockClient:
procedure SockClientSetGlobal(I: ansistring; P: Integer);
procedure SetTimeoutAndBuffer(SocketHandle: Integer);
// new 3.0 features:
function DroppedConnection: Boolean;
function WaitForData(itimeout: Longint): Boolean;
// new 4.0 features:
procedure RestartansicharactersPerSecondTimer;
function ansicharactersPerSecondWritten: Integer;
function ansicharactersPerSecondReceived: Integer;
published
property TLSActive: Boolean read FTLS write FTLS;
property TLSClientThread: TThread read FClientThread write FClientThread;
property BindTo: ansistring read fsBindTo
write fsBindTo;
property Connected: Boolean read IsConnected;
property ansicharactersToRead: Integer read CountmyWaiting;
property ReceiveLength: Integer read CountmyWaiting; // Borland Friendly
property ValidSocket: Boolean read IsValidSocket;
property LastReadTimeout: Boolean read DidReadTimeout;
property LastCommandStatus: Integer read FErrStatus write FErrStatus;
property OutputBufferSize: TDXBlockSizeFlags read fBlockSizeFlags
write SetfBlockSizeFlags;
property TooManyansicharacters: Integer read fTooManyansicharacters
write fTooManyansicharacters;
property IsUDPMode: Boolean read fbIsUDP
write fbIsUDP;
property IsKeepAliveMode: Boolean read fbIsKeepAlive write fbIsKeepAlive;
property PeerIPAddress: ansistring read GlobalPeerIPAddress
write GlobalPeerIPAddress;
property PeerPort: Integer read GlobalPeerPort
write GlobalPeerPort;
property LocalIPAddress: ansistring read GetMyLocalIPAddr;
property LocalPort: Integer read GetMyLocalPort;
property Readable: Boolean read IsReadable;
property Writable: Boolean read IsWritable;
property ReleaseDate: ansistring read GetReleaseDate
write SetReleaseDate;
property OnFilter: TDXFilterCallBack read feOnFilter
write feOnFilter;
{$IFDEF CODE_TRACER}
property DXCodeTracer: TDXCodeTracer read CodeTracer
write CodeTracer;
{$ENDIF}
{$IFDEF TLS_EDITION}
property OnReadFilter: TDXFilterCallBack read feOnReadFilter
write feOnReadFilter;
{$ENDIF}
end;
//客户端对象
TAsioClient = class(TDXSock)
private
public
FHost, Facc, Fpsd: ansistring;
FPort: Word;
Socket: TAsioClient;
constructor Create;
destructor Destroy; override;
function GetCanUseSize: integer;
procedure SetConnParam(Ihost: ansistring; Iport: word);
procedure SendAsioHead(Ilen: integer);
procedure WriteBuff(var obj; Ilen: integer);
procedure WriteStream(Istream: TStream);
function Getipandport(IConn: TAsioClient): ansistring;
function GetHead: Integer; //读取报头
procedure SendHead(ICmd: Integer); //发送报头
procedure SendObject(IObj: TObject); //发送对象
procedure GetObject(IObj: TObject; IClass: TClass); overload;
//接收对象 自己根据类之类来创建对象
procedure GetObject(IObj: TObject); overload;
//由外部代入已经创建好的对象
procedure SendZipFile(IFileName: ansistring); //发送压缩文件
function GetZipFile(IFileName: ansistring): Integer; //接收压缩文件 //MMWIN:MEMBERSCOPY
function GetZipStream(IStream: TStream; IConn: TAsioClient): integer;
function GetStream(IStream: TStream; IConn: TAsioClient): integer;
function SendZIpStream(IStream: tStream; IConn: TAsioClient;
IisEnc: boolean = false): Integer;
//连接
function Connto(IIP: ansistring; Iport: Word): boolean;
procedure OnCreate; virtual; abstract;
procedure OnDestory; virtual; abstract;
end;
var
GSocketClient: TAsioClient;
implementation
uses
SysUtils, untfunctions, Math, Types, Messages, Dialogs;
//public fun
var
{$IFNDEF LINUX}
DLLData: TWSAData;
{$ENDIF}
StartupResult: Integer;
var
GlobalTimeout: TTimeVal; //6-9
const
_WSAEINTR = 'Interrupted system call'; // 10004 L:4
_WSAEBADF = 'Bad file number'; // 10009 L:9
_WSAEACCES = 'Permission denied'; // 10013 L:13
_WSAEFAULT = 'Bad address'; // 10014 L:14
_WSAEINVAL = 'Invalid argument'; // 10022 L:22
_WSAEMFILE = 'Too many open files'; // 10024 L:24
_WSAEWOULDBLOCK = 'Operation would block'; // 10035 L:11 (?L:35?)
_WSAEINPROGRESS = 'Operation now in progress'; // 10036 L:115
_WSAEALREADY = 'Operation already in progress'; // 10037 L:114
_WSAENOTSOCK = 'Socket operation on non-socket'; // 10038 L:88
_WSAEDESTADDRREQ = 'Destination address required'; // 10039 L:89
_WSAEMSGSIZE = 'Message too long'; // 10040 L:90
_WSAEPROTOTYPE = 'Protocol wrong type for socket'; // 10041 L:91
_WSAENOPROTOOPT = 'Protocol not available'; // 10042 L:92
_WSAEPROTONOSUPPORT = 'Protocol not supported'; // 10043 L:93
_WSAESOCKTNOSUPPORT = 'Socket type not supported'; // 10044 L:94
_WSAEOPNOTSUPP = 'Operation not supported on socket'; // 10045 L:95
_WSAEPFNOSUPPORT = 'Protocol family not supported'; // 10046 L:96
_WSAEAFNOSUPPORT = 'Address family not supported by protocol family'; // 10047 L:97
_WSAEADDRINUSE = 'Address already in use'; // 10048 L:98
_WSAEADDRNOTAVAIL = 'Can''t assign requested address'; // 10049 L:99
_WSAENETDOWN = 'Network is down'; // 10050 L:100
_WSAENETUNREACH = 'Network is unreachable'; // 10051 L:101
_WSAENETRESET = 'Network dropped connection on reset'; // 10052 L:102
_WSAECONNABORTED = 'Software caused connection abort'; // 10053 L:103
_WSAECONNRESET = 'Connection reset by peer'; // 10054 L:104
_WSAENOBUFS = 'No buffer space available'; // 10055 L:105
_WSAEISCONN = 'Socket is already connected'; // 10056 L:106
_WSAENOTCONN = 'Socket is not connected'; // 10057 L:107
_WSAESHUTDOWN = 'Can''t send after socket shutdown'; // 10058 L:108
_WSAETOOMANYREFS = 'Too many references can''t splice'; // 10059 L:109
_WSAETIMEDOUT = 'Connection timed out'; // 10060 L:110
_WSAECONNREFUSED = 'Connection refused'; // 10061 L:111
_WSAELOOP = 'Too many levels of symbolic links'; // 10062 L:40
_WSAENAMETOOLONG = 'File name too long'; // 10063 L:36
_WSAEHOSTDOWN = 'Host is down'; // 10064 L:112
_WSAEHOSTUNREACH = 'No route to host'; // 10065 L:113
_WSAENOTEMPTY = 'Directory not empty'; // 10066 L:39
_WSAEPROCLIM = 'Too many processes'; // 10067
_WSAEUSERS = 'Too many users'; // 10068 L:87
_WSAEDQUOT = 'Disk quota exceeded'; // 10069 L:122
_WSAESTALE = 'Stale NFS file handle'; // 10070 L:116
_WSAEREMOTE = 'Too many levels of remote in path'; // 10071 L:66
_WSASYSNOTREADY = 'Network sub-system is unusable'; // 10091
_WSAVERNOTSUPPORTED = 'WSOCK32.DLL DLL cannot support this application'; // 10092
_WSANOTINITIALISED = 'WSOCK32.DLL not initialized'; // 10093
_WSAHOST_NOT_FOUND = 'Host not found'; // 11001 L:1
_WSATRY_AGAIN = 'Non-authoritative host not found'; // 11002 L:2
_WSANO_RECOVERY = 'Non-recoverable error'; // 11003 L:3
_WSANO_DATA = 'No Data'; // 11004 L:4
_WSAUNKNOWN = 'Unknown Socket Error';
const
Alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
AlphabetLength = 64;
{$IFDEF VER100}
TIME_ZONE_ID_STANDARD = 1;
TIME_ZONE_ID_DAYLIGHT = 2;
{$ENDIF}
{$IFNDEF VER90}
ole32 = 'ole32.dll';
{$ENDIF}
crc_32_tab: array[0..255] of LONGINT = (
$00000000, $77073096, $EE0E612C, $990951BA, $076DC419, $706AF48F, $E963A535, $9E6495A3,
$0EDB8832, $79DCB8A4, $E0D5E91E, $97D2D988, $09B64C2B, $7EB17CBD, $E7B82D07, $90BF1D91,
$1DB71064, $6AB020F2, $F3B97148, $84BE41DE, $1ADAD47D, $6DDDE4EB, $F4D4B551, $83D385C7,
$136C9856, $646BA8C0, $FD62F97A, $8A65C9EC, $14015C4F, $63066CD9, $FA0F3D63, $8D080DF5,
$3B6E20C8, $4C69105E, $D56041E4, $A2677172, $3C03E4D1, $4B04D447, $D20D85FD, $A50AB56B,
$35B5A8FA, $42B2986C, $DBBBC9D6, $ACBCF940, $32D86CE3, $45DF5C75, $DCD60DCF, $ABD13D59,
$26D930AC, $51DE003A, $C8D75180, $BFD06116, $21B4F4B5, $56B3C423, $CFBA9599, $B8BDA50F,
$2802B89E, $5F058808, $C60CD9B2, $B10BE924, $2F6F7C87, $58684C11, $C1611DAB, $B6662D3D,
$76DC4190, $01DB7106, $98D220BC, $EFD5102A, $71B18589, $06B6B51F, $9FBFE4A5, $E8B8D433,
$7807C9A2, $0F00F934, $9609A88E, $E10E9818, $7F6A0DBB, $086D3D2D, $91646C97, $E6635C01,
$6B6B51F4, $1C6C6162, $856530D8, $F262004E, $6C0695ED, $1B01A57B, $8208F4C1, $F50FC457,
$65B0D9C6, $12B7E950, $8BBEB8EA, $FCB9887C, $62DD1DDF, $15DA2D49, $8CD37CF3, $FBD44C65,
$4DB26158, $3AB551CE, $A3BC0074, $D4BB30E2, $4ADFA541, $3DD895D7, $A4D1C46D, $D3D6F4FB,
$4369E96A, $346ED9FC, $AD678846, $DA60B8D0, $44042D73, $33031DE5, $AA0A4C5F, $DD0D7CC9,
$5005713C, $270241AA, $BE0B1010, $C90C2086, $5768B525, $206F85B3, $B966D409, $CE61E49F,
$5EDEF90E, $29D9C998, $B0D09822, $C7D7A8B4, $59B33D17, $2EB40D81, $B7BD5C3B, $C0BA6CAD,
$EDB88320, $9ABFB3B6, $03B6E20C, $74B1D29A, $EAD54739, $9DD277AF, $04DB2615, $73DC1683,
$E3630B12, $94643B84, $0D6D6A3E, $7A6A5AA8, $E40ECF0B, $9309FF9D, $0A00AE27, $7D079EB1,
$F00F9344, $8708A3D2, $1E01F268, $6906C2FE, $F762575D, $806567CB, $196C3671, $6E6B06E7,
$FED41B76, $89D32BE0, $10DA7A5A, $67DD4ACC, $F9B9DF6F, $8EBEEFF9, $17B7BE43, $60B08ED5,
$D6D6A3E8, $A1D1937E, $38D8C2C4, $4FDFF252, $D1BB67F1, $A6BC5767, $3FB506DD, $48B2364B,
$D80D2BDA, $AF0A1B4C, $36034AF6, $41047A60, $DF60EFC3, $A867DF55, $316E8EEF, $4669BE79,
$CB61B38C, $BC66831A, $256FD2A0, $5268E236, $CC0C7795, $BB0B4703, $220216B9, $5505262F,
$C5BA3BBE, $B2BD0B28, $2BB45A92, $5CB36A04, $C2D7FFA7, $B5D0CF31, $2CD99E8B, $5BDEAE1D,
$9B64C2B0, $EC63F226, $756AA39C, $026D930A, $9C0906A9, $EB0E363F, $72076785, $05005713,
$95BF4A82, $E2B87A14, $7BB12BAE, $0CB61B38, $92D28E9B, $E5D5BE0D, $7CDCEFB7, $0BDBDF21,
$86D3D2D4, $F1D4E242, $68DDB3F8, $1FDA836E, $81BE16CD, $F6B9265B, $6FB077E1, $18B74777,
$88085AE6, $FF0F6A70, $66063BCA, $11010B5C, $8F659EFF, $F862AE69, $616BFFD3, $166CCF45,
$A00AE278, $D70DD2EE, $4E048354, $3903B3C2, $A7672661, $D06016F7, $4969474D, $3E6E77DB,
$AED16A4A, $D9D65ADC, $40DF0B66, $37D83BF0, $A9BCAE53, $DEBB9EC5, $47B2CF7F, $30B5FFE9,
$BDBDF21C, $CABAC28A, $53B39330, $24B4A3A6, $BAD03605, $CDD70693, $54DE5729, $23D967BF,
$B3667A2E, $C4614AB8, $5D681B02, $2A6F2B94, $B40BBE37, $C30C8EA1, $5A05DF1B, $2D02EF8D);
crc_arc_tab: array[0..$FF] of Word =
($00000, $0C0C1, $0C181, $00140, $0C301, $003C0, $00280, $0C241,
$0C601, $006C0, $00780, $0C741, $00500, $0C5C1, $0C481, $00440,
$0CC01, $00CC0, $00D80, $0CD41, $00F00, $0CFC1, $0CE81, $00E40,
$00A00, $0CAC1, $0CB81, $00B40, $0C901, $009C0, $00880, $0C841,
$0D801, $018C0, $01980, $0D941, $01B00, $0DBC1, $0DA81, $01A40,
$01E00, $0DEC1, $0DF81, $01F40, $0DD01, $01DC0, $01C80, $0DC41,
$01400, $0D4C1, $0D581, $01540, $0D701, $017C0, $01680, $0D641,
$0D201, $012C0, $01380, $0D341, $01100, $0D1C1, $0D081, $01040,
$0F001, $030C0, $03180, $0F141, $03300, $0F3C1, $0F281, $03240,
$03600, $0F6C1, $0F781, $03740, $0F501, $035C0, $03480, $0F441,
$03C00, $0FCC1, $0FD81, $03D40, $0FF01, $03FC0, $03E80, $0FE41,
$0FA01, $03AC0, $03B80, $0FB41, $03900, $0F9C1, $0F881, $03840,
$02800, $0E8C1, $0E981, $02940, $0EB01, $02BC0, $02A80, $0EA41,
$0EE01, $02EC0, $02F80, $0EF41, $02D00, $0EDC1, $0EC81, $02C40,
$0E401, $024C0, $02580, $0E541, $02700, $0E7C1, $0E681, $02640,
$02200, $0E2C1, $0E381, $02340, $0E101, $021C0, $02080, $0E041,
$0A001, $060C0, $06180, $0A141, $06300, $0A3C1, $0A281, $06240,
$06600, $0A6C1, $0A781, $06740, $0A501, $065C0, $06480, $0A441,
$06C00, $0ACC1, $0AD81, $06D40, $0AF01, $06FC0, $06E80, $0AE41,
$0AA01, $06AC0, $06B80, $0AB41, $06900, $0A9C1, $0A881, $06840,
$07800, $0B8C1, $0B981, $07940, $0BB01, $07BC0, $07A80, $0BA41,
$0BE01, $07EC0, $07F80, $0BF41, $07D00, $0BDC1, $0BC81, $07C40,
$0B401, $074C0, $07580, $0B541, $07700, $0B7C1, $0B681, $07640,
$07200, $0B2C1, $0B381, $07340, $0B101, $071C0, $07080, $0B041,
$05000, $090C1, $09181, $05140, $09301, $053C0, $05280, $09241,
$09601, $056C0, $05780, $09741, $05500, $095C1, $09481, $05440,
$09C01, $05CC0, $05D80, $09D41, $05F00, $09FC1, $09E81, $05E40,
$05A00, $09AC1, $09B81, $05B40, $09901, $059C0, $05880, $09841,
$08801, $048C0, $04980, $08941, $04B00, $08BC1, $08A81, $04A40,
$04E00, $08EC1, $08F81, $04F40, $08D01, $04DC0, $04C80, $08C41,
$04400, $084C1, $08581, $04540, $08701, $047C0, $04680, $08641,
$08201, $042C0, $04380, $08341, $04100, $081C1, $08081, $04040);
crc_16_tab: array[0..$FF] of Word =
($00000, $01021, $02042, $03063, $04084, $050A5, $060C6, $070E7,
$08108, $09129, $0A14A, $0B16B, $0C18C, $0D1AD, $0E1CE, $0F1EF,
$01231, $00210, $03273, $02252, $052B5, $04294, $072F7, $062D6,
$09339, $08318, $0B37B, $0A35A, $0D3BD, $0C39C, $0F3FF, $0E3DE,
$02462, $03443, $00420, $01401, $064E6, $074C7, $044A4, $05485,
$0A56A, $0B54B, $08528, $09509, $0E5EE, $0F5CF, $0C5AC, $0D58D,
$03653, $02672, $01611, $00630, $076D7, $066F6, $05695, $046B4,
$0B75B, $0A77A, $09719, $08738, $0F7DF, $0E7FE, $0D79D, $0C7BC,
$048C4, $058E5, $06886, $078A7, $00840, $01861, $02802, $03823,
$0C9CC, $0D9ED, $0E98E, $0F9AF, $08948, $09969, $0A90A, $0B92B,
$05AF5, $04AD4, $07AB7, $06A96, $01A71, $00A50, $03A33, $02A12,
$0DBFD, $0CBDC, $0FBBF, $0EB9E, $09B79, $08B58, $0BB3B, $0AB1A,
$06CA6, $07C87, $04CE4, $05CC5, $02C22, $03C03, $00C60, $01C41,
$0EDAE, $0FD8F, $0CDEC, $0DDCD, $0AD2A, $0BD0B, $08D68, $09D49,
$07E97, $06EB6, $05ED5, $04EF4, $03E13, $02E32, $01E51, $00E70,
$0FF9F, $0EFBE, $0DFDD, $0CFFC, $0BF1B, $0AF3A, $09F59, $08F78,
$09188, $081A9, $0B1CA, $0A1EB, $0D10C, $0C12D, $0F14E, $0E16F,
$01080, $000A1, $030C2, $020E3, $05004, $04025, $07046, $06067,
$083B9, $09398, $0A3FB, $0B3DA, $0C33D, $0D31C, $0E37F, $0F35E,
$002B1, $01290, $022F3, $032D2, $04235, $05214, $06277, $07256,
$0B5EA, $0A5CB, $095A8, $08589, $0F56E, $0E54F, $0D52C, $0C50D,
$034E2, $024C3, $014A0, $00481, $07466, $06447, $05424, $04405,
$0A7DB, $0B7FA, $08799, $097B8, $0E75F, $0F77E, $0C71D, $0D73C,
$026D3, $036F2, $00691, $016B0, $06657, $07676, $04615, $05634,
$0D94C, $0C96D, $0F90E, $0E92F, $099C8, $089E9, $0B98A, $0A9AB,
$05844, $04865, $07806, $06827, $018C0, $008E1, $03882, $028A3,
$0CB7D, $0DB5C, $0EB3F, $0FB1E, $08BF9, $09BD8, $0ABBB, $0BB9A,
$04A75, $05A54, $06A37, $07A16, $00AF1, $01AD0, $02AB3, $03A92,
$0FD2E, $0ED0F, $0DD6C, $0CD4D, $0BDAA, $0AD8B, $09DE8, $08DC9,
$07C26, $06C07, $05C64, $04C45, $03CA2, $02C83, $01CE0, $00CC1,
$0EF1F, $0FF3E, $0CF5D, $0DF7C, $0AF9B, $0BFBA, $08FD9, $09FF8,
$06E17, $07E36, $04E55, $05E74, $02E93, $03EB2, $00ED1, $01EF0);
///
// Internal Version Control Routines (used for DCU's mainly)
///
///
// Windows/Operating System Routines
///
procedure ProcessWindowsMessageQueue;
{$IFDEF LINUX}
begin
Application.ProcessMessages;
end;
{$ELSE}
var
MsgRec: TMsg;
begin
if not IsConsole then
while PeekMessage(MsgRec, 0, 0, 0, PM_REMOVE) do begin
TranslateMessage(MsgRec);
DispatchMessage(MsgRec)
end;
end;
{$ENDIF}
function HiByteOfWord(const W: Word): Byte;
begin
Result := Hi(W);
end;
procedure UNPACKTIME(const P: LONGINT; var DT: TDATETIME);
begin
DT := FILEDATETODATETIME(P);
end;
procedure PACKTIME(var DT: TDATETIME; var P: LONGINT);
begin
P := DATETIMETOFILEDATE(DT);
end;
function GetDosDate: LongInt;
begin
Result := DATETIMETOFILEDATE(Now);
end;
function GetDOW: Word;
begin
Result := DayOfWeek(Now);
end;
function TimeCounter: Comp;
begin
Result := TimeStampToMSecs(DateTimeToTimeStamp(Now));
end;
function TimeOut(const MyTime: Comp): Boolean;
begin
Result := MyTime <= TimeCounter;
end;
function AddBackSlash(const S: ansistring): ansistring;
begin
Result := S;
if Copy(Result, Length(Result), 1) <> '\' then Result := Result + '\';
end;
function NoBackSlash(const S: ansistring): ansistring;
var
I: Integer;
begin
Result := S;
I := Length(S);
if I > 0 then
if Result[I] = '\' then Delete(Result, Length(Result), 1);
end;
function MakeBytesToWord(const A, B: Byte): Word;
begin
Result := (A shl 8) + B;
end;
function WindowsWriteFile(hFile: THandle; const Buffer; nNumberOfBytesToWrite: DWORD;
var lpNumberOfBytesWritten: DWORD): Boolean;
begin
{$IFDEF LINUX}
lpNumberOfBytesWritten := FileWrite(hFile, Buffer, nNumberOfBytesToWrite);
Result := lpNumberOfBytesWritten = nNumberOfBytesToWrite;
{$ELSE}
Result := WriteFile(hFile, Buffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, nil);
{$ENDIF}
end;
procedure ShowMessageWindow(const Caption, Message: ansistring);
begin
{$IFDEF LINUX}
MessageDlg(Caption, Message, mtError, [mbOk], 0);
{$ELSE}
MessageBoxA(0, Pansichar(Message), Pansichar(Caption), MB_ICONEXCLAMATION or MB_SYSTEMMODAL);
{$ENDIF}
end;
procedure DoSleepEX(const Interval: DWord);
begin
{$IFDEF LINUX}
Sleep(Interval);
{$ELSE}
SleepEx(Interval, False {True});
{$ENDIF}
end;
{$IFDEF LINUX}
function CoCreateGuid(var GUID: TGUID): HResult;
begin
Result := CreateGUID(GUID);
end;
{$ENDIF}
///
// Numeric Routines
///
function IsansicharAlphaNumeric(const C: ansichar): Boolean;
begin
{$IFNDEF ASM8086}
Result := C in ['0'..'9', 'A'..'Z', 'a'..'z'];
{$ELSE}
asm
mov AL,C
cmp AL, $30 // 0
jl @NoMatch // it's before '0' so Result=False/Exit
cmp AL, $7A // z
jg @NoMatch // it's after 'z' so Result=False/Exit
cmp AL, $39 // 9
jg @TryAlpha // it's after '9' so see if it is Alpha now
jmp @Matched // it's 0..9 so Result=True/Exit
@TryAlpha:
cmp AL, $41 // A
jl @NoMatch // it's before 'A' so Result=False/Exit
cmp AL, $5A // Z
jg @TryLower // it's after 'Z' so see if it is lowecase Alpha
jmp @Matched // it's 'A'..'Z' so Result=True/Exit
@TryLower:
cmp AL, $61 // a
jl @NoMatch // it's before 'a' so Result=False/Exit
jmp @Matched // it's 'a'..'z' so Result=True/Exit
@NoMatch:
mov Result,0
jmp @TheEnd
@Matched:
mov Result,1
@TheEnd:
end{asm}
{$ENDIF}
end;
function IsansicharAlpha(const c: ansichar): Boolean;
begin
{$IFNDEF ASM8086}
Result := C in ['A'..'Z', 'a'..'z'];
{$ELSE}
asm
mov AL,C
cmp AL, $41 // A
jl @NoMatch // it's before 'A' so Result=False/Exit
cmp AL, $7A // z
jg @NoMatch // it's after 'z' so Result=False/Exit
cmp AL, $5A // Z
jg @TryLower // it's after 'Z' so see if it is lower now
jmp @Matched // it's A..Z so Result=True/Exit
@TryLower:
cmp AL, $61 // a
jl @NoMatch // it's before 'a' so Result=False/Exit
jmp @Matched // it's 'a'..'z' so Result=True/Exit
@NoMatch:
mov Result,0
jmp @TheEnd
@Matched:
mov Result,1
@TheEnd:
end{asm}
{$ENDIF}
end;
function IsNumeric(const c: ansichar): Boolean;
begin
{$IFNDEF ASM8086}
Result := IsansicharAlphaNumeric(c) and not IsansicharAlpha(c);
{$ELSE}
asm
mov AL,C
cmp AL, $30 // 0
jl @NoMatch // it's before '0' so Result=False/Exit
cmp AL, $39 // 9
jg @NoMatch // it's after '9' so Result=False/Exit
jmp @Matched // it's 0..9 so Result=True/Exit
@NoMatch:
mov Result,0
jmp @TheEnd
@Matched:
mov Result,1
@TheEnd:
end{asm}
{$ENDIF}
end;
function isNumericansistring(const S: ansistring): Boolean;
var
Loop, MaxLoop: Integer;
begin
Result := True;
MaxLoop := Length(S);
Loop := 0;
while (Loop < MaxLoop) and (Result) do begin
if S[Loop + 1] <> '.' then
Result := IsNumeric(S[Loop + 1]);
Inc(Loop);
end;
end;
function Min(const I1, I2: Integer): Integer;
begin
{$IFNDEF ASM8086}
if I1 < I2 then
Result := I1
else
Result := I2;
{$ELSE}
Result := I1;
asm
mov ECX, I2 // Store I2 in ECX
mov EDX, I1 // Store I1 in EDX
cmp EDX, ECX // compare I2 to I1
jl @TheEnd // if I2
mov Result,ECX // result=I2/Exit
@TheEnd:
end; {asm}
{$ENDIF}
end;
function Max(const I1, I2: Integer): Integer;
begin
{$IFNDEF ASM8086}
if I1 > I2 then
Result := I1
else
Result := I2;
{$ELSE}
Result := I1;
asm
mov ECX, I2 // Store I2 in ECX
mov EDX, I1 // Store I1 in EDX
cmp EDX, ECX // compare I2 to I1
jg @TheEnd // if I2>I1 then Exit {result already set}
@ItIsLess:
mov Result,ECX // result=I2/Exit
@TheEnd:
end; {asm}
{$ENDIF}
end;
function ansistringToInteger(const S: ansistring): Integer;
var
E: Integer;
begin
Val(S, Result, E);
end;
procedure SwapMove(Source: Word; var Dest);
begin
Source := (HI(Source)) + (LO(Source) * 256);
Move(Source, Dest, 2);
end;
function IntToCommaStr(const Number: Integer): ansistring;
var
StrPos: Integer;
begin
Result := IntToStr(Number);
StrPos := Length(Result) - 2;
while StrPos > 1 do begin
Insert(',', Result, StrPos);
StrPos := StrPos - 3;
end;
end;
function BinaryToansistring(const Number: Byte): ansistring;
var
Temp2: Byte;
i: Word;
begin
Setlength(Result, 8);
Fillchar(Result[1], 8, '0');
Temp2 := $80;
for i := 1 to 8 do begin
if (Number and Temp2) <> 0 then Result[i] := '1';
Temp2 := Temp2 shr 1;
end;
end;
function ansistringToBinary(S: ansistring): Byte;
var
i: Word;
Temp1: Byte;
Temp2: Byte;
begin
S := Trim(S);
while Length(S) < 8 do
S := '0' + S;
Temp1 := 0;
Temp2 := $80;
for i := 1 to 8 do begin
if S[i] = '1' then Inc(Temp1, Temp2);
Temp2 := Temp2 shr 1;
end;
Result := Temp1;
end;
//==============================================================================
type
ansicharSet = set of ansichar;
function Center(S: ansistring; MaxWidth: Integer): ansistring;
var
I: Integer;
Ws: ansistring;
begin
if Length(S) mod 2 = 0 then
Result := S
else
Result := S + #32;
if Length(Result) >= MaxWidth then Exit;
I := MaxWidth - Length(Result);
if I mod 2 <> 0 then begin
Result := Result + #32;
Dec(I);
end;
if I > 0 then begin
SetLength(Ws, I div 2);
Fillchar(Ws[1], I div 2, #32);
Result := Ws + Result + Ws;
end;
end;
function LeftJustifyCh(const S: ansistring; const Ch: ansichar; const MaxLength: Integer): ansistring;
begin
if MaxLength < Length(S) then begin
Result := Copy(S, 1, MaxLength);
Exit;
end;
SetLength(Result, MaxLength);
Fillchar(Result[1], MaxLength, Ch);
Move(S[1], Result[1], Min(MaxLength, Length(S)));
end;
function RightJustifyCh(const S: ansistring; const Ch: ansichar; const MaxLength: Integer): ansistring;
begin
if MaxLength < Length(S) then begin
Result := Copy(S, 1, MaxLength);
Exit;
end;
SetLength(Result, MaxLength);
Fillchar(Result[1], MaxLength, Ch);
Move(S[1], Result[MaxLength - Pred(Length(S))], Min(MaxLength, Length(S)));
end;
function EncodeTabs(S: ansistring; TabSize: Byte): ansistring;
var
Ws: ansistring;
begin
Setlength(Ws, Tabsize);
Fillchar(Ws[1], TabSize, #32);
Result := stringReplace(S, Ws, #9, [rfReplaceAll]);
end;
function DecodeTabs(S: ansistring; TabSize: Byte): ansistring;
var
Ws: ansistring;
begin
Setlength(Ws, Tabsize);
Fillchar(Ws[1], TabSize, #32);
Result := stringReplace(S, #9, Ws, [rfReplaceAll]);
end;
function Filter(S: ansistring; CS: ansicharSet): ansistring;
var
Loop: Integer;
begin
Result := '';
for Loop := 1 to Length(S) do begin
if not (S[Loop] in CS) then begin
Result := Result + S[Loop];
end;
end;
end;
function SoundEx(S: ansistring): ansistring;
const
Table: array[1..26] of ansichar = '.123.12..22455.12623.1.2.2';
var
Soundansistring: string[255];
I1: Integer;
I2: Integer;
isNum: boolean;
Ch: ansichar;
begin
Result := S;
if S = '' then Exit;
isNum := true;
repeat
Ch := UpCase(S[1]);
if Ch > #64 then
isNum := false
else
Delete(S, 1, 1);
until (isNum = false) or (S = '');
Result := S;
if S = '' then Exit;
Soundansistring[0] := #255;
Fillchar(Soundansistring[1], 255, '0');
// Step 1: ASCII to Soundex
for I1 := 1 to Length(S) - 1 do begin
I2 := Ord(UpCase(S[I1 + 1])) - 64;
if ((I2 < 1) or (I2 > 26)) then I2 := 1;
Soundansistring[I1] := Table[I2];
end;
// Initialize for second pass
I1 := 1;
repeat
while (Soundansistring[I1] = '.') do
Delete(Soundansistring, I1, 1);
while ((Soundansistring[I1] = Soundansistring[I1 + 1]) and (Soundansistring[I1] <> '0')) do
Delete(Soundansistring, I1, 1);
Inc(I1);
until (Soundansistring[I1] = '0');
Result := Ch + Copy(Soundansistring, 1, 3);
end;
function QuickPos(const aFindansistring, aSourceansistring: ansistring): integer;
var
SourceLen, aSourceLen, aFindLen, StartPos: integer;
begin
{$IFNDEF ASM8086}
Result := Pos(aFindansistring, aSourceansistring);
{$ELSE}
Result := 0;
aSourceLen := Length(aSourceansistring);
if aSourceLen = 0 then Exit;
aFindLen := Length(aFindansistring);
if (aFindLen = 0) or (aFindlen > AsourceLen) then Exit; {GSW FIX!}
StartPos := 1;
SourceLen := aSourceLen - aFindLen;
SourceLen := (SourceLen - StartPos) + 2;
asm
push ESI
push EDI
push EBX
mov EDI, aSourceansistring
add EDI, StartPos
dec EDI
mov ESI, aFindansistring
mov ECX, SourceLen
mov Al, [ESI]
@ScaSB:
mov Ah, [EDI]
cmp Ah,Al
jne @Nextansichar
@Compareansistrings:
mov EBX, aFindLen
dec EBX
jz @FullMatch
@CompareNext:
mov Al, [ESI+EBX]
mov Ah, [EDI+EBX]
cmp Al, Ah
jz @Matches
mov Al, [ESI]
jmp @Nextansichar
@Matches:
dec EBX
jnz @CompareNext
@FullMatch:
mov EAX, EDI
sub EAX, aSourceansistring
inc EAX
mov Result, EAX
jmp @TheEnd
@Nextansichar:
inc EDI
dec ECX
jnz @ScaSB
mov Result,0
@TheEnd:
pop EBX
pop EDI
pop ESI
end; {asm}
{$ENDIF}
end;
function ansicharPos(const C: ansichar; const aSource: ansistring): Integer;
var
L: Integer;
begin
L := Length(aSource);
Result := 0;
if L = 0 then exit;
asm
PUSH EDI //Preserve this register
mov EDI, aSource //Point EDI at aSource
mov ECX, L //Make a note of how many ansichars to search through
mov AL, C //and which ansichar we want
@Loop:
mov AH, [EDI]
inc EDI
xor AH, AL
jz @Found
dec ECX
jnz @Loop
jmp @NotFound
@Found:
sub EDI, aSource //EDI has been incremented, so EDI-OrigAdress = ansichar pos !
mov Result, EDI
jmp @TheEnd
@NotFound:
mov Result, 0 // fix (ozz)
@TheEnd:
POP EDI
end;
end;
function Fetch(var S: ansistring; const Sub: ansistring; const IgnoreCase: Boolean): ansistring;
var
P: Integer;
begin
if IgnoreCase then
P := QuickPos(Uppercase(Sub), Uppercase(S))
else
P := QuickPos(Sub, S);
if (P = 0) then begin
Result := S;
S := '';
end
else begin
Result := Copy(S, 1, P - 1);
Delete(S, 1, P + (Length(Sub) - 1));
end;
end;
function FetchByansichar(var S: ansistring; const Sub: ansichar; const IgnoreCase: Boolean): ansistring;
var
P: Integer;
begin
if IgnoreCase then
P := ansicharPos(Upcase(Sub), Uppercase(S))
else
P := ansicharPos(Sub, S);
if (P = 0) then begin
Result := S;
S := '';
end
else begin
Result := Copy(S, 1, P - 1);
Delete(S, 1, P);
end;
end;
function Uppercase(const S: ansistring): ansistring;
{$IFNDEF ASM8086}
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := S;
MaxLoop := Length(Result);
for Loop := MaxLoop downto 1 do
if Result[Loop] in ['a'..'z'] then Dec(Result[Loop], 32);
end;
{$ELSE}
var
LenOfansistring: Integer;
FirstSource, FirstDest: Pointer;
begin
LenOfansistring := Length(S);
if LenOfansistring = 0 then begin
Result := '';
Exit;
end;
SetLength(Result, LenOfansistring);
FirstSource := Pointer(s);
FirstDest := Pointer(Result);
asm
PUSH ESI //Firstly and most importantly
PUSH EDI //Delphi uses EBX, ESI, EDI extensively, so we need to
//push them onto the stack, and then pop them off after
mov ESI, FirstSource//Move the address of Result into ESI
mov EDI, FirstDest //ESI and EDI are 2 generic "data moving" registers
//ESI = Source, EDI = Destination
//MovSB (Moveansistring Byte, there is also, MovSW word and MovSD double)
//MovXX copy from EDI to ESI, and then INC *both* ESI and EDI
// and also DEC ECX (generic ansistring length counter)
//But I will not use these as I need to Uppercase the results
mov ECX, LenOfansistring//ECX will contain a count of how many ansichars left to do
@Nextansichar:
mov AL, [ESI] //Move ESI^ into AL
// AL = ansichar, AX = Word, EAX = DWord, all different parts
// of the same register
cmp AL, $61
jl @NoUpper // < 'a' don't convert
cmp AL, $7A
jg @NoUpper // > 'z' don't convert
and AL, $DF // Convert to uppercase
@NoUpper:
mov [EDI], AL // Put AL back into EDI^ (That's what [] means)
Inc ESI //Point to next ansicharacter
Inc EDI
Dec ECX //Decrement the count, if it reaches 0, the ZERO flag will be set
jnz @Nextansichar //"J"ump if "n"ot "z"ero to the next ansicharacter
POP EDI
POP ESI
end; {asm}
end;
{$ENDIF}
function Lowercase(const S: ansistring): ansistring;
{$IFNDEF ASM8086}
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := S;
MaxLoop := Length(Result);
for Loop := MaxLoop downto 1 do
if Result[Loop] in ['A'..'Z'] then Inc(Result[Loop], 32);
end;
{$ELSE}
var
LenOfansistring: Integer;
FirstSource, FirstDest: Pointer;
begin
LenOfansistring := Length(S);
if LenOfansistring = 0 then begin
Result := '';
Exit;
end;
SetLength(Result, LenOfansistring);
FirstSource := Pointer(S);
FirstDest := Pointer(Result);
asm
PUSH ESI //Firstly and most importantly
PUSH EDI //Delphi uses EBX, ESI, EDI extensively, so we need to
//push them onto the stack, and then pop them off after
mov ESI, FirstSource//Move the address of Result into ESI
mov EDI, FirstDest //ESI and EDI are 2 generic "data moving" registers
//ESI = Source, EDI = Destination
//MovSB (Moveansistring Byte, there is also, MovSW word and MovSD double)
//MovXX copy from EDI to ESI, and then INC *both* ESI and EDI
// and also DEC ECX (generic ansistring length counter)
//But I will not use these as I need to Uppercase the results
mov ECX, LenOfansistring//ECX will contain a count of how many ansichars left to do
@Nextansichar:
mov AL, [ESI] //Move ESI^ into AL
// AL = ansichar, AX = Word, EAX = DWord, all different parts
// of the same register
cmp AL, 'A'
jl @NoUpper // < 'a' don't convert
cmp AL, 'Z'
jg @NoUpper // > 'z' don't convert
xor AL, $20 // Convert to lowercase
@NoUpper:
mov [EDI], AL // Put AL back into EDI^ (That's what [] means)
Inc ESI //Point to next ansicharacter
Inc EDI
Dec ECX //Decrement the count, if it reaches 0, the ZERO flag will be set
jnz @Nextansichar //"J"ump if "n"ot "z"ero to the next ansicharacter
POP EDI
POP ESI
end; {asm}
end;
{$ENDIF}
function ProperCase(const S: ansistring): ansistring;
var
Len: Integer;
MaxLen: Integer;
begin
Len := Length(S);
MaxLen := Len;
SetLength(Result, Len);
Result := Lowercase(S);
while Len > 0 do begin
if not (Result[Len] in ['a'..'z']) and (Len < MaxLen) then
Result[Len + 1] := Upcase(Result[Len + 1]);
Dec(Len);
end;
if (MaxLen > 0) and (Result[1] in ['a'..'z']) then
Result[1] := Upcase(Result[1]);
end;
function Trim(const S: ansistring): ansistring;
var
I, L: Integer;
begin
L := Length(S);
I := 1;
while (I <= L) and (S[I] <= ' ') do
Inc(I);
if I > L then
Result := ''
else begin
while S[L] <= ' ' do
Dec(L);
Result := Copy(S, I, L - I + 1);
end;
end;
function NoCRLF(const S: ansistring): ansistring;
begin
Result := stringReplace(S, #13#10, '', [rfReplaceAll]);
end;
function NoAngleBrackets(const S: ansistring): ansistring;
var
LenOfStr: Integer;
begin
Result := S;
LenOfStr := Length(Result);
if LenOfStr > 1 then
if (Result[1] = '<') and (Result[LenOfStr] = '>') then
Result := Copy(Result, 2, LenOfStr - 2);
end;
// Known Commands should be a 0 based array!
// For testing Winshoes products against ours, this command is useless to our
// engine. We use a dynamic parser which provides a much more flexible
// development solution for you.
function InStrArray(const SearchStr: ansistring; const KnownCommands: array of ansistring): Integer;
begin
for Result := High(KnownCommands) downto Low(KnownCommands) do
if SearchStr = KnownCommands[Result] then Exit;
Result := -1;
end;
procedure Inverseansistring(var S: ansistring; Count: Integer);
var
TmpStr: ansistring;
Ctr: Integer;
Ch: ansichar;
begin
TmpStr := Copy(S, 1, Count);
Ctr := 0;
while Count > 0 do begin
Ch := TmpStr[Count];
Dec(Count);
Move(Ch, S[Ctr + 1], 1);
Inc(Ctr);
end;
end;
function HexDump(const S: ansistring): ansistring;
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := '';
Loop := 0;
MaxLoop := Length(S);
while Loop < MaxLoop do begin
Result := Result + IntToHex(Ord(S[Loop + 1]), 2) + #32;
Inc(Loop);
end;
end;
function Replaceansichar(const Source: ansistring; const Oldansichar, Newansichar: ansichar): ansistring;
var
Loop: Integer;
begin
Result := Source;
if Oldansichar = Newansichar then Exit;
Loop := Length(Source);
while Loop > 0 do begin
if Result[Loop] = Oldansichar then Result[Loop] := Newansichar;
Dec(loop);
end;
end;
function ExtractLeft(const aSourceansistring: ansistring; const Size: Integer): ansistring;
begin
if Size > Length(aSourceansistring) then
Result := aSourceansistring
else begin
Setlength(Result, Size);
Move(aSourceansistring[1], Result[1], Size);
end;
end;
function ExtractRight(const aSourceansistring: ansistring; const Size: Integer): ansistring;
var
Len: Integer;
begin
Len := Length(aSourceansistring);
if Size > Len then
Result := aSourceansistring
else begin
Setlength(Result, Size);
Move(aSourceansistring[Len - Pred(Size)], Result[1], Size);
end;
end;
function ExtractWordAt(const Text: ansistring; Position: Integer): ansistring;
var
Done: Boolean;
StartAt: Integer;
Len: Integer;
OrgPosition: Integer;
begin
Len := Length(Text);
Result := '';
Done := not (UpCase(Text[Position]) in ['A'..'Z', '0'..'9']);
if (Position > 0) and (Position <= Len) and not Done then begin
OrgPosition := Position;
while (Position > 0) and not Done do begin
Done := not (UpCase(Text[Position]) in ['A'..'Z', '0'..'9']);
if not Done then Dec(Position);
end;
StartAt := Position;
Position := OrgPosition;
Done := False;
while (Position <= Len) and not Done do begin
Done := not (UpCase(Text[Position]) in ['A'..'Z', '0'..'9']);
if not Done then Inc(Position);
end;
Result := Copy(Text, StartAt + 1, Pred(Position) - StartAt);
end;
end;
function LeftJustify(const S: ansistring; const MaxLength: Integer): ansistring;
begin
Result := LeftJustifyCh(S, #32, MaxLength);
end;
function RightJustify(const S: ansistring; const MaxLength: Integer): ansistring;
begin
Result := RightJustifyCh(S, #32, MaxLength);
end;
function Cleanansichar(const Inansichar: ansichar): ansichar;
const
Ctlansichars: string[32] = 'oooooooooXoollo><|!Pg*|^v><-^v';
Hiansichars: string[64] = 'CueaaaageeeiiiAAEaaooouuyOUcLYPfarounNao?--//!<>***|||||||||||||';
Hiansichars2: string[64] = '|--|-+||||=+|=++-=--==-||||*****abcnEduto0nd80En=+>
begin
case Inansichar of
#0..#31: Result := Ctlansichars[Ord(Inansichar) + 1];
#128..#191: Result := Hiansichars[Ord(Inansichar) - 127];
#192..#255: Result := Hiansichars2[Ord(Inansichar) - 191];
else
Result := Inansichar;
end;
end;
function CleanStr(const InStr: ansistring): ansistring;
begin
Result := '';
while Length(Result) < Length(InStr) do
Result := Result + Cleanansichar(InStr[Length(Result) + 1]);
end;
function PosLastansichar(const Ch: ansichar; const S: ansistring): Integer;
var
I: Integer;
begin
i := Length(S);
while ((i > 0) and (s[i] <> ch)) do
Dec(i);
Result := I;
end;
function AsciiToOem(const ax: ansistring): ansistring;
var
i: integer;
begin
Result := AX;
for i := Length(Result) downto 1 do begin
case Ord(Result[i]) of
132: Result[i] := ansichar(228);
142: Result[i] := ansichar(196);
129: Result[i] := ansichar(252);
154: Result[i] := ansichar(220);
148: Result[i] := ansichar(246);
153: Result[i] := ansichar(214);
225: Result[i] := ansichar(223);
end;
end;
end;
function OemToAscii(const ax: ansistring): ansistring;
var
i: integer;
begin
Result := AX;
for i := Length(Result) downto 1 do begin
case Ord(Result[i]) of
228: Result[i] := ansichar(132);
196: Result[i] := ansichar(142);
252: Result[i] := ansichar(129);
220: Result[i] := ansichar(154);
246: Result[i] := ansichar(148);
214: Result[i] := ansichar(153);
223: Result[i] := ansichar(225);
end;
end;
end;
function WordCount(const S: ansistring): Integer;
var
I, Len: Integer;
begin
Len := Length(S);
Result := 0;
I := 1;
while I <= Len do begin
while (i <= len) and ((S[i] = #32) or (S[i] = #9) or (S[i] = ';')) do
inc(i);
if I <= len then inc(Result);
while (I <= len) and (S[i] <> #32) and (S[i] <> #9) and (S[i] <> ';') do
inc(i);
end;
end;
function CRC32Byansichar(const Ch: ansichar; const starting_crc: LONGINT): LONGINT;
begin
Result := crc_32_tab[BYTE(starting_crc xor LONGINT(Ord(Ch)))] xor ((starting_crc shr 8) and $00FFFFFF);
end;
function CRC32Byansistring(const S: ansistring; const starting_crc: LONGINT): LONGINT;
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := starting_crc;
MaxLoop := Length(S);
for Loop := 1 to MaxLoop do
// Result:=CRC32Byansichar(S[Loop],Result);
Result := crc_32_tab[BYTE(Result xor LONGINT(Ord(S[Loop])))] xor ((Result shr 8) and $00FFFFFF);
end;
function CRC16Byansichar(const Ch: ansichar; const starting_crc: word): word;
begin
Result := crc_16_tab[BYTE(starting_crc xor Word(Ord(Ch)))] xor ((starting_crc shr 8) and $00FF)
end;
function CRC16Byansistring(const S: ansistring; const starting_crc: word): word;
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := starting_crc;
MaxLoop := Length(S);
for Loop := 1 to MaxLoop do
// Result:=CRC16Byansichar(S[Loop],Result);
Result := crc_16_tab[BYTE(Result xor Word(Ord(S[Loop])))] xor ((Result shr 8) and $00FF)
end;
function CRCARCByansichar(const Ch: ansichar; const starting_crc: word): word;
begin
Result := crc_arc_tab[BYTE(starting_crc xor Word(Ord(Ch)))] xor ((starting_crc shr 8) and $00FF)
end;
function CRCARCByansistring(const S: ansistring; const starting_crc: word): word;
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := starting_crc;
MaxLoop := Length(S);
for Loop := 1 to MaxLoop do
// Result:=CRCARCByansichar(S[Loop],Result);
Result := crc_arc_tab[BYTE(Result xor Word(Ord(S[Loop])))] xor ((Result shr 8) and $00FF)
end;
procedure SetLongBit(var L: LongInt; const Bit: Byte; const Setting: Boolean);
var
Mask: LongInt;
begin
Mask := 1;
Mask := Mask shl (Bit - 1);
if Setting then
L := L or Mask
else
L := (L and (not Mask));
end;
function GetLongBit(const L: LongInt; const Bit: Byte): Boolean;
var
Mask: LongInt;
begin
Mask := 1;
Mask := Mask shl (Bit - 1);
Result := (L and Mask) <> 0;
end;
procedure SetWordBit(var L: Word; const Bit: Byte; const Setting: Boolean);
var
Mask: Word;
begin
Mask := 1;
Mask := Mask shl (Bit - 1);
if Setting then
L := L or Mask
else
L := (L and (not Mask));
end;
function GetWordBit(const L: Word; const Bit: Byte): Boolean;
var
Mask: Word;
begin
Mask := 1;
Mask := Mask shl (Bit - 1);
Result := (L and Mask) <> 0;
end;
procedure SetByteBit(var L: Byte; const Bit: Byte; const Setting: Boolean);
var
Mask: Byte;
begin
Mask := 1;
Mask := Mask shl (Bit - 1);
if Setting then
L := L or Mask
else
L := (L and (not Mask));
end;
function GetByteBit(const L: Byte; const Bit: Byte): Boolean;
var
Mask: Byte;
begin
Mask := 1;
Mask := Mask shl (Bit - 1);
Result := (L and Mask) <> 0;
end;
function Replicate(const Source: ansistring; NumberOfTimes: Integer): ansistring;
var
SourceLength: Integer;
Dest: Integer;
begin
Dest := 1;
SourceLength := Length(Source);
SetLength(Result, SourceLength * NumberOfTimes);
while NumberOfTimes > 0 do begin
Move(Source[1], Result[Dest], SourceLength);
Inc(Dest, SourceLength);
Dec(NumberOfTimes);
end;
end;
function IsWildCard(const Source: ansistring): Boolean;
begin
Result := ansicharPos('*', Source) + ansicharPos('?', Source) + ansicharPos('%', Source) > 0;
end;
///
// Internet Routines
///
function GetIndex(const c: ansichar): Integer;
var
i: Integer;
{$IFDEF ASM8086}
S: ansistring;
{$ENDIF}
begin
{$IFNDEF ASM8086}
i := ansicharPos(c, Alphabet); //overkill for just 1 ansicharacter
{$ELSE}
S := Alphabet;
asm
PUSH EDI //Preserve this register
mov EDI, S //Point EDI at Alphabet ansistring
mov ECX, AlphaBetLength //Tell CPU how big Alphabet is
mov AL, C //and which ansichar we want
RepNE ScaSB //"Rep"eat while "N"ot "E"qual
//this is the same as
//While (EDI^ <> AL) and (ECX>0) do begin
// Inc(EDI);
// Dec(ECX);
//end;
jnz @NotFound //Zero flag will be set if there was a match
sub EDI, S //EDI has been incremented, so EDI-OrigAdress = ansichar pos !
mov I, EDI
@NotFound:
POP EDI
end;
{$ENDIF}
if (i > 0) then Dec(i);
result := i;
end;
function Base64Toansistring(const S: ansistring): ansistring;
var
i: Integer;
function DecodeUnit(const InStr: ansistring): Shortstring;
var
a, b, c, d: Byte;
begin
a := GetIndex(InStr[1]);
b := GetIndex(InStr[2]);
if InStr[3] = '=' then begin
SetLength(Result, 1);
result[1] := ansichar((a shl 2) or (b shr 4));
end
else
if InStr[4] = '=' then begin
SetLength(Result, 2);
c := GetIndex(InStr[3]);
result[1] := ansichar((a shl 2) or (b shr 4));
result[2] := ansichar((b shl 4) or (c shr 2));
end
else begin
c := GetIndex(InStr[3]);
d := GetIndex(InStr[4]);
SetLength(result, 3);
result[1] := ansichar((a shl 2) or (b shr 4));
result[2] := ansichar((b shl 4) or (c shr 2));
result[3] := ansichar((c shl 6) or d);
end;
end;
begin
Result := '';
for i := ((Length(s) div 4) - 1) downto 0 do
Result := DecodeUnit(Copy(s, i * 4 + 1, 4)) + Result;
end;
function ansistringToBase64(const S1: ansistring): ansistring;
const
Table: ansistring = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
var
I, K, L: Integer;
S: ansistring;
begin
L := Length(S1);
if L mod 3 <> 0 then Inc(L, 3);
SetLength(S, (L div 3) * 4);
Fillchar(S[1], Length(S), '=');
I := 0;
K := 1;
while I < Length(S1) do begin
S[K] := Table[1 + (Ord(S1[I + 1]) shr 2)];
S[K + 1] := Table[1 + (((Ord(S1[I + 1]) and $03) shl 4) or (Ord(S1[I + 2]) shr 4))];
if I + 1 >= Length(S1) then Break;
S[K + 2] := Table[1 + (((Ord(S1[I + 2]) and $0F) shl 2) or (Ord(S1[I + 3]) shr 6))];
if I + 2 >= Length(S1) then Break;
S[K + 3] := Table[1 + (Ord(S1[I + 3]) and $3F)];
Inc(I, 3);
Inc(K, 4);
end;
Result := S;
end;
function FixDottedIP(const S: ansistring): ansistring;
var
n: Cardinal;
begin
Result := '.' + S;
n := QuickPos('.0', Result);
while n > 0 do begin
Delete(Result, n + 1, 1);
n := QuickPos('.0', Result);
end;
n := QuickPos('..', Result);
while N > 0 do begin
Insert('0', Result, n + 1);
n := QuickPos('..', Result);
end;
if Result[Length(Result)] = '.' then Result := Result + '0';
Delete(Result, 1, 1);
end;
function IPAddressFormatted(const I1, I2, I3, I4: Integer): ansistring;
begin
Result := IntToStr(I4);
while Length(Result) < 3 do
Result := '0' + Result;
Result := IntToStr(I3) + '.' + Result;
while Length(Result) < 7 do
Result := '0' + Result;
Result := IntToStr(I2) + '.' + Result;
while Length(Result) < 11 do
Result := '0' + Result;
Result := IntToStr(I1) + '.' + Result;
while Length(Result) < 15 do
Result := '0' + Result;
end;
function IPansistringFormated(S: ansistring): ansistring;
var
n1, n2, n3, n4: Integer;
begin
N1 := StrToInt(Copy(S, 1, ansicharPos('.', S) - 1));
Delete(S, 1, ansicharPos('.', S));
N2 := StrToInt(Copy(S, 1, ansicharPos('.', S) - 1));
Delete(S, 1, ansicharPos('.', S));
N3 := StrToInt(Copy(S, 1, ansicharPos('.', S) - 1));
Delete(S, 1, ansicharPos('.', S));
N4 := ansistringToInteger(S);
Result := IPAddressFormatted(N1, N2, N3, N4);
end;
function EscapeDecode(const S: ansistring): ansistring;
var
ch: ansichar;
val: ansistring;
I: Integer;
begin
Result := S;
I := ansicharPos('%', Result);
while I > 0 do begin
Val := '$' + Copy(Result, I + 1, 2);
try
Ch := ansichar(StrToInt(Val));
except
Ch := 'a';
end;
Result := Copy(Result, 1, I - 1) + Ch + Copy(Result, I + 3, Length(Result));
I := ansicharPos('%', Result);
end;
I := ansicharPos('+', Result);
while I > 0 do begin
Result := Copy(Result, 1, I - 1) + #32 + Copy(Result, I + 1, Length(Result));
I := ansicharPos('+', Result);
end;
end;
function LocalTimeZoneBias: Integer;
{$IFDEF LINUX}
var
TV: TTimeval;
TZ: TTimezone;
begin
gettimeofday(TV, TZ);
Result := TZ.tz_minuteswest;
end;
{$ELSE}
var
TimeZoneInformation: TTimeZoneInformation;
Bias: Longint;
begin
case GetTimeZoneInformation(TimeZoneInformation) of
TIME_ZONE_ID_STANDARD: Bias := TimeZoneInformation.Bias + TimeZoneInformation.StandardBias;
TIME_ZONE_ID_DAYLIGHT: Bias := TimeZoneInformation.Bias + ((TimeZoneInformation.DaylightBias div 60) * -100);
else
Bias := TimeZoneInformation.Bias;
end;
Result := Bias;
end;
{$ENDIF}
function TimeZone: ansistring;
{$IFDEF LINUX}
begin
Result := ShortTimeZone;
end;
{$ELSE}
var
lpTimeZoneInfo: TTimeZoneInformation;
begin
Result := '';
if GetTimeZoneInformation(lpTimeZoneInfo) = TIME_ZONE_ID_STANDARD then
{$IFDEF VER90}
Result := WideansicharToansistring({@} Pointer(lpTimeZoneInfo.StandardName))
{$ELSE}
Result := lpTimeZoneInfo.StandardName
{$ENDIF}
else
if GetTimeZoneInformation(lpTimeZoneInfo) = TIME_ZONE_ID_DAYLIGHT then
{$IFDEF VER90}
Result := WideansicharToansistring({@} Pointer(lpTimeZoneInfo.DaylightName));
{$ELSE}
Result := lpTimeZoneInfo.DaylightName;
{$ENDIF}
end;
{$ENDIF}
function ShortTimeZone: ansistring;
{$IFDEF LINUX}
var
T: TTime_T;
UT: TUnixTime;
begin
__time(@T);
localtime_r(@T, UT);
Result := Pansichar(UT.__tm_zone);
end;
{$ELSE}
var
TPos: Integer;
begin
Result := TimeZone;
TPos := 1;
while TPos <= Length(Result) do
if not (Result[TPos] in ['A'..'Z']) then
Delete(Result, TPos, 1)
else
Inc(TPos);
end;
{$ENDIF}
function TimeZoneBias: ansistring;
begin
Result := IntToStr(LocalTimeZoneBIAS);
while Length(Result) < 4 do
Result := '0' + Result;
if IsNumeric(Result[1]) then Result := '-' + Result;
end;
function EscapeEncode(const S: ansistring): ansistring;
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := '';
MaxLoop := Length(S);
for Loop := 1 to MaxLoop do
if S[Loop] in ['0'..'9', '.', '-'] then
Result := Result + S[Loop]
else
if S[Loop] = #32 then
Result := Result + '+'
else
if (S[Loop] < #21) or
(S[Loop] > #127) then
Result := Result + '%' + IntToHex(Ord(S[Loop]), 2)
else
Result := Result + S[Loop]
end;
function EncodeDomain(S: ansistring): ansistring;
var
Dot: Integer;
begin
Result := '';
while (S <> '') do begin
Dot := ansicharPos('.', S);
case Dot of
0: begin
Result := Result + Chr(Length(S)) + S;
S := '';
end;
else begin
Result := Result + Chr(Dot - 1) + Copy(S, 1, Dot - 1);
Delete(S, 1, Dot);
end;
end;
end;
Result := Result + #0;
end;
function EncodeAddress(S: ansistring): ansistring;
var
Dot: Integer;
begin
Result := '';
while (S <> '') do begin
Dot := Pos('.', S);
case Dot of
0: begin
Result := Result + Chr(Length(S)) + S;
S := '';
end;
else begin
Result := Result + Chr(Dot - 1) + Copy(S, 1, Dot - 1);
Delete(S, 1, Dot);
end;
end;
end;
Result := Result + #7'in-addr'#4'arpa'#0;
end;
function DecodeDomain(S: ansistring): ansistring;
var
L: Integer;
begin
Result := '';
while Length(S) > 0 do begin
L := Ord(S[1]);
if L > Length(S) then begin
Result := '';
Exit;
end;
Result := Result + Copy(S, 2, L) + '.';
Delete(S, 1, L + 1);
end;
if Copy(Result, Length(Result), 1) = '.' then Delete(Result, Length(Result), 1);
end;
function GetActualEmailAddress(Parm, Command: ansistring): ansistring;
var
Colon, Quote: Integer;
begin
// posibilities are:
// [cmd]:
// [cmd] :
// [cmd]:
// [cmd] :
// [cmd]
// [cmd]
// you can also have "firstname lastname" in there also
Quote := ansicharPos('"', Parm);
if Quote > 0 then begin
if ansicharPos('>', Parm) > Quote then begin
Delete(Parm, 1, Quote);
Delete(Parm, 1, ansicharPos('"', Parm));
end
else begin
Colon := PosLastansichar('"', Parm);
Delete(Parm, Quote, Colon - Pred(Quote));
end;
end;
// check if space, if so let remove everything before
Trim(Parm);
// ok now possibilities are:
// [cmd]:
// :
// :
// [cmd]
Colon := ansicharPos(':', Parm);
// check if colon, if so let remove everything before
if Colon > 0 then
Delete(Parm, 1, Colon);
// ok now possibilities are:
//
// [cmd]
// now let check if we have a command
if lowercase(copy(parm, 1, length(command))) = lowercase(command) then
delete(Parm, 1, length(command));
// we trim to make sure we dont have any space left in there
Parm := Trim(Parm);
// and return the result with no brackets
Result := NoAngleBrackets(Parm);
end;
///
// Date and/or Time Routines
///
function DayOfTheYear(const DT: TDateTime): Integer;
var
J, Y: Word;
begin
DecodeDate(DT, Y, J, J);
Result := Trunc(DT) - Trunc(EncodeDate(Y, 1, 1)) + 1;
end;
function DaysLeftThisYear(const DT: TDateTime): Integer;
var
J, Y: Word;
begin
DecodeDate(DT, Y, J, J);
case IsLeapYear(Y) of
True: Result := 366 - DayOfTheYear(DT);
False: Result := 365 - DayOfTheYear(DT);
end;
end;
function DaysThisMonth(const DT: TDateTime): Integer;
var
J, M, Y: Word;
begin
DecodeDate(DT, Y, M, J);
case M of
2:
if IsLeapYear(Y) then
Result := 29
else
Result := 28;
4, 6, 9, 11: Result := 30;
else
Result := 31;
end;
end;
function DaysLeftThisMonth(const DT: TDateTime): Integer;
var
J, M, Y: Word;
begin
DecodeDate(DT, Y, M, J);
case M of
2:
if IsLeapYear(Y) then
Result := 29
else
Result := 28;
4, 6, 9, 11: Result := 30;
else
Result := 31;
end;
Result := Result - J;
end;
function IsTimeAM(const DT: TDateTime): Boolean;
begin
Result := Frac(DT) < 0.5;
end;
function IsTimePM(const DT: TDateTime): Boolean;
begin
Result := Frac(DT) > 0.5;
end;
function IsTimeNoon(const DT: TDateTime): Boolean;
begin
Result := Frac(DT) = 0.5;
end;
function IsTimeMidnight(const DT: TDateTime): Boolean;
begin
Result := Frac(DT) = 0.0;
end;
function DateTimeToGMT(const DT: TDateTime): TDateTime;
begin
Result := DT + LocalTimeZoneBias / 1440;
end;
function DateTimeToLocal(const DT: TDateTime): TDateTime;
begin
Result := DT - LocalTimeZoneBias / 1440;
end;
function IsLeapYear(const Year: Word): Boolean;
begin
Result := ((Year and 3) = 0) and ((Year mod 100 > 0) or (Year mod 400 = 0));
end;
function ToUnixSlashes(const S: ansistring): ansistring;
{.$IFNDEF ASM8086}
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := S;
MaxLoop := Length(Result);
for Loop := 1 to MaxLoop do
if Result[Loop] = '\' then Result[Loop] := '/';
end;
(*
{$ElSE}
Var
LenOfResult:Integer;
Firstansichar:Pointer;
Begin
Result:=S;
LenOfResult:=Length(Result);
If LenOfResult<1 then Exit;
Firstansichar:=Pointer(Result);
asm
push ESI
mov ESI, Firstansichar;
mov ECX, LenOfResult
@Loop:
mov Al, [ESI]
cmp Al, '\'
jne @NoChange
mov Al, '/'
mov [ESI], Al
@NoChange:
Inc ESI
Dec ECX
jnz @Loop
pop ESI
end;
End;
{$ENDIF}
*)
function ToDOSSlashes(const S: ansistring): ansistring;
{.$IFNDEF ASM8086}
var
Loop: Integer;
MaxLoop: Integer;
begin
Result := S;
MaxLoop := Length(Result);
for Loop := 1 to MaxLoop do
if Result[Loop] = '/' then Result[Loop] := '\';
end;
(*
{$ElSE}
Var
LenOfResult:Integer;
Firstansichar:Pointer;
Begin
Result:=S;
LenOfResult:=Length(Result);
If LenOfResult<1 then Exit;
Firstansichar:=Pointer(Result);
asm
push ESI
mov ESI, Firstansichar;
mov ECX, LenOfResult
@Loop:
mov Al, [ESI]
cmp Al, '/'
jne @NoChange
mov Al, '\'
mov [ESI], Al
@NoChange:
Inc ESI
Dec ECX
jnz @Loop
pop ESI
end;
End;
{$ENDIF}
*)
function ToOSSlashes(const S: ansistring): ansistring;
begin
{$IFDEF LINUX}
Result := ToUnixSlashes(S);
{$ELSE}
Result := ToDOSSlashes(S);
{$ENDIF}
end;
(******************************************************************************
CHANGEDIR: {Rewritten to call Windows.API for the result!}
The GetFullPathName function merges the name of the current drive and
directory with the specified filename to determine the full path and
filename of the specified file. It also calculates the address of the
filename portion of the full path and filename. This function does not
verify that the resulting path and filename are valid or that they
refer to an existing file on the associated volume.
******************************************************************************)
function ChangeDir(const S, RP: string): string;
{$IFDEF LINUX}
begin
Result := ''; // redesign
end;
{$ELSE}
var
FileName: string;
FName: Pchar;
Buffer: array[0..MAX_PATH - 1] of char;
begin
FileName := ToDOSSlashes(S + RP);
Setstring(Result, Buffer, GetFullPathName(Pchar(FileName), SizeOf(Buffer),
Buffer, FName));
end;
{$ENDIF}
function DateTimeToGMTRFC822(const DT: TDateTime): ansistring;
begin
Result := FormatDateTime('ddd, dd mmm yyyy hh:nn:ss', DateTimeToGMT(DT)) + ' GMT';
end;
function DateTimeToGMTRFC850(const DT: TDateTime): ansistring;
begin
Result := FormatDateTime('dddd, dd-mmm-yy hh:nn:ss', DateTimeToGMT(DT)) + ' GMT';
end;
function DateTimeToRFC850(const DT: TDateTime): ansistring;
begin
Result := FormatDateTime('dddd, dd-mmm-yy hh:nn:ss', DT) + #32 + ShortTimeZone;
end;
function DateTimeToRFC850Bias(const DT: TDateTime): ansistring;
begin
Result := FormatDateTime('ddd, dd mmm yyyy hh:nn:ss', DT) + #32 + TimeZoneBias;
end;
function RFCToDateTime(S: ansistring): TDateTime;
var
M, D, Y: Word;
H, N, Sc, T: Word;
Ch, CHtag: ansichar;
Ts: ansistring;
PosCh: integer;
begin
posch := ansicharPos(';', S);
if posch > 0 then
delete(s, posCH, length(s) - posCh + 1);
T := 0;
Ch := S[3];
S := Uppercase(S);
if Ch = #32 then begin
Delete(S, 1, 4);
Ts := Copy(S, 1, ansicharPos(#32, S) - 1);
Delete(S, 1, Length(TS));
S := Trim(S);
M := QuickPos(TS, #32#32'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC') div 3;
Ts := Copy(S, 1, ansicharPos(#32, S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
D := StrToInt(TS);
except
D := 1;
end;
Ch := S[3];
if Ch <> ':' then begin
Ts := Copy(S, 1, ansicharPos(#32, S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
Y := StrToInt(TS);
except
DecodeDate(Now, Y, T, T);
T := 0;
end;
end;
Ts := Copy(S, 1, ansicharPos(':', S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
H := StrToInt(TS);
except
H := 0;
end;
Ts := Copy(S, 1, 2);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
N := StrToInt(TS);
except
N := 0;
end;
Ts := Copy(S, 1, 2);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
Sc := StrToInt(TS);
except
Sc := 0;
end;
if S <> '' then begin
Ch := S[1];
if Ch in ['0'..'9'] then begin
try
Y := StrToInt(S);
except
DecodeDate(Now, Y, T, T);
T := 0;
end;
end;
end;
end
else
if Ch = ',' then begin // RFC 822 or RFC 1123
Delete(S, 1, ansicharPos(#32, S));
S := Trim(S);
Ts := Copy(S, 1, ansicharPos(#32, S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
D := StrToInt(TS);
except
D := 1;
end;
Ts := Copy(S, 1, ansicharPos(#32, S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
M := QuickPos(TS, #32#32'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC') div 3;
Ts := Copy(S, 1, ansicharPos(#32, S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
Y := StrToInt(TS);
except
DecodeDate(Now, Y, T, T);
T := 0;
end;
Ts := Copy(S, 1, ansicharPos(':', S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
H := StrToInt(TS);
except
H := 0;
end;
Ts := Copy(S, 1, 2);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
N := StrToInt(TS);
except
N := 0;
end;
Ts := Copy(S, 1, 2);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
Sc := StrToInt(TS);
except
Sc := 0;
end;
end
else begin // RFC 850 or RFC 1036
Delete(S, 1, ansicharPos(#32, S));
S := Trim(S);
chtag := '-';
posCh := ansicharpos(chtag, S);
if (posCH > 0) and (posCh < 5) then
chtag := '-'
else
chtag := ' ';
Ts := Copy(S, 1, ansicharPos(chtag, S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
D := StrToInt(TS);
except
D := 1;
end;
Ts := Copy(S, 1, ansicharPos(chtag, S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
M := QuickPos(TS, #32#32'JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC') div 3;
Ts := Copy(S, 1, ansicharPos(#32, S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
Y := StrToInt(TS);
except
DecodeDate(Now, Y, T, T);
T := 0;
end;
Ts := Copy(S, 1, ansicharPos(':', S) - 1);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
H := StrToInt(TS);
except
H := 0;
end;
Ts := Copy(S, 1, 2);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
N := StrToInt(TS);
except
N := 0;
end;
Ts := Copy(S, 1, 2);
Delete(S, 1, Length(TS) + 1);
S := Trim(S);
try
Sc := StrToInt(TS);
except
Sc := 0;
end;
end;
if Y < 100 then begin
DecodeDate(Now, Y, T, T);
end;
try
Result := EncodeDate(Y, M, D) + EncodeTime(H, N, Sc, T);
except
result := now;
end;
end;
{$IFDEF VER100}
function ansistringReplace(const S, OldPattern, NewPattern: ansistring;
Flags: TReplaceFlags): ansistring;
var
SearchStr, Patt, NewStr: ansistring;
Offset: Integer;
begin
if rfIgnoreCase in Flags then begin
SearchStr := AnsiUpperCase(S);
Patt := AnsiUpperCase(OldPattern);
end
else begin
SearchStr := S;
Patt := OldPattern;
end;
NewStr := S;
Result := '';
while SearchStr <> '' do begin
{$IFDEF VER90}
Offset := Pos(Patt, SearchStr);
{$ELSE}
Offset := AnsiPos(Patt, SearchStr);
{$ENDIF}
if Offset = 0 then begin
Result := Result + NewStr;
Break;
end;
Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern;
NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt);
if not (rfReplaceAll in Flags) then begin
Result := Result + NewStr;
Break;
end;
SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt);
end;
end;
procedure FreeAndNil(var Obj);
var
Temp: TObject;
begin
Temp := TObject(Obj);
Pointer(Obj) := nil;
Temp.Free;
end;
{$ENDIF}
function PansicharLen(Str: Pansichar): integer;
{$IFDEF ASM8086}
asm
MOV EDX,7
ADD EDX,EAX { pointer+7 used in the end }
PUSH EBX { is necessary; even in your version}
MOV EBX,[EAX] { read first 4 bytes}
ADD EAX,4 { increment pointer}
@L1: LEA ECX,[EBX-$01010101] { subtract 1 from each byte}
XOR EBX,-1 { invert all bytes}
AND ECX,EBX { and these two}
MOV EBX,[EAX] { read next 4 bytes}
ADD EAX,4 { increment pointer}
AND ECX,80808080H { test all sign bits}
JZ @L1 { no zero bytes, continue loop}
TEST ECX,00008080H { test first two bytes}
JNZ @L2 { *was JNZ SHORT @L2*}
SHR ECX,16 { not in the first 2 bytes}
ADD EAX,2
@L2: SHL CL,1 { use carry flag to avoid a branch}
POP EBX { Likewise; see above}
SBB EAX,EDX { compute length}
end;
{$ELSE}
var
p: ^cardinal;
q: pansichar;
bytes, r1, r2: cardinal;
begin
p := pointer(tStr);
repeat
q := pansichar(p^);
r2 := cardinal({@} Pointer(q[-$01010101]));
r1 := cardinal(q) xor $FFFFFFFF;
bytes := r1 and r2;
inc(p);
until (bytes and $80808080) <> 0;
result := integer(p) - integer(tStr) - 4;
if (bytes and $00008080) = 0 then begin
bytes := bytes shr 16;
inc(result, 2);
end;
if (bytes and $80) = 0 then
inc(result);
end;
{$ENDIF}
{$IFDEF ASM8086}
function LRot16(X: Word; c: longint): Word; assembler;
asm
mov ecx,&c
mov ax,&X
rol ax,cl
mov &Result,ax
end;
function RRot16(X: Word; c: longint): Word; assembler;
asm
mov ecx,&c
mov ax,&X
ror ax,cl
mov &Result,ax
end;
function LRot32(X: DWord; c: longint): DWord; register; assembler;
asm
mov ecx, edx
rol eax, cl
end;
function RRot32(X: DWord; c: longint): DWord; register; assembler;
asm
mov ecx, edx
ror eax, cl
end;
function SwapDWord(X: DWord): DWord; register; assembler;
asm
xchg al,ah
rol eax,16
xchg al,ah
end;
{$ELSE}
function LRot16(X: Word; c: longint): Word;
begin
LRot16 := (X shl c) or (X shr (16 - c));
end;
function RRot16(X: Word; c: longint): Word;
begin
RRot16 := (X shr c) or (X shl (16 - c));
end;
function LRot32(X: DWord; c: longint): DWord;
begin
LRot32 := (X shl c) or (X shr (32 - c));
end;
function RRot32(X: DWord; c: longint): DWord;
begin
RRot32 := (X shr c) or (X shl (32 - c));
end;
function SwapDWord(X: DWord): DWord;
begin
Result := (X shr 24) or ((X shr 8) and $FF00) or ((X shl 8) and $FF0000) or (X shl 24);
end;
{$ENDIF}
function WildCompare(LookingFor, SourceStr: ansistring): Boolean;
var
Ws: ansistring;
MaxInputWord: Integer;
MaxWild: Integer;
cInput: Integer;
cWild: Integer;
HelpWild: ansistring;
LengthHelpWild: Integer;
Q: Integer;
function FindPart(helpwilds, input_word: ansistring): integer;
var
Q1, Q2, Q3: Integer;
Diff: Integer;
begin
Q1 := ansicharPos('?', helpwilds);
if Q1 = 0 then
Result := QuickPos(helpwilds, input_word)
else begin
Q3 := Length(helpwilds);
Diff := Length(input_word) - Q3;
if Diff < 0 then begin
Result := 0;
Exit;
end;
for Q1 := 0 to Diff do begin
for Q2 := 1 to Q3 do begin
if (input_word[Q1 + Q2] = helpwilds[Q2]) or
(helpwilds[Q2] = '?') then begin
if Q2 = Q3 then begin
Result := Q1 + 1;
Exit;
end;
end
else
Break;
end;
end;
Result := 0;
end;
end;
function SearchNext(var WildS: ansistring): Integer;
begin
Result := ansicharPos('*', WildS);
if Result <> 0 then WildS := Copy(WildS, 1, Result - 1);
end;
begin
Ws := LookingFor;
while ansicharPos('%', Ws) > 0 do
Ws[ansicharPos('%', Ws)] := '*';
while QuickPos('**', Ws) > 0 do
Delete(Ws, QuickPos('**', Ws), 1);
MaxInputWord := Length(SourceStr);
MaxWild := Length(Ws);
cInput := 1;
cWild := 1;
Result := True;
repeat
if SourceStr[cInput] = Ws[cWild] then begin
inc(cWild);
inc(cInput);
continue;
end
else
if Ws[cWild] = '?' then begin
inc(cWild);
inc(cInput);
continue;
end
else
if Ws[cWild] = '*' then begin
HelpWild := Copy(Ws, cWild + 1, MaxWild);
q := SearchNext(HelpWild);
LengthHelpWild := Length(HelpWild);
if Q = 0 then begin
if HelpWild = '' then Exit;
for Q := 0 to LengthHelpWild - 1 do
if (HelpWild[LengthHelpWild - Q] <> SourceStr[MaxInputWord - Q]) and
(HelpWild[LengthHelpWild - Q] <> '?') then begin
Result := False;
Exit;
end;
Exit;
end;
Inc(cWild, 1 + LengthHelpWild);
Q := FindPart(HelpWild, Copy(SourceStr, cInput, Length(SourceStr)));
if Q = 0 then begin
Result := False;
Exit;
end;
cInput := Q + LengthHelpWild;
Continue;
end;
Result := False;
Exit;
until (cInput > MaxInputWord) or (cWild > MaxWild);
if cInput <= MaxInputWord then
Result := False
else
if cWild <= MaxWild then
Result := False;
end;
// DXSock 4.0 Additions
function SizeStamp(CPS: Integer): ansistring;
begin
if CPS < 1024 then Result := IntToStr(CPS) + 'bps'
else if CPS < 1024000 then Result := IntToStr(CPS div 1024) + 'kbps'
else if CPS < 1024000000 then Result := IntToStr(CPS div 1024000) + 'mbps'
else Result := IntToStr(CPS div 1024000000) + 'gbps';
end;
procedure DivMod(Dividend: Integer; Divisor: Word;
var Result, Remainder: Word);
asm
PUSH EBX
MOV EBX,EDX
MOV EDX,EAX
SHR EDX,16
DIV BX
MOV EBX,Remainder
MOV [ECX],AX
MOV [EBX],DX
POP EBX
end;
function GetUserName: string;
var
N: DWord;
Buf: array[0..1023] of char;
begin
N := SizeOf(Buf) - 1;
Windows.GetUserName(Buf, N);
Result := Pansichar(@Buf[0]);
end;
function GetComputerName: string;
var
N: DWORD;
Buf: array[0..16] of char;
begin
N := SizeOf(Buf) - 1;
Windows.GetComputerName(Buf, N);
Result := Pansichar(@Buf[0]);
end;
function GetAbsoluteFileName(CurrentDir, RelativeName: ansistring): ansistring;
function IncPtr(P: Pointer; Delta: Longint): Pointer; register;
asm
add eax, edx
end;
function IsAbsoluteFileName(FileName: ansistring): Boolean;
var
P: PWord;
begin
P := PWord(Pansichar(FileName));
Result := P^ = $5C5C; // Network name
if not Result then begin
P := IncPtr(P, 1);
Result := P^ = $5C3A; // Local name
end;
end;
procedure RemoveLastSubDir(var Dir: ansistring);
var
P: Longint;
begin
P := Length(Dir);
while (P > 0) and (Dir[P] <> '\') do Dec(P);
if P = 0 then Dir := '' else Dir := Copy(Dir, 1, P - 1);
end;
function FindDots(Name: ansistring; var P: Longint): Longint;
var
Ptr: PInteger;
begin
Ptr := IncPtr(Pansichar(Name), P);
while (P >= 0) and ((Ptr^ and $00FFFFFF) <> $5C2E2E) do begin
Dec(P);
Ptr := IncPtr(Ptr, -1);
end;
Inc(P);
Result := P;
end;
var
Drive: ansistring;
begin
if IsAbsoluteFileName(RelativeName) then Result := RelativeName
else begin
if Copy(CurrentDir, Length(CurrentDir), 1) = '\' then Delete(CurrentDir, Length(CurrentDir), 1);
if Copy(RelativeName, 1, 1) = '\' then Delete(RelativeName, 1, 1);
Drive := ExtractFileDrive(CurrentDir);
Delete(CurrentDir, 1, Length(Drive) + 1);
Result := IncludeTrailingBackslash(Drive + '\' + CurrentDir) + RelativeName;
end;
end;
function GetTempDirectory: string;
var
Buf: array[0..MAX_PATH - 1] of char;
begin
GetTempPath(SizeOf(Buf), @Buf);
Result := IncludeTrailingBackslash(Pansichar(@Buf));
end;
function GetTempFile(const ThreeLetterPrefix: string): string;
var
Buf: array[0..MAX_PATH - 1] of char;
begin
GetTempFileName(Pchar(GetTempDirectory), Pchar(ThreeLetterPrefix), 0, @Buf);
Result := Pansichar(@Buf);
end;
//==============================================================================
{$IFDEF LINUX}
function WSAGetLastError: Integer;
begin
Result := System.GetLastError
end;
{$ENDIF}
function CreateSocket(sin_family, socket_type, protocol: integer;
var ErrorCode: Integer): TSocket;
begin
ErrorCode := 0;
Result := {$IFDEF LINUX}Libc.
{$ELSE}Winsock.
{$ENDIF}Socket(sin_family, socket_type, protocol);
if Result = Invalid_Socket then ErrorCode := WSAGetLastError;
end;
function SetErrorCode(ResultCode: Integer): Integer;
begin
if ResultCode = Socket_Error then Result := WSAGetLastError
else Result := 0;
end;
procedure SetNagle(Sock: TSocket;
TurnOn: Boolean;
var ErrorCode: Integer);
var
TA: array[0..3] of ansichar;
begin
if not TurnOn then TA := '1111'
else TA := '0000';
ErrorCode := SetErrorCode(SetSockOpt(Sock, IPPROTO_TCP, TCP_NODELAY, @TA, SizeofInt));
end;
procedure SetBlocking(Sock: TSocket;
UseBlocking: Boolean;
var ErrorCode: Integer);
{$IFDEF LINUX}
const
FIONBIO = $5421;
{$ENDIF}
var
{$IFDEF VER90}
iBlocking: u_long;
{$ELSE}
iBlocking: Integer;
{$ENDIF}
begin
if UseBlocking then iBlocking := 0
else iBlocking := 1;
ErrorCode := SetErrorCode(
{$IFDEF VER90}
Winsock.ioctlsocket(Sock, FIONBIO, iBlocking)
{$ELSE}
{$IFDEF LINUX}Libc.ioctl(Sock, FIONBIO, iBlocking)
{$ELSE}Winsock.ioctlsocket(Sock, FIONBIO, iBlocking)
{$ENDIF}
{$ENDIF}
);
end;
procedure SetReceiveTimeout(Sock: TSocket;
TimeoutMS: Integer;
var ErrorCode: Integer);
begin
ErrorCode := SetErrorCode(setsockopt(Sock, SOL_SOCKET, SO_RCVTIMEO, @TimeoutMS, SizeOfInt));
end;
procedure SetSendTimeout(Sock: TSocket;
TimeoutMS: Integer;
var ErrorCode: Integer);
begin
ErrorCode := SetErrorCode(setsockopt(Sock, SOL_SOCKET, SO_SNDTIMEO, @TimeoutMS, SizeofInt));
end;
procedure SetReceiveBuffer(Sock: TSocket;
WantedSize: Integer;
var ErrorCode: Integer);
begin
ErrorCode := SetErrorCode(setsockopt(Sock, SOL_SOCKET, SO_RCVBUF, @WantedSize, SizeofInt));
end;
procedure ResetBufferAndTimeout(Sock: TSocket;
TimeoutMS: Integer;
WantedSize: Integer);
begin
setsockopt(Sock, SOL_SOCKET, SO_SNDTIMEO, @TimeoutMS, SizeofInt);
setsockopt(Sock, SOL_SOCKET, SO_RCVTIMEO, @TimeoutMS, SizeOfInt);
setsockopt(Sock, SOL_SOCKET, SO_RCVBUF, @WantedSize, SizeofInt);
setsockopt(Sock, SOL_SOCKET, SO_SNDBUF, @WantedSize, SizeofInt);
end;
function GetSockStatusBool(Sock: TSocket;
SO_Flag: Integer;
var ErrorCode: Integer): Boolean;
var
Rslt: Boolean;
begin
// 7-27
ErrorCode := SetErrorCode(GetSockOpt(Sock, SOL_SOCKET, SO_Flag, Pansichar(@Rslt), SizeofInt));
if ErrorCode = 0 then Result := Rslt
else Result := False;
end;
function GetSockStatusInt(Sock: TSocket;
SO_Flag: Integer;
var ErrorCode: Integer): Integer;
var
Rslt: Integer;
begin
// 7-27
ErrorCode := SetErrorCode(GetSockOpt(Sock, SOL_SOCKET, SO_Flag, Pansichar(@Rslt), SizeofInt));
if ErrorCode = 0 then Result := Rslt
else Result := 0;
end;
procedure SetSockStatusBool(Sock: TSocket;
SO_Flag: Integer;
Setting: Boolean;
var ErrorCode: Integer);
var
intval: integer;