<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: pascal code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Thu, 24 Jul 2008 23:14:00 GMT</pubDate>
    <description>DZone Snippets: pascal code</description>
    <item>
      <title>Thread Process //Pascal class</title>
      <link>http://snippets.dzone.com/posts/show/5729</link>
      <description>A thread class to open processes on windows and retrieve its output (input isn't supported but it's easy to add).&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unit Process;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Windows, Classes, TLHelp32;&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  INITIALIZATION_TIMEOUT = 10000;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TStringArray = array of string;&lt;br /&gt;  TProcessArray = array of Cardinal;&lt;br /&gt;  TExceptionEvent = procedure(Sender: TObject; Exception: Exception) of object;&lt;br /&gt;  EProcessError = class(Exception);&lt;br /&gt;&lt;br /&gt;  TProcessThread = class(TThread)&lt;br /&gt;  private&lt;br /&gt;    FException: Exception;&lt;br /&gt;    FWatching, FStarted, FSuspended: Boolean;&lt;br /&gt;    FDirectory, FPath, FCommandLine, FEnvironment: PChar;&lt;br /&gt;    FData: string;&lt;br /&gt;    FOnProcessTerminated, FOnDataAvailable: TNotifyEvent;&lt;br /&gt;    InputRead, InputWrite, OutputRead, OutputWrite: THandle;&lt;br /&gt;    FMainProcess: PROCESS_INFORMATION;&lt;br /&gt;    FOnException: TExceptionEvent;&lt;br /&gt;    FOnProcessStarted: TNotifyEvent;&lt;br /&gt;    function GetPriority: TThreadPriority;&lt;br /&gt;    procedure SetPriority(const Value: TThreadPriority);&lt;br /&gt;    procedure FreeResources;&lt;br /&gt;  protected&lt;br /&gt;    procedure CallDataAvailable; virtual;&lt;br /&gt;    procedure CallProcessTerminated; virtual;&lt;br /&gt;    procedure CallProcessOpened; virtual;&lt;br /&gt;    procedure CallException; virtual;&lt;br /&gt;    procedure Execute; override;&lt;br /&gt;  public&lt;br /&gt;    constructor Create(Path, CommandLine, Directory: string; Environment: TStrings = nil; Watch: Boolean = True);&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;&lt;br /&gt;    function IsProcessAlive: Boolean;&lt;br /&gt;    procedure Resume;&lt;br /&gt;    procedure Suspend;&lt;br /&gt;    property OnDataAvailable: TNotifyEvent read FOnDataAvailable write FOnDataAvailable;&lt;br /&gt;    property OnProcessTerminated: TNotifyEvent read FOnProcessTerminated write FOnProcessTerminated;&lt;br /&gt;    property OnProcessStarted: TNotifyEvent read FOnProcessStarted write FOnProcessStarted;&lt;br /&gt;    property OnException: TExceptionEvent read FOnException write FOnException;&lt;br /&gt;    property Data: string read FData;&lt;br /&gt;    property Process: PROCESS_INFORMATION read FMainProcess;&lt;br /&gt;    property Priority: TThreadPriority read GetPriority write SetPriority;&lt;br /&gt;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TProcessLineThread = class;&lt;br /&gt;  TOnNewLineEvent = procedure(ProcessLine:  TProcessLineThread; const Line: string) of object;&lt;br /&gt;  TProcessLineThread = class(TProcessThread)&lt;br /&gt;  private&lt;br /&gt;    FCurrentLine: string;&lt;br /&gt;    FOnNewLine: TOnNewLineEvent;&lt;br /&gt;    procedure DataAvailable(Sender: TObject);&lt;br /&gt;    procedure Finished(Sender: TObject);&lt;br /&gt;  public&lt;br /&gt;    constructor Create(Path, CommandLine, Directory: string; Environment: TStrings = nil);&lt;br /&gt;    property OnNewLine: TOnNewLineEvent read FOnNewLine write FOnNewLine;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;function KillProcess(const Process: Cardinal): Boolean;&lt;br /&gt;function GetChildrenProcesses(const Process: Cardinal; const IncludeParent: Boolean = True): TProcessArray;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  Priorities: array [TThreadPriority] of Integer =&lt;br /&gt;   (THREAD_PRIORITY_IDLE, THREAD_PRIORITY_LOWEST, THREAD_PRIORITY_BELOW_NORMAL,&lt;br /&gt;    THREAD_PRIORITY_NORMAL, THREAD_PRIORITY_ABOVE_NORMAL,&lt;br /&gt;    THREAD_PRIORITY_HIGHEST, THREAD_PRIORITY_TIME_CRITICAL);&lt;br /&gt;&lt;br /&gt;function GetChildrenProcesses(const Process: Cardinal; const IncludeParent: Boolean): TProcessArray;&lt;br /&gt;var&lt;br /&gt;  Snapshot: Cardinal;&lt;br /&gt;  ProcessList: PROCESSENTRY32;&lt;br /&gt;  Current: Integer;&lt;br /&gt;begin&lt;br /&gt;  Current := 0;&lt;br /&gt;  SetLength(Result, 1);&lt;br /&gt;  Result[0] := Process;&lt;br /&gt;  repeat&lt;br /&gt;    ProcessList.dwSize := SizeOf(PROCESSENTRY32);&lt;br /&gt;    Snapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);&lt;br /&gt;    if (Snapshot = INVALID_HANDLE_VALUE) or not Process32First(Snapshot, ProcessList) then&lt;br /&gt;      Continue;&lt;br /&gt;    repeat&lt;br /&gt;      if ProcessList.th32ParentProcessID = Result[Current] then&lt;br /&gt;      begin&lt;br /&gt;        SetLength(Result, Length(Result) + 1);&lt;br /&gt;        Result[Length(Result) - 1] := ProcessList.th32ProcessID;&lt;br /&gt;      end;&lt;br /&gt;    until Process32Next(Snapshot, ProcessList) = False;&lt;br /&gt;    Inc(Current);&lt;br /&gt;  until Current &gt;= Length(Result);&lt;br /&gt;  if not IncludeParent then&lt;br /&gt;    Result := Copy(Result, 2, Length(Result));&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function KillProcess(const Process: Cardinal): Boolean;&lt;br /&gt;var&lt;br /&gt;  Handle: Cardinal;&lt;br /&gt;  List: TProcessArray;&lt;br /&gt;  I: Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := True;&lt;br /&gt;  List := GetChildrenProcesses(Process);&lt;br /&gt;  for I := Length(List) - 1 downto 0 do&lt;br /&gt;    if Result then&lt;br /&gt;    begin&lt;br /&gt;      Handle := OpenProcess(PROCESS_TERMINATE, false, List[I]);&lt;br /&gt;      Result := (Handle &lt;&gt; 0) and TerminateProcess(Handle, 0) and CloseHandle(Handle);&lt;br /&gt;    end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TProcessThread }&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.CallDataAvailable;&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FOnDataAvailable) then&lt;br /&gt;    FOnDataAvailable(Self);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.Resume;&lt;br /&gt;var&lt;br /&gt;  SuspendCount: Integer;&lt;br /&gt;begin&lt;br /&gt;  if FStarted then&lt;br /&gt;  begin&lt;br /&gt;    FStarted := True;&lt;br /&gt;    SuspendCount := ResumeThread(FMainProcess.hThread);&lt;br /&gt;    CheckThreadError(SuspendCount &gt;= 0);&lt;br /&gt;    if SuspendCount = 1 then&lt;br /&gt;      FSuspended := False;&lt;br /&gt;  end;&lt;br /&gt;  inherited Resume;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TProcessThread.GetPriority: TThreadPriority;&lt;br /&gt;begin&lt;br /&gt;  if FStarted then&lt;br /&gt;  begin&lt;br /&gt;    CheckThreadError(GetThreadPriority(FMainProcess.hThread) &lt;&gt; THREAD_PRIORITY_ERROR_RETURN);&lt;br /&gt;  end;&lt;br /&gt;  Result := inherited Priority;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TProcessThread.IsProcessAlive: Boolean;&lt;br /&gt;var&lt;br /&gt;  Status: Cardinal;&lt;br /&gt;begin&lt;br /&gt;  GetExitCodeProcess(FMainProcess.hProcess, Status);&lt;br /&gt;  Result := Status = STILL_ACTIVE;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.SetPriority(const Value: TThreadPriority);&lt;br /&gt;begin&lt;br /&gt;  if FStarted then&lt;br /&gt;    CheckThreadError(SetThreadPriority(FMainProcess.hThread, Priorities[Value]));&lt;br /&gt;  inherited Priority := Value;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.Suspend;&lt;br /&gt;var&lt;br /&gt;  OldSuspend: Boolean;&lt;br /&gt;begin&lt;br /&gt;  if FStarted then&lt;br /&gt;  begin&lt;br /&gt;    OldSuspend := FSuspended;&lt;br /&gt;    try&lt;br /&gt;      FSuspended := True;&lt;br /&gt;      CheckThreadError(Integer(SuspendThread(FMainProcess.hThread)) &gt;= 0);&lt;br /&gt;    except&lt;br /&gt;      FSuspended := OldSuspend;&lt;br /&gt;      raise;&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;  inherited Suspend;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.CallException;&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FOnException) then&lt;br /&gt;    FOnException(Self, FException);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.CallProcessOpened;&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FOnProcessStarted) then&lt;br /&gt;    FOnProcessStarted(Self);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.CallProcessTerminated;&lt;br /&gt;begin&lt;br /&gt;  if Assigned(FOnProcessTerminated) then&lt;br /&gt;    FOnProcessTerminated(Self);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor TProcessThread.Create(Path, CommandLine, Directory: string; Environment: TStrings; Watch: Boolean);&lt;br /&gt;var&lt;br /&gt;  Len, I: Integer;&lt;br /&gt;begin&lt;br /&gt;  inherited Create(True);&lt;br /&gt;&lt;br /&gt;  if (Length(CommandLine) &gt; 0) and (Length(Path) &gt; 0) then&lt;br /&gt;    CommandLine := ' ' + CommandLine;&lt;br /&gt;&lt;br /&gt;  if Length(Path) &gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    GetMem(FPath, Length(Path) + 1);&lt;br /&gt;    StrCopy(FPath, PChar(Path));&lt;br /&gt;  end;&lt;br /&gt;  if Length(CommandLine) &gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    GetMem(FCommandLine, Length(CommandLine) + 1);&lt;br /&gt;    StrCopy(FCommandLine, PChar(CommandLine));&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  if Length(Directory) &gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    GetMem(FDirectory, Length(Directory) + 1);&lt;br /&gt;    StrCopy(FDirectory, PChar(Directory));&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  FWatching := Watch;&lt;br /&gt;&lt;br /&gt;  if Assigned(Environment) then&lt;br /&gt;  begin&lt;br /&gt;    GetMem(FEnvironment, 1);&lt;br /&gt;    Len := 1;&lt;br /&gt;    for I := 0 to Environment.Count - 1 do&lt;br /&gt;    begin&lt;br /&gt;      Inc(Len, Length(Environment[I]) + 1);&lt;br /&gt;      ReallocMem(FEnvironment, Len);&lt;br /&gt;      SetEnvironmentVariable(PChar(Environment.Names[I]), PChar(Environment.ValueFromIndex[I]));&lt;br /&gt;      StrCopy(FEnvironment + Len - Length(Environment[I]) - 2, PChar(Environment[I]));&lt;br /&gt;    end;&lt;br /&gt;    (FEnvironment + Len - 1)^ := #0;&lt;br /&gt;    FreeMem(FEnvironment);&lt;br /&gt;    FEnvironment := nil;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;destructor TProcessThread.Destroy;&lt;br /&gt;begin&lt;br /&gt;  FreeMem(FPath);&lt;br /&gt;  FreeMem(FCommandLine);&lt;br /&gt;  FreeMem(FDirectory);&lt;br /&gt;  FreeResources;&lt;br /&gt;  if Assigned(FEnvironment) then&lt;br /&gt;    FreeMem(FEnvironment);&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.Execute;&lt;br /&gt;const&lt;br /&gt;  MAX_BUFFER = 512 * 1024;&lt;br /&gt;var&lt;br /&gt;  MaxBytes, Available, BytesRead: Cardinal;&lt;br /&gt;  Buffer: array[0..MAX_BUFFER] of Char;&lt;br /&gt;&lt;br /&gt;  function Read: Boolean;&lt;br /&gt;  begin&lt;br /&gt;    Result := True;&lt;br /&gt;    FillChar(Buffer, MAX_BUFFER, #0);&lt;br /&gt;    PeekNamedPipe(OutputRead, @Buffer, MAX_BUFFER, @BytesRead, @Available, nil);&lt;br /&gt;&lt;br /&gt;    if BytesRead &lt; MAX_BUFFER then&lt;br /&gt;    begin&lt;br /&gt;      MaxBytes := BytesRead;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      MaxBytes := MAX_BUFFER;&lt;br /&gt;&lt;br /&gt;    if MaxBytes &gt; 0 then&lt;br /&gt;      if ReadFile(OutputRead, Buffer, MaxBytes, BytesRead, nil) then&lt;br /&gt;      begin&lt;br /&gt;        if BytesRead &gt; 0 then&lt;br /&gt;        begin&lt;br /&gt;          FData := StrPas(Buffer);&lt;br /&gt;          Synchronize(CallDataAvailable);&lt;br /&gt;        end;&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;        Result := False;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  Startup: STARTUPINFO;&lt;br /&gt;  SecurityDescriptor: SECURITY_DESCRIPTOR;&lt;br /&gt;  SecurityAttributes: SECURITY_ATTRIBUTES;&lt;br /&gt;begin&lt;br /&gt;  try&lt;br /&gt;    ZeroMemory(@Startup, SizeOf(STARTUPINFO));&lt;br /&gt;    Startup.cb := SizeOf(STARTUPINFO);&lt;br /&gt;    ZeroMemory(@SecurityDescriptor, SizeOf(SECURITY_DESCRIPTOR));&lt;br /&gt;    ZeroMemory(@SecurityAttributes, SizeOf(SECURITY_ATTRIBUTES));&lt;br /&gt;    InputRead := 0;&lt;br /&gt;    InputWrite := 0;&lt;br /&gt;    OutputRead := 0;&lt;br /&gt;    OutputWrite := 0;&lt;br /&gt;&lt;br /&gt;    if Win32Platform = VER_PLATFORM_WIN32_NT then&lt;br /&gt;    begin&lt;br /&gt;      InitializeSecurityDescriptor(@SecurityDescriptor, SECURITY_DESCRIPTOR_REVISION);&lt;br /&gt;      SetSecurityDescriptorDacl(@SecurityDescriptor, True, nil, False);&lt;br /&gt;      SecurityAttributes.lpSecurityDescriptor := @SecurityDescriptor;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      SecurityAttributes.lpSecurityDescriptor := nil;&lt;br /&gt;    SecurityAttributes.nLength := SizeOf(SECURITY_ATTRIBUTES);&lt;br /&gt;    SecurityAttributes.bInheritHandle := True;&lt;br /&gt;    if not CreatePipe(OutputRead, OutputWrite, @SecurityAttributes, 0)&lt;br /&gt;    or not CreatePipe(InputRead, InputWrite, @SecurityAttributes, 0) then&lt;br /&gt;      raise EProcessError.Create('Error while opening pipes');&lt;br /&gt;&lt;br /&gt;    SetHandleInformation(OutputRead, HANDLE_FLAG_INHERIT, 0);&lt;br /&gt;    SetHandleInformation(InputWrite, HANDLE_FLAG_INHERIT, 0);&lt;br /&gt;&lt;br /&gt;    GetStartupInfo(Startup);&lt;br /&gt;    Startup.dwFlags := STARTF_USESHOWWINDOW OR STARTF_USESTDHANDLES;&lt;br /&gt;&lt;br /&gt;    Startup.hStdOutput := OutputWrite;&lt;br /&gt;    Startup.hStdError := OutputWrite;&lt;br /&gt;    Startup.hStdInput := InputRead;&lt;br /&gt;&lt;br /&gt;    FlushFileBuffers(OutputWrite);&lt;br /&gt;    FlushFileBuffers(OutputRead);&lt;br /&gt;    FlushFileBuffers(InputRead);&lt;br /&gt;    FlushFileBuffers(InputWrite);&lt;br /&gt;&lt;br /&gt;    Startup.wShowWindow := SW_HIDE;&lt;br /&gt;&lt;br /&gt;    if not CreateProcess(FPath, FCommandLine, nil, nil, True, CREATE_NEW_CONSOLE OR NORMAL_PRIORITY_CLASS, FEnvironment, FDirectory, Startup, FMainProcess) then&lt;br /&gt;      raise EProcessError.Create('Error while starting Process: ' + SysErrorMessage(GetLastError) + ':' + FPath + ':' + FCommandLine + ':' + FDirectory);&lt;br /&gt;    WaitForInputIdle(FMainProcess.hProcess, INITIALIZATION_TIMEOUT);&lt;br /&gt;    FStarted := True;&lt;br /&gt;    SetPriority(GetPriority);&lt;br /&gt;    Synchronize(CallProcessOpened);&lt;br /&gt;    &lt;br /&gt;    if not FWatching then&lt;br /&gt;      Exit;&lt;br /&gt;&lt;br /&gt;    repeat&lt;br /&gt;      if not Read then&lt;br /&gt;        Break;&lt;br /&gt;    until not IsProcessAlive or Terminated;&lt;br /&gt;    Read;&lt;br /&gt;&lt;br /&gt;    if not IsProcessAlive then&lt;br /&gt;      Synchronize(CallProcessTerminated);&lt;br /&gt;      &lt;br /&gt;  except&lt;br /&gt;    on E: Exception do&lt;br /&gt;    begin&lt;br /&gt;      FException := E;&lt;br /&gt;      Synchronize(CallException);&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TProcessThread.FreeResources;&lt;br /&gt;begin&lt;br /&gt;  KillProcess(FMainProcess.dwProcessId);&lt;br /&gt;&lt;br /&gt;  if OutputRead &lt;&gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    CloseHandle(OutputRead);&lt;br /&gt;    OutputRead := 0;&lt;br /&gt;  end;&lt;br /&gt;  if OutputWrite &lt;&gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    CloseHandle(OutputWrite);&lt;br /&gt;    OutputWrite := 0;&lt;br /&gt;  end;&lt;br /&gt;  if InputWrite &lt;&gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    CloseHandle(InputWrite);&lt;br /&gt;    InputWrite := 0;&lt;br /&gt;  end;&lt;br /&gt;  if InputRead &lt;&gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    CloseHandle(InputRead);&lt;br /&gt;    InputRead := 0;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{  TProcessLineThread }&lt;br /&gt;&lt;br /&gt;constructor  TProcessLineThread.Create(Path, CommandLine, Directory: string; Environment: TStrings);&lt;br /&gt;begin&lt;br /&gt;  inherited Create(Path, CommandLine, Directory, Environment);&lt;br /&gt;  OnDataAvailable := DataAvailable;&lt;br /&gt;  OnTerminate := Finished;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure  TProcessLineThread.DataAvailable(Sender: TObject);&lt;br /&gt;var&lt;br /&gt;  I, L: Integer;&lt;br /&gt;begin&lt;br /&gt;  I := 0;&lt;br /&gt;  L := Length(Data);&lt;br /&gt;  while I &lt; L do&lt;br /&gt;  begin&lt;br /&gt;    Inc(I);&lt;br /&gt;    if Data[I] in [#13, #10] then&lt;br /&gt;    begin&lt;br /&gt;      if (I &lt; L) and (Data[I+1] in [#13, #10]) then&lt;br /&gt;        Inc(I);&lt;br /&gt;      if Assigned(FOnNewLine) then&lt;br /&gt;        FOnNewLine(Self, FCurrentLine);&lt;br /&gt;      FCurrentLine := '';&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      FCurrentLine := FCurrentLine + Data[I];&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure  TProcessLineThread.Finished(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  if (FCurrentLine &lt;&gt; '') and Assigned(FOnNewLine) then&lt;br /&gt;    FOnNewLine(Self, FCurrentLine);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Mon, 07 Jul 2008 07:25:12 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5729</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>Pascal's triangle in Ruby</title>
      <link>http://snippets.dzone.com/posts/show/4700</link>
      <description>&lt;code&gt;&lt;br /&gt;&lt;br /&gt;# cf. http://www.ruby-forum.com/topic/97105&lt;br /&gt;&lt;br /&gt;6.times { k=0; p $*.map!{|i|k+k=i} &lt;&lt; 1 }&lt;br /&gt;&lt;br /&gt;# ... or ...&lt;br /&gt;&lt;br /&gt;ar=[]; 6.times { k=0; p ar.map!{|i|k+k=i} &lt;&lt; 1 }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;# a more general approach (for polynomials)&lt;br /&gt;&lt;br /&gt;class Polynomial&lt;br /&gt;&lt;br /&gt;   def triangle(nterms, row, pos=nil)&lt;br /&gt;&lt;br /&gt;      return nil if nterms &lt; 2 || row &lt; 1&lt;br /&gt;      nterms = nterms - 2&lt;br /&gt;      num_of_rows = row&lt;br /&gt;&lt;br /&gt;      var1 = 0 + nterms   &lt;br /&gt;      var2 = 1 + nterms&lt;br /&gt;      var3 = 3 + nterms &lt;br /&gt;  &lt;br /&gt;      ar1 = [0, 1, 0]   # first row&lt;br /&gt;      var1.times { ar1.push(0) }&lt;br /&gt;      var1.times { ar1.unshift(0) }&lt;br /&gt;&lt;br /&gt;      ar2 = []&lt;br /&gt;      ar3 = []&lt;br /&gt;      ar4 = [[1]]&lt;br /&gt;&lt;br /&gt;      for num in 0..(num_of_rows - 1)  &lt;br /&gt;&lt;br /&gt;         nextnum = ar1.size - var2&lt;br /&gt;&lt;br /&gt;         for nextn in 1..nextnum&lt;br /&gt;            sum = 0&lt;br /&gt;            count = 0&lt;br /&gt;            ar1.each do |n|  &lt;br /&gt;               count += 1 &lt;br /&gt;               if count &lt; var3 then t = sum += n; ar2 &lt;&lt; t else break end &lt;br /&gt;            end&lt;br /&gt;&lt;br /&gt;            ar3 &lt;&lt; ar2.last&lt;br /&gt;            ar2.clear&lt;br /&gt;            ar1.shift&lt;br /&gt;&lt;br /&gt;         end   # second for-loop&lt;br /&gt;&lt;br /&gt;         ar1.clear&lt;br /&gt;         ar1 &lt;&lt; ar3&lt;br /&gt;         ar1.flatten!&lt;br /&gt;&lt;br /&gt;         var2.times { ar1.push(0) }&lt;br /&gt;         var2.times { ar1.unshift(0) }&lt;br /&gt;&lt;br /&gt;         ar4 &lt;&lt; ar3&lt;br /&gt;         ar3 = []&lt;br /&gt;&lt;br /&gt;      end  # first for-loop&lt;br /&gt;&lt;br /&gt;      if !pos.nil?&lt;br /&gt;         ret = ar4.at(row).at(pos)&lt;br /&gt;         return "No such position: #{pos} in row: #{row}" if ret.nil?&lt;br /&gt;         ret&lt;br /&gt;      else&lt;br /&gt;         ar4.map! { |r| r.join('-') }&lt;br /&gt;         ar4&lt;br /&gt;      end&lt;br /&gt;   end &lt;br /&gt;end &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;puts Polynomial.new.triangle(2, 5)&lt;br /&gt;puts Polynomial.new.triangle(3, 5)&lt;br /&gt;puts Polynomial.new.triangle(4, 5)&lt;br /&gt;puts Polynomial.new.triangle(5, 5)&lt;br /&gt;puts Polynomial.new.triangle(5, 4, 8)&lt;br /&gt;puts Polynomial.new.triangle(4, 9)&lt;br /&gt;puts Polynomial.new.triangle(4, 9, 10)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;#------------------------&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class Integer&lt;br /&gt;   def fak&lt;br /&gt;      f=1&lt;br /&gt;      (2..self).each { |i| f *= i   }&lt;br /&gt;      f&lt;br /&gt;   end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;module Enumerable&lt;br /&gt;   def sum&lt;br /&gt;      inject { |n, m| n + m  }&lt;br /&gt;   end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;# cf. http://blade.nagaokaut.ac.jp/~sinara/ruby/math/combinatorics/array-rep_perm.rb&lt;br /&gt;class Array&lt;br /&gt;  def rep_perm(n)&lt;br /&gt;    if n &lt; 0&lt;br /&gt;    elsif n == 0&lt;br /&gt;      yield([])&lt;br /&gt;    else&lt;br /&gt;      rep_perm(n - 1) do |x|&lt;br /&gt;	each do |y|&lt;br /&gt;	  yield(x + [y])&lt;br /&gt;	end&lt;br /&gt;      end&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;nterms = 2&lt;br /&gt;exponent = 80&lt;br /&gt;exponent = 8&lt;br /&gt;&lt;br /&gt;# create the same number of variable names as there are terms &lt;br /&gt;# example: ['a', 'b'] for (a+b)**3&lt;br /&gt;&lt;br /&gt;var_names = ('a'..'z').to_a.slice(0, nterms)&lt;br /&gt;#var_names = (('a'..'z').to_a &lt;&lt; ('A'..'Z').to_a &lt;&lt; ('aa'..'zz').to_a).flatten!.slice(0, nterms)&lt;br /&gt;&lt;br /&gt;ar1 = []&lt;br /&gt;(0..exponent).to_a.rep_perm(nterms) { |x| p x; ar1 &lt;&lt; x if x.sum == exponent }   # example: ... if [2,6].sum == 8&lt;br /&gt;ar1.reverse!&lt;br /&gt;&lt;br /&gt;#p ar1&lt;br /&gt;#puts ar1&lt;br /&gt;&lt;br /&gt;ar2 = []&lt;br /&gt;&lt;br /&gt;ar1.each do |term|&lt;br /&gt;&lt;br /&gt;   #puts "term: #{term.inspect}"  # example: term: [5, 0, 0]&lt;br /&gt;   count = 0&lt;br /&gt;   var1 = 1&lt;br /&gt;   term.each { |i| var1 *= i.fak }&lt;br /&gt;   var2 = exponent.fak / var1 &lt;br /&gt;   var3 = "#{var2}   (  #{ term.join('-') &lt;&lt; '-' } )"  # prepare term for parsing with gsub below&lt;br /&gt;   ar2 &lt;&lt; var3&lt;br /&gt;&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;#p ar2&lt;br /&gt;&lt;br /&gt;result = ar2.collect do |term|&lt;br /&gt;   p term&lt;br /&gt;   count = -1&lt;br /&gt;   term.gsub!(/(\d+)-/)  { count += 1;  "#{var_names.at(count)}" &lt;&lt; '**' &lt;&lt; $1 &lt;&lt; ' ' }&lt;br /&gt;   term.gsub!(/^(\d+)( +)/, '\1\2*\2')&lt;br /&gt;end&lt;br /&gt;&lt;br /&gt;puts result&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 26 Oct 2007 17:02:28 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/4700</guid>
      <author>ntk ()</author>
    </item>
    <item>
      <title>Single linked list unit</title>
      <link>http://snippets.dzone.com/posts/show/3253</link>
      <description>This code is a simple pascal library to handle single-linked-lists&lt;br /&gt;&lt;br /&gt;function llsGetItem(id: cardinal; var start: pointer): pointer;&lt;br /&gt;&lt;br /&gt;   Returns an item of specified ID, it remains in list&lt;br /&gt;&lt;br /&gt;function llsTakeOutItem(id: cardinal; var start: pointer): pointer;&lt;br /&gt;&lt;br /&gt;   Returns an item of specified ID, it is removed from list&lt;br /&gt;&lt;br /&gt;procedure llsInsertItem(item: pointer; var start: pointer);&lt;br /&gt;&lt;br /&gt;   Inserts an item to list(item is a valid header)&lt;br /&gt;&lt;br /&gt;function llsGetItemCount(start: pointer): cardinal;&lt;br /&gt;&lt;br /&gt;   Gets number of items&lt;br /&gt;&lt;br /&gt;function llsNewSLLHeader: PSLLItem;&lt;br /&gt;&lt;br /&gt;   Allocates list item header&lt;br /&gt;&lt;br /&gt;procedure llsKillSLLHeader(hdr: pointer);&lt;br /&gt;&lt;br /&gt;   Deallocated list item header&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unit SLLMan;&lt;br /&gt;interface&lt;br /&gt;type&lt;br /&gt;  PSLLItem = ^TSLLItem;&lt;br /&gt;  TSLLItem = record&lt;br /&gt;    Next: pointer;&lt;br /&gt;    Data: pointer;&lt;br /&gt;   end;&lt;br /&gt;&lt;br /&gt;function llsGetItem(id: cardinal; var start: pointer): pointer;&lt;br /&gt;function llsTakeOutItem(id: cardinal; var start: pointer): pointer;&lt;br /&gt;procedure llsInsertItem(item: pointer; var start: pointer);&lt;br /&gt;function llsGetItemCount(start: pointer): cardinal;&lt;br /&gt;function llsNewSLLHeader: PSLLItem;&lt;br /&gt;procedure llsKillSLLHeader(hdr: pointer);&lt;br /&gt;       // These ids are numbered from 0&lt;br /&gt;implementation&lt;br /&gt;function malloc(size: cardinal): pointer;&lt;br /&gt;begin&lt;br /&gt;  GetMem(result,size);&lt;br /&gt;end;&lt;br /&gt;function llsGetItemCount(start: pointer): cardinal;&lt;br /&gt;var&lt;br /&gt;  cur: PSLLItem;&lt;br /&gt;  tmp: cardinal;&lt;br /&gt;begin&lt;br /&gt;  if start = nil then begin llsGetItemCount := 0; Exit; end;&lt;br /&gt;  tmp := 1;  cur := start;&lt;br /&gt;  while (cur^.Next &lt;&gt; nil) do&lt;br /&gt;  begin&lt;br /&gt;    Inc(tmp);&lt;br /&gt;    cur := cur^.Next;&lt;br /&gt;  end;&lt;br /&gt;  llsGetItemCount := tmp;&lt;br /&gt;end;&lt;br /&gt;procedure llsKillSLLHeader(hdr: pointer);&lt;br /&gt;begin&lt;br /&gt;  if hdr = nil then Exit;&lt;br /&gt;  Free(hdr);&lt;br /&gt;end;&lt;br /&gt;function llsNewSLLHeader: PSLLItem;&lt;br /&gt;var&lt;br /&gt;  tmp: PSLLItem;&lt;br /&gt;begin&lt;br /&gt;  tmp := malloc(sizeof(TSLLItem));&lt;br /&gt;  tmp^.Next := nil;&lt;br /&gt;  tmp^.Data := nil;&lt;br /&gt;  llsNewSLLHeader := tmp;&lt;br /&gt;end;&lt;br /&gt;function llsGetItem(id: cardinal; var start: pointer): pointer;&lt;br /&gt;var&lt;br /&gt;  cur: PSLLItem;&lt;br /&gt;begin&lt;br /&gt;  if start = nil then begin llsGetItem := nil; Exit; end;&lt;br /&gt;  cur := start;&lt;br /&gt;  while (id&lt;&gt;0) do&lt;br /&gt;  begin&lt;br /&gt;    if cur^.Next &lt;&gt; nil then&lt;br /&gt;        begin&lt;br /&gt;          Dec(id);&lt;br /&gt;          cur := cur^.Next;&lt;br /&gt;        end else&lt;br /&gt;        begin&lt;br /&gt;          llsGetItem := nil;&lt;br /&gt;          Exit;&lt;br /&gt;        end;&lt;br /&gt;  end;&lt;br /&gt;  llsGetItem := cur;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function llsTakeOutItem(id: cardinal; var start: pointer): pointer;&lt;br /&gt;var&lt;br /&gt;  tmp: PSLLItem;&lt;br /&gt;  last: PSLLItem;&lt;br /&gt;begin&lt;br /&gt;  if start = nil then begin llsTakeOutItem := nil; Exit; end;&lt;br /&gt;  if (id = 0) then&lt;br /&gt;    begin&lt;br /&gt;      tmp := start;&lt;br /&gt;      if tmp^.Next = nil then start := nil else start := tmp^.Next;&lt;br /&gt;      llsTakeOutItem := tmp;&lt;br /&gt;      Exit;&lt;br /&gt;    end;&lt;br /&gt;  tmp := start;&lt;br /&gt;  repeat&lt;br /&gt;    dec(id);&lt;br /&gt;    last := tmp;&lt;br /&gt;    tmp := tmp^.Next;&lt;br /&gt;  until (id = 0);&lt;br /&gt;  last^.Next := tmp^.Next;&lt;br /&gt;  llsTakeOutitem := tmp;&lt;br /&gt;end;&lt;br /&gt;procedure llsInsertItem(item: pointer; var start: pointer);&lt;br /&gt;var&lt;br /&gt;  cur: PSLLItem;&lt;br /&gt;begin&lt;br /&gt; if start = nil then&lt;br /&gt;  begin&lt;br /&gt;    start := item;&lt;br /&gt;    exit;&lt;br /&gt;  end;&lt;br /&gt; cur := start;&lt;br /&gt; while (cur^.Next&lt;&gt;nil) do cur := cur^.Next;&lt;br /&gt; cur^.Next := item;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 07 Jan 2007 17:58:21 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3253</guid>
      <author>darktemplar (Piotr)</author>
    </item>
    <item>
      <title>Wave Plotter //Pascal Class</title>
      <link>http://snippets.dzone.com/posts/show/2201</link>
      <description>A wave plotter component that is able to draw sin, poly and squared lines, I used this in a osciloscope xD&lt;br /&gt;&lt;br /&gt;I didn't liked this code, but the draw part (TWaveShape.paint) is looking cool, I used the same "X" coord to draw the 3 kinds of lines :)&lt;br /&gt;&lt;br /&gt;I mean:&lt;br /&gt;&lt;br /&gt;loop(x){&lt;br /&gt;  case waveType of&lt;br /&gt;    wtSin: y := lala;&lt;br /&gt;    wtPoly: y := lele;&lt;br /&gt;    wtSqr: y := lili;&lt;br /&gt;  end;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unit WavePlotter;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  forms, dialogs, SysUtils, Classes, Controls, Graphics;&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  PI2 = PI * 2;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TWaveType = ( wtSqr, wtPoly, wtSin );&lt;br /&gt;&lt;br /&gt;  TWave = class( TPersistent )&lt;br /&gt;  public&lt;br /&gt;    waveType: TWaveType;&lt;br /&gt;    color: TColor;&lt;br /&gt;    offset: integer;&lt;br /&gt;    frequency, amplitude, volts, interval, gain: extended;&lt;br /&gt;&lt;br /&gt;    procedure AssignTo(Dest: TPersistent); override;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TWaveShape = class( TGraphicControl )&lt;br /&gt;  protected&lt;br /&gt;    fWaves: TList;&lt;br /&gt;    fBoxSize: integer;&lt;br /&gt;    fLineColor: TColor;&lt;br /&gt;&lt;br /&gt;    function getWave(const index: integer): TWave;&lt;br /&gt;    procedure setBoxSize(const Value: integer);&lt;br /&gt;&lt;br /&gt;    function getBackgroundColor: TColor;&lt;br /&gt;    procedure setBackgroundColor(const Value: TColor);&lt;br /&gt;    procedure setLineColor(const Value: TColor);&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    constructor create( AOwner: TComponent ); override;&lt;br /&gt;    destructor destroy; override;&lt;br /&gt;&lt;br /&gt;    procedure clear;&lt;br /&gt;    procedure delete( const index: integer );&lt;br /&gt;&lt;br /&gt;    function add: integer;&lt;br /&gt;&lt;br /&gt;    property waves[ const index: integer]: TWave read GetWave;&lt;br /&gt;&lt;br /&gt;  published&lt;br /&gt;    procedure paint; override;&lt;br /&gt;    property boxSize: integer read fBoxSize write setBoxSize;&lt;br /&gt;    property backgroundColor: TColor read getBackgroundColor write setBackgroundColor;&lt;br /&gt;    property lineColor: TColor read fLineColor write setLineColor;&lt;br /&gt;&lt;br /&gt;    //inherited&lt;br /&gt;    //property Canvas;&lt;br /&gt;    property Align;&lt;br /&gt;    property Anchors;&lt;br /&gt;    property Constraints;&lt;br /&gt;    property DragCursor;&lt;br /&gt;    property DragKind;&lt;br /&gt;    property DragMode;&lt;br /&gt;    property Enabled;&lt;br /&gt;    //property Font;&lt;br /&gt;    property ParentColor;&lt;br /&gt;    //property ParentFont;&lt;br /&gt;    property ParentShowHint;&lt;br /&gt;    property PopupMenu;&lt;br /&gt;    property ShowHint;&lt;br /&gt;    property Visible;&lt;br /&gt;    property OnClick;&lt;br /&gt;    property OnContextPopup;&lt;br /&gt;    property OnDblClick;&lt;br /&gt;    property OnDragDrop;&lt;br /&gt;    property OnDragOver;&lt;br /&gt;    property OnEndDock;&lt;br /&gt;    property OnEndDrag;&lt;br /&gt;    property OnMouseDown;&lt;br /&gt;    property OnMouseMove;&lt;br /&gt;    property OnMouseUp;&lt;br /&gt;    property OnStartDock;&lt;br /&gt;    property OnStartDrag;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;function max( const a, b: integer ): integer;&lt;br /&gt;begin&lt;br /&gt;  if a &gt; b then&lt;br /&gt;    result := a&lt;br /&gt;  else&lt;br /&gt;    result := b;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TWaveShape }&lt;br /&gt;&lt;br /&gt;function TWaveShape.add: integer;&lt;br /&gt;begin&lt;br /&gt;  result := fWaves.add( TWave.Create );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TWaveShape.clear;&lt;br /&gt;begin&lt;br /&gt;  while fWaves.count &gt; 0 do begin&lt;br /&gt;    TWave( fWaves[0] ).free;&lt;br /&gt;    fWaves.delete( 0 );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor TWaveShape.create(AOwner: TComponent);&lt;br /&gt;begin&lt;br /&gt;  inherited;&lt;br /&gt;  fWaves := TList.create;&lt;br /&gt;  fLineColor := clGray;&lt;br /&gt;  color := clBtnFace;&lt;br /&gt;  fBoxSize := 50;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TWaveShape.delete(const index: integer);&lt;br /&gt;begin&lt;br /&gt;  if ( index &gt; -1 ) and ( index &lt; fWaves.count ) then begin&lt;br /&gt;    TWave( fWaves[index] ).free;&lt;br /&gt;    fWaves.delete( index );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;destructor TWaveShape.destroy;&lt;br /&gt;begin&lt;br /&gt;  fWaves.free;&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TWaveShape.getBackgroundColor: TColor;&lt;br /&gt;begin&lt;br /&gt;  result := color;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TWaveShape.getWave(const index: integer): TWave;&lt;br /&gt;begin&lt;br /&gt;  result := nil;&lt;br /&gt;  if ( index &gt; -1 ) and ( index &lt; fWaves.count ) then&lt;br /&gt;    result := TWave( fWaves[ index ] );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TWaveShape.paint;&lt;br /&gt;var&lt;br /&gt;  k, x: integer;&lt;br /&gt;  lastX, lastY: array of integer;&lt;br /&gt;  y: extended;&lt;br /&gt;begin&lt;br /&gt;  if not enabled then&lt;br /&gt;    exit;&lt;br /&gt;  canvas.brush.color := color;&lt;br /&gt;  canvas.fillRect( clientRect );&lt;br /&gt;&lt;br /&gt;  setLength( lastY, fWaves.count );&lt;br /&gt;  setLength( lastX, fWaves.count );&lt;br /&gt;  for k := 0 to high( lastY ) do begin&lt;br /&gt;    lastY[k] := clientHeight div 2 + waves[k].offset;&lt;br /&gt;    lastX[k] := 0;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  for x := 0 to max( clientWidth, clientHeight ) do begin&lt;br /&gt;    with canvas do begin&lt;br /&gt;      pen.color := fLineColor;&lt;br /&gt;      pen.width := 1;&lt;br /&gt;      pen.style := psDot;&lt;br /&gt;&lt;br /&gt;      if x mod fBoxSize = 0 then begin&lt;br /&gt;        moveTo( 0, x + trunc( frac( clientHeight / 2 / fBoxSize ) * fBoxSize ) );&lt;br /&gt;        lineTo( clientWidth, x + trunc( frac( clientHeight / 2 / fBoxSize ) * fBoxSize ) );&lt;br /&gt;&lt;br /&gt;        moveTo( x, 0 );&lt;br /&gt;        lineTo( x, clientHeight );&lt;br /&gt;      end;&lt;br /&gt;&lt;br /&gt;      for k := 0 to fWaves.count - 1 do begin&lt;br /&gt;        with waves[k] do begin&lt;br /&gt;          pen.color := color;&lt;br /&gt;          pen.width := 1;&lt;br /&gt;          pen.style := psSolid;&lt;br /&gt;&lt;br /&gt;          y := pi*k + PI2 * x * interval / fBoxSize * frequency;&lt;br /&gt;&lt;br /&gt;          case waveType of&lt;br /&gt;            wtSin:&lt;br /&gt;              y := sin( y );&lt;br /&gt;            wtPoly: begin&lt;br /&gt;              y := frac( y / PI2 );&lt;br /&gt;              if y &lt;= 0.25 then&lt;br /&gt;                y := y / 0.25&lt;br /&gt;              else if y &lt;= 0.75 then&lt;br /&gt;                y := ( -y + 0.5 ) / 0.25&lt;br /&gt;              else&lt;br /&gt;                y := ( y - 1 ) / 0.25;&lt;br /&gt;            end;&lt;br /&gt;            wtSqr: begin&lt;br /&gt;              if frac( y / PI2 ) &lt;= 0.5 then&lt;br /&gt;                y := 1&lt;br /&gt;              else&lt;br /&gt;                y := -1;&lt;br /&gt;            end;&lt;br /&gt;          end;&lt;br /&gt;          y := ( y * ( fBoxSize / volts ) * amplitude * gain ) + clientHeight / 2 + offset;&lt;br /&gt;          moveTo( lastX[k], lastY[k] );&lt;br /&gt;          lastX[k] := x;&lt;br /&gt;          lastY[k] := trunc( y );&lt;br /&gt;          lineTo( x, lastY[k] );&lt;br /&gt;        end;&lt;br /&gt;      end;&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TWaveShape.setBackgroundColor(const Value: TColor);&lt;br /&gt;begin&lt;br /&gt;  color := Value;&lt;br /&gt;  Invalidate;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TWaveShape.setBoxSize(const Value: integer);&lt;br /&gt;begin&lt;br /&gt;  fBoxSize := Value;&lt;br /&gt;  invalidate;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;procedure TWaveShape.setLineColor(const Value: TColor);&lt;br /&gt;begin&lt;br /&gt;  fLineColor := Value;&lt;br /&gt;  Invalidate;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TWave }&lt;br /&gt;&lt;br /&gt;procedure TWave.AssignTo(Dest: TPersistent);&lt;br /&gt;begin&lt;br /&gt;  if Dest.ClassType &lt;&gt; TWave then&lt;br /&gt;    inherited;&lt;br /&gt;  with TWave( Dest ) do begin&lt;br /&gt;    waveType := self.waveType;&lt;br /&gt;    color := self.color;&lt;br /&gt;    offset := self.offset;&lt;br /&gt;    frequency := self.frequency;&lt;br /&gt;    amplitude := self.amplitude;&lt;br /&gt;    volts := self.volts;&lt;br /&gt;    interval := self.interval;&lt;br /&gt;    gain := self.gain;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 15 Jun 2006 19:28:29 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2201</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>Simple Stack //Pascal Class</title>
      <link>http://snippets.dzone.com/posts/show/2198</link>
      <description>A simple pointer stack...&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unit Stack;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Classes;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TStack = class&lt;br /&gt;  private&lt;br /&gt;    FList: PPointerList;&lt;br /&gt;    FCapacity, FCount: Cardinal;&lt;br /&gt;    procedure Grow;&lt;br /&gt;  public&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;    procedure Push( const Data: Pointer );&lt;br /&gt;    function Pop: Pointer;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TStack }&lt;br /&gt;&lt;br /&gt;destructor TStack.Destroy;&lt;br /&gt;begin&lt;br /&gt;  FreeMem( FList );&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TStack.Grow;&lt;br /&gt;begin&lt;br /&gt;  if FCapacity &gt; 64 then&lt;br /&gt;    Inc( FCapacity, FCapacity div 4 )&lt;br /&gt;  else&lt;br /&gt;    if FCapacity &gt; 8 then&lt;br /&gt;      Inc( FCapacity, 16 )&lt;br /&gt;    else&lt;br /&gt;      Inc( FCapacity, 4 );&lt;br /&gt;  ReallocMem( FList, FCapacity * SizeOf( Pointer ) );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TStack.Pop: Pointer;&lt;br /&gt;begin&lt;br /&gt;  if FCount &gt; 0 then&lt;br /&gt;  begin&lt;br /&gt;    Dec( FCount );&lt;br /&gt;    Result := FList^[FCount];&lt;br /&gt;  end&lt;br /&gt;  else&lt;br /&gt;    Result := nil;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TStack.Push(const Data: Pointer);&lt;br /&gt;begin&lt;br /&gt;  if FCapacity = FCount then&lt;br /&gt;    Grow;&lt;br /&gt;  FList^[FCount] := Data;&lt;br /&gt;  Inc( FCount );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 15 Jun 2006 19:15:30 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2198</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>Files Joiner/Unjoiner //Pascal class</title>
      <link>http://snippets.dzone.com/posts/show/2197</link>
      <description>This is just a snippet since I didn't added some units that can be replaced without major efforts:&lt;br /&gt;- PathParser.pas: parses paths shortcuts (it's on my bigbold snippets, search on my tags)&lt;br /&gt;- Stack.pas: implements a simple stack (it's on my bigbold snippets, search on my tags)&lt;br /&gt;- ZlibEx.pas: used to compress/decompress the file contents (My ZlibEx is a modified version of this file: http://www.dellapasqua.com/delphizlib)&lt;br /&gt;- MD5.pas: used to calculate the file hash and check consistency when unjoining files&lt;br /&gt;- SysUtils2: Some idiot functions =b&lt;br /&gt;&lt;br /&gt;I used this in a personalized installer that I've made in my first job =b&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unit FileJoiner;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, SysUtils2, Classes, MD5, ZlibEx, PathParser, Stack;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TOverwriteMode = ( omNo, omAskUser, omIfNewer, omIfOlder, omIfDiff );&lt;br /&gt;  TOverwriteAction = ( oaOverwriteAll, oaNoOverwriteAll, oaYes, oaNo );&lt;br /&gt;&lt;br /&gt;  TFileHeader = record&lt;br /&gt;    MD5Hash: TDigestStr;&lt;br /&gt;    ModificationDate: TDateTime;&lt;br /&gt;    Attributes: LongWord;&lt;br /&gt;    Overwrite: TOverwriteMode;&lt;br /&gt;    Size: Int64;&lt;br /&gt;    MustKeep: Boolean;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TFileJoinerItem = class&lt;br /&gt;  public&lt;br /&gt;    Source, Destiny: string;&lt;br /&gt;    MustKeep, Recurse: Boolean;&lt;br /&gt;    Overwrite: TOverwriteMode;&lt;br /&gt;&lt;br /&gt;    constructor Create( const FromPath, ToPath: string; const OverwriteMode: TOverwriteMode = omIfNewer; const Recursive: Boolean = True; const MustKeepFile: Boolean = False ); overload;&lt;br /&gt;    function Assign( Item: TFileJoinerItem ): TFileJoinerItem;&lt;br /&gt;&lt;br /&gt;    procedure Save( const Stream: TStream );&lt;br /&gt;    procedure Load( const Stream: TStream );&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TCustomFileJoiner = class;&lt;br /&gt;&lt;br /&gt;  TFileJoinerFilesCallback = procedure( Sender: TCustomFileJoiner; Item: TFileJoinerItem ) of object;&lt;br /&gt;  TFileJoinerNotifyEvent = procedure( Sender: TCustomFileJoiner ) of object;&lt;br /&gt;  TFileJoinerFileExists = procedure( Sender: TCustomFileJoiner; var CanOverwrite: TOverwriteAction ) of object;&lt;br /&gt;&lt;br /&gt;  TJoinerStatus = ( jsIdle, jsJoining, jsUnjoining );&lt;br /&gt;&lt;br /&gt;  TCustomFileJoiner = class&lt;br /&gt;  private&lt;br /&gt;    FStream: TStream;&lt;br /&gt;    FCurFile, FTotalFiles: LongWord;&lt;br /&gt;    FCurSize, FTotalSize, FCurPosition, FCurWrittenBytes: Int64;&lt;br /&gt;    FCurFilename: string;&lt;br /&gt;    FCurFileInfo: TFileHeader;&lt;br /&gt;    FOnFileExists: TFileJoinerFileExists;&lt;br /&gt;    FOnWorkEnd, FOnWorkBegin, FOnWork, FOnProcessFile: TFileJoinerNotifyEvent;&lt;br /&gt;&lt;br /&gt;    procedure ProgressNotifier( Sender: TObject );&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    //properties&lt;br /&gt;    property CurFilename: string read FCurFilename;&lt;br /&gt;    property CurFileInfo: TFileHeader read FCurFileInfo;&lt;br /&gt;    property CurFilePosition: Int64 read FCurPosition;&lt;br /&gt;    property CurWrittenBytes: Int64 read FCurWrittenBytes;&lt;br /&gt;    property CurSize: Int64 read FCurSize;&lt;br /&gt;    property CurFile: LongWord read FCurFile;&lt;br /&gt;&lt;br /&gt;    property TotalSize: Int64 read FTotalSize;&lt;br /&gt;    property TotalFiles: LongWord read FTotalFiles;&lt;br /&gt;&lt;br /&gt;    //events&lt;br /&gt;    property OnWorkBegin: TFileJoinerNotifyEvent read FOnWorkBegin write FOnWorkBegin;&lt;br /&gt;    property OnWork: TFileJoinerNotifyEvent read FOnWork write FOnWork;&lt;br /&gt;    property OnWorkEnd: TFileJoinerNotifyEvent read FOnWorkEnd write FOnWorkEnd;&lt;br /&gt;    property OnProcessFile: TFileJoinerNotifyEvent read FOnProcessFile write FOnProcessFile;&lt;br /&gt;    property OnFileExists: TFileJoinerFileExists read FOnFileExists write FOnFileExists;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TFileJoiner = class( TCustomFileJoiner )&lt;br /&gt;  private&lt;br /&gt;    FPaths: TList;&lt;br /&gt;&lt;br /&gt;    function GetItem(const Index: Integer): TFileJoinerItem;&lt;br /&gt;    function GetCount: Integer;&lt;br /&gt;    procedure StreamFile( Sender: TCustomFileJoiner; Item: TFileJoinerItem );&lt;br /&gt;    procedure Compress( Input: TStream );&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    constructor Create;&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;&lt;br /&gt;    procedure Join( const Filename: string ); overload;&lt;br /&gt;    procedure Join( const Stream: TStream ); overload;&lt;br /&gt;&lt;br /&gt;    procedure SaveList( const Filename: string ); overload;&lt;br /&gt;    procedure SaveList( Stream: TStream ); overload;&lt;br /&gt;    procedure LoadList( const Filename: string ); overload;&lt;br /&gt;    procedure LoadList( Stream: TStream ); overload;&lt;br /&gt;&lt;br /&gt;    procedure CountFiles;&lt;br /&gt;&lt;br /&gt;    function Add( const FromPath, ToPath: string; const OverwriteMode: TOverwriteMode = omIfNewer; const Recursive: Boolean = False; const MustKeep: Boolean = False ): Integer;&lt;br /&gt;    procedure Clear;&lt;br /&gt;    procedure Remove( const Index: Integer );&lt;br /&gt;    procedure ListFiles( const Callback: TFileJoinerFilesCallback );&lt;br /&gt;&lt;br /&gt;    property Count: Integer read GetCount;&lt;br /&gt;    property Items[ const Index: Integer ]: TFileJoinerItem read GetItem; default;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  TFileUnjoiner = class( TCustomFileJoiner )&lt;br /&gt;  private&lt;br /&gt;    FDataBegin: Int64;&lt;br /&gt;    procedure Decompress( Output: TStream );&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    procedure Assign( const Filename: string ); overload;&lt;br /&gt;    procedure Assign( Stream: TStream ); overload;&lt;br /&gt;    procedure UnJoin;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TCustomFileJoiner }&lt;br /&gt;&lt;br /&gt;procedure TCustomFileJoiner.ProgressNotifier(Sender: TObject);&lt;br /&gt;begin&lt;br /&gt;  if Assigned( FOnWork ) then&lt;br /&gt;    with TStream( Sender ) do&lt;br /&gt;    begin&lt;br /&gt;      FCurWrittenBytes := Position - FCurPosition;&lt;br /&gt;      FCurPosition := Position;&lt;br /&gt;      FOnWork( Self );&lt;br /&gt;    end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ TFileJoiner }&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.Join( const Filename: string );&lt;br /&gt;begin&lt;br /&gt;  FStream := TFileStream.Create( Filename, fmCreate );&lt;br /&gt;  try&lt;br /&gt;    Join( FStream );&lt;br /&gt;  finally&lt;br /&gt;    FStream.Free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.Join( const Stream: TStream );&lt;br /&gt;var&lt;br /&gt;  Pos: array[0..1] of Int64;&lt;br /&gt;begin&lt;br /&gt;  FStream := Stream;&lt;br /&gt;  if Assigned( FOnWorkBegin ) then&lt;br /&gt;    FOnWorkBegin( Self );&lt;br /&gt;&lt;br /&gt;  FCurFile := 0;&lt;br /&gt;  FCurSize := 0;&lt;br /&gt;&lt;br /&gt;  //record position to get back later and reserve space on the file to record the "totals"&lt;br /&gt;  Pos[0] := FStream.Position;&lt;br /&gt;  FStream.Seek( SizeOf( FCurFile ) + SizeOf( FCurSize ), soCurrent );&lt;br /&gt;&lt;br /&gt;  //write files&lt;br /&gt;  ListFiles( StreamFile );&lt;br /&gt;&lt;br /&gt;  //write the totals and get back&lt;br /&gt;  Pos[1] := Stream.Position;&lt;br /&gt;  FStream.Position := Pos[0];&lt;br /&gt;  FStream.Write( FCurFile, SizeOf( FCurFile ) );&lt;br /&gt;  FStream.Write( FCurSize, SizeOf( FCurSize ) );&lt;br /&gt;  FStream.Position := Pos[1];&lt;br /&gt;&lt;br /&gt;  //job done&lt;br /&gt;  if Assigned( FOnWorkEnd ) then&lt;br /&gt;    FOnWorkEnd( Self );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.StreamFile( Sender: TCustomFileJoiner; Item: TFileJoinerItem );&lt;br /&gt;var&lt;br /&gt;  InputFile: TFileStream;&lt;br /&gt;  Pos: array[0..1] of Int64;&lt;br /&gt;begin&lt;br /&gt;  try&lt;br /&gt;    Inc( FCurFile );&lt;br /&gt;    FCurPosition := 0;&lt;br /&gt;    FCurFilename := Item.Source;&lt;br /&gt;&lt;br /&gt;    FCurFileInfo.MD5Hash := FileMD5Digest( Item.Source );&lt;br /&gt;    FCurFileInfo.ModificationDate := FileDateToDateTime( FileAge( Item.Source ) );&lt;br /&gt;    FCurFileInfo.Attributes := FileGetAttr( Item.Source );&lt;br /&gt;    FCurFileInfo.Overwrite := Item.Overwrite;&lt;br /&gt;&lt;br /&gt;    InputFile := TFileStream.Create( Item.Source, fmOpenRead or fmShareDenyWrite );&lt;br /&gt;    try&lt;br /&gt;      FCurFileInfo.Size := InputFile.Size;&lt;br /&gt;      if Assigned( FOnProcessFile ) then&lt;br /&gt;        FOnProcessFile( Self );&lt;br /&gt;&lt;br /&gt;      Pos[0] := FStream.Position;&lt;br /&gt;      //reserve space for the file header and EOF position&lt;br /&gt;      FStream.Seek( SizeOf( FCurFileInfo ) + SizeOf( Pos[0] ), soCurrent );&lt;br /&gt;      StringWrite( FStream, Item.Destiny );&lt;br /&gt;&lt;br /&gt;      Compress( InputFile );&lt;br /&gt;&lt;br /&gt;      //update the header and get back&lt;br /&gt;      Pos[1] := FStream.Position;&lt;br /&gt;      FStream.Position := Pos[0];&lt;br /&gt;      FStream.Write( FCurFileInfo, SizeOf( FCurFileInfo ) );&lt;br /&gt;      FStream.Write( Pos[1], SizeOf( Pos[1] ) );&lt;br /&gt;      FStream.Position := Pos[1];&lt;br /&gt;&lt;br /&gt;      //update summary&lt;br /&gt;      Inc( FCurSize, FCurFileInfo.Size );&lt;br /&gt;    finally&lt;br /&gt;      InputFile.Free;&lt;br /&gt;    end;&lt;br /&gt;  except&lt;br /&gt;    on E: Exception do&lt;br /&gt;      raise EWriteError.CreateFmt( '%s.StreamFile: Error on joining: "%s" - %s',  [ ClassName, FCurFilename, E.Message ] );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TFileJoiner.Add(const FromPath, ToPath: string;&lt;br /&gt;  const OverwriteMode: TOverwriteMode; const Recursive: Boolean; const MustKeep: Boolean ): Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := FPaths.Add( TFileJoinerItem.Create( FromPath, ToPath, OverwriteMode, Recursive, MustKeep ) );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.Clear;&lt;br /&gt;var&lt;br /&gt;  I: Integer;&lt;br /&gt;begin&lt;br /&gt;  for I := FPaths.Count - 1 downto 0 do&lt;br /&gt;  begin&lt;br /&gt;    TFileJoinerItem( FPaths[I] ).Free;&lt;br /&gt;    FPaths.Delete( I );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor TFileJoiner.Create;&lt;br /&gt;begin&lt;br /&gt;  FPaths := TList.Create;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;destructor TFileJoiner.Destroy;&lt;br /&gt;begin&lt;br /&gt;  Clear;&lt;br /&gt;  FPaths.Free;&lt;br /&gt;  inherited;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.CountFiles;&lt;br /&gt;type&lt;br /&gt;  PStackItem = ^TStackItem;&lt;br /&gt;  TStackItem = record&lt;br /&gt;    Data: PChar;&lt;br /&gt;    Searcher: TSearchRec;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  I: Integer;&lt;br /&gt;  Path, Filter: string;&lt;br /&gt;  Stack: TStack;&lt;br /&gt;  CurStack, X: PStackItem;&lt;br /&gt;begin&lt;br /&gt;  FTotalFiles := 0;&lt;br /&gt;  FTotalSize := 0;&lt;br /&gt;&lt;br /&gt;  Stack := TStack.Create;&lt;br /&gt;  try&lt;br /&gt;    for I := 0 to FPaths.Count - 1 do&lt;br /&gt;    begin&lt;br /&gt;      Path := Self[I].Source;&lt;br /&gt;      if LastDelimiter( '*?', ExtractFileName( Path ) ) &lt;&gt; 0 then&lt;br /&gt;      begin&lt;br /&gt;        Filter := ExtractFileName( Path );&lt;br /&gt;        Path := ExtractFilePath( Path );&lt;br /&gt;      end&lt;br /&gt;      else if FileExists( Path ) then&lt;br /&gt;      else if DirectoryExists( Path ) then&lt;br /&gt;      begin&lt;br /&gt;        Filter := '*';&lt;br /&gt;        Path := AddSlash( Path );&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;        raise Exception.CreateFmt( '%s.GetFilesSumary: "%s" n&#227;o encontrado', [ ClassName, Path ] );&lt;br /&gt;&lt;br /&gt;      New( CurStack );&lt;br /&gt;      CurStack^.Data := CopyString( Path );&lt;br /&gt;      repeat&lt;br /&gt;        with CurStack^ do&lt;br /&gt;        begin&lt;br /&gt;          if FindFirst( Data + Filter, faDirectory, Searcher ) = 0 then&lt;br /&gt;          begin&lt;br /&gt;            repeat&lt;br /&gt;              Inc( FTotalFiles );&lt;br /&gt;              Inc( FTotalSize, Searcher.Size );&lt;br /&gt;            until FindNext( Searcher ) &lt;&gt; 0;&lt;br /&gt;            FindClose( Searcher );&lt;br /&gt;          end;&lt;br /&gt;&lt;br /&gt;          if Self[I].Recurse and ( FindFirst( Data + Filter, faArchive, Searcher ) = 0 ) then&lt;br /&gt;          begin&lt;br /&gt;            repeat&lt;br /&gt;              if Searcher.Name[1] &lt;&gt; '.' then&lt;br /&gt;              begin&lt;br /&gt;                New( X );&lt;br /&gt;                X^.Data := CopyString( AddSlash( Data + Searcher.Name ) );&lt;br /&gt;                Stack.Push( X );&lt;br /&gt;              end;&lt;br /&gt;            until FindNext( Searcher ) &lt;&gt; 0;&lt;br /&gt;            FindClose( Searcher );&lt;br /&gt;          end;&lt;br /&gt;          FreeMem( Data );&lt;br /&gt;          Dispose( CurStack );&lt;br /&gt;          CurStack := Stack.Pop;&lt;br /&gt;        end;&lt;br /&gt;      until CurStack = nil;&lt;br /&gt;    end;&lt;br /&gt;  finally&lt;br /&gt;    Stack.Free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TFileJoiner.GetItem(const Index: Integer): TFileJoinerItem;&lt;br /&gt;begin&lt;br /&gt;  Result := FPaths.Items[ Index ];&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TFileJoiner.GetCount: Integer;&lt;br /&gt;begin&lt;br /&gt;  Result := FPaths.Count;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TFileJoiner.ListFiles( const Callback: TFileJoinerFilesCallback);&lt;br /&gt;type&lt;br /&gt;  PStackItem = ^TStackItem;&lt;br /&gt;  TStackItem = record&lt;br /&gt;    Source, Destiny: PChar;&lt;br /&gt;    Searcher: TSearchRec;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;  Stack: TStack;&lt;br /&gt;  Filter: string;&lt;br /&gt;  Current, X: PStackItem;&lt;br /&gt;  Data: TFileJoinerItem;&lt;br /&gt;  I: Integer;&lt;br /&gt;begin&lt;br /&gt;  Stack := TStack.Create;&lt;br /&gt;  try&lt;br /&gt;    Data := TFileJoinerItem.Create;&lt;br /&gt;    try&lt;br /&gt;      for I := 0 to FPaths.Count - 1 do&lt;br /&gt;      begin&lt;br /&gt;        Data.Assign( Self[I] );&lt;br /&gt;        with Data do&lt;br /&gt;        begin&lt;br /&gt;          Destiny := AddSlash( Destiny );&lt;br /&gt;          if LastDelimiter( '*?', ExtractFileName( Source ) ) &lt;&gt; 0 then&lt;br /&gt;          begin&lt;br /&gt;            Filter := ExtractFileName( Source );&lt;br /&gt;            Source := ExtractFilePath( Source );&lt;br /&gt;          end&lt;br /&gt;          else if FileExists( Source ) then&lt;br /&gt;          begin&lt;br /&gt;            Destiny := Destiny + ExtractFileName( Data.Source );&lt;br /&gt;            Callback( Self, Data );&lt;br /&gt;            Continue;&lt;br /&gt;          end&lt;br /&gt;          else if DirectoryExists( Source ) then&lt;br /&gt;          begin&lt;br /&gt;            Filter := '*';&lt;br /&gt;            Destiny := AddSlash( Destiny + ExtractFileName( RemoveSlash( Source ) ) );&lt;br /&gt;            Source := AddSlash( Source );&lt;br /&gt;          end&lt;br /&gt;          else&lt;br /&gt;            raise Exception.CreateFmt( '%s.ListFiles: "%s" n&#227;o encontrado', [ ClassName, Source ] );&lt;br /&gt;        end;&lt;br /&gt;&lt;br /&gt;        New( Current );&lt;br /&gt;        with Current^ do&lt;br /&gt;        begin&lt;br /&gt;          Source := CopyString( Data.Source );&lt;br /&gt;          Destiny := CopyString( Data.Destiny );&lt;br /&gt;        end;&lt;br /&gt;&lt;br /&gt;        repeat&lt;br /&gt;          with Current^ do&lt;br /&gt;          begin&lt;br /&gt;            if FindFirst( Source + Filter, faDirectory, Searcher ) = 0 then&lt;br /&gt;            begin&lt;br /&gt;              repeat&lt;br /&gt;                Data.Source := Source + Searcher.Name;&lt;br /&gt;                Data.Destiny := Destiny + Searcher.Name;&lt;br /&gt;                Callback( Self, Data )&lt;br /&gt;              until FindNext( Searcher ) &lt;&gt; 0;&lt;br /&gt;              FindClose( Searcher );&lt;br /&gt;            end;&lt;br /&gt;&lt;br /&gt;            if Data.Recurse and ( FindFirst( Source + '*', faArchive, Searcher ) = 0 ) then&lt;br /&gt;            begin&lt;br /&gt;              repeat&lt;br /&gt;                if Searcher.Name[1] &lt;&gt; '.' then&lt;br /&gt;                begin&lt;br /&gt;                  New( X );&lt;br /&gt;                  X^.Source := CopyString( AddSlash( Source + Searcher.Name ) );&lt;br /&gt;                  X^.Destiny := CopyString( AddSlash( Destiny + Searcher.Name ) );&lt;br /&gt;                  Stack.Push( X );&lt;br /&gt;                end;&lt;br /&gt;              un</description>
      <pubDate>Thu, 15 Jun 2006 19:09:02 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2197</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>Fast Sequential Search/Replace Engine supporting wildcards, backward search, whole words, etc... //Pascal Class</title>
      <link>http://snippets.dzone.com/posts/show/2196</link>
      <description>A quite fast unit to search/replace strings sequentially (while Seeker.Search() do...) in files/strings done mostly with pointers to improve speed. It's able to search backward, count end of lines, check case-sensitiveness, match whole words and handle wildcards (* and ?), &lt;br /&gt;&lt;br /&gt;The search method was divided into 4 specialized methods, again to improve speed. The right method is choosed according to the options that were setted (wildcard, search backward, etc...)&lt;br /&gt;&lt;br /&gt;This is an old code that doesn't match my current skills, anyway it has some cool techniques that I really enjoyed :)&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;//&lt;br /&gt;//    TNotesSeeker - classe de buscas do Notes.&lt;br /&gt;//&lt;br /&gt;//    Notes, http://notes.codigolivre.org.br&lt;br /&gt;//    Copyright (C) 2003-2004, Equipe do Notes.&lt;br /&gt;//&lt;br /&gt;//    This program is free software; you can redistribute it and/or modify&lt;br /&gt;//    it under the terms of the GNU General Public License as published by&lt;br /&gt;//    the Free Software Foundation; either version 2 of the License, or&lt;br /&gt;//    (at your option) any later version.&lt;br /&gt;//&lt;br /&gt;//    This program is distributed in the hope that it will be useful,&lt;br /&gt;//    but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;//    GNU General Public License for more details.&lt;br /&gt;//&lt;br /&gt;//    You should have received a copy of the GNU General Public License&lt;br /&gt;//    along with this program; if not, write to the Free Software&lt;br /&gt;//    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA&lt;br /&gt;//&lt;br /&gt;//    **************************************************************&lt;br /&gt;//    Revision #0&lt;br /&gt;//      Version  : 1.0.0&lt;br /&gt;//      Date     : 2003-11-30 22:00:00 GMT -3:00&lt;br /&gt;//      Reviewer : Jonas Raoni Soares Silva&lt;br /&gt;//      Changes  : Criada a classe.&lt;br /&gt;//    **************************************************************&lt;br /&gt;//    Revision #1&lt;br /&gt;//      Version  : 1.0.1&lt;br /&gt;//      Date     : 2004-09-09 03:30:00 GMT -3:00&lt;br /&gt;//      Reviewer : Jonas Raoni Soares Silva&lt;br /&gt;//      Changes  : Acho q acabaram-se os bugs... Ser&#225;??? :]&lt;br /&gt;//    **************************************************************&lt;br /&gt;&lt;br /&gt;(*&lt;br /&gt;@abstract(NotesSeeker - classe de buscas do Notes.)&lt;br /&gt;@author(Jonas Raoni Soares Silva &lt;jonblackjack@bol.com.br&gt;)&lt;br /&gt;@created(30 Nov 2003)&lt;br /&gt;*)&lt;br /&gt;&lt;br /&gt;unit NotesSeeker;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  SysUtils, Classes;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;  @code(ENotesSeekerException) -&lt;br /&gt;    Notificar erros na classe TNotesSeeker de forma&lt;br /&gt;    profissional, facilitando a intercepta&#231;&#227;o e/ou log de&lt;br /&gt;    erros&lt;br /&gt;}&lt;br /&gt;  ENotesSeekerException = class ( Exception )&lt;br /&gt;  public&lt;br /&gt;    constructor Create(const Msg: string);&lt;br /&gt;    constructor CreateFmt(const Msg: string; const Args: array of const);&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  {Op&#245;es de pesquisa: &lt;BR&gt;&lt;br /&gt;   @code(nsHandleEOL) - se voc&#234; precisar buscar por quebras de linhas, voc&#234; precisa setar esta op&#231;&#227;o.&lt;BR&gt;&lt;br /&gt;   @code(nsCaseSensitive) - diferenciar mai&#250;sculas de min&#250;sculas.&lt;BR&gt;&lt;br /&gt;   @code(nsWholeWords) - retorna apenas palavras inteiras.&lt;BR&gt;&lt;br /&gt;   @code(nsBackward) - busca de traz para frente. &lt;BR&gt;&lt;br /&gt;   @code(nsHandleWildCard) - usa coringas * e ? na pesquisa.}&lt;br /&gt;  TNotesSeekerOption = ( nsHandleEOL, nsCaseSensitive, nsWholeWords, nsBackward, nsHandleWildCard );&lt;br /&gt;  { Set de @link(TNotesSeekerOption).}&lt;br /&gt;  TNotesSeekerOptions = set of TNotesSeekerOption;&lt;br /&gt;&lt;br /&gt;  TSearchFunction = function: Boolean of object;&lt;br /&gt;&lt;br /&gt;{&lt;br /&gt;  @code(TNotesSeeker) -&lt;br /&gt;    Permite fazer buscas em strings com v&#225;rias op&#231;&#245;es&lt;br /&gt;}&lt;br /&gt;  TNotesSeeker = class(TObject)&lt;br /&gt;  private&lt;br /&gt;    Jump, LineJump: Cardinal;&lt;br /&gt;    FList: TList;&lt;br /&gt;  protected&lt;br /&gt;    FMatches, FStartAt, FEOLLen, FSearchLen, FCurCol,&lt;br /&gt;    FCurLine, FMatchLen, FMatchLine, FMatchCol: Cardinal;&lt;br /&gt;&lt;br /&gt;    FBufferEnd, FBuffer, FBufferBegin, FBufferBackup,&lt;br /&gt;    FEOL, FSearchBegin, FSearch, FSearchEnd: PChar;&lt;br /&gt;&lt;br /&gt;    FOptions: TNotesSeekerOptions;&lt;br /&gt;&lt;br /&gt;    FContextRightLenght, FContextLeftLenght: Cardinal;&lt;br /&gt;&lt;br /&gt;    FKeepText: Boolean;&lt;br /&gt;&lt;br /&gt;    function GetText: string;&lt;br /&gt;    function GetReplacedText: string;&lt;br /&gt;    function GetContext: string;&lt;br /&gt;    function GetSearchStr: string;&lt;br /&gt;    function GetRemainingText: string;&lt;br /&gt;    function GetCurByte: Cardinal;&lt;br /&gt;    function GetEOL: string;&lt;br /&gt;&lt;br /&gt;    procedure SetOptions(const Value: TNotesSeekerOptions);&lt;br /&gt;    procedure SetText( const Value: string);&lt;br /&gt;    procedure SetSearchStr(const Value: string);&lt;br /&gt;    procedure SetEOL(const Value: string);&lt;br /&gt;&lt;br /&gt;    procedure FreeBuffer;&lt;br /&gt;    procedure FreeEOL;&lt;br /&gt;    procedure FreeSearchStr;&lt;br /&gt;&lt;br /&gt;    {Search Engines}&lt;br /&gt;    function SearchForward: Boolean;&lt;br /&gt;    function SearchForwardWithWildCard: Boolean;&lt;br /&gt;    function SearchBackward: Boolean;&lt;br /&gt;    function SearchBackwardWithWildCard: Boolean;&lt;br /&gt;&lt;br /&gt;  public&lt;br /&gt;    { Efetua a busca: se o termo procurado for encontrado, retorna true, caso contr&#225;rio retorna false }&lt;br /&gt;    Search: TSearchFunction;&lt;br /&gt;&lt;br /&gt;    { M&#233;todo construtor }&lt;br /&gt;    constructor Create; virtual;&lt;br /&gt;    { M&#233;todo destruidor }&lt;br /&gt;    destructor Destroy; override;&lt;br /&gt;&lt;br /&gt;    { Armazena o tamanho do "match", quando a op&#231;&#227;o wildcard estiver desligada esta ser&#225; igual ao tamanho da pr&#243;pria string procurada }&lt;br /&gt;    property MatchLength: Cardinal read FMatchLen;&lt;br /&gt;    { Quando HandleEOL fizer parte das op&#231;&#245;es, armazenar&#225; a linha onde a string procurada foi encontrada }&lt;br /&gt;    property CurLine: Cardinal read FMatchLine;&lt;br /&gt;    { Armazenar&#225; a coluna onde a string procurada foi encontrada, se HandleEOL n&#227;o estiver nas op&#231;&#245;es, armazenar&#225; a mesma coisa que a propriedade CurByte }&lt;br /&gt;    property CurCol: Cardinal read FMatchCol;&lt;br /&gt;    { Armazena a posi&#231;&#227;o ou byte "absoluto" onde a string foi encontrada }&lt;br /&gt;    property CurByte: Cardinal read GetCurByte;&lt;br /&gt;    { Especifica a posi&#231;&#227;o/byte inicial onde a busca dever&#225; come&#231;ar }&lt;br /&gt;    property StartAt: Cardinal read FStartAt write FStartAt;&lt;br /&gt;    { Retorna o contexto onde a string procurada foi encontrada }&lt;br /&gt;    property Context: string read GetContext;&lt;br /&gt;    { Especifica a quantidade de caracteres que dever&#227;o fazer parte do contexto encontrado ao lado esquerdo da string procurada }&lt;br /&gt;    property ContextLeftLenght: Cardinal read FContextLeftLenght write FContextLeftLenght;&lt;br /&gt;    { Especifica a quantidade de caracteres que dever&#227;o fazer parte do contexto encontrado ao lado direito da string procurada }&lt;br /&gt;    property ContextRightLenght: Cardinal read FContextRightLenght write FContextRightLenght;&lt;br /&gt;    { Armazena o n&#250;mero de strings que coincidiram com a busca at&#233; o presente momento }&lt;br /&gt;    property Matches: Cardinal read FMatches;&lt;br /&gt;    { Permite alterar a sequ&#234;ncia de caracteres que demarcam o fim de uma linha }&lt;br /&gt;    property EOL: string read GetEOL write SetEOL;&lt;br /&gt;    { Armazena as op&#231;&#245;es atualmente habilitadas para a busca, podendo ser alterada a qualquer momento }&lt;br /&gt;    property Options: TNotesSeekerOptions read FOptions write SetOptions;&lt;br /&gt;    { Termo a ser procurado no texto }&lt;br /&gt;    property SearchStr: string read GetSearchStr write SetSearchStr;&lt;br /&gt;    { Texto onde a busca ser&#225; efetuada }&lt;br /&gt;    property Text: string read GetText write SetText;&lt;br /&gt;    { Texto restante ao t&#233;rmino da busca }&lt;br /&gt;    property RemainingText: string read GetRemainingText;&lt;br /&gt;    { Especifica se a classe dever&#225; manter uma c&#243;pia do texto setado inicialmente }&lt;br /&gt;    property KeepText: Boolean read FKeepText write FKeepText;&lt;br /&gt;    { Retorna o texto com os replaces, caso KeepText seja falso, essa propriedade se torna sin&#244;nimo da propriedade Text }&lt;br /&gt;    property ReplacedText: string read GetReplacedText;&lt;br /&gt;&lt;br /&gt;    { Prepara tudo para uma nova busca }&lt;br /&gt;    procedure StartSearch;&lt;br /&gt;    { Carrega o texto da busca a partir de um arquivo }&lt;br /&gt;    procedure LoadFromFile( const AFilename: string );&lt;br /&gt;    { Carrega o texto da busca a partir de um stream }&lt;br /&gt;    procedure LoadFromStream( const AStream: TStream );&lt;br /&gt;    { Carrega o texto da busca a partir de um buffer }&lt;br /&gt;    procedure LoadFromBuffer( const ABuffer: PChar );&lt;br /&gt;    { Efetua a substitui&#231;&#227;o da string encontrada pela string contida em "S" }&lt;br /&gt;    procedure Replace( const S: String );&lt;br /&gt;    { Modo pr&#225;tico para setar as op&#231;&#245;es }&lt;br /&gt;    procedure EnableOptions( const CaseSensitive: Boolean = true; const WholeWords: Boolean = false; const HandleEOL: Boolean = true; const HandleWildCard: Boolean = false; const Backward: Boolean = false );&lt;br /&gt;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  { Compara Str1 e Str2 de tr&#225;s pra frente, se as duas forem iguais retorna true, caso contr&#225;rio false }&lt;br /&gt;  function StrLRComp( S1, S2: PChar; const S2Begin: PChar ): Boolean;&lt;br /&gt;  { Converte para mai&#250;sculo (ANSI) -&gt; VALEUUUUU TIO RUSS&#195;O hahaha, o que tem no delphi "aplica a altera&#231;&#227;o"&lt;br /&gt;    Id&#233;ia de manter tabela com tudo mai&#250;sculo arrancada de "QStrings 6.07.424 Copyright (C) 2000, 2003 Andrew Dryazgov [ andrewdr@newmail.ru ]" }&lt;br /&gt;  function AnsiUpCase(Ch: Char): Char;&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  { Caracteres que definem delimitadores de palavra, usada quando a op&#231;&#227;o WholeWords est&#225; ativa }&lt;br /&gt;  WhiteSpaces: set of Char = [' ',#9,#13,#10,'!','"','#','$','%','&amp;','''','(',')','*','+','-','/',':',';','&lt;','=','&gt;','?','@','[','\',']','^','`','{','|','}','~'];&lt;br /&gt;&lt;br /&gt;const&lt;br /&gt;  //fiz algumas altera&#231;&#245;es hehe, o tiozaum russo devia t&#225; come&#231;ano a ficar cego enqto fazia isso :)&lt;br /&gt;  ToUpperChars: array[0..255] of Char =&lt;br /&gt;    (#$00,#$01,#$02,#$03,#$04,#$05,#$06,#$07,#$08,#$09,#$0A,#$0B,#$0C,#$0D,#$0E,#$0F,&lt;br /&gt;     #$10,#$11,#$12,#$13,#$14,#$15,#$16,#$17,#$18,#$19,#$1A,#$1B,#$1C,#$1D,#$1E,#$1F,&lt;br /&gt;     #$20,#$21,#$22,#$23,#$24,#$25,#$26,#$27,#$28,#$29,#$2A,#$2B,#$2C,#$2D,#$2E,#$2F,&lt;br /&gt;     #$30,#$31,#$32,#$33,#$34,#$35,#$36,#$37,#$38,#$39,#$3A,#$3B,#$3C,#$3D,#$3E,#$3F,&lt;br /&gt;     #$40,#$41,#$42,#$43,#$44,#$45,#$46,#$47,#$48,#$49,#$4A,#$4B,#$4C,#$4D,#$4E,#$4F,&lt;br /&gt;     #$50,#$51,#$52,#$53,#$54,#$55,#$56,#$57,#$58,#$59,#$5A,#$5B,#$5C,#$5D,#$5E,#$5F,&lt;br /&gt;     #$60,#$41,#$42,#$43,#$44,#$45,#$46,#$47,#$48,#$49,#$4A,#$4B,#$4C,#$4D,#$4E,#$4F,&lt;br /&gt;     #$50,#$51,#$52,#$53,#$54,#$55,#$56,#$57,#$58,#$59,#$5A,#$7B,#$7C,#$7D,#$7E,#$7F,&lt;br /&gt;     #$80,#$81,#$82,#$81,#$84,#$85,#$86,#$87,#$88,#$89,#$8A,#$8B,#$8C,#$8D,#$8E,#$8F,&lt;br /&gt;     #$90,#$91,#$92,#$93,#$94,#$95,#$96,#$97,#$98,#$99,#$8A,#$9B,#$8C,#$9D,#$9E,#$9F,&lt;br /&gt;     #$A0,#$A1,#$A1,#$A3,#$A4,#$A5,#$A6,#$A7,#$A8,#$A9,#$AA,#$AB,#$AC,#$AD,#$AE,#$AF,&lt;br /&gt;     #$B0,#$B1,#$B2,#$B2,#$A5,#$B5,#$B6,#$B7,#$A8,#$B9,#$BA,#$BB,#$BC,#$BD,#$BE,#$BF,&lt;br /&gt;     #$C0,#$C1,#$C2,#$C3,#$C4,#$C5,#$C6,#$C7,#$C8,#$C9,#$CA,#$CB,#$CC,#$CD,#$CE,#$CF,&lt;br /&gt;     #$D0,#$D1,#$D2,#$D3,#$D4,#$D5,#$D6,#$D7,#$D8,#$D9,#$DA,#$DB,#$DC,#$DD,#$DE,#$DF,&lt;br /&gt;     #$C0,#$C1,#$C2,#$C3,#$C4,#$C5,#$C6,#$C7,#$C8,#$C9,#$CA,#$CB,#$CC,#$CD,#$CE,#$CF,&lt;br /&gt;     #$D0,#$D1,#$D2,#$D3,#$D4,#$D5,#$D6,#$F7,#$D8,#$D9,#$DA,#$DB,#$DC,#$DD,#$DE,#$9F);&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;function StrLRComp( S1, S2: PChar; const S2Begin: PChar ): Boolean;&lt;br /&gt;begin&lt;br /&gt;  while ( S2 &lt;&gt; S2Begin ) and ( S1^ = S2^ ) do begin&lt;br /&gt;    dec( S1 );&lt;br /&gt;    dec( S2 );&lt;br /&gt;  end;&lt;br /&gt;  Result := ( S1^ = S2^ ) and ( S2 = S2Begin );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function AnsiUpCase(Ch: Char): Char;&lt;br /&gt;begin&lt;br /&gt;  Result := ToUpperChars[ ord( ch ) ];&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{ class : TNotesSeeker }&lt;br /&gt;&lt;br /&gt;{ TNotesSeeker : protected }&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.GetText: string;&lt;br /&gt;begin&lt;br /&gt;  if Assigned( FBufferBackup ) then&lt;br /&gt;    Result := StrPas( FBufferBackup )&lt;br /&gt;  else&lt;br /&gt;    Result := ReplacedText;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.GetReplacedText: string;&lt;br /&gt;begin&lt;br /&gt;  Result := StrPas( FBufferBegin );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.GetContext: string;&lt;br /&gt;var&lt;br /&gt;  BeginAt, EndAt: PChar;&lt;br /&gt;begin&lt;br /&gt;  if not ( nsBackward in FOptions ) then begin&lt;br /&gt;    BeginAt := FBuffer - FMatchLen - FContextLeftLenght;&lt;br /&gt;    EndAt := FBuffer+FContextRightLenght;&lt;br /&gt;  end&lt;br /&gt;  else begin&lt;br /&gt;    BeginAt := FBuffer+1-FContextLeftLenght;&lt;br /&gt;    EndAt := FBuffer+1+FMatchLen+FContextRightLenght;&lt;br /&gt;  end;&lt;br /&gt;  if BeginAt &gt; EndAt then&lt;br /&gt;    raise ENotesSeekerException.CreateFmt('GetContext::Range Error "BeginAt(%d) &gt; EndAt(%d)"', [Integer(BeginAt), Integer(EndAt)]);&lt;br /&gt;  if BeginAt &lt; FBufferBegin then&lt;br /&gt;    BeginAt := FBufferBegin;&lt;br /&gt;  if EndAt &gt; FBufferEnd then&lt;br /&gt;    EndAt := FBufferEnd;&lt;br /&gt;&lt;br /&gt;  SetString( Result, BeginAt, EndAt-BeginAt );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.GetSearchStr: string;&lt;br /&gt;begin&lt;br /&gt;  Result := StrPas( FSearchBegin );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.GetRemainingText: string;&lt;br /&gt;begin&lt;br /&gt;  Result := '';&lt;br /&gt;  if not ( nsBackward in FOptions ) then&lt;br /&gt;    Result := StrPas( FBuffer )&lt;br /&gt;  else if FBuffer-FBufferBegin &gt; -1 then&lt;br /&gt;    SetString( Result, FBufferBegin, FBuffer-FBufferBegin+1 );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.GetCurByte: Cardinal;&lt;br /&gt;begin&lt;br /&gt;  if nsBackward in FOptions then&lt;br /&gt;    Result := FBufferEnd-1 - FBuffer - FMatchLen&lt;br /&gt;  else&lt;br /&gt;    Result := FBuffer - FMatchLen - FBufferBegin;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.GetEOL: string;&lt;br /&gt;begin&lt;br /&gt;  Result := StrPas( FEOL );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.SetOptions(const Value: TNotesSeekerOptions);&lt;br /&gt;begin&lt;br /&gt;  FOptions := Value;&lt;br /&gt;  if nsBackward in Value then&lt;br /&gt;    if nsHandleWildCard in Value then&lt;br /&gt;      Search := SearchBackwardWithWildCard&lt;br /&gt;    else&lt;br /&gt;      Search := SearchBackward&lt;br /&gt;  else if nsHandleWildCard in Value then&lt;br /&gt;    Search := SearchForwardWithWildCard&lt;br /&gt;  else&lt;br /&gt;    Search := SearchForward;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.SetText( const Value: string );&lt;br /&gt;begin&lt;br /&gt;  LoadFromBuffer( PChar( Value ) );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.SetSearchStr(const Value: string);&lt;br /&gt;begin&lt;br /&gt;  FreeSearchStr;&lt;br /&gt;  FSearchLen := Length( Value );&lt;br /&gt;  GetMem( FSearchBegin, FSearchLen+1 );&lt;br /&gt;  StrCopy( FSearchBegin, PChar( Value ) );&lt;br /&gt;  FSearch := FSearchBegin;&lt;br /&gt;  FSearchEnd := StrEnd( FSearchBegin );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.SetEOL(const Value: string);&lt;br /&gt;begin&lt;br /&gt;  FreeEOL;&lt;br /&gt;  FEOLLen := Length( Value );&lt;br /&gt;  GetMem( FEOL, FEOLLen+1 );&lt;br /&gt;  StrCopy( FEOL, PChar( Value ) );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.FreeBuffer;&lt;br /&gt;begin&lt;br /&gt;  if Assigned( FBufferBegin ) then begin&lt;br /&gt;    FBufferEnd := nil;&lt;br /&gt;    FBuffer := nil;&lt;br /&gt;    FreeMem( FBufferBegin );&lt;br /&gt;  end;&lt;br /&gt;  if Assigned( FBufferBackup ) then begin&lt;br /&gt;    FreeMem( FBufferBackup );&lt;br /&gt;    FBufferBackup := nil;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.FreeEOL;&lt;br /&gt;begin&lt;br /&gt;  if Assigned( FEOL ) then begin&lt;br /&gt;    FreeMem( FEOL );&lt;br /&gt;    FEOL := nil;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.FreeSearchStr;&lt;br /&gt;begin&lt;br /&gt;  if Assigned( FSearchBegin ) then begin&lt;br /&gt;    FreeMem( FSearchBegin );&lt;br /&gt;    FSearchBegin := nil;&lt;br /&gt;    FSearch := nil;&lt;br /&gt;    FSearchEnd := nil;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{ TNotesSeeker : public }&lt;br /&gt;&lt;br /&gt;constructor TNotesSeeker.Create;&lt;br /&gt;begin&lt;br /&gt;  EOL := #13#10;&lt;br /&gt;  FContextLeftLenght := 10;&lt;br /&gt;  FContextRightLenght := 20;&lt;br /&gt;  Search := SearchForward;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;destructor TNotesSeeker.Destroy;&lt;br /&gt;begin&lt;br /&gt;  FreeBuffer;&lt;br /&gt;  FreeSearchStr;&lt;br /&gt;  FreeEOL;&lt;br /&gt;  inherited Destroy;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.LoadFromBuffer( const ABuffer: PChar );&lt;br /&gt;begin&lt;br /&gt;  FreeBuffer;&lt;br /&gt;  GetMem( FBufferBegin, StrLen( ABuffer )+1 );&lt;br /&gt;  FBuffer := StrCopy( FBufferBegin, ABuffer );&lt;br /&gt;  FBufferEnd :=  StrEnd( FBufferBegin );&lt;br /&gt;  if FKeepText then begin&lt;br /&gt;    GetMem( FBufferBackup, StrLen( FBufferBegin )+1 );&lt;br /&gt;    StrCopy( FBufferBackup, FBufferBegin );&lt;br /&gt;  end;  &lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.LoadFromFile(const AFilename: string);&lt;br /&gt;var&lt;br /&gt;  FS: TFileStream;&lt;br /&gt;begin&lt;br /&gt;  if not FileExists( AFilename ) then&lt;br /&gt;    raise ENotesSeekerException.CreateFmt( 'LoadFromFile::Arquivo "%s" n&#227;o encontrado', [AFilename] );&lt;br /&gt;  FS := TFileStream.Create( AFilename, fmOpenRead );&lt;br /&gt;  try&lt;br /&gt;    LoadFromStream( FS );&lt;br /&gt;  finally&lt;br /&gt;    FS.Free;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.LoadFromStream(const AStream: TStream);&lt;br /&gt;var&lt;br /&gt;  Size: Int64;&lt;br /&gt;begin&lt;br /&gt;  FreeBuffer;&lt;br /&gt;  Size := AStream.Size;&lt;br /&gt;  GetMem( FBuffer, Size+1 );&lt;br /&gt;  Size := AStream.Read( FBuffer^, Size );&lt;br /&gt;  ( FBuffer+Size )^ := #0;&lt;br /&gt;  FBufferEnd := (FBuffer+Size);&lt;br /&gt;  FBufferBegin := FBuffer;&lt;br /&gt;  if FKeepText then begin&lt;br /&gt;    GetMem( FBufferBackup, StrLen( FBufferBegin )+1 );&lt;br /&gt;    StrCopy( FBufferBackup, FBufferBegin );&lt;br /&gt;  end;  &lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.StartSearch;&lt;br /&gt;begin&lt;br /&gt;  FMatches := 0;&lt;br /&gt;  FCurLine := 0;&lt;br /&gt;  FCurCol := 0;&lt;br /&gt;&lt;br /&gt;  if FSearchLen = 0 then&lt;br /&gt;    raise ENotesSeekerException.Create( 'StartSearch::Propriedade SearchStr est&#225; vazia.' );&lt;br /&gt;&lt;br /&gt;  if ( FBufferBackup &lt;&gt; FBufferBegin ) and Assigned( FBufferBackup ) then begin&lt;br /&gt;    FreeMem( FBufferBegin );&lt;br /&gt;    GetMem( FBufferBegin, StrLen( FBufferBackup )+1 );&lt;br /&gt;    FBuffer := StrCopy( FBufferBegin, FBufferBackup );&lt;br /&gt;    FBufferEnd := FBuffer + StrLen( FBufferBackup );&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  if nsBackward in FOptions then&lt;br /&gt;    FBuffer := FBufferEnd-1&lt;br /&gt;  else&lt;br /&gt;    FBuffer := FBufferBegin;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.Replace(const S: String);&lt;br /&gt;var&lt;br /&gt;  TempBuff: PChar;&lt;br /&gt;  BufferOffset: Integer;&lt;br /&gt;begin&lt;br /&gt;  TempBuff := nil;&lt;br /&gt;  if not ( nsBackward in FOptions ) then begin&lt;br /&gt;    BufferOffset := FBuffer-FMatchLen - FBufferBegin + Length( S );&lt;br /&gt;    GetMem( TempBuff, ( FBuffer-FMatchLen - FBufferBegin) + Length(S) + ( FBufferEnd - FBuffer ) + 1 );&lt;br /&gt;    FBufferEnd := StrLCopy( StrLCopy( StrLCopy( TempBuff, FBufferBegin, FBuffer-FMatchLen - FBufferBegin )+(FBuffer-FMatchLen - FBufferBegin), PChar( S ), Length( S ) )+Length( S ), FBuffer, FBufferEnd - FBuffer )+(FBufferEnd - FBuffer);&lt;br /&gt;    FreeMem( FBufferBegin );&lt;br /&gt;    FBufferBegin := TempBuff;&lt;br /&gt;    FBuffer := FBufferBegin + BufferOffset;&lt;br /&gt;  end&lt;br /&gt;  else begin&lt;br /&gt;    BufferOffset := FBufferEnd - (FBuffer + FMatchLen) + Length( S );&lt;br /&gt;    if FBuffer &lt; FBufferBegin then&lt;br /&gt;      GetMem( TempBuff, FBufferEnd - (FBuffer+FMatchLen) + Length( S ) + ( FBuffer - FBufferBegin ) + 1 )&lt;br /&gt;    else&lt;br /&gt;      GetMem( TempBuff, FBufferEnd - (FBuffer+FMatchLen) + Length( S ) + ( FBuffer - FBufferBegin ) + 1 );&lt;br /&gt;    FBufferEnd := StrLCopy( StrLCopy( StrLCopy( TempBuff, FBufferBegin, FBuffer-FBufferBegin+1 )+(FBuffer-FBufferBegin+1), PChar( S ), Length( S ) )+Length( S ), FBuffer+FMatchLen+1, FBufferEnd-1 - (FBuffer+FMatchLen) )+ ( FBufferEnd-1 - (FBuffer+FMatchLen) );&lt;br /&gt;    FreeMem( FBufferBegin );&lt;br /&gt;    FBufferBegin := TempBuff;&lt;br /&gt;    FBuffer := FBufferEnd - BufferOffset;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{ ENotesSeekerException }&lt;br /&gt;{ ENotesSeekerException : public }&lt;br /&gt;&lt;br /&gt;constructor ENotesSeekerException.Create(const Msg: string);&lt;br /&gt;begin&lt;br /&gt;  inherited Create( 'TNotesSeeker.'+Msg );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;constructor ENotesSeekerException.CreateFmt(const Msg: string; const Args: array of const);&lt;br /&gt;begin&lt;br /&gt;  inherited CreateFmt( 'TNotesSeeker.'+Msg, Args );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;procedure TNotesSeeker.EnableOptions(const CaseSensitive, WholeWords, HandleEOL, HandleWildCard, Backward: Boolean);&lt;br /&gt;  var Opcoes: TNotesSeekerOptions;&lt;br /&gt;begin&lt;br /&gt;  if CaseSensitive then Include( Opcoes, nsCaseSensitive ) else Exclude( Opcoes, nsCaseSensitive );&lt;br /&gt;  if HandleEOL then Include( Opcoes, nsHandleEOL ) else Exclude( Opcoes, nsHandleEOL );&lt;br /&gt;  if Backward then Include( Opcoes, nsBackward ) else Exclude( Opcoes, nsBackward );&lt;br /&gt;  if HandleWildCard then Include( Opcoes, nsHandleWildCard ) else Exclude( Opcoes, nsHandleWildCard );&lt;br /&gt;  if WholeWords then Include( Opcoes, nsWholeWords ) else Exclude( Opcoes, nsWholeWords );&lt;br /&gt;  SetOptions( Opcoes );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.SearchForward: Boolean;&lt;br /&gt;begin&lt;br /&gt;  Result := True;&lt;br /&gt;  LineJump := 0;&lt;br /&gt;  FMatchLine := 0;&lt;br /&gt;  FMatchCol := 0;&lt;br /&gt;  FMatchLen := 0;&lt;br /&gt;  FSearch := FSearchBegin;&lt;br /&gt;&lt;br /&gt;  if FBufferBegin + FStartAt &gt; FBufferEnd then&lt;br /&gt;    FStartAt := FBufferEnd - FBufferBegin;&lt;br /&gt;  while FStartAt &gt; FBuffer-FBufferBegin do begin&lt;br /&gt;    if ( nsHandleEOL in FOptions ) and ( FBuffer^ = FEOL^ ) and ( StrLComp( FBuffer, FEOL, FEOLLen ) = 0 ) then begin&lt;br /&gt;      Inc( FBuffer, FEOLLen );&lt;br /&gt;      Inc( FCurLine );&lt;br /&gt;      FCurCol := 0;&lt;br /&gt;      Continue;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      Inc( FCurCol );&lt;br /&gt;    Inc( FBuffer );&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  while FBuffer &lt;&gt; FBufferEnd do begin&lt;br /&gt;    if ( (nsCaseSensitive in FOptions ) and ( FBuffer^ = FSearch^ ) ) or ( not(nsCaseSensitive in FOptions ) and ( AnsiUpCase( FBuffer^ ) = AnsiUpCase( FSearch^ ) ) ) then begin&lt;br /&gt;      Inc( FMatchLen );&lt;br /&gt;      Inc( FSearch );&lt;br /&gt;      if Result then begin&lt;br /&gt;        Result := False;&lt;br /&gt;        FMatchCol := FCurCol;&lt;br /&gt;        FMatchLine := FCurLine;&lt;br /&gt;        if ( nsWholeWords in FOptions ) and ( FBuffer &gt; FBufferBegin ) and not ( (FBuffer-1)^ in WhiteSpaces ) then begin&lt;br /&gt;          FSearch := FSearchBegin;&lt;br /&gt;          FMatchLen := 0;&lt;br /&gt;          FMatchLine := 0;&lt;br /&gt;          FMatchCol := 0;&lt;br /&gt;        end;&lt;br /&gt;      end;&lt;br /&gt;      if ( nsWholeWords in FOptions ) and ( FMatchLen = FSearchLen ) and ( FBuffer &lt; FBufferEnd-1 ) and not ( (FBuffer+1)^ in WhiteSpaces ) then begin&lt;br /&gt;        FSearch := FSearchBegin;&lt;br /&gt;        FMatchLen := 0;&lt;br /&gt;        FMatchLine := 0;&lt;br /&gt;        FMatchCol := 0;&lt;br /&gt;      end;&lt;br /&gt;&lt;br /&gt;      if ( nsHandleEOL in FOptions ) and ( FBuffer^ = FEOL^ ) and ( StrLComp( FBuffer, FEOL, FEOLLen ) = 0 ) then begin&lt;br /&gt;        Inc( FCurLine );&lt;br /&gt;        FCurCol := 0;&lt;br /&gt;        LineJump := FEOLLen-1;&lt;br /&gt;      end&lt;br /&gt;      else if LineJump = 0 then&lt;br /&gt;        Inc( FCurCol )&lt;br /&gt;      else&lt;br /&gt;        Dec( LineJump );&lt;br /&gt;&lt;br /&gt;      Inc( FBuffer );&lt;br /&gt;      if FSearch^ = #0 then begin&lt;br /&gt;        Result := True;&lt;br /&gt;        Inc( FMatches );&lt;br /&gt;        Exit;&lt;br /&gt;      end;&lt;br /&gt;    end&lt;br /&gt;    else begin&lt;br /&gt;      Result := True;&lt;br /&gt;      FMatchLen := 0;&lt;br /&gt;      FMatchLine := 0;&lt;br /&gt;      FMatchCol := 0;&lt;br /&gt;      &lt;br /&gt;      if FSearch &lt;&gt; FSearchBegin then begin&lt;br /&gt;        FSearch := FSearchBegin;&lt;br /&gt;        Continue;&lt;br /&gt;      end;&lt;br /&gt;&lt;br /&gt;      if ( nsHandleEOL in FOptions ) and ( FBuffer^ = FEOL^ ) and ( StrLComp( FBuffer, FEOL, FEOLLen ) = 0 ) then begin&lt;br /&gt;        Inc( FCurLine );&lt;br /&gt;        FCurCol := 0;&lt;br /&gt;        LineJump := FEOLLen-1;&lt;br /&gt;      end&lt;br /&gt;      else if LineJump = 0 then&lt;br /&gt;        Inc( FCurCol )&lt;br /&gt;      else&lt;br /&gt;        Dec( LineJump );&lt;br /&gt;&lt;br /&gt;      Inc( FBuffer )        &lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;  Result := False;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.SearchForwardWithWildCard: Boolean;&lt;br /&gt;begin&lt;br /&gt;  Result := True;&lt;br /&gt;  Jump := 1;&lt;br /&gt;  LineJump := 0;&lt;br /&gt;  FMatchLine := 0;&lt;br /&gt;  FMatchCol := 0;&lt;br /&gt;  FMatchLen := 0;&lt;br /&gt;  FSearch := FSearchBegin;&lt;br /&gt;&lt;br /&gt;  if FBufferBegin + FStartAt &gt; FBufferEnd then&lt;br /&gt;    FStartAt := FBufferEnd - FBufferBegin;&lt;br /&gt;  while FStartAt &gt; FBuffer-FBufferBegin do begin&lt;br /&gt;    if ( nsHandleEOL in FOptions ) and ( FBuffer^ = FEOL^ ) and ( StrLComp( FBuffer, FEOL, FEOLLen ) = 0 ) then begin&lt;br /&gt;      Inc( FBuffer, FEOLLen );&lt;br /&gt;      Inc( FCurLine );&lt;br /&gt;      FCurCol := 0;&lt;br /&gt;      Continue;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      Inc( FCurCol );&lt;br /&gt;    Inc( FBuffer );&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  while FBuffer &lt;&gt; FBufferEnd do begin&lt;br /&gt;    if FSearch^ = '?' then begin&lt;br /&gt;      Inc( FMatchLen );&lt;br /&gt;      Inc( FSearch );&lt;br /&gt;    end&lt;br /&gt;    else if FSearch^ = '*' then begin&lt;br /&gt;      if (FSearch+Jump)^ = '?' then begin&lt;br /&gt;        Inc( FMatchLen );&lt;br /&gt;        Inc( Jump );&lt;br /&gt;      end&lt;br /&gt;      else if (FSearch+Jump)^ = '*' then begin&lt;br /&gt;        Inc( FSearch, Jump );&lt;br /&gt;        Jump := 1;&lt;br /&gt;        continue;&lt;br /&gt;      end&lt;br /&gt;      else if ( ( nsCaseSensitive in FOptions ) and ( FBuffer^ = (FSearch+Jump)^ ) ) or ( not( nsCaseSensitive in FOptions ) and ( AnsiUpCase( FBuffer^ ) = AnsiUpCase( (FSearch+Jump)^ ) )  ) then begin&lt;br /&gt;        Inc( FMatchLen );&lt;br /&gt;        Inc( Jump );&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;        Inc( FMatchLen );&lt;br /&gt;      if (FSearch+Jump)^ = #0 then begin&lt;br /&gt;        if (FSearch+Jump-1)^ = '*' then begin&lt;br /&gt;          Inc( FMatchLen, FBufferEnd-FBuffer - 1 );&lt;br /&gt;          FBuffer := FBufferEnd - 1;&lt;br /&gt;        end;&lt;br /&gt;        FSearch := FSearchEnd;&lt;br /&gt;      end;&lt;br /&gt;    end&lt;br /&gt;    else if ( ( nsCaseSensitive in FOptions ) and ( FBuffer^ = FSearch^ ) ) or ( not ( nsCaseSensitive in FOptions ) and ( AnsiUpCase( FBuffer^ ) = AnsiUpCase( FSearch^ ) ) ) then begin&lt;br /&gt;      Inc( FMatchLen );&lt;br /&gt;      Inc( FSearch );&lt;br /&gt;    end&lt;br /&gt;    else begin&lt;br /&gt;      Result := True;&lt;br /&gt;      FMatchLen := 0;&lt;br /&gt;      FMatchLine := 0;&lt;br /&gt;      FMatchCol := 0;&lt;br /&gt;      Jump := 1;&lt;br /&gt;      if FSearch &lt;&gt; FSearchBegin then begin&lt;br /&gt;        FSearch := FSearchBegin;&lt;br /&gt;        Continue;&lt;br /&gt;      end;&lt;br /&gt;&lt;br /&gt;      if ( nsHandleEOL in FOptions ) and ( FBuffer^ = FEOL^ ) and ( StrLComp( FBuffer, FEOL, FEOLLen ) = 0 ) then begin&lt;br /&gt;        Inc( FCurLine );&lt;br /&gt;        FCurCol := 0;&lt;br /&gt;        LineJump := FEOLLen-1;&lt;br /&gt;      end&lt;br /&gt;      else if LineJump = 0 then&lt;br /&gt;        Inc( FCurCol )&lt;br /&gt;      else&lt;br /&gt;        Dec( LineJump );&lt;br /&gt;&lt;br /&gt;      Inc( FBuffer );&lt;br /&gt;      continue;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    if Result then begin&lt;br /&gt;      Result := False;&lt;br /&gt;      FMatchCol := FCurCol;&lt;br /&gt;      FMatchLine := FCurLine;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    if ( nsHandleEOL in FOptions ) and ( FBuffer^ = FEOL^ ) and ( StrLComp( FBuffer, FEOL, FEOLLen ) = 0 ) then begin&lt;br /&gt;      Inc( FCurLine );&lt;br /&gt;      FCurCol := 0;&lt;br /&gt;      LineJump := FEOLLen-1;&lt;br /&gt;    end&lt;br /&gt;    else if LineJump = 0 then&lt;br /&gt;      Inc( FCurCol )&lt;br /&gt;    else&lt;br /&gt;      Dec( LineJump );&lt;br /&gt;&lt;br /&gt;    Inc( FBuffer );&lt;br /&gt;&lt;br /&gt;    if FSearch^ = #0 then begin&lt;br /&gt;      Result := True;&lt;br /&gt;      Inc( FMatches );&lt;br /&gt;      Exit;&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;  Result := False;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.SearchBackward: Boolean;&lt;br /&gt;begin&lt;br /&gt;  Result := True;&lt;br /&gt;  LineJump := 0;&lt;br /&gt;  FMatchLine := 0;&lt;br /&gt;  FMatchCol := 0;&lt;br /&gt;  FMatchLen := 0;&lt;br /&gt;  FSearch := FSearchEnd-1;&lt;br /&gt;&lt;br /&gt;  if FBufferEnd - FStartAt &lt; FBufferBegin then&lt;br /&gt;    FStartAt := FBufferEnd - FBufferBegin;&lt;br /&gt;  while FStartAt &gt; FBufferEnd-1 - FBuffer do begin&lt;br /&gt;    if ( nsHandleEOL in FOptions ) and ( FBuffer-FBufferBegin &gt;= FEOLLen ) and StrLRComp( FBuffer, FEOL+FEOLLen-1, FEOL ) then begin&lt;br /&gt;      Dec( FBuffer, FEOLLen );&lt;br /&gt;      Inc( FCurLine );&lt;br /&gt;      FCurCol := 0;&lt;br /&gt;      Continue;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      Inc( FCurCol );&lt;br /&gt;    Dec( FBuffer );&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  while FBuffer &lt;&gt; FBufferBegin-1 do begin&lt;br /&gt;    if ( (nsCaseSensitive in FOptions ) and ( FBuffer^ = FSearch^ ) ) or ( not(nsCaseSensitive in FOptions ) and ( AnsiUpCase( FBuffer^ ) = AnsiUpCase( FSearch^ ) ) ) then begin&lt;br /&gt;      Inc( FMatchLen );&lt;br /&gt;      Dec( FSearch );&lt;br /&gt;      if Result then begin&lt;br /&gt;        Result := False;&lt;br /&gt;        FMatchCol := FCurCol;&lt;br /&gt;        FMatchLine := FCurLine;&lt;br /&gt;&lt;br /&gt;        if ( nsWholeWords in FOptions ) and ( FBuffer &lt; FBufferEnd-1 ) and not ( (FBuffer+1)^ in WhiteSpaces ) then begin&lt;br /&gt;          FSearch := FSearchEnd-1;&lt;br /&gt;          FMatchLen := 0;&lt;br /&gt;          FMatchLine := 0;&lt;br /&gt;          FMatchCol := 0;&lt;br /&gt;        end;&lt;br /&gt;      end;&lt;br /&gt;      if ( nsWholeWords in FOptions ) and ( FMatchLen = FSearchLen ) and ( FBuffer &gt; FBufferBegin ) and not ( (FBuffer-1)^ in WhiteSpaces ) then begin&lt;br /&gt;        FSearch := FSearchEnd-1;&lt;br /&gt;        FMatchLen := 0;&lt;br /&gt;        FMatchLine := 0;&lt;br /&gt;        FMatchCol := 0;&lt;br /&gt;      end;&lt;br /&gt;&lt;br /&gt;      if ( nsHandleEOL in FOptions ) and ( FBuffer-FBufferBegin &gt;= FEOLLen ) and StrLRComp( FBuffer, FEOL+FEOLLen-1, FEOL ) then begin&lt;br /&gt;        Inc( FCurLine );&lt;br /&gt;        FCurCol := 0;&lt;br /&gt;        LineJump := FEOLLen-1;&lt;br /&gt;      end&lt;br /&gt;      else if LineJump = 0 then&lt;br /&gt;        Inc( FCurCol )&lt;br /&gt;      else&lt;br /&gt;        Dec( LineJump );&lt;br /&gt;&lt;br /&gt;      Dec( FBuffer );&lt;br /&gt;      if FSearch = FSearchBegin-1 then begin&lt;br /&gt;        Result := True;&lt;br /&gt;        Inc( FMatches );&lt;br /&gt;        Exit;&lt;br /&gt;      end;&lt;br /&gt;    end&lt;br /&gt;    else begin&lt;br /&gt;      Result := True;&lt;br /&gt;      FMatchLen := 0;&lt;br /&gt;      FMatchLine := 0;&lt;br /&gt;      FMatchCol := 0;&lt;br /&gt;&lt;br /&gt;      if FSearch &lt;&gt; FSearchEnd-1 then begin&lt;br /&gt;        FSearch := FSearchEnd-1;&lt;br /&gt;        Continue;&lt;br /&gt;      end;&lt;br /&gt;&lt;br /&gt;      if ( nsHandleEOL in FOptions ) and ( FBuffer-FBufferBegin &gt;= FEOLLen ) and StrLRComp( FBuffer, FEOL+FEOLLen-1, FEOL ) then begin&lt;br /&gt;        Inc( FCurLine );&lt;br /&gt;        FCurCol := 0;&lt;br /&gt;        LineJump := FEOLLen-1;&lt;br /&gt;      end&lt;br /&gt;      else if LineJump = 0 then&lt;br /&gt;        Inc( FCurCol )&lt;br /&gt;      else&lt;br /&gt;        Dec( LineJump );&lt;br /&gt;&lt;br /&gt;      Dec( FBuffer );&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;  Result := False;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TNotesSeeker.SearchBackwardWithWildCard: Boolean;&lt;br /&gt;begin&lt;br /&gt;  Result := True;&lt;br /&gt;  Jump := 1;&lt;br /&gt;  LineJump := 0;&lt;br /&gt;  FMatchLine := 0;&lt;br /&gt;  FMatchCol := 0;&lt;br /&gt;  FMatchLen := 0;&lt;br /&gt;  FSearch := FSearchEnd-1;&lt;br /&gt;&lt;br /&gt;  if FBufferEnd - FStartAt &lt; FBufferBegin then&lt;br /&gt;    FStartAt := FBufferEnd - FBufferBegin;&lt;br /&gt;  while FStartAt &gt; FBufferEnd-1 - FBuffer do begin&lt;br /&gt;    if ( nsHandleEOL in FOptions ) and ( FBuffer^ = FEOL^ ) and ( StrLComp( FBuffer, FEOL, FEOLLen ) = 0 ) then begin&lt;br /&gt;      Dec( FBuffer, FEOLLen );&lt;br /&gt;      Inc( FCurLine );&lt;br /&gt;      FCurCol := 0;&lt;br /&gt;      Continue;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      Inc( FCurCol );&lt;br /&gt;    Dec( FBuffer );&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;  while FBuffer &lt;&gt; FBufferBegin-1 do begin&lt;br /&gt;    if FSearch^ = '?' then begin&lt;br /&gt;      Inc( FMatchLen );&lt;br /&gt;      Dec( FSearch );&lt;br /&gt;    end&lt;br /&gt;    else if FSearch^ = '*' then begin&lt;br /&gt;      if (FSearch-Jump)^ = '?' then begin&lt;br /&gt;        Inc( FMatchLen );&lt;br /&gt;        Inc( Jump );&lt;br /&gt;      end&lt;br /&gt;      else if (FSearch-Jump)^ = '*' then begin&lt;br /&gt;        Dec( FSearch, Jump );&lt;br /&gt;        Jump := 1;&lt;br /&gt;        continue;&lt;br /&gt;      end&lt;br /&gt;      else if ( ( nsCaseSensitive in FOptions ) and ( FBuffer^ = (FSearch-Jump)^ ) ) or ( not( nsCaseSensitive in FOptions ) and ( AnsiUpCase( FBuffer^ ) = AnsiUpCase( (FSearch-Jump)^ ) )  ) then begin&lt;br /&gt;        Inc( FMatchLen );&lt;br /&gt;        Inc( Jump );&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;        Inc( FMatchLen );&lt;br /&gt;      if (FSearch-Jump) = FSearchBegin-1 then begin&lt;br /&gt;        if (FSearch-Jump+1)^ = '*' then begin&lt;br /&gt;          Inc( FMatchLen, FBuffer-FBufferBegin );&lt;br /&gt;          FBuffer := FBufferBegin;&lt;br /&gt;        end;&lt;br /&gt;        FSearch := FSearchBegin-1;&lt;br /&gt;      end;&lt;br /&gt;    end&lt;br /&gt;    else if ( ( nsCaseSensitive in FOptions ) and ( FBuffer^ = FSearch^ ) ) or ( not ( nsCaseSensitive in FOptions ) and ( AnsiUpCase( FBuffer^ ) = AnsiUpCase( FSearch^ ) ) ) then begin&lt;br /&gt;      Inc( FMatchLen );&lt;br /&gt;      Dec( FSearch );&lt;br /&gt;    end&lt;br /&gt;    else begin&lt;br /&gt;      Result := True;&lt;br /&gt;      FMatchLen := 0;&lt;br /&gt;      FMatchLine := 0;&lt;br /&gt;      FMatchCol := 0;&lt;br /&gt;      Jump := 1;&lt;br /&gt;&lt;br /&gt;      if FSearch &lt;&gt; FSearchEnd-1 then begin&lt;br /&gt;        FSearch := FSearchEnd-1;&lt;br /&gt;        Continue;&lt;br /&gt;      end;&lt;br /&gt;&lt;br /&gt;      if ( nsHandleEOL in FOptions ) and ( FBuffer-FBufferBegin &gt;= FEOLLen ) and StrLRComp( FBuffer, FEOL+FEOLLen-1, FEOL ) then begin&lt;br /&gt;        Inc( FCurLine );&lt;br /&gt;        FCurCol := 0;&lt;br /&gt;        LineJump := FEOLLen-1;&lt;br /&gt;      end&lt;br /&gt;      else if LineJump = 0 then&lt;br /&gt;        Inc( FCurCol )&lt;br /&gt;      else&lt;br /&gt;        Dec( LineJump );&lt;br /&gt;&lt;br /&gt;      Dec( FBuffer );&lt;br /&gt;      Continue;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    if Result then begin&lt;br /&gt;      Result := False;&lt;br /&gt;      FMatchCol := FCurCol;&lt;br /&gt;      FMatchLine := FCurLine;&lt;br /&gt;    end;&lt;br /&gt;&lt;br /&gt;    if ( nsHandleEOL in FOptions ) and ( FBuffer-FBufferBegin &gt;= FEOLLen ) and StrLRComp( FBuffer, FEOL+FEOLLen-1, FEOL ) then begin&lt;br /&gt;      Inc( FCurLine );&lt;br /&gt;      FCurCol := 0;&lt;br /&gt;      LineJump := FEOLLen-1;&lt;br /&gt;    end&lt;br /&gt;    else if LineJump = 0 then&lt;br /&gt;      Inc( FCurCol )&lt;br /&gt;    else&lt;br /&gt;      Dec( LineJump );&lt;br /&gt;&lt;br /&gt;    Dec( FBuffer );&lt;br /&gt;    if FSearch = FSearchBegin-1 then begin&lt;br /&gt;      Result := True;&lt;br /&gt;      Inc( FMatches );&lt;br /&gt;      Exit;&lt;br /&gt;    end;&lt;br /&gt;  end;&lt;br /&gt;  Result := False;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 15 Jun 2006 18:55:44 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2196</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>Path parser //Pascal class</title>
      <link>http://snippets.dzone.com/posts/show/2195</link>
      <description>An unit to get the special folders' path under windows and it also parses paths shortcuts in the form "$(shortcut)/folder/file.ext".&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;unit PathParser;&lt;br /&gt;&lt;br /&gt;interface&lt;br /&gt;&lt;br /&gt;uses&lt;br /&gt;  Classes, SysUtils, TypInfo, SysUtils2, ShlObj, ShellApi, Registry, Windows;&lt;br /&gt;&lt;br /&gt;type&lt;br /&gt;  TSpecialFolder = ( sfDesktop, sfAppData, sfTemplates, sfPrograms,&lt;br /&gt;    sfPersonal, sfFavorites, sfStartup, sfRecent, sfSendTo, sfStartMenu,&lt;br /&gt;    sfFonts, sfHistory, sfCookies, sfInternetCache, sfCommonFavorites,&lt;br /&gt;    sfCommonDesktop, sfCommonStartup, sfCommonPrograms, sfCommonStartMenu,&lt;br /&gt;    sfProgramFiles, sfTemporary, sfWindows, sfSystem );&lt;br /&gt;&lt;br /&gt;  TSpecialFolderSet = set of TSpecialFolder;&lt;br /&gt;&lt;br /&gt;  TPathParser = class( TStringList )&lt;br /&gt;  public&lt;br /&gt;    constructor Create( const UseDefaultMap: Boolean = True );&lt;br /&gt;    class function GetSpecialFolder( const Name: TSpecialFolder ): string;&lt;br /&gt;    function Parse( Path: string ): string;&lt;br /&gt;  end;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;implementation&lt;br /&gt;&lt;br /&gt;{ TPathParser }&lt;br /&gt;&lt;br /&gt;uses Dialogs;&lt;br /&gt;&lt;br /&gt;constructor TPathParser.Create(const UseDefaultMap: Boolean);&lt;br /&gt;var&lt;br /&gt;  I: TSpecialFolder;&lt;br /&gt;begin&lt;br /&gt;  CaseSensitive := False;&lt;br /&gt;  if UseDefaultMap then begin&lt;br /&gt;    for I := Low( TSpecialFolder ) to High( TSpecialFolder ) do&lt;br /&gt;      Add( RemoveSlash( LowerCase( Copy( GetEnumName( TypeInfo( TSpecialFolder ),&lt;br /&gt;        Ord( I ) ), 3, MAX_PATH ) ) + '=' + GetSpecialFolder( I ) ) );&lt;br /&gt;    Add( RemoveSlash( Format( 'windowsvolume=%s', [ GetSpecialFolder( sfWindows )[1] ] ) ) );&lt;br /&gt;  end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;class function TPathParser.GetSpecialFolder(&lt;br /&gt;  const Name: TSpecialFolder): string;&lt;br /&gt;const&lt;br /&gt;  FoldersMap: array[TSpecialFolder] of Cardinal = ( CSIDL_DESKTOP,&lt;br /&gt;    CSIDL_APPDATA, CSIDL_TEMPLATES, CSIDL_PROGRAMS, CSIDL_PERSONAL,&lt;br /&gt;    CSIDL_FAVORITES, CSIDL_STARTUP, CSIDL_RECENT, CSIDL_SENDTO, CSIDL_STARTMENU,&lt;br /&gt;    CSIDL_FONTS, CSIDL_HISTORY, CSIDL_COOKIES, CSIDL_INTERNET_CACHE,&lt;br /&gt;    CSIDL_COMMON_FAVORITES, CSIDL_COMMON_DESKTOPDIRECTORY, CSIDL_COMMON_STARTUP,&lt;br /&gt;    CSIDL_COMMON_PROGRAMS, CSIDL_COMMON_STARTMENU, 0, 0, 0, 0 );&lt;br /&gt;var&lt;br /&gt;  Res: Bool;&lt;br /&gt;  Path: array[0..MAX_PATH-1] of Char;&lt;br /&gt;  Reg: TRegistry;&lt;br /&gt;begin&lt;br /&gt;  Result := '';&lt;br /&gt;  case Name of&lt;br /&gt;    sfWindows: GetWindowsDirectory( Path, MAX_PATH );&lt;br /&gt;    sfTemporary: GetTempPath( MAX_PATH, Path );&lt;br /&gt;    sfSystem: GetSystemDirectory( Path, MAX_PATH );&lt;br /&gt;    sfProgramFiles:&lt;br /&gt;    begin&lt;br /&gt;      Reg := TRegistry.Create( KEY_READ );&lt;br /&gt;      try&lt;br /&gt;        Reg.RootKey := HKEY_LOCAL_MACHINE;&lt;br /&gt;        Reg.OpenKey( 'SOFTWARE\Microsoft\Windows\CurrentVersion', False );&lt;br /&gt;        Result := AddSlash( Reg.ReadString( 'ProgramFilesDir' ) );&lt;br /&gt;      finally&lt;br /&gt;        Reg.Free;&lt;br /&gt;      end;&lt;br /&gt;      Exit;&lt;br /&gt;    end;&lt;br /&gt;  else&lt;br /&gt;    Res := ShGetSpecialFolderPath( 0, Path, FoldersMap[ Name ], False );&lt;br /&gt;    if not Res then&lt;br /&gt;      raise Exception.Create( ClassName + '.GetSpecialFolder: Error on ShGetSpecialFolderPath' );&lt;br /&gt;  end;&lt;br /&gt;  Result := AddSlash( Path );&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function TPathParser.Parse(Path: string): string;&lt;br /&gt;var&lt;br /&gt;  S: string;&lt;br /&gt;  I, I2, Pos: Integer;&lt;br /&gt;begin&lt;br /&gt;  I := 1;&lt;br /&gt;  while I &lt;= Length( Path )-3 do&lt;br /&gt;  begin&lt;br /&gt;    if ( Path[I] = '$' ) and ( Path[I+1] = '(' ) then&lt;br /&gt;    begin&lt;br /&gt;      I2 := I + 2;&lt;br /&gt;      while ( I2 &lt;= Length( Path ) ) and ( Path[I2] &lt;&gt; ')' ) do&lt;br /&gt;        Inc( I2 );&lt;br /&gt;      if I2 &gt; Length( Path ) then&lt;br /&gt;        Break;&lt;br /&gt;      S := Copy( Path, I + 2, I2 - ( I + 2 ) );&lt;br /&gt;      System.Delete( Path, I, I2 - I + 1 );&lt;br /&gt;      Pos := IndexOfName( S );&lt;br /&gt;      if Pos &gt; -1 then&lt;br /&gt;      begin&lt;br /&gt;        System.Insert( ValueFromIndex[Pos], Path, I );&lt;br /&gt;        Inc( I, Length( ValueFromIndex[Pos] ) );&lt;br /&gt;      end&lt;br /&gt;      else&lt;br /&gt;        raise Exception.CreateFmt( '%s.Parse: Vari&#225;vel "%s" inexistente', [ ClassName, S ] ); //I := I2 + 1;&lt;br /&gt;    end&lt;br /&gt;    else&lt;br /&gt;      Inc( I );&lt;br /&gt;  end;&lt;br /&gt;  Result := Path;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;end.&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 15 Jun 2006 18:40:23 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2195</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>Simple bit operations //Pascal functions</title>
      <link>http://snippets.dzone.com/posts/show/2194</link>
      <description>Get, Clear, Set and Enable bit operations for pascal.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;function GetBit(const Value: DWord; const Bit: Byte): Boolean;&lt;br /&gt;begin&lt;br /&gt;  Result := (Value and (1 shl Bit)) &lt;&gt; 0;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function ClearBit(const Value: DWord; const Bit: Byte): DWord;&lt;br /&gt;begin&lt;br /&gt;	Result := Value and not (1 shl Bit);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function SetBit(const Value: DWord; const Bit: Byte): DWord;&lt;br /&gt;begin&lt;br /&gt;	Result := Value or (1 shl Bit);&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;function EnableBit(const Value: DWord; const Bit: Byte; const TurnOn: Boolean): DWord;&lt;br /&gt;begin&lt;br /&gt;	Result := (Value or (1 shl Bit)) xor (Integer(not TurnOn) shl Bit);&lt;br /&gt;end;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Thu, 15 Jun 2006 18:35:07 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2194</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>pascal triangle plotter XD</title>
      <link>http://snippets.dzone.com/posts/show/440</link>
      <description>&lt;code&gt;&lt;br /&gt;//+ Jonas Raoni Soares Silva&lt;br /&gt;//@ http://jsfromhell.com&lt;br /&gt;&lt;br /&gt;#include &lt;stdio.h&gt;&lt;br /&gt;#include &lt;conio.h&gt;&lt;br /&gt;&lt;br /&gt;#define MAX 16&lt;br /&gt;&lt;br /&gt;int main () {&lt;br /&gt;	int unsigned vetor[MAX], grau, i = 0, j, top, left;&lt;br /&gt;&lt;br /&gt;	clrscr();&lt;br /&gt;&lt;br /&gt;	printf( "Dado o grau, printar o triangulo de pascal\n" );&lt;br /&gt;&lt;br /&gt;	while( grau &gt; MAX &amp;&amp; printf( "Digite um numero entre 0 e %d para o grau: ", MAX ) &amp;&amp; scanf( "%u", &amp;grau ) );&lt;br /&gt;	while( i++ &lt; grau &amp;&amp; !( j = 0 ) &amp;&amp; printf( "\n" ) )&lt;br /&gt;		while( j &lt; i &amp;&amp; ( j == 0 &amp;&amp; ( top = left = vetor[j] = 1 ) ? 1 : j &gt; 0 &amp;&amp; j &lt; i-1 &amp;&amp; ( top = vetor[j] ) &amp;&amp; ( vetor[j] = left + top ) &amp;&amp; ( left = top ) ? 1 : ( vetor[j] = 1 ) ) &amp;&amp; printf( "%-5d", vetor[j] ) &amp;&amp; ++j );&lt;br /&gt;	getch();&lt;br /&gt;	return 0;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sat, 02 Jul 2005 03:59:46 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/440</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
  </channel>
</rss>
