📄 sockets.pas
字号:
begin
if (Index < 0) or (Index > FCount) then
Exit;
if FCount = FCapacity then
Grow;
if Index < FCount then
System.Move(FList^[Index], FList^[Index + 1],
(FCount - Index) * SizeOf(Pointer));
FList^[Index] := Item;
Inc(FCount);
if Item <> nil then
Notify(Item, lnAdded);
end;
function TList.Last: Pointer;
begin
Result := Get(FCount - 1);
end;
procedure TList.Move(CurIndex, NewIndex: Integer);
var
Item: Pointer;
begin
if CurIndex <> NewIndex then
begin
if (NewIndex < 0) or (NewIndex >= FCount) then
Exit;
Item := Get(CurIndex);
FList^[CurIndex] := nil;
Delete(CurIndex);
Insert(NewIndex, nil);
FList^[NewIndex] := Item;
end;
end;
procedure TList.Put(Index: Integer; Item: Pointer);
var
Temp: Pointer;
begin
if (Index < 0) or (Index >= FCount) then
Exit;
if Item <> FList^[Index] then
begin
Temp := FList^[Index];
FList^[Index] := Item;
if Temp <> nil then
Notify(Temp, lnDeleted);
if Item <> nil then
Notify(Item, lnAdded);
end;
end;
function TList.Remove(Item: Pointer): Integer;
begin
Result := IndexOf(Item);
if Result >= 0 then
Delete(Result);
end;
procedure TList.Pack;
var
I: Integer;
begin
for I := FCount - 1 downto 0 do
if Items[I] = nil then
Delete(I);
end;
procedure TList.SetCapacity(NewCapacity: Integer);
begin
if (NewCapacity < FCount) or (NewCapacity > MaxListSize) then
Exit;
if NewCapacity <> FCapacity then
begin
ReallocMem(FList, NewCapacity * SizeOf(Pointer));
FCapacity := NewCapacity;
end;
end;
procedure TList.SetCount(NewCount: Integer);
var
I: Integer;
begin
if (NewCount < 0) or (NewCount > MaxListSize) then
Exit;
if NewCount > FCapacity then
SetCapacity(NewCount);
if NewCount > FCount then
FillChar(FList^[FCount], (NewCount - FCount) * SizeOf(Pointer), 0)
else
for I := FCount - 1 downto NewCount do
Delete(I);
FCount := NewCount;
end;
procedure QuickSort(SortList: PPointerList; L, R: Integer;
SCompare: TListSortCompare);
var
I, J: Integer;
P, T: Pointer;
begin
repeat
I := L;
J := R;
P := SortList^[(L + R) shr 1];
repeat
while SCompare(SortList^[I], P) < 0 do
Inc(I);
while SCompare(SortList^[J], P) > 0 do
Dec(J);
if I <= J then
begin
T := SortList^[I];
SortList^[I] := SortList^[J];
SortList^[J] := T;
Inc(I);
Dec(J);
end;
until I > J;
if L < J then
QuickSort(SortList, L, J, SCompare);
L := I;
until I >= R;
end;
procedure TList.Sort(Compare: TListSortCompare);
begin
if (FList <> nil) and (Count > 0) then
QuickSort(FList, 0, Count - 1, Compare);
end;
function TList.Extract(Item: Pointer): Pointer;
var
I: Integer;
begin
Result := nil;
I := IndexOf(Item);
if I >= 0 then
begin
Result := Item;
FList^[I] := nil;
Delete(I);
Notify(Result, lnExtracted);
end;
end;
procedure TList.Notify(Ptr: Pointer; Action: TListNotification);
begin
//nothing
end;
procedure TList.Assign(ListA: TList; AOperator: TListAssignOp; ListB: TList);
var
I: Integer;
LTemp, LSource: TList;
begin
if ListB <> nil then
begin
LSource := ListB;
Assign(ListA);
end
else
LSource := ListA;
case AOperator of
laCopy:
begin
Clear;
Capacity := LSource.Capacity;
for I := 0 to LSource.Count - 1 do
Add(LSource[I]);
end;
laAnd:
for I := Count - 1 downto 0 do
if LSource.IndexOf(Items[I]) = -1 then
Delete(I);
laOr:
for I := 0 to LSource.Count - 1 do
if IndexOf(LSource[I]) = -1 then
Add(LSource[I]);
laXor:
begin
LTemp := TList.Create;
try
LTemp.Capacity := LSource.Count;
for I := 0 to LSource.Count - 1 do
if IndexOf(LSource[I]) = -1 then
LTemp.Add(LSource[I]);
for I := Count - 1 downto 0 do
if LSource.IndexOf(Items[I]) <> -1 then
Delete(I);
I := Count + LTemp.Count;
if Capacity < I then
Capacity := I;
for I := 0 to LTemp.Count - 1 do
Add(LTemp[I]);
finally
LTemp.Free;
end;
end;
laSrcUnique:
for I := Count - 1 downto 0 do
if LSource.IndexOf(Items[I]) <> -1 then
Delete(I);
laDestUnique:
begin
LTemp := TList.Create;
try
LTemp.Capacity := LSource.Count;
for I := LSource.Count - 1 downto 0 do
if IndexOf(LSource[I]) = -1 then
LTemp.Add(LSource[I]);
Assign(LTemp);
finally
LTemp.Free;
end;
end;
end;
end;
{ TThread }
type
TSyncProc = record
Thread: TThread;
Signal: THandle;
end;
PSyncProc = ^TSyncProc;
var
ProcPosted: Boolean;
SyncList: TList = nil;
ThreadLock: TRTLCriticalSection;
ThreadCount: Integer;
WakeMainThread: TNotifyEvent = nil;
procedure AddThread;
begin
EnterCriticalSection(ThreadLock);
try
if (ThreadCount = 0) and (SyncList = nil) then
SyncList := TList.Create;
Inc(ThreadCount);
finally
LeaveCriticalSection(ThreadLock);
end;
end;
procedure RemoveThread;
begin
EnterCriticalSection(ThreadLock);
try
Dec(ThreadCount);
finally
LeaveCriticalSection(ThreadLock);
end;
end;
function CheckSynchronize: Boolean;
var
SyncProc: PSyncProc;
begin
Result := False;
if GetCurrentThreadID <> MainThreadID then
Exit;
if ProcPosted then
begin
EnterCriticalSection(ThreadLock);
try
Result := (SyncList <> nil) and (SyncList.Count > 0);
if Result then
begin
while SyncList.Count > 0 do
begin
SyncProc := SyncList[0];
SyncList.Delete(0);
try
SyncProc.Thread.FMethod;
except
SyncProc.Thread.FSynchronizeException := AcquireExceptionObject;
end;
SetEvent(SyncProc.signal);
end;
ProcPosted := False;
end;
finally
LeaveCriticalSection(ThreadLock);
end;
end else Result := False;
end;
function ThreadProc(Thread: TThread): Integer;
var
FreeThread: Boolean;
begin
try
if not Thread.Terminated then
try
Thread.Execute;
except
Thread.FFatalException := AcquireExceptionObject;
end;
finally
FreeThread := Thread.FFreeOnTerminate;
Result := Thread.FReturnValue;
Thread.FFinished := True;
Thread.DoTerminate;
if FreeThread then Thread.Free;
EndThread(Result);
end;
end;
constructor TThread.Create(CreateSuspended: Boolean);
begin
inherited Create;
AddThread;
FSuspended := CreateSuspended;
FCreateSuspended := CreateSuspended;
FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
end;
destructor TThread.Destroy;
begin
if (FThreadID <> 0) and not FFinished then
begin
Terminate;
if FCreateSuspended then
Resume;
WaitFor;
end;
if FHandle <> 0 then CloseHandle(FHandle);
inherited Destroy;
FFatalException.Free;
RemoveThread;
end;
procedure TThread.AfterConstruction;
begin
if not FCreateSuspended then
Resume;
end;
procedure TThread.CheckThreadError(ErrCode: Integer);
begin
end;
procedure TThread.CheckThreadError(Success: Boolean);
begin
if not Success then
CheckThreadError(GetLastError);
end;
procedure TThread.CallOnTerminate;
begin
if Assigned(FOnTerminate) then FOnTerminate(Self);
end;
procedure TThread.DoTerminate;
begin
if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;
const
Priorities: array [TThreadPriority] of Integer =
(THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL,
THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL,
THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL);
function TThread.GetPriority: TThreadPriority;
var
P: Integer;
I: TThreadPriority;
begin
P := GetThreadPriority(FHandle);
CheckThreadError(P <> THREAD_PRIORITY_ERROR_RETURN);
Result := tpNormal;
for I := Low(TThreadPriority) to High(TThreadPriority) do
if Priorities[I] = P then Result := I;
end;
procedure TThread.SetPriority(Value: TThreadPriority);
begin
CheckThreadError(SetThreadPriority(FHandle, Priorities[Value]));
end;
procedure TThread.Synchronize(Method: TThreadMethod);
var
SyncProc: TSyncProc;
begin
SyncProc.Signal := CreateEvent(nil, True, False, nil);
try
EnterCriticalSection(ThreadLock);
try
FSynchronizeException := nil;
FMethod := Method;
SyncProc.Thread := Self;
SyncList.Add(@SyncProc);
ProcPosted := True;
if Assigned(WakeMainThread) then
WakeMainThread(Self);
LeaveCriticalSection(ThreadLock);
try
WaitForSingleObject(SyncProc.Signal, INFINITE);
finally
EnterCriticalSection(ThreadLock);
end;
finally
LeaveCriticalSection(ThreadLock);
end;
finally
CloseHandle(SyncProc.Signal);
end;
if Assigned(FSynchronizeException) then raise FSynchronizeException;
end;
procedure TThread.SetSuspended(Value: Boolean);
begin
if Value <> FSuspended then
if Value then
Suspend else
Resume;
end;
procedure TThread.Suspend;
begin
FSuspended := True;
CheckThreadError(Integer(SuspendThread(FHandle)) >= 0);
end;
procedure TThread.Resume;
var
SuspendCount: Integer;
begin
SuspendCount := ResumeThread(FHandle);
CheckThreadError(SuspendCount >= 0);
if SuspendCount = 1 then
FSuspended := False;
end;
procedure TThread.Terminate;
begin
FTerminated := True;
end;
function TThread.WaitFor: LongWord;
var
H: THandle;
WaitResult: Cardinal;
Msg: TMsg;
begin
H := FHandle;
if GetCurrentThreadID = MainThreadID then
begin
WaitResult := 0;
repeat
if WaitResult = WAIT_OBJECT_0 + 1 then
PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
Sleep(0);
CheckSynchronize;
WaitResult := MsgWaitForMultipleObjects(1, H, False, 0, QS_SENDMESSAGE);
until WaitResult = WAIT_OBJECT_0;
end else WaitForSingleObject(H, INFINITE);
CheckThreadError(GetExitCodeThread(H, Result));
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -