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

📄 stdfuncs.pas

📁 FIBPlus is a component suite intended for work with InterBase. It is direct, fast and flexible Inter
💻 PAS
📖 第 1 页 / 共 3 页
字号:
{***************************************************************}
{ FIBPlus - component library for direct access to Firebird and }
{ InterBase databases                                           }
{                                                               }
{    FIBPlus is based in part on the product                    }
{    Free IB Components, written by Gregory H. Deatz for        }
{    Hoagland, Longo, Moran, Dunst & Doukas Company.            }
{    mailto:gdeatz@hlmdd.com                                    }
{                                                               }
{    Copyright (c) 1998-2007 Devrace Ltd.                       }
{    Written by Serge Buzadzhy (buzz@devrace.com)               }
{                                                               }
{ ------------------------------------------------------------- }
{    FIBPlus home page: http://www.fibplus.com/                 }
{    FIBPlus support  : http://www.devrace.com/support/         }
{ ------------------------------------------------------------- }
{                                                               }
{  Please see the file License.txt for full license information }
{***************************************************************}

(*
 * StdFuncs -
 *   A file chock full of functions that should exist in Delphi, but
 *   dont, like "Max", "GetTempFile", "Soundex", etc...
 *)
unit StdFuncs;

{$i FIBPlus.inc}

interface

uses

 Classes, SysUtils,DB,
 {$IFDEF WINDOWS}
   Windows,Messages
  {$IFDEF D6+},FMTBcd, Variants{$ELSE},ExtCtrls  {$ENDIF};
 {$ENDIF}
 {$IFDEF LINUX}
   Types,FMTBcd, Variants;
 {$ENDIF}

type
  EParserError = class(Exception);
  TCharSet = set of Char;
  TDynArray = array of variant;
  PDynArray=^TDynArray;
  
{$IFDEF WINDOWS}
 {$IFNDEF D6+}
  TFIBTimer = TTimer;
 {$ELSE}
  TFIBTimer = class(TComponent)
  private
    FInterval: Cardinal;
    FWindowHandle: HWND;
    FOnTimer: TNotifyEvent;
    FEnabled: Boolean;
    procedure UpdateTimer;
    procedure SetEnabled(Value: Boolean);
    procedure SetInterval(Value: Cardinal);
    procedure SetOnTimer(Value: TNotifyEvent);
    procedure WndProc(var Msg: TMessage);
  protected
    procedure Timer; dynamic;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Enabled: Boolean read FEnabled write SetEnabled default True;
    property Interval: Cardinal read FInterval write SetInterval default 1000;
    property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
  end;
 {$ENDIF}
{$ENDIF}
{$IFDEF LINUX}
  TFIBTimer = class(TComponent)
  private
    FEnabled: Boolean;
    FInterval: Cardinal;
    FKeepAlive: Boolean;
    FOnTimer: TNotifyEvent;
    FStreamedEnabled: Boolean;
    FTr: TThread;
    procedure SetEnabled(const Value: Boolean);
    procedure SetInterval(const Value: Cardinal);
    procedure SetOnTimer(const Value: TNotifyEvent);
    procedure SetKeepAlive(const Value: Boolean);
  protected
    procedure DoOnTimer;
    procedure Loaded; override;
    procedure StopTimer;
    procedure UpdateTimer;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
    property Enabled: Boolean read FEnabled write SetEnabled default False;
    property Interval: Cardinal read FInterval write SetInterval default 1000;
    property KeepAlive: Boolean read FKeepAlive write SetKeepAlive default False;
    property OnTimer: TNotifyEvent read FOnTimer write SetOnTimer;
  end;


  TTimeThread = class(TThread)
  private
    FSusp: Boolean;
    FInt: Cardinal;
    FTimer: TFIBTimer;
  protected
    procedure DoSuspend;
    procedure Execute; override;
  public
    constructor Create(ATimer: TFIBTimer);
    destructor Destroy; override;
    procedure Stop;
    property Interval: Cardinal read FInt;
  end;
{$ENDIF}



function ConvertFromBase(sNum: String; iBase: Integer; cDigits: String): Integer;
function ConvertToBase(iNum, iBase: Integer; cDigits: String): String;




function Max(n1, n2: Integer): Integer;
function MaxD(n1, n2: Double): Double;
function Min(n1, n2: Integer): Integer;{$IFDEF D9+} inline;{$ENDIF}
function MinD(n1, n2: Double): Double;
function Signum(Arg:Integer) :Integer; {$IFDEF D9+} inline;{$ENDIF}

function RandomString(iLength: Integer): String;
//function RandomInteger(iLow, iHigh: Integer): Integer;
function Soundex(st: String): String;
function StripString(const st: String; const CharsToStrip: String): String;
function ClosestWeekday(const d: TDateTime): TDateTime;
function Year(d: TDateTime): Integer;
function Month(d: TDateTime): Integer;
function DayOfYear(d: TDateTime): Integer;
function DayOfMonth(d: TDateTime): Integer;

procedure WeekOfYear(d: TDateTime; var Year, Week: Integer);
function  Degree10(Degree:integer):Extended;{$IFDEF D9+} inline;{$ENDIF}
function  ExtPrecision(Value:Extended) :integer;{$IFDEF D9+} inline;{$ENDIF}
function  RoundExtend(Value: Extended;Decimals:integer): Extended;

// Comp type stuff


function  CompWithScaleToStr(Value: Int64;Scale:integer;DSep:Char): string; overload;


//end Comp type stuff

function  Int64ToBCD(Value: Int64;Scale:integer; var BCD: TBcd ): Boolean; {$IFDEF D9+} inline;{$ENDIF}
function  ExtendedToBCD(const Value:Extended;NeedScale:integer):TBCD;

function  BCDToExtended(BCD: TBcd; var Value: Extended): Boolean;
function  BCDToCompWithScale(BCD: TBcd; var Value: Int64;var Scale:byte): Boolean;
{$IFNDEF D6+}
function  BCDToStr(BCD: TBcd): String;
{$ENDIF}
function  BCDToSQLStr(BCD: TBcd): String;
function  CompareBCD(const BCD1,BCD2: TBcd): integer;{$IFDEF D9+} inline;{$ENDIF}
{$IFDEF D6+}
function  fFormatBcd(const Format: string; Bcd: TBcd): string;
function  FormatNumericString(const Format,Source: string; OneSectionFormat:boolean=False ): string;
{$ENDIF}




function  TimeStamp(const aDate,aTime:integer):TTimeStamp;
function  CmpFullName(cmp:TComponent):string;
function  CmpInLoadedState(Cmp:TComponent):boolean;  {$IFDEF D9+} inline;{$ENDIF}
procedure FullClearStrings(aStrings:TStrings);

function HookTimeStampToMSecs(const TimeStamp:TTimeStamp): Int64;
function HookTimeStampToDateTime(const TimeStamp: TTimeStamp): TDateTime;
function IBStrToTime(const Str:string):TDateTime;

function IntDateToDateTime(aDate:integer):TDateTime;
//DB rtns


function FieldOldValAsString(Field:TField;SQLFormat:boolean):string;

function BCDFieldAsSQLString(Field:TField;OldVal:boolean):variant;
function BCDFieldAsString(Field:TField;OldVal:boolean):variant;
function GetBCDFieldData(Field:TField;OldVal:boolean; var BCD:TBcd):boolean;

function GetBit(InByte:Byte; Index:byte):Boolean;{$IFDEF D9+} inline;{$ENDIF}
function SetBit(InByte:Byte; Index:byte; value :Boolean):Byte;

function HexStr2Int(const S: String): Integer;
function HexStr2IntStr(const S: String): string;

{$IFNDEF D6+}
type
  PBoolean      = ^Boolean;
function CreateGUID(out Guid: TGUID): HResult;
//function IsEqualGUID(const guid1, guid2: TGUID): Boolean;  stdcall;  {$EXTERNALSYM IsEqualGUID}


function DirectoryExists(const Name: string): Boolean;
function ForceDirectories(Dir: string): Boolean;

{$ENDIF}
procedure InitFPU;


procedure StreamToVariant(Stream:TMemoryStream; var Value : Variant);
procedure StreamToVariantArray(Stream:TMemoryStream; var Value : Variant);
function  VariantToStream(Value : Variant;Stream:TStream): integer; {Length of Blob}

function  StringIsDateTimeDefValue(const s:string):boolean; {$IFDEF D9+} inline;{$ENDIF}

{$IFNDEF D6+}
// Cut from system.pas Delphi 6
 function Utf8Encode(const WS: WideString): String;
 function Utf8Decode(const S: String): WideString;
{$ENDIF}

{$IFDEF WINDOWS}
function ConvertFromCodePage( const Source : string; FromCodePage:LongWord) : WideString;
function ConvertToCodePage(const Source : WideString; ToCodePage : LongWord) : string;
{$ENDIF}
var
  TempPath: PChar;
  TempPathLength: Integer;

const
    E10:array [-18..18] of Double =
     ( 1E-18,1E-17, 1E-16, 1E-15, 1E-14, 1E-13, 1E-12, 1E-11,
       1E-10, 1E-9, 1E-8, 1E-7, 1E-6, 1E-5, 1E-4, 1E-3,1E-2, 1E-1,
       1,
       1E1, 1E2, 1E3, 1E4, 1E5, 1E6, 1E7, 1E8,1E9, 1E10,
       1E11, 1E12, 1E13, 1E14, 1E15, 1E16, 1E17, 1E18
      );


    IE10:array [0..18] of int64 =
     (
       1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000,1000000000,
       10000000000,100000000000,1000000000000,10000000000000,100000000000000,
       1000000000000000,10000000000000000,100000000000000000,1000000000000000000
      );
      
const
   AppPathTemplate='{APP_PATH}';


implementation

uses FIBConsts,StrUtil;


{$IFDEF WINDOWS}

function ConvertToCodePage(const Source : WideString;
                           ToCodePage : LongWord) : string;
var
      L :integer;
begin
   L := Length(Source);
   SetLength(Result,L);
   if
    WideCharToMultiByte(ToCodePage, 0,  PWideChar(Source), L, PChar(Result), L, nil, nil)=0
   then
    Result:=Source
end;

function ConvertFromCodePage(const Source : string; FromCodePage:LongWord) : WideString;
var
      L :integer;
begin
  L := Length(Source);
  SetLength(Result,L);
  if
   MultiByteToWideChar(FromCodePage, 0,  PChar(Source), L, PWideChar(Result), L)=0
  then
    Result :=Source
end;
{$ENDIF}


{$IFNDEF D6+}
// Cut from system.pas Delphi 6
function UnicodeToUtf8(Dest: PChar; MaxDestBytes: Cardinal; Source: PWideChar; SourceChars: Cardinal): Cardinal;
var
  i, count: Cardinal;
  c: Cardinal;
begin
  Result := 0;
  if Source = nil then Exit;
  count := 0;
  i := 0;
  if Dest <> nil then
  begin
    while (i < SourceChars) and (count < MaxDestBytes) do
    begin
      c := Cardinal(Source[i]);
      Inc(i);
      if c <= $7F then
      begin
        Dest[count] := Char(c);
        Inc(count);
      end
      else if c > $7FF then
      begin
        if count + 3 > MaxDestBytes then
          break;
        Dest[count] := Char($E0 or (c shr 12));
        Dest[count+1] := Char($80 or ((c shr 6) and $3F));
        Dest[count+2] := Char($80 or (c and $3F));
        Inc(count,3);
      end
      else //  $7F < Source[i] <= $7FF
      begin
        if count + 2 > MaxDestBytes then
          break;
        Dest[count] := Char($C0 or (c shr 6));
        Dest[count+1] := Char($80 or (c and $3F));
        Inc(count,2);
      end;
    end;
    if count >= MaxDestBytes then count := MaxDestBytes-1;
    Dest[count] := #0;
  end
  else
  begin
    while i < SourceChars do
    begin
      c := Integer(Source[i]);
      Inc(i);
      if c > $7F then
      begin
        if c > $7FF then
          Inc(count);
        Inc(count);
      end;
      Inc(count);
    end;
  end;
  Result := count+1;  // convert zero based index to byte count
end;

function Utf8Encode(const WS: WideString): String;
var
  L: Integer;
  Temp: String;
begin
  Result := '';
  if WS = '' then Exit;
  SetLength(Temp, Length(WS) * 3); // SetLength includes space for null terminator

  L := UnicodeToUtf8(PChar(Temp), Length(Temp)+1, PWideChar(WS), Length(WS));
  if L > 0 then
    SetLength(Temp, L-1)
  else
    Temp := '';
  Result := Temp;
end;

function Utf8ToUnicode(Dest: PWideChar; MaxDestChars: Cardinal; Source: PChar; SourceBytes: Cardinal): Cardinal;
var
  i, count: Cardinal;
  c: Byte;
  wc: Cardinal;
begin
  if Source = nil then
  begin
    Result := 0;
    Exit;
  end;
  Result := Cardinal(-1);
  count := 0;
  i := 0;
  if Dest <> nil then
  begin
    while (i < SourceBytes) and (count < MaxDestChars) do
    begin
      wc := Cardinal(Source[i]);
      Inc(i);
      if (wc and $80) <> 0 then
      begin
        wc := wc and $3F;
        if i > SourceBytes then Exit;           // incomplete multibyte char
        if (wc and $20) <> 0 then
        begin
          c := Byte(Source[i]);
          Inc(i);
          if (c and $C0) <> $80 then  Exit;     // malformed trail byte or out of range char
          if i > SourceBytes then Exit;         // incomplete multibyte char
          wc := (wc shl 6) or (c and $3F);
        end;
        c := Byte(Source[i]);
        Inc(i);
        if (c and $C0) <> $80 then Exit;       // malformed trail byte

        Dest[count] := WideChar((wc shl 6) or (c and $3F));
      end
      else
        Dest[count] := WideChar(wc);
      Inc(count);
    end;
	if count >= MaxDestChars then count := MaxDestChars-1;
	Dest[count] := #0;
  end
  else
  begin
	while (i <= SourceBytes) do
	begin
	  c := Byte(Source[i]);
	  Inc(i);
	  if (c and $80) <> 0 then
	  begin
		if (c and $F0) = $F0 then Exit;  // too many bytes for UCS2
		if (c and $40) = 0 then Exit;    // malformed lead byte
		if i > SourceBytes then Exit;         // incomplete multibyte char

		if (Byte(Source[i]) and $C0) <> $80 then Exit;  // malformed trail byte
		Inc(i);
		if i > SourceBytes then Exit;         // incomplete multibyte char
		if ((c and $20) <> 0) and ((Byte(Source[i]) and $C0) <> $80) then Exit; // malformed trail byte
		Inc(i);
	  end;
	  Inc(count);
	end;
  end;
  Result := count+1;
end;

function Utf8Decode(const S: String): WideString;
var
  L: Integer;
  Temp: WideString;
begin
  Result := '';
  if S = '' then Exit;
  SetLength(Temp, Length(S));

  L := Utf8ToUnicode(PWideChar(Temp), Length(Temp)+1, PChar(S), Length(S));
  if L > 0 then
    SetLength(Temp, L-1)
  else
    Temp := '';
  Result := Temp;
end;

{$ENDIF}

{$IFDEF LINUX}
{SVD TTimeThread }

constructor TTimeThread.Create(ATimer: TFIBTimer);
begin
  inherited Create(True);

  FreeOnTerminate := True;
  FInt := ATimer.FInterval;
  FTimer := ATimer;
  Priority := 0;
  Resume;
end;

destructor TTimeThread.Destroy;
begin
  Stop;
  inherited Destroy;
end;

procedure TTimeThread.DoSuspend;
begin
  FSusp := True;
  Suspend;
end;

procedure TTimeThread.Execute;
var
  TickCount: Comp;
  function GetTickCount: Comp;
  begin
     Result := TimeStampToMSecs(DateTimeToTimeStamp(Now));
  end;
begin

  while not Terminated do
  begin
    FSusp := False;

    TickCount := GetTickCount;

    while (not Terminated)and(GetTickCount - FInt  < TickCount) do
      Sleep(1);

    if not Terminated then
      Synchronize(FTimer.DoOnTimer);
  end;
end;

procedure TTimeThread.Stop;
begin
  Terminate;
  if Suspended then
    Resume;
  Sleep(0);
end;

constructor TFIBTimer.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  FInterval := 1000;
end;

destructor TFIBTimer.Destroy;
begin
  StopTimer;
  inherited Destroy;
end;

procedure TFIBTimer.DoOnTimer;
begin
  if csDestroying in ComponentState then
    Exit;

  try
    if Assigned(FOnTimer) then
      FOnTimer(Self);
  except
    raise Exception.Create('DoOnTimer');
  end;
end;

procedure TFIBTimer.Loaded;
begin
  inherited Loaded;
  SetEnabled(FStreamedEnabled);
end;

procedure TFIBTimer.SetEnabled(const Value: Boolean);
begin
  if csLoading in ComponentState then
    FStreamedEnabled := Value
  else
  if FEnabled <> Value then
  begin
    FEnabled := Value;
    UpdateTimer;
  end;
end;

procedure TFIBTimer.SetInterval(const Value: Cardinal);
begin
  if FInterval <> Value then
  begin
    FInterval := Value;
    UpdateTimer;
  end;
end;

procedure TFIBTimer.SetKeepAlive(const Value: Boolean);
begin
  if FKeepAlive <> Value then
  begin
    StopTimer;
    FKeepAlive := Value;
    UpdateTimer;
  end;
end;

procedure TFIBTimer.SetOnTimer(const Value: TNotifyEvent);
begin
  if @FOnTimer <> @Value then
  begin
    FOnTimer := Value;
    UpdateTimer;
  end;
end;

procedure TFIBTimer.StopTimer;
begin
  if FTr is TTimeThread then
    TTimeThread(FTr).Stop;
  FTr := nil;
end;

procedure TFIBTimer.UpdateTimer;
var
  DoEnable: Boolean;
begin
  if ComponentState * [csDesigning, csLoading] <> [] then
    Exit;

  DoEnable := FEnabled and Assigned(FOnTimer) and (FInterval > 0);

  if not KeepAlive then
    StopTimer;

  if DoEnable then
  begin
    if FTr is TTimeThread then
      TTimeThread(FTr).FInt := FInterval
    else
      FTr := TTimeThread.Create(Self);

    if FTr.Suspended then
      FTr.Resume;
  end
  else
  if FTr is TTimeThread then

⌨️ 快捷键说明

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