⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sortlists.pas

📁 由delphi实现的bt下载器示例程序
💻 PAS
📖 第 1 页 / 共 3 页
字号:

      if e >= n then
      begin
        system.Move(list[e+1], list[n], (count-e-1) * 4);
        dec(TListRef(self).FCount, e-n+1);
      end;
    finally
      unlock;
    end;
  except
  end;
end;

procedure TRuler.InvalidRange(BPos, Len: Cardinal);
var
  b, e, c, n: Integer;
  v : Cardinal;
begin
  if len = 0 then exit;
  try
    lock;
    try
      v := bpos + len;
      b := 0;
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if BPos < Cardinal(Items[c]) then
          e := c - 1
        else if BPos > Cardinal(Items[c]) then
          b := c + 1
        else begin
          b := c;
          break;
        end;
      end;
      if b >= count then
      begin
        add(pointer(bpos));
        add(pointer(v));
        exit;
      end;
      if b and 1 = 0 then
        if cardinal(items[b]) > v then
        begin
          insert(b, pointer(v));
          insert(b, pointer(bpos));
          exit;
        end
        else begin
          items[b] := pointer(bpos);
          inc(b);
        end;

      n := b;
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if v < Cardinal(Items[c]) then
          e := c - 1
        else if v > Cardinal(items[c]) then
          b := c + 1
        else begin
          e := c;
          break;
        end;
      end;

      if e and 1 <> 0 then
      begin
        items[e] := pointer(v);
        dec(e);
      end;

      if e >= n then
      begin
        system.Move(list[e+1], list[n], (count-e-1)*4);
        dec(TListRef(Self).FCount, e-n+1);
      end;
    finally
      unlock;
    end;
  except
  end;
end;

function TRuler.GetValidRange(BPos, EPos: Cardinal;
  var Dest: Pointer): Integer;
var
  b, e, c, n: Integer;
  p: PIntegerArray;
begin
  result := 0;
  try
    lock;
    try
      p := Dest;
      b := 0;
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if BPos < Cardinal(Items[c]) then
          e := c - 1
        else if BPos > Cardinal(Items[c]) then
          b := c + 1
        else begin
          b := c + 1;
          break;
        end;
      end;
      n := b;
      if (n and 1 = 0) then
        dec(n);
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if EPos < cardinal(Items[c]) then
          e := c - 1
        else if EPos > cardinal(Items[c]) then
          b := c + 1
        else begin
          e := c - 1;
          break;
        end;
      end;

      if e and 1 <> 0 then
        inc(e);

      if e <= n then
      begin
        result := 0;
        reallocmem(dest, 0);
      end
      else begin
        result := e - n + 1;
        reallocmem(p, result * 4);
        if n < 0 then
        begin
          p[0] := BPos;
          if count > 0 then
            system.Move(list[0], p[1], (result - 1) * 4)
          else
            p[1] := EPos;
        end
        else if e >=count  then
        begin
          system.Move(list[n], p[0], (result-1) * 4);
          p[result-1] := EPos;
        end
        else system.Move(list[n], p[0], result * 4);
        if cardinal(p[0]) < BPos then
          p[0] := bpos;
        if cardinal(p[result-1]) > EPos then
          p[result-1] := EPos;
        Dest := p;
      end;
    finally
      unlock;
    end;
  except
  end;
end;

function TRuler.GetValidRange(BPos, EPos: Cardinal): string;
var
  b, e, c, n, l: Integer;
  p: PIntegerArray;
begin
  try
    lock;
    try
      b := 0;
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if BPos < Cardinal(Items[c]) then
          e := c - 1
        else if BPos > Cardinal(Items[c]) then
          b := c + 1
        else begin
          b := c+1;
          break;
        end;
      end;
      n := b;
      if (n and 1 = 0) then
        dec(n);
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if EPos < cardinal(Items[c]) then
          e := c - 1
        else if EPos > cardinal(Items[c]) then
          b := c + 1
        else begin
          e := c - 1;
          break;
        end;
      end;
      if e and 1 <> 0 then
        inc(e);
      if e <= n then
      begin
        result := '';
      end
      else begin
        l := e - n + 1;
        setlength(result, l * 4);
        p := pointer(result);
        if n < 0 then
        begin
          p[0] := BPos;
          if count > 0 then
            system.Move(list[0], p[1], (l - 1) * 4)
          else
            p[1] := EPos;
        end
        else if b >=count  then
        begin
          system.Move(list[n], p[0], (l-1) * 4);
          p[l-1] := EPos;
        end
        else system.Move(list[n], p[0], l * 4);
        if cardinal(p[0]) < BPos then
          p[0] := bpos;
        if cardinal(p[l-1]) > EPos then
          p[l-1] := EPos;
      end;
    finally
      unlock;
    end;
  except
  end;
end;

function TRuler.GetInvalidRange(BPos, EPos: Cardinal;
  var Dest: Pointer): Integer;
var
  b, e, c, n: Integer;
  p: PIntegerArray;
begin
  result := 0;
  try
    lock;
    try
      p := Dest;
      b := 0;
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if BPos < Cardinal(Items[c]) then
          e := c - 1
        else if BPos > Cardinal(Items[c]) then
          b := c + 1
        else begin
          b := c+1;
          break;
        end;
      end;
      n := b;
      if (n and 1 <> 0) then
        Dec(n);
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if EPos < cardinal(Items[c]) then
          e := c - 1
        else if EPos > cardinal(Items[c]) then
          b := c + 1
        else begin
          e := c - 1;
          break;
        end;
      end;
      if e and 1 = 0 then
          Inc(e);
      if e <= n then
      begin
        result := 0;
        reallocmem(dest, 0);
      end
      else begin
        result := e - n + 1;
        reallocmem(p, result * 4);
        if n < 0 then
        begin
          p[0] := BPos;
          system.Move(list[0], p[1], (result - 1) * 4);
        end
        else if e >=count  then
        begin
          system.Move(list[n], p[0], (result-1) * 4);
          p[result-1] := EPos;
        end
        else system.Move(list[n], p[0], result * 4);
        if cardinal(p[0]) < BPos then
          p[0] := bpos;
        if cardinal(p[result-1]) > EPos then
          p[result-1] := EPos;
        Dest := p;
      end;
    finally
      unlock;
    end;
  except
  end;
end;

function TRuler.GetInvalidRange(BPos, EPos: Cardinal): string;
var
  b, e, c, n, l: Integer;
  p: PIntegerArray;
begin
  try
    lock;
    try
      b := 0;
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if BPos < Cardinal(Items[c]) then
          e := c - 1
        else if BPos > Cardinal(Items[c]) then
          b := c + 1
        else begin
          b := c + 1;
          break;
        end;
      end;
      n := b;
      if (n and 1 <> 0) then
        Dec(n);
      e := count - 1;
      while b <= e do
      begin
        c := (b + e) shr 1;
        if EPos < cardinal(Items[c]) then
          e := c - 1
        else if EPos > cardinal(Items[c]) then
          b := c + 1
        else begin
          e := c - 1;
          break;
        end;
      end;
      if e and 1 = 0 then
        Inc(e);
      if e <= n then
        result := ''
      else begin
        l := e - n + 1;
        setlength(result, l * 4);
        p := pointer(result);
        if n < 0 then
        begin
          p[0] := BPos;
          system.Move(list[0], p[1], (l - 1) * 4);
        end
        else if e >=count  then
        begin
          system.Move(list[n], p[0], (l-1) * 4);
          p[l-1] := EPos;
        end
        else system.Move(list[n], p[0], l * 4);
        if cardinal(p[0]) < BPos then
          p[0] := bpos;
        if cardinal(p[l-1]) > EPos then
          p[l-1] := EPos;
      end;
    finally
      unlock;
    end;
  except
  end;
end;

procedure TRuler.InvertRuler(BPos, EPos: Cardinal);
var
  p: Pointer;
  l: Integer;
begin
  try
    lock;
    try
      p := nil;
      l := getvalidrange(bpos, epos, p);
      with TListRef(self) do
      begin
        reallocmem(FList, 0);
        FCount := l;
        FCapacity := l;
        FList := p;
      end;
    finally
      unlock;
    end;
  except
  end;
end;

procedure TRuler.CombineWithInvalid(ARuler: TRuler);
var
  i, b, e, l, dtlen: Integer;
  dt: pointer;
begin
  try
    lock;
    try
      dt := nil;
      i := 0;
      capacity := count + ARuler.Count;
      while i < count do
      begin
        dtlen := aruler.GetInvalidRange(cardinal(Items[i]), cardinal(Items[i+1]), dt);
        if capacity < count + dtlen-2 then
          capacity := count + dtlen - 2;
        b := i+2;
        e := i + dtlen;
        l := count - b;
        system.Move(list[b], list[e], l * 4);
        if dtlen > 0 then
          system.Move(dt^, list[i], dtlen * 4);
        inc(TListRef(Self).FCount, dtlen - 2);
        Inc(i, 2);
      end;
      reallocmem(dt, 0);
    finally
      unlock;
    end;
  except
  end;
end;

procedure TRuler.CombineWithValid(ARuler: TRuler);
var
  i, b, e, l, dtlen: Integer;
  dt: pointer;
