📄 dbf_parser.pas
字号:
end;
function TLargeIntFieldVar.GetFieldType: TExpressionType;
begin
Result := etLargeInt;
end;
procedure TLargeIntFieldVar.Refresh(Buffer: PChar);
begin
if not FDbfFile.GetFieldDataFromDef(FieldDef, FieldDef.FieldType, Buffer, @FFieldVal, false) then
FFieldVal := 0;
end;
{$endif}
//--TDateTimeFieldVar---------------------------------------------------------
function TDateTimeFieldVar.GetFieldVal: Pointer;
begin
Result := @FFieldVal;
end;
function TDateTimeFieldVar.GetFieldType: TExpressionType;
begin
Result := etDateTime;
end;
procedure TDateTimeFieldVar.Refresh(Buffer: PChar);
begin
if not FDbfFile.GetFieldDataFromDef(FieldDef, ftDateTime, Buffer, @FFieldVal, false) then
FFieldVal.DateTime := 0.0;
end;
//--TBooleanFieldVar---------------------------------------------------------
function TBooleanFieldVar.GetFieldVal: Pointer;
begin
Result := @FFieldVal;
end;
function TBooleanFieldVar.GetFieldType: TExpressionType;
begin
Result := etBoolean;
end;
procedure TBooleanFieldVar.Refresh(Buffer: PChar);
var
lFieldVal: word;
begin
if FDbfFile.GetFieldDataFromDef(FieldDef, ftBoolean, Buffer, @lFieldVal, false) then
FFieldVal := lFieldVal <> 0
else
FFieldVal := false;
end;
//--TDbfParser---------------------------------------------------------------
constructor TDbfParser.Create(ADbfFile: Pointer);
begin
FDbfFile := ADbfFile;
FFieldVarList := TStringList.Create;
FCaseInsensitive := true;
FRawStringFields := true;
inherited Create;
end;
destructor TDbfParser.Destroy;
begin
ClearExpressions;
inherited;
FreeAndNil(FFieldVarList);
end;
function TDbfParser.GetResultType: TExpressionType;
begin
// if not a real expression, return type ourself
if FIsExpression then
Result := inherited GetResultType
else
Result := FFieldType;
end;
function TDbfParser.GetResultLen: Integer;
begin
// set result len for fixed length expressions / fields
case ResultType of
etBoolean: Result := 1;
etInteger: Result := 4;
etFloat: Result := 8;
etDateTime: Result := 8;
etString:
begin
if not FIsExpression and (TStringFieldVar(FFieldVarList.Objects[0]).RawStringField) then
Result := TStringFieldVar(FFieldVarList.Objects[0]).FieldDef.Size
else
Result := -1;
end;
else
Result := -1;
end;
end;
procedure TDbfParser.SetCaseInsensitive(NewInsensitive: Boolean);
begin
if FCaseInsensitive <> NewInsensitive then
begin
// clear and regenerate functions
FCaseInsensitive := NewInsensitive;
FillExpressList;
end;
end;
procedure TDbfParser.SetPartialMatch(NewPartialMatch: boolean);
begin
if FPartialMatch <> NewPartialMatch then
begin
// refill function list
FPartialMatch := NewPartialMatch;
FillExpressList;
end;
end;
procedure TDbfParser.SetRawStringFields(NewRawFields: Boolean);
var
I: integer;
begin
if FRawStringFields <> NewRawFields then
begin
// clear and regenerate functions, custom fields will be deleted too
FRawStringFields := NewRawFields;
for I := 0 to FFieldVarList.Count - 1 do
if FFieldVarList.Objects[I] is TStringFieldVar then
TStringFieldVar(FFieldVarList.Objects[I]).RawStringField := NewRawFields;
end;
end;
procedure TDbfParser.FillExpressList;
var
lExpression: string;
begin
lExpression := FCurrentExpression;
ClearExpressions;
FWordsList.FreeAll;
FWordsList.AddList(DbfWordsGeneralList, 0, DbfWordsGeneralList.Count - 1);
if FCaseInsensitive then
begin
FWordsList.AddList(DbfWordsInsensGeneralList, 0, DbfWordsInsensGeneralList.Count - 1);
if FPartialMatch then
begin
FWordsList.AddList(DbfWordsInsensPartialList, 0, DbfWordsInsensPartialList.Count - 1);
end else begin
FWordsList.AddList(DbfWordsInsensNoPartialList, 0, DbfWordsInsensNoPartialList.Count - 1);
end;
end else begin
FWordsList.AddList(DbfWordsSensGeneralList, 0, DbfWordsSensGeneralList.Count - 1);
if FPartialMatch then
begin
FWordsList.AddList(DbfWordsSensPartialList, 0, DbfWordsSensPartialList.Count - 1);
end else begin
FWordsList.AddList(DbfWordsSensNoPartialList, 0, DbfWordsSensNoPartialList.Count - 1);
end;
end;
if Length(lExpression) > 0 then
ParseExpression(lExpression);
end;
function TDbfParser.GetVariableInfo(VarName: string): TDbfFieldDef;
begin
Result := TDbfFile(FDbfFile).GetFieldInfo(VarName);
end;
procedure TDbfParser.HandleUnknownVariable(VarName: string);
var
FieldInfo: TDbfFieldDef;
TempFieldVar: TFieldVar;
begin
// is this variable a fieldname?
FieldInfo := GetVariableInfo(VarName);
if FieldInfo = nil then
raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_UNKNOWN_FIELD, [VarName]);
// define field in parser
case FieldInfo.FieldType of
ftString:
begin
TempFieldVar := TStringFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
TempFieldVar.ExprWord := DefineStringVariable(VarName, TempFieldVar.FieldVal);
TStringFieldVar(TempFieldVar).RawStringField := FRawStringFields;
end;
ftBoolean:
begin
TempFieldVar := TBooleanFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
TempFieldVar.ExprWord := DefineBooleanVariable(VarName, TempFieldVar.FieldVal);
end;
ftFloat:
begin
TempFieldVar := TFloatFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
TempFieldVar.ExprWord := DefineFloatVariable(VarName, TempFieldVar.FieldVal);
end;
ftAutoInc, ftInteger, ftSmallInt:
begin
TempFieldVar := TIntegerFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
TempFieldVar.ExprWord := DefineIntegerVariable(VarName, TempFieldVar.FieldVal);
end;
{$ifdef SUPPORT_INT64}
ftLargeInt:
begin
TempFieldVar := TLargeIntFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
TempFieldVar.ExprWord := DefineLargeIntVariable(VarName, TempFieldVar.FieldVal);
end;
{$endif}
ftDate, ftDateTime:
begin
TempFieldVar := TDateTimeFieldVar.Create(FieldInfo, TDbfFile(FDbfFile));
TempFieldVar.ExprWord := DefineDateTimeVariable(VarName, TempFieldVar.FieldVal);
end;
else
raise EDbfError.CreateFmt(STRING_INDEX_BASED_ON_INVALID_FIELD, [VarName]);
end;
// add to our own list
FFieldVarList.AddObject(VarName, TempFieldVar);
end;
function TDbfParser.CurrentExpression: string;
begin
Result := FCurrentExpression;
end;
procedure TDbfParser.ClearExpressions;
var
I: Integer;
begin
inherited;
// test if already freed
if FFieldVarList <> nil then
begin
// free field list
for I := 0 to FFieldVarList.Count - 1 do
begin
// replacing with nil = undefining variable
FWordsList.DoFree(TFieldVar(FFieldVarList.Objects[I]).FExprWord);
TFieldVar(FFieldVarList.Objects[I]).Free;
end;
FFieldVarList.Clear;
end;
// clear expression
FCurrentExpression := EmptyStr;
end;
procedure TDbfParser.ValidateExpression(AExpression: string);
begin
end;
procedure TDbfParser.ParseExpression(AExpression: string);
begin
// clear any current expression
ClearExpressions;
// is this a simple field or complex expression?
FIsExpression := GetVariableInfo(AExpression) = nil;
if FIsExpression then
begin
// parse requested
CompileExpression(AExpression);
end else begin
// simple field, create field variable for it
HandleUnknownVariable(AExpression);
FFieldType := TFieldVar(FFieldVarList.Objects[0]).FieldType;
end;
ValidateExpression(AExpression);
// if no errors, assign current expression
FCurrentExpression := AExpression;
end;
function TDbfParser.ExtractFromBuffer(Buffer: PChar): PChar;
var
I: Integer;
begin
// prepare all field variables
for I := 0 to FFieldVarList.Count - 1 do
TFieldVar(FFieldVarList.Objects[I]).Refresh(Buffer);
// complex expression?
if FIsExpression then
begin
// execute expression
EvaluateCurrent;
Result := ExpResult;
end else begin
// simple field, get field result
Result := TFieldVar(FFieldVarList.Objects[0]).FieldVal;
// if string then dereference
if FFieldType = etString then
Result := PPChar(Result)^;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -