分享

TStringList的源代码

 quasiceo 2013-01-19

TStringList的源代码

  PStringItem = ^TStringItem;
  TStringItem = record
    FString: string;
    FObject: TObject;
  end;

  PStringItemList = ^TStringItemList;
  TStringItemList = array[0..MaxListSize] of TStringItem;

一个非常大的结构体数组。

 

  TStringList = class(TStrings)
  private
    FList: PStringItemList;
    FCount: Integer;
    FCapacity: Integer;
    FSorted: Boolean;

 

function TStringList.Get(Index: Integer): string; 
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Result := FList^[Index].FString;
end;//返回的是字符串,而不是对象。

 

function TStringList.GetObject(Index: Integer): TObject;
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Result := FList^[Index].FObject;//返回的是对象
end;

 

function TStringList.GetCount: Integer;
begin
  Result := FCount;
end;//元素个数

function TStringList.GetCapacity: Integer;
begin
  Result := FCapacity;
end;//得到的最大容量

//两个事件.

procedure TStringList.Changed;
begin
  if (FUpdateCount = 0) and Assigned(FOnChange) then
    FOnChange(Self);
end;

 

 

procedure TStringList.Changing;
begin
  if (FUpdateCount = 0) and Assigned(FOnChanging) then
    FOnChanging(Self);
end;

 

type

  Str18 = string[18];
 var
  P: ^Str18;
begin
  New(P);
  P^ := 'Now you see it...';
  Dispose(P); { Now you don't... }
end;

Use Dispose in Delphi code to free the memory which a pointer addresses. After a call to Dispose, the value of P is undefined and it is an error to reference P.

 

You can create dynamic variables by calling the GetMem or New procedure. Such variables are allocated on the heap and are not managed automatically. Once you create one, it is your responsibility ultimately to free the variable's memory; use FreeMem to destroy variables created by GetMem and Dispose to destroy variables created by New. Other standard routines that operate on dynamic variables include ReallocMem, AllocMem, Initialize, Finalize, StrAlloc, and StrDispose.

Long strings, wide strings, dynamic arrays, variants, and interfaces are also heap-allocated dynamic variables, but their memory is managed automatically.

 

procedure TStringList.Put(Index: Integer; const S: string);
begin
  if Sorted then Error(@SSortedListError, 0);
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  FList^[Index].FString := S;
  Changed;
end;

procedure TStringList.PutObject(Index: Integer; AObject: TObject);
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  FList^[Index].FObject := AObject;
  Changed;
end;

 

procedure TStringList.Delete(Index: Integer); //删除一个元素。
begin
  if (Index < 0) or (Index >= FCount) then Error(@SListIndexError, Index);
  Changing;
  Finalize(FList^[Index]);
  Dec(FCount);
  if Index < FCount then
    System.Move(FList^[Index + 1], FList^[Index],
      (FCount - Index) * SizeOf(TStringItem));
  Changed;
end;

 

 

procedure TStringList.CustomSort(Compare: TStringListSortCompare);//使用快速排序功能
begin
  if not Sorted and (FCount > 1) then
  begin
    Changing;
    QuickSort(0, FCount - 1, Compare);
    Changed;
  end;
end;

 

procedure TStringList.Sort;  //排序调用此函数, 该函数调用快速排序功能。
begin
  CustomSort(StringListCompareStrings);
end;

 

function TStringList.Find(const S: string; var Index: Integer): Boolean;
var
  L, H, I, C: Integer;
begin
  Result := False;
  L := 0;
  H := FCount - 1;
  while L <= H do
  begin
    I := (L + H) shr 1;//使用折半查找。
    C := CompareStrings(FList^[I].FString, S);
    if C < 0 then L := I + 1 else
    begin
      H := I - 1;
      if C = 0 then
      begin
        Result := True;
        if Duplicates <> dupAccept then L := I;
      end;
    end;
  end;
  Index := L;
end;

 

procedure TStrings.BeginUpdate;  //开始更新, 根据更新次数来设置更新状态. 是更新次数加1。
begin
  if FUpdateCount = 0 then SetUpdateState(True);
  Inc(FUpdateCount);
end;

 

 

procedure TStringList.SetUpdateState(Updating: Boolean);// 根据状态来调用事件。
begin
  if Updating then Changing else Changed;  //调用Changing事件。
end;

 

procedure TStrings.EndUpdate; //减少更新次数。设置更新状态。
begin
  Dec(FUpdateCount);
  if FUpdateCount = 0 then SetUpdateState(False);  调用Changed事件
end;

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约