begin
  try
    lock;
    try
      dt := nil;
      i := 0;
      capacity := count + aruler.Count;
      while i < count do
      begin
        dtlen := aruler.GetValidRange(cardinal(items[i]), cardinal(Items[I+1]), dt);
        if capacity < count + dtlen - 2 then
          capacity := count + dtlen - 2;
        b := i + 2;
        e := i + dtlen;
        l := count - b;
        system.Move(list[b], list[e], l * 4);
        if dtlen > 0 then
          system.Move(dt^, list[i], dtlen * 4);
        inc(TListRef(Self).FCount, dtlen - 2);
      end;
      reallocmem(dt, 0);
    finally
      unlock;
    end;
  except
  end;
end;

procedure TRuler.CopyInvalidFrom(ARuler: TRuler; BPos, EPos: Cardinal);
var
  dt: Pointer;
  dtLen: Integer;
begin
  try
    lock;
    try
      dt := nil;
      dtlen := aruler.GetInvalidRange(bpos, epos, dt);
      with TListRef(Self) do
      begin
        reallocmem(FList, 0);
        FList := dt;
        fcount := dtlen;
        fcapacity := dtlen;
      end;
    finally
      unlock;
    end;
  except
  end;
end;

procedure TRuler.CopyValidFrom(ARuler: TRuler; BPos, EPos: Cardinal);
var
  dt: Pointer;
  dtLen: Integer;
begin
  try
    lock;
    try
      dt := nil;
      dtlen := aruler.GetValidRange(bpos, epos, dt);
      with TListRef(Self) do
      begin
        reallocmem(FList, 0);
        FList := dt;
        fcount := dtlen;
        fcapacity := dtlen;
      end;
    finally
      unlock;
    end;
  except
  end;
end;

procedure TRuler.Lock;
begin
  entercriticalsection(flock);
end;

procedure TRuler.Unlock;
begin
  leavecriticalsection(flock);
end;

//procedure TRuler.AddRef;
//begin
//  interlockedincrement(fref);
//end;

//procedure TRuler.ReleaseRef;
//begin
//  if interlockeddecrement(fref)<0 then
//    free;
//end;

function TRuler.GetInnerData: string;
begin
  result := '';
  try
    Lock;
    try
      setlength(result, count * 4);
      if count > 0 then
        system.Move(list^, result[1], count * 4);
    finally
      Unlock;
    end;
  except
  end;
end;

procedure TRuler.SetInnerData(s: string);
var
  l: Integer;
begin
  try
    Lock;
    try
      l := Length(s) div 4;
      with TListRef(Self) do
        if l = 0 then
        begin
          reallocmem(flist, 0);
          fcount := 0;
          fcapacity := 0;
        end
        else begin
          if l > fcapacity then
          begin
            reallocmem(flist, l * 4);
            fcapacity := l;
          end;
          system.Move(s[1], list^, l * 4);
          fcount := l;
        end;
    finally
      Unlock;
    end;
  except
  end;
end;

procedure TRuler.SetInnerData(const Buf; Cnt: Integer);
begin
  try
    Lock;
    try
      with TListRef(Self) do
        if Cnt = 0 then
        begin
          reallocmem(flist, 0);
          fcount := 0;
          fcapacity := 0;
        end
        else begin
          if cnt > fcapacity then
          begin
            reallocmem(flist, cnt * 4);
            fcapacity := cnt;
          end;
          system.Move(buf, flist^, cnt * 4);
          fcount := cnt;
        end;
    finally
      Unlock;
    end;
  except
  end;
end;

function TRuler.GetInvalidBlock(RangeB, RangeE: Cardinal; IsRand: Boolean;
  var BPos, Len: Cardinal): Boolean;
begin
  result := false;
  try
    Lock;
    try
      result := combineInvalid(List, count, rangeb, rangee, RangeE-RangeB, isrand, bpos, len);
    finally
      Unlock;
    end;
  except
  end;
end;

function TRuler.GetValidBlock(RangeB, RangeE: Cardinal; IsRand: Boolean;
  var BPos, Len: Cardinal): Boolean;
begin
  result := false;
  try
    Lock;
    try
      result := combinevalid(list, count, rangeb, rangee, rangee-rangeb, isrand, bpos, len);
    finally
      Unlock;
    end;
  except
  end;
end;

function TRuler.GetCount: Integer;
begin
  Lock;
  try
    result := inherited Count;
  finally
    Unlock;
  end;
end;

procedure TRuler.SetCount(const Value: Integer);
begin
  try
    Lock;
    try
      inherited Count := Value;
    finally
      Unlock;
    end;
  except
  end;
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -