Files
lazarus-ccr/components/flashfiler/sourcelaz/ffconvff.pas

960 lines
37 KiB
ObjectPascal
Raw Normal View History

{*********************************************************}
{* FlashFiler: Field conversion for server *}
{*********************************************************}
(* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1
*
* 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/
*
* 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 TurboPower FlashFiler
*
* The Initial Developer of the Original Code is
* TurboPower Software
*
* Portions created by the Initial Developer are Copyright (C) 1996-2002
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** *)
{$I ffdefine.inc}
unit ffconvff;
interface
uses
ffllbase,
fflldict,
ffsrbde,
ffstdate,
SysUtils;
function FFConvertSingleField(aSourceValue,
aTargetValue: Pointer;
aSourceType,
aTargetType: TffFieldType;
aSourceLength,
aTargetLength: Integer): TffResult;
{ This is the low-level data conversion routine for converting one FlashFiler
datatype to another. This is primarily used by the table restructure
operation. This routine accepts an input and output field specification
and determines if the input field can be converted to the output field.
If so, it copies and translates the input field data into the output
field.
This routine serves two purposes for table restructuring:
1) when the records are read, it does the data conversion between
the input fields and the output fields;
2) when the field map is initially validated (before the data is read/
written), it is used to determine if each field map entry is legal
(without actually moving any data around).
By serving double-duty like this, we centralize this fairly detailed
logic and reduce the likelihood of mistakes in updating it. Specifically,
when used for situation #2, nil is passed in for the field pointers and
the logic checks for this in the case statement. This lets the
logic flow through the case statement to find the correct datatype
matches, but stops short of actually copying any data.
Note on BLOB Conversions: BLOB-to-BLOB and ByteArray-to-BLOB conversions
are legal and this routine validates that fact (when called with nil value
pointers), but does not actually copy to/from BLOB fields. The caller
is responsible for detecting a BLOB target field and handling the data
conversion. All this routine does it tell you that such a conversion is
legal.
Note on null field values: This routine assumes it will not see a null
input value (that is, it assumes null input values are captured by the
caller and handled at that level). After all, if the input value is null,
the output value will always be null regardless of the datatypes involved.
It is intended that this routine could be compiled into both a server app
and a client app. Specifically, this routine is used by FF Explorer to
perform real time validation of table restructure field assignments
without waiting for the whole restructure package to be sent to the
server and subsequently fail if the user selected incompatible datatypes.
Parameters:
aSourceValue and aTargetValue point to the input and output field values
(that is, the start position within the record buffers where these values
can be found). If both are nil, then only an assignment compatabiliy
check is performed, no data is actually moved.
aSourceType and aTargetType indicate the FlashFiler datatype of the
fields.
aSourceLength and aTargetLength are the maximum lengths, in bytes, of
each data field (ignored if only doing assignment compatability check).
}
implementation
uses
typinfo,
ffconst,
ffllexcp;
function FFRemoveThousandSeparator(const str : string): string;
begin
Result := str;
while pos(ThousandSeparator, Result)>0 do
Delete(Result, pos(ThousandSeparator, Result), 1);
end;
function FFConvertSingleField(aSourceValue,
aTargetValue: Pointer;
aSourceType,
aTargetType: TffFieldType;
aSourceLength,
aTargetLength: Integer): TffResult;
var
MinLength: Integer;
srcBoolean: ^Boolean absolute aSourceValue;
WorkString: String[11]; {!!.10}
{ workspacelength equals Length(IntToStr(Low(Integer))),
used for converting various int-types to string }
{Begin !!.13}
aCode,
intRes: Integer;
wordRes: TffWord32;
{End !!.13}
begin
Result := DBIERR_NONE;
MinLength := FFMinI(aSourceLength, aTargetLength);
case aSourceType of
fftBoolean: begin
{ Booleans can be translated into char or string fields (Y or N), or
integer numeric fields (ordinal value, 0 - false, 1 - true) }
case aTargetType of
fftBoolean:
if Assigned(aTargetValue) then
Boolean(aTargetValue^) := srcBoolean^;
fftChar:
if Assigned(aTargetValue) then
if srcBoolean^ then Char(aTargetValue^) := 'Y'
else Char(aTargetValue^) := 'N';
fftByte, fftInt8:
if Assigned(aTargetValue) then
Byte(aTargetValue^) := Ord(srcBoolean^);
fftWord16, fftInt16:
if Assigned(aTargetValue) then
Word(aTargetValue^) := Ord(srcBoolean^);
fftWord32, fftInt32:
if Assigned(aTargetValue) then
LongInt(aTargetValue^) := Ord(srcBoolean^);
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then
if srcBoolean^ then TffShStr(aTargetValue^) := 'Y'
else TffShStr(aTargetValue^) := 'N';
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then
if srcBoolean^ then FFStrPCopy(aTargetValue, 'Y')
else FFStrPCopy(aTargetValue, 'N');
fftWideChar:
if Assigned(aTargetValue) then
if srcBoolean^ then WideChar(aTargetValue^) := FFCharToWideChar('Y')
else WideChar(aTargetValue^) := FFCharToWideChar('N');
fftWideString:
if Assigned(aTargetValue) then
if srcBoolean^ then FFShStrLToWideStr('Y', aTargetValue, 1)
else FFShStrLToWideStr('N', aTargetValue, 1);
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftChar: begin
case aTargetType of
fftChar:
if Assigned(aTargetValue) then
Char(aTargetValue^) := Char(aSourceValue^);
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then
TffShStr(aTargetValue^) := Char(aSourceValue^);
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then
FFStrPCopy(aTargetValue, Char(aSourceValue^));
fftWideChar:
if Assigned(aTargetValue) then
WideChar(aTargetValue^) := FFCharToWideChar(Char(aSourceValue^));
fftWideString:
if Assigned(aTargetValue) then
FFShStrLToWideStr(Char(aSourceValue^), aTargetValue, 1);
fftBLOB..ffcLastBLOBType: ;
{ Validate only; do not actually move BLOB data around. }
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftWideChar: begin
case aTargetType of
fftChar:
if Assigned(aTargetValue) then
Char(aTargetValue^) := FFWideCharToChar(WideChar(aSourceValue^));
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then
TffShStr(aTargetValue^) := FFWideCharToChar(WideChar(aSourceValue^));
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then
FFStrPCopy(aTargetValue, FFWideCharToChar(WideChar(aSourceValue^)));
fftWideChar:
if Assigned(aTargetValue) then
WideChar(aTargetValue^) := WideChar(aSourceValue^);
fftWideString:
if Assigned(aTargetValue) then begin
PWideChar(aTargetValue)^ := WideChar(aSourceValue^);
PWideChar(LongInt(aTargetValue) + SizeOf(WideChar))^ := WideChar(#0);
end;
fftBLOB..ffcLastBLOBType: ;
{ Validate only; do not actually move BLOB data around. }
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftByte: begin
case aTargetType of
fftByte:
if Assigned(aTargetValue) then
Byte(aTargetValue^) := Byte(aSourceValue^);
fftWord16, fftInt16:
if Assigned(aTargetValue) then
TffWord16(aTargetValue^) := Byte(aSourceValue^);
fftWord32, fftInt32, fftAutoInc:
if Assigned(aTargetValue) then
TffWord32(aTargetValue^) := Byte(aSourceValue^);
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := Byte(aSourceValue^);
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := Byte(aSourceValue^);
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := Byte(aSourceValue^);
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := Byte(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := Byte(aSourceValue^);
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
{Begin !!.10}
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(Byte(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
TffShStr(aTargetValue^) := WorkString;
end;
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(Byte(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFStrPCopy(aTargetValue, WorkString);
end;
fftWideString:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
WorkString := IntToStr(Byte(aSourceValue^));
if Length(WorkString)>(aTargetLength div SizeOf(WideChar))-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFShStrLToWideStr(WorkString, aTargetValue, Length(WorkString));
end;
{End !!.10}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftWord16: begin
case aTargetType of
fftWord16:
if Assigned(aTargetValue) then
TffWord16(aTargetValue^) := TffWord16(aSourceValue^);
fftWord32, fftInt32, fftAutoInc:
if Assigned(aTargetValue) then
TffWord32(aTargetValue^) := TffWord16(aSourceValue^);
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := TffWord16(aSourceValue^);
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := TffWord16(aSourceValue^);
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := TffWord16(aSourceValue^);
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := TffWord16(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := TffWord16(aSourceValue^);
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
{Begin !!.10}
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(TffWord16(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
TffShStr(aTargetValue^) := WorkString;
end;
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(TffWord16(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFStrPCopy(aTargetValue, WorkString);
end;
fftWideString:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
WorkString := IntToStr(TffWord16(aSourceValue^));
if Length(WorkString)>(aTargetLength div SizeOf(WideChar))-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFShStrLToWideStr(WorkString, aTargetValue, Length(WorkString));
end;
{End !!.10}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftWord32,
fftAutoInc: begin
case aTargetType of
fftWord32,
fftAutoInc:
if Assigned(aTargetValue) then
TffWord32(aTargetValue^) := TffWord32(aSourceValue^);
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := TffWord32(aSourceValue^);
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := TffWord32(aSourceValue^);
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := TffWord32(aSourceValue^);
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := TffWord32(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := TffWord32(aSourceValue^);
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
{Begin !!.10}
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(TffWord32(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
TffShStr(aTargetValue^) := WorkString;
end;
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(TffWord32(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFStrPCopy(aTargetValue, WorkString);
end;
fftWideString:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
WorkString := IntToStr(TffWord32(aSourceValue^));
if Length(WorkString)>(aTargetLength div SizeOf(WideChar))-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFShStrLToWideStr(WorkString, aTargetValue, Length(WorkString));
end;
{End !!.10}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftInt8: begin
case aTargetType of
fftInt8:
if Assigned(aTargetValue) then
ShortInt(aTargetValue^) := ShortInt(aSourceValue^);
fftInt16:
if Assigned(aTargetValue) then
SmallInt(aTargetValue^) := ShortInt(aSourceValue^);
fftInt32:
if Assigned(aTargetValue) then
LongInt(aTargetValue^) := ShortInt(aSourceValue^);
{Begin !!.10}
fftWord32, fftAutoInc:
if Assigned(aTargetValue) then begin
if ShortInt(aSourceValue^)<0 then
Result := DBIERR_INVALIDFLDXFORM
else
TffWord32(aTargetValue^) := ShortInt(aSourceValue^);
end;
{End !!.10}
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := ShortInt(aSourceValue^);
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := ShortInt(aSourceValue^);
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := ShortInt(aSourceValue^);
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := ShortInt(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := ShortInt(aSourceValue^);
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
{Begin !!.10}
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(ShortInt(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
TffShStr(aTargetValue^) := WorkString;
end;
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(ShortInt(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFStrPCopy(aTargetValue, WorkString);
end;
fftWideString:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
WorkString := IntToStr(ShortInt(aSourceValue^));
if Length(WorkString)>(aTargetLength div SizeOf(WideChar))-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFShStrLToWideStr(WorkString, aTargetValue, Length(WorkString));
end;
{End !!.10}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftInt16: begin
case aTargetType of
fftInt16:
if Assigned(aTargetValue) then
SmallInt(aTargetValue^) := SmallInt(aSourceValue^);
fftInt32:
if Assigned(aTargetValue) then
LongInt(aTargetValue^) := SmallInt(aSourceValue^);
{Begin !!.10}
fftWord32, fftAutoInc:
if Assigned(aTargetValue) then begin
if SmallInt(aSourceValue^)<0 then
Result := DBIERR_INVALIDFLDXFORM
else
TffWord32(aTargetValue^) := SmallInt(aSourceValue^);
end;
{End !!.10}
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := SmallInt(aSourceValue^);
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := SmallInt(aSourceValue^);
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := SmallInt(aSourceValue^);
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := SmallInt(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := SmallInt(aSourceValue^);
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
{Begin !!.10}
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(SmallInt(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
TffShStr(aTargetValue^) := WorkString;
end;
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(SmallInt(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFStrPCopy(aTargetValue, WorkString);
end;
fftWideString:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
WorkString := IntToStr(SmallInt(aSourceValue^));
if Length(WorkString)>(aTargetLength div SizeOf(WideChar))-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFShStrLToWideStr(WorkString, aTargetValue, Length(WorkString));
end;
{End !!.10}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftInt32: begin
case aTargetType of
fftInt32:
if Assigned(aTargetValue) then
LongInt(aTargetValue^) := LongInt(aSourceValue^);
{Begin !!.10}
fftWord32, fftAutoInc:
if Assigned(aTargetValue) then begin
if LongInt(aSourceValue^)<0 then
Result := DBIERR_INVALIDFLDXFORM
else
TffWord32(aTargetValue^) := LongInt(aSourceValue^);
end;
{End !!.10}
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := LongInt(aSourceValue^);
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := LongInt(aSourceValue^);
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := LongInt(aSourceValue^);
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := LongInt(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := LongInt(aSourceValue^);
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
{Begin !!.10}
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(LongInt(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
TffShStr(aTargetValue^) := WorkString;
end;
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then begin
WorkString := IntToStr(LongInt(aSourceValue^));
if Length(WorkString)>aTargetLength-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFStrPCopy(aTargetValue, WorkString);
end;
fftWideString:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
WorkString := IntToStr(LongInt(aSourceValue^));
if Length(WorkString)>(aTargetLength div SizeOf(WideChar))-1 then
Result := DBIERR_INVALIDFLDXFORM
else
FFShStrLToWideStr(WorkString, aTargetValue, Length(WorkString));
end;
{End !!.10}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftSingle: begin
case aTargetType of
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := Single(aSourceValue^);
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := Single(aSourceValue^);
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := Single(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := Single(aSourceValue^) * 10000.0; {!!.10}
// Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftDouble: begin
case aTargetType of
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := Double(aSourceValue^);
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := Double(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := Double(aSourceValue^) * 10000.0; {!!.10}
// Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftExtended: begin
case aTargetType of
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := Extended(aSourceValue^);
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := Extended(aSourceValue^);
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftComp:
case aTargetType of
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := Comp(aSourceValue^);
else Result := DBIERR_INVALIDFLDXFORM;
end;
fftCurrency: begin
case aTargetType of
fftCurrency:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := Comp(aSourceValue^);
{Begin !!.10}
fftSingle:
if Assigned(aTargetValue) then begin
Single(aTargetValue^) := Comp(aSourceValue^);
Single(aTargetValue^) := Single(aTargetValue^) / 10000.0;
end;
fftDouble:
if Assigned(aTargetValue) then begin
Double(aTargetValue^) := Comp(aSourceValue^);
Double(aTargetValue^) := Double(aTargetValue^) / 10000.0;
end;
{End !!.10}
fftExtended:
if Assigned(aTargetValue) then begin
Extended(aTargetValue^) := Comp(aSourceValue^);
Extended(aTargetValue^) := Extended(aTargetValue^) / 10000.0;
end;
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftStDate: begin
case aTargetType of
fftStDate:
if Assigned(aTargetValue) then
LongInt(aTargetValue^) := LongInt(aSourceValue^);
fftDateTime:
if Assigned(aTargetValue) then
TDateTime(aTargetValue^) :=
StDateToDateTime(LongInt(aSourceValue^))
+ 693594.0; {TDateTime's are stored as Delphi 1 values}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftStTime: begin
case aTargetType of
fftStTime:
if Assigned(aTargetValue) then
LongInt(aTargetValue^) := LongInt(aSourceValue^);
fftDateTime:
if Assigned(aTargetValue) then
TDateTime(aTargetValue^) := StTimeToDateTime(LongInt(aSourceValue^));
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftDateTime: begin
case aTargetType of
fftDateTime:
if Assigned(aTargetValue) then
TDateTime(aTargetValue^) := TDateTime(aSourceValue^);
fftStDate:
if Assigned(aTargetValue) then
LongInt(aTargetValue^) := DateTimeToStDate(TDateTime(aSourceValue^)
- 693594.0); { TDateTime's are stored as Delphi 1 values }
fftStTime:
if Assigned(aTargetValue) then
LongInt(aTargetValue^) := DateTimeToStTime(TDateTime(aSourceValue^));
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftBLOB..ffcLastBLOBType:
if not (aTargetType in [fftBLOB..ffcLastBLOBType]) then
Result := DBIERR_INVALIDFLDXFORM;
{ Validate only; do not actually move BLOB data around. }
fftByteArray: begin
case aTargetType of
fftByteArray:
if Assigned(aTargetValue) then
Move(aSourceValue^, aTargetValue^, MinLength);
fftBLOB..ffcLastBLOBType: ;
{ Validate only; do not move BLOB data around. }
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftShortString, fftShortAnsiStr: begin
case aTargetType of
fftChar:
if Assigned(aTargetValue) then
Char(aTargetValue^) := TffShStr(aSourceValue^)[1];
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then
TffShStr(aTargetValue^) := Copy(TffShStr(aSourceValue^), 1, MinLength - 1);
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then
FFStrPCopy(aTargetValue, Copy(TffShStr(aSourceValue^), 1, MinLength - 1));
fftWideChar:
if Assigned(aTargetValue) then
WideChar(aTargetValue^) := FFCharToWideChar(TffShStr(aSourceValue^)[1]);
fftWideString:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
MinLength := FFMinI(aSourceLength - 1, (aTargetLength div SizeOf(WideChar)) - 1);
FFShStrLToWideStr(TffShStr(aSourceValue^), aTargetValue, MinLength);
end;
fftBLOB..ffcLastBLOBType: ;
{ Validate only; do not actually move BLOB data around. }
{Begin !!.13}
fftByte:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(TffShStr(aSourceValue^)), intRes, aCode);
if (aCode=0) and (intRes>=Low(Byte)) and (intRes<=High(Byte)) then
Byte(aTargetValue^) := intRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftWord16:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(TffShStr(aSourceValue^)), wordRes, aCode);
if (aCode=0) then
TffWord16(aTargetValue^) := wordRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftInt16:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(TffShStr(aSourceValue^)), intRes, aCode);
if (aCode=0) and (intRes>=Low(SmallInt)) and (intRes<=High(SmallInt)) then
Smallint(aTargetValue^) := intRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftWord32, fftAutoInc:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(TffShStr(aSourceValue^)), wordRes, aCode);
if (aCode=0) then
TffWord32(aTargetValue^) := wordRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftInt32:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(TffShStr(aSourceValue^)), intRes, aCode);
if (aCode=0) then
Integer(aTargetValue^) := intRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(TffShStr(aSourceValue^)));
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(TffShStr(aSourceValue^)));
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(TffShStr(aSourceValue^)));
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(TffShStr(aSourceValue^)));
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(TffShStr(aSourceValue^)));
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
{End !!.13}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftNullString, fftNullAnsiStr: begin
case aTargetType of
fftChar:
if Assigned(aTargetValue) then
Char(aTargetValue^) := FFStrPas(aSourceValue)[1];
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then
TffShStr(aTargetValue^) := Copy(FFStrPas(aSourceValue), 1, MinLength - 1);
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then
StrLCopy(aTargetValue, aSourceValue, MinLength - 1);
fftWideChar:
if Assigned(aTargetValue) then
WideChar(aTargetValue^) := FFCharToWideChar(Char(aSourceValue^));
fftWideString:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
MinLength := FFMinI(aSourceLength - 1, (aTargetLength div SizeOf(WideChar)) - 1);
FFNullStrLToWideStr(aSourceValue, aTargetValue, MinLength);
end;
fftBLOB..ffcLastBLOBType: ;
{ Validate only; do not actually move BLOB data around. }
{Begin !!.13}
fftByte:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(PChar(aSourceValue)), intRes, aCode);
if (aCode=0) and (intRes>=Low(Byte)) and (intRes<=High(Byte)) then
Byte(aTargetValue^) := intRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftWord16:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(PChar(aSourceValue)), wordRes, aCode);
if (aCode=0) then
TffWord16(aTargetValue^) := wordRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftInt16:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(PChar(aSourceValue)), intRes, aCode);
if (aCode=0) and (intRes>=Low(SmallInt)) and (intRes<=High(SmallInt)) then
Smallint(aTargetValue^) := intRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftWord32, fftAutoInc:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(PChar(aSourceValue)), wordRes, aCode);
if (aCode=0) then
TffWord32(aTargetValue^) := wordRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftInt32:
if Assigned(aTargetValue) then begin
Val(FFRemoveThousandSeparator(PChar(aSourceValue)), intRes, aCode);
if (aCode=0) then
Integer(aTargetValue^) := intRes
else
Result := DBIERR_INVALIDFLDXFORM;
end;
fftSingle:
if Assigned(aTargetValue) then
Single(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(PChar(aSourceValue)));
fftDouble:
if Assigned(aTargetValue) then
Double(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(PChar(aSourceValue)));
fftExtended:
if Assigned(aTargetValue) then
Extended(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(PChar(aSourceValue)));
fftComp:
if Assigned(aTargetValue) then
Comp(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(PChar(aSourceValue)));
fftCurrency:
if Assigned(aTargetValue) then begin
Comp(aTargetValue^) := StrToFloat(FFRemoveThousandSeparator(PChar(aSourceValue)));
Comp(aTargetValue^) := Comp(aTargetValue^) * 10000.0;
end;
{End !!.13}
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
fftWideString: begin
case aTargetType of
fftChar:
if Assigned(aTargetValue) then
Char(aTargetValue^) := FFWideCharToChar(WideChar(aSourceValue^));
fftShortString, fftShortAnsiStr:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
MinLength := FFMinI(aTargetLength - 1, (aSourceLength div SizeOf(WideChar)) - 1);
TffShStr(aTargetValue^) := FFWideStrLToShStr(aSourceValue, MinLength);
end;
fftNullString, fftNullAnsiStr:
if Assigned(aTargetValue) then begin
{ Note: the length of a "wide" field is the number of bytes
it occupies, not the number of wide chars it will hold. }
MinLength := FFMinI(aTargetLength - 1, (aSourceLength div SizeOf(WideChar)) - 1);
FFWideStrLToNullStr(aSourceValue, aTargetValue, MinLength);
end;
fftWideChar:
if Assigned(aTargetValue) then
WideChar(aTargetValue^) := WideChar(aSourceValue^);
fftWideString:
if Assigned(aTargetValue) then
FFWideStrLToWideStr(aSourceValue, aTargetValue, FFMinI(aSourceLength, aTargetLength) - 1);
fftBLOB..ffcLastBLOBType: ;
{ Validate only; do not actually move BLOB data around. }
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
else Result := DBIERR_INVALIDFLDXFORM;
end;
end;
end.