You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
7.2 KiB
Plaintext
261 lines
7.2 KiB
Plaintext
unit VirtualTrees.Classes;
|
|
|
|
// The contents of this file are subject to the Mozilla Public License
|
|
// Version 1.1 (the "License"); you may not use this file except in compliance
|
|
// with the License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
|
|
//
|
|
// Alternatively, you may redistribute this library, use and/or modify it under the terms of the
|
|
// GNU Lesser General Public License as published by the Free Software Foundation;
|
|
// either version 2.1 of the License, or (at your option) any later version.
|
|
// You may obtain a copy of the LGPL at http://www.gnu.org/copyleft/.
|
|
//
|
|
// Software distributed under the License is distributed on an "AS IS" basis,
|
|
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the
|
|
// specific language governing rights and limitations under the License.
|
|
//
|
|
// The original code is VirtualTrees.pas, released September 30, 2000.
|
|
//
|
|
// The initial developer of the original code is digital publishing AG (Munich, Germany, www.digitalpublishing.de),
|
|
// written by Mike Lischke (public@soft-gems.net, www.soft-gems.net).
|
|
//
|
|
// Portions created by digital publishing AG are Copyright
|
|
// (C) 1999-2001 digital publishing AG. All Rights Reserved.
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
interface
|
|
|
|
{$WARN UNSAFE_TYPE OFF}
|
|
{$WARN UNSAFE_CAST OFF}
|
|
{$WARN UNSAFE_CODE OFF}
|
|
|
|
uses
|
|
Winapi.Windows;
|
|
|
|
type
|
|
// Helper classes to speed up rendering text formats for clipboard and drag'n drop transfers.
|
|
TBufferedRawByteString = class
|
|
private
|
|
FStart,
|
|
FPosition,
|
|
FEnd: PAnsiChar;
|
|
function GetAsString: RawByteString;
|
|
public
|
|
destructor Destroy; override;
|
|
|
|
procedure Add(const S: RawByteString);
|
|
procedure AddNewLine;
|
|
|
|
property AsString: RawByteString read GetAsString;
|
|
end;
|
|
|
|
TBufferedString = class
|
|
private
|
|
FStart,
|
|
FPosition,
|
|
FEnd: PWideChar;
|
|
function GetAsString: string;
|
|
public
|
|
destructor Destroy; override;
|
|
|
|
procedure Add(const S: string);
|
|
procedure AddNewLine;
|
|
|
|
property AsString: string read GetAsString;
|
|
end;
|
|
|
|
TCriticalSection = class(TObject)
|
|
protected
|
|
FSection: TRTLCriticalSection;
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
|
|
procedure Enter;
|
|
procedure Leave;
|
|
end;
|
|
|
|
|
|
|
|
implementation
|
|
|
|
//----------------- TBufferedRawByteString ------------------------------------------------------------------------------------
|
|
|
|
const
|
|
AllocIncrement = 2 shl 11; // Must be a power of 2.
|
|
|
|
destructor TBufferedRawByteString.Destroy;
|
|
|
|
begin
|
|
FreeMem(FStart);
|
|
inherited;
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TBufferedRawByteString.GetAsString: RawByteString;
|
|
|
|
begin
|
|
SetString(Result, FStart, FPosition - FStart);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TBufferedRawByteString.Add(const S: RawByteString);
|
|
|
|
var
|
|
NewLen,
|
|
LastOffset,
|
|
Len: NativeInt;
|
|
|
|
begin
|
|
Len := Length(S);
|
|
// Make room for the new string.
|
|
if FEnd - FPosition <= Len then
|
|
begin
|
|
// Round up NewLen so it is always a multiple of AllocIncrement.
|
|
NewLen := FEnd - FStart + (Len + AllocIncrement - 1) and not (AllocIncrement - 1);
|
|
// Keep last offset to restore it correctly in the case that FStart gets a new memory block assigned.
|
|
LastOffset := FPosition - FStart;
|
|
ReallocMem(FStart, NewLen);
|
|
FPosition := FStart + LastOffset;
|
|
FEnd := FStart + NewLen;
|
|
end;
|
|
Move(PAnsiChar(S)^, FPosition^, Len);
|
|
Inc(FPosition, Len);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TBufferedRawByteString.AddNewLine;
|
|
|
|
var
|
|
NewLen,
|
|
LastOffset: NativeInt;
|
|
|
|
begin
|
|
// Make room for the CR/LF characters.
|
|
if FEnd - FPosition <= 2 then
|
|
begin
|
|
// Round up NewLen so it is always a multiple of AllocIncrement.
|
|
NewLen := FEnd - FStart + (2 + AllocIncrement - 1) and not (AllocIncrement - 1);
|
|
// Keep last offset to restore it correctly in the case that FStart gets a new memory block assigned.
|
|
LastOffset := FPosition - FStart;
|
|
ReallocMem(FStart, NewLen);
|
|
FPosition := FStart + LastOffset;
|
|
FEnd := FStart + NewLen;
|
|
end;
|
|
FPosition^ := #13;
|
|
Inc(FPosition);
|
|
FPosition^ := #10;
|
|
Inc(FPosition);
|
|
end;
|
|
|
|
//----------------- TBufferedString --------------------------------------------------------------------------------
|
|
|
|
destructor TBufferedString.Destroy;
|
|
|
|
begin
|
|
FreeMem(FStart);
|
|
inherited;
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
function TBufferedString.GetAsString: string;
|
|
|
|
begin
|
|
SetString(Result, FStart, FPosition - FStart);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TBufferedString.Add(const S: string);
|
|
|
|
var
|
|
NewLen,
|
|
LastOffset,
|
|
Len: Integer;
|
|
|
|
begin
|
|
Len := Length(S);
|
|
if Len = 0 then
|
|
exit;//Nothing to do
|
|
// Make room for the new string.
|
|
if FEnd - FPosition <= Len then
|
|
begin
|
|
// Round up NewLen so it is always a multiple of AllocIncrement.
|
|
NewLen := FEnd - FStart + (Len + AllocIncrement - 1) and not (AllocIncrement - 1);
|
|
// Keep last offset to restore it correctly in the case that FStart gets a new memory block assigned.
|
|
LastOffset := FPosition - FStart;
|
|
ReallocMem(FStart, 2 * NewLen);
|
|
FPosition := FStart + LastOffset;
|
|
FEnd := FStart + NewLen;
|
|
end;
|
|
Move(PWideChar(S)^, FPosition^, 2 * Len);
|
|
Inc(FPosition, Len);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TBufferedString.AddNewLine;
|
|
|
|
var
|
|
NewLen,
|
|
LastOffset: Integer;
|
|
|
|
begin
|
|
// Make room for the CR/LF characters.
|
|
if FEnd - FPosition <= 4 then
|
|
begin
|
|
// Round up NewLen so it is always a multiple of AllocIncrement.
|
|
NewLen := FEnd - FStart + (2 + AllocIncrement - 1) and not (AllocIncrement - 1);
|
|
// Keep last offset to restore it correctly in the case that FStart gets a new memory block assigned.
|
|
LastOffset := FPosition - FStart;
|
|
ReallocMem(FStart, 2 * NewLen);
|
|
FPosition := FStart + LastOffset;
|
|
FEnd := FStart + NewLen;
|
|
end;
|
|
FPosition^ := #13;
|
|
Inc(FPosition);
|
|
FPosition^ := #10;
|
|
Inc(FPosition);
|
|
end;
|
|
|
|
//----------------- TCriticalSection -----------------------------------------------------------------------------------
|
|
|
|
constructor TCriticalSection.Create;
|
|
|
|
begin
|
|
inherited Create;
|
|
InitializeCriticalSection(FSection);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
destructor TCriticalSection.Destroy;
|
|
|
|
begin
|
|
DeleteCriticalSection(FSection);
|
|
|
|
inherited Destroy;
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TCriticalSection.Enter;
|
|
|
|
begin
|
|
EnterCriticalSection(FSection);
|
|
end;
|
|
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
procedure TCriticalSection.Leave;
|
|
|
|
begin
|
|
LeaveCriticalSection(FSection);
|
|
end;
|
|
|
|
|
|
end.
|