123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- unit dbf_common;
- interface
- {$I dbf_common.inc}
- uses
- SysUtils, Classes, DB
- {$ifndef WIN32}
- , Types, dbf_wtil
- {$ifdef KYLIX}
- , Libc
- {$endif}
- {$endif}
- ;
- const
- TDBF_MAJOR_VERSION = 6;
- TDBF_MINOR_VERSION = 48;
- TDBF_SUB_MINOR_VERSION = 0;
- TDBF_TABLELEVEL_FOXPRO = 25;
- type
- EDbfError = class (EDatabaseError);
- EDbfWriteError = class (EDbfError);
- TDbfFieldType = char;
- TXBaseVersion = (xUnknown, xClipper, xBaseIII, xBaseIV, xBaseV, xFoxPro, xBaseVII);
- TSearchKeyType = (stEqual, stGreaterEqual, stGreater);
- TDateTimeHandling = (dtDateTime, dtBDETimeStamp);
- //-------------------------------------
- PDateTime = ^TDateTime;
- {$ifdef FPC_VERSION}
- TDateTimeAlias = type TDateTime;
- TDateTimeRec = record
- case TFieldType of
- ftDate: (Date: Longint);
- ftTime: (Time: Longint);
- ftDateTime: (DateTime: TDateTimeAlias);
- end;
- {$else}
- PtrInt = Longint;
- {$endif}
- PSmallInt = ^SmallInt;
- PCardinal = ^Cardinal;
- PDouble = ^Double;
- PString = ^String;
- PDateTimeRec = ^TDateTimeRec;
- {$ifdef SUPPORT_INT64}
- PLargeInt = ^Int64;
- {$endif}
- {$ifdef DELPHI_3}
- dword = cardinal;
- {$endif}
- //-------------------------------------
- {$ifndef SUPPORT_FREEANDNIL}
- // some procedures for the less lucky who don't have newer versions yet :-)
- procedure FreeAndNil(var v);
- {$endif}
- procedure FreeMemAndNil(var P: Pointer);
- //-------------------------------------
- {$ifndef SUPPORT_PATHDELIM}
- const
- {$ifdef WIN32}
- PathDelim = '\';
- {$else}
- PathDelim = '/';
- {$endif}
- {$endif}
- {$ifndef SUPPORT_INCLTRAILPATHDELIM}
- function IncludeTrailingPathDelimiter(const Path: string): string;
- {$endif}
- //-------------------------------------
- function GetCompletePath(const Base, Path: string): string;
- function GetCompleteFileName(const Base, FileName: string): string;
- function IsFullFilePath(const Path: string): Boolean; // full means not relative
- function DateTimeToBDETimeStamp(aDT: TDateTime): double;
- function BDETimeStampToDateTime(aBT: double): TDateTime;
- function GetStrFromInt(Val: Integer; const Dst: PChar): Integer;
- procedure GetStrFromInt_Width(Val: Integer; const Width: Integer; const Dst: PChar; const PadChar: Char);
- {$ifdef SUPPORT_INT64}
- function GetStrFromInt64(Val: Int64; const Dst: PChar): Integer;
- procedure GetStrFromInt64_Width(Val: Int64; const Width: Integer; const Dst: PChar; const PadChar: Char);
- {$endif}
- procedure FindNextName(BaseName: string; var OutName: string; var Modifier: Integer);
- {$ifdef USE_CACHE}
- function GetFreeMemory: Integer;
- {$endif}
- // OH 2000-11-15 dBase7 support. Swap Byte order for 4 and 8 Byte Integer
- function SwapWord(const Value: word): word;
- function SwapInt(const Value: dword): dword;
- { SwapInt64 NOTE: do not call with same value for Value and Result ! }
- procedure SwapInt64(Value, Result: Pointer); register;
- function TranslateString(FromCP, ToCP: Cardinal; Src, Dest: PChar; Length: Integer): Integer;
- // Returns a pointer to the first occurence of Chr in Str within the first Length characters
- // Does not stop at null (#0) terminator!
- function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer;
- // Delphi 3 does not have a Min function
- {$ifdef DELPHI_3}
- {$ifndef DELPHI_4}
- function Min(x, y: integer): integer;
- function Max(x, y: integer): integer;
- {$endif}
- {$endif}
- implementation
- {$ifdef WIN32}
- uses
- Windows;
- {$endif}
- //====================================================================
- function GetCompletePath(const Base, Path: string): string;
- begin
- if IsFullFilePath(Path)
- then begin
- Result := Path;
- end else begin
- if Length(Base) > 0 then
- Result := ExpandFileName(IncludeTrailingPathDelimiter(Base) + Path)
- else
- Result := ExpandFileName(Path);
- end;
- // add last backslash if not present
- if Length(Result) > 0 then
- Result := IncludeTrailingPathDelimiter(Result);
- end;
- function IsFullFilePath(const Path: string): Boolean; // full means not relative
- begin
- {$ifdef WIN32}
- Result := Length(Path) > 1;
- if Result then
- // check for 'x:' or '\\' at start of path
- Result := ((Path[2]=':') and (upcase(Path[1]) in ['A'..'Z']))
- or ((Path[1]='\') and (Path[2]='\'));
- {$else} // Linux
- Result := Length(Path) > 0;
- if Result then
- Result := Path[1]='/';
- {$endif}
- end;
- //====================================================================
- function GetCompleteFileName(const Base, FileName: string): string;
- var
- lpath: string;
- lfile: string;
- begin
- lpath := GetCompletePath(Base, ExtractFilePath(FileName));
- lfile := ExtractFileName(FileName);
- lpath := lpath + lfile;
- result := lpath;
- end;
- // it seems there is no pascal function to convert an integer into a PChar???
- procedure GetStrFromInt_Width(Val: Integer; const Width: Integer; const Dst: PChar; const PadChar: Char);
- var
- Temp: array[0..10] of Char;
- I, J: Integer;
- NegSign: boolean;
- begin
- {$I getstrfromint.inc}
- end;
- {$ifdef SUPPORT_INT64}
- procedure GetStrFromInt64_Width(Val: Int64; const Width: Integer; const Dst: PChar; const PadChar: Char);
- var
- Temp: array[0..19] of Char;
- I, J: Integer;
- NegSign: boolean;
- begin
- {$I getstrfromint.inc}
- end;
- {$endif}
- // it seems there is no pascal function to convert an integer into a PChar???
- // NOTE: in dbf_dbffile.pas there is also a convert routine, but is slightly different
- function GetStrFromInt(Val: Integer; const Dst: PChar): Integer;
- var
- Temp: array[0..10] of Char;
- I, J: Integer;
- begin
- Val := Abs(Val);
- // we'll have to store characters backwards first
- I := 0;
- J := 0;
- repeat
- Temp[I] := Chr((Val mod 10) + Ord('0'));
- Val := Val div 10;
- Inc(I);
- until Val = 0;
- // remember number of digits
- Result := I;
- // copy value, remember: stored backwards
- repeat
- Dst[J] := Temp[I-1];
- Inc(J);
- Dec(I);
- until I = 0;
- // done!
- end;
- {$ifdef SUPPORT_INT64}
- function GetStrFromInt64(Val: Int64; const Dst: PChar): Integer;
- var
- Temp: array[0..19] of Char;
- I, J: Integer;
- begin
- Val := Abs(Val);
- // we'll have to store characters backwards first
- I := 0;
- J := 0;
- repeat
- Temp[I] := Chr((Val mod 10) + Ord('0'));
- Val := Val div 10;
- Inc(I);
- until Val = 0;
- // remember number of digits
- Result := I;
- // copy value, remember: stored backwards
- repeat
- Dst[J] := Temp[I-1];
- inc(J);
- dec(I);
- until I = 0;
- // done!
- end;
- {$endif}
- function DateTimeToBDETimeStamp(aDT: TDateTime): double;
- var
- aTS: TTimeStamp;
- begin
- aTS := DateTimeToTimeStamp(aDT);
- Result := TimeStampToMSecs(aTS);
- end;
- function BDETimeStampToDateTime(aBT: double): TDateTime;
- var
- aTS: TTimeStamp;
- begin
- aTS := MSecsToTimeStamp(aBT);
- Result := TimeStampToDateTime(aTS);
- end;
- //====================================================================
- {$ifndef SUPPORT_FREEANDNIL}
- procedure FreeAndNil(var v);
- var
- Temp: TObject;
- begin
- Temp := TObject(v);
- TObject(v) := nil;
- Temp.Free;
- end;
- {$endif}
- procedure FreeMemAndNil(var P: Pointer);
- var
- Temp: Pointer;
- begin
- Temp := P;
- P := nil;
- FreeMem(Temp);
- end;
- //====================================================================
- {$ifndef SUPPORT_INCLTRAILPATHDELIM}
- {$ifndef SUPPORT_INCLTRAILBACKSLASH}
- function IncludeTrailingPathDelimiter(const Path: string): string;
- var
- len: Integer;
- begin
- Result := Path;
- len := Length(Result);
- if len = 0 then
- Result := PathDelim
- else
- if Result[len] <> PathDelim then
- Result := Result + PathDelim;
- end;
- {$else}
- function IncludeTrailingPathDelimiter(const Path: string): string;
- begin
- {$ifdef WIN32}
- Result := IncludeTrailingBackslash(Path);
- {$else}
- Result := IncludeTrailingSlash(Path);
- {$endif}
- end;
- {$endif}
- {$endif}
- {$ifdef USE_CACHE}
- function GetFreeMemory: Integer;
- var
- MemStatus: TMemoryStatus;
- begin
- GlobalMemoryStatus(MemStatus);
- Result := MemStatus.dwAvailPhys;
- end;
- {$endif}
- //====================================================================
- // Utility routines
- //====================================================================
- function SwapWord(const Value: word): word;
- begin
- Result := ((Value and $FF) shl 8) or ((Value shr 8) and $FF);
- end;
- {$ifdef USE_ASSEMBLER_486_UP}
- function SwapInt(const Value: dword): dword; register; assembler;
- asm
- BSWAP EAX;
- end;
- procedure SwapInt64(Value {EAX}, Result {EDX}: Pointer); register; assembler;
- asm
- MOV ECX, dword ptr [EAX]
- MOV EAX, dword ptr [EAX + 4]
- BSWAP ECX
- BSWAP EAX
- MOV dword ptr [EDX+4], ECX
- MOV dword ptr [EDX], EAX
- end;
- {$else}
- function SwapInt(const Value: Cardinal): Cardinal;
- begin
- PByteArray(@Result)[0] := PByteArray(@Value)[3];
- PByteArray(@Result)[1] := PByteArray(@Value)[2];
- PByteArray(@Result)[2] := PByteArray(@Value)[1];
- PByteArray(@Result)[3] := PByteArray(@Value)[0];
- end;
- procedure SwapInt64(Value, Result: Pointer); register;
- var
- PtrResult: PByteArray;
- PtrSource: PByteArray;
- begin
- // temporary storage is actually not needed, but otherwise compiler crashes (?)
- PtrResult := PByteArray(Result);
- PtrSource := PByteArray(Value);
- PtrResult[0] := PtrSource[7];
- PtrResult[1] := PtrSource[6];
- PtrResult[2] := PtrSource[5];
- PtrResult[3] := PtrSource[4];
- PtrResult[4] := PtrSource[3];
- PtrResult[5] := PtrSource[2];
- PtrResult[6] := PtrSource[1];
- PtrResult[7] := PtrSource[0];
- end;
- {$endif}
- function TranslateString(FromCP, ToCP: Cardinal; Src, Dest: PChar; Length: Integer): Integer;
- var
- WideCharStr: array[0..1023] of WideChar;
- wideBytes: Cardinal;
- begin
- if Length = -1 then
- Length := StrLen(Src);
- Result := Length;
- if (FromCP = GetOEMCP) and (ToCP = GetACP) then
- OemToCharBuff(Src, Dest, Length)
- else
- if (FromCP = GetACP) and (ToCP = GetOEMCP) then
- CharToOemBuff(Src, Dest, Length)
- else
- if FromCP = ToCP then
- begin
- if Src <> Dest then
- Move(Src^, Dest^, Length);
- end else begin
- // does this work on Win95/98/ME?
- wideBytes := MultiByteToWideChar(FromCP, MB_PRECOMPOSED, Src, Length, LPWSTR(@WideCharStr[0]), 1024);
- WideCharToMultiByte(ToCP, 0, LPWSTR(@WideCharStr[0]), wideBytes, Dest, Length, nil, nil);
- end;
- end;
- procedure FindNextName(BaseName: string; var OutName: string; var Modifier: Integer);
- var
- Extension: string;
- begin
- Extension := ExtractFileExt(BaseName);
- BaseName := Copy(BaseName, 1, Length(BaseName)-Length(Extension));
- repeat
- Inc(Modifier);
- OutName := ChangeFileExt(BaseName+'_'+IntToStr(Modifier), Extension);
- until not FileExists(OutName);
- end;
- {$ifdef FPC}
- function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer;
- var
- I: Integer;
- begin
- I := System.IndexByte(Buffer, Length, Chr);
- if I = -1 then
- Result := nil
- else
- Result := Buffer+I;
- end;
- {$else}
- function MemScan(const Buffer: Pointer; Chr: Byte; Length: Integer): Pointer;
- asm
- PUSH EDI
- MOV EDI,Buffer
- MOV AL, Chr
- MOV ECX,Length
- REPNE SCASB
- MOV EAX,0
- JNE @@1
- MOV EAX,EDI
- DEC EAX
- @@1: POP EDI
- end;
- {$endif}
- {$ifdef DELPHI_3}
- {$ifndef DELPHI_4}
- function Min(x, y: integer): integer;
- begin
- if x < y then
- result := x
- else
- result := y;
- end;
- function Max(x, y: integer): integer;
- begin
- if x < y then
- result := y
- else
- result := x;
- end;
- {$endif}
- {$endif}
- end.
|