📄 kbmmemcsvstreamformat.pas
字号:
s:=s+#13+#10;
l:=length(s);
// Write line.
WorkStream.WriteBuffer(Pointer(s)^, l);
// Increment savecounter.
inc(FSaveCount);
end;
finally
OverrideActiveRecordBuffer:=nil;
end;
end;
end;
end;
function TkbmCustomCSVStreamFormat.GetChunk:boolean;
begin
remaining_in_buf:=WorkStream.Read(pointer(buf)^,CSVBUFSIZE);
bufptr:=buf;
Result:=remaining_in_buf>0;
// Show progress.
inc(ProgressCnt);
ProgressCnt:=ProgressCnt mod 100;
if (ProgressCnt=0) then
FDataset.Progress(trunc((WorkStream.Position / StreamSize) * 100),mtpcLoad);
end;
function TkbmCustomCSVStreamFormat.GetLine:boolean;
var
EOL,EOF:boolean;
ep,sp:PChar;
TmpStr:string;
begin
// Cut out a line.
EOL:=false;
EOF:=false;
Line:='';
sp:=bufptr;
ep:=bufptr;
while true do
begin
// Check if need another chunk.
if remaining_in_buf=0 then
begin
// Add to line.
if EOL then
SetString(TmpStr,sp,ep-sp+1)
else
SetString(TmpStr,sp,bufptr-sp);
Line:=Line+TmpStr;
// Check if EOF.
if not GetChunk then
begin
EOF:=true;
break;
end;
sp:=bufptr;
ep:=bufptr-1;
end;
// Check if we got EOL character, skip them and finally break.
if (bufptr^) in [#0, #10, #13] then
begin
if not EOL then ep:=bufptr-1;
EOL:=true
end
else if EOL then
begin
SetString(TmpStr,sp,ep-sp+1);
Line:=Line+TmpStr;
break;
end;
// Prepare to look at next char.
Inc(bufptr);
dec(remaining_in_buf);
end;
lptr:=PChar(Line);
elptr:=PChar(Line)+Length(Line);
Result:=(not EOF);
end;
function TkbmCustomCSVStreamFormat.GetWord(var null:boolean):string;
type
tfsmstate=(stStart,stQuote,stText,stDelim);
var
sptr:PChar;
TmpStr:string;
l:integer;
state: tfsmstate;
begin
Result:='';
// Check if parsing without quote.
if FCSVQuote=#0 then
begin
sptr:=lptr;
while (lptr^ <> FCSVFieldDelimiter) and (lptr^ <> FCSVRecordDelimiter) and (lptr<elptr) do inc(lptr);
l:=lptr-sptr;
if (lptr>=elptr) then inc(l); // Allow for missing fieldseperator/recordseperator at end of line.
if (lptr^ = #0) then dec(l);
SetString(Result,sptr,l);
null:=(length(Result)<=0);
if (lptr^=FCSVFieldDelimiter) or (lptr^=FCSVRecordDelimiter) then inc(lptr);
end
else
begin
sptr:=lptr;
state:=stStart;
null:=false;
while state<>stDelim do
begin
if (lptr>=elptr) then
begin
if state=stText then
begin
SetString(TmpStr,sptr,lptr-sptr);
Result:=Result+TmpStr;
end;
exit;
end;
case state of
stStart:
if lptr^=FCSVQuote then
begin
state:=stQuote;
inc(sptr);
end
else if lptr^=FCSVFieldDelimiter then
begin
state:=stDelim;
null:=true;
end
else
state:=stText;
stText:
if lptr^=FCSVFieldDelimiter then
begin
SetString(TmpStr,sptr,lptr-sptr);
sptr:=lptr;
Result:=Result+TmpStr;
state:=stDelim;
end;
stQuote:
if lptr^=FCSVQuote then
begin
// Either got endquote or got double quote.
SetString(TmpStr,sptr,lptr-sptr);
Result:=Result+TmpStr;
inc(lptr);
if lptr^=FCSVQuote then
Result:=Result+FCSVQuote
else
state:=stDelim;
sptr:=lptr;
inc(sptr);
end;
end;
inc(lptr);
end;
end;
end;
{
function TkbmCustomCSVStreamFormat.GetWord(var null:boolean):string;
type
tfsmstate=(stStart,stQuote,stText,stDelim);
var
sptr:PChar;
TmpStr:string;
l:integer;
state: tfsmstate;
begin
Result:='';
// Check if parsing without quote.
if FCSVQuote=#0 then
begin
sptr:=lptr;
while (lptr^ <> FCSVFieldDelimiter) and (lptr^ <> FCSVRecordDelimiter) and (lptr<elptr) do inc(lptr);
l:=lptr-sptr;
if (lptr>=elptr) then inc(l); // Allow for missing fieldseperator/recordseperator at end of line.
SetString(Result,sptr,l);
null:=(length(Result)<=0);
if (lptr^=FCSVFieldDelimiter) or (lptr^=FCSVRecordDelimiter) then inc(lptr);
end
else
begin
sptr:=lptr;
state:=stStart;
null:=false;
while state<>stDelim do
begin
if (lptr>=elptr) then exit;
case state of
stStart:
case lptr^ of
'"': begin
state:=stQuote;
inc(sptr);
end;
',': begin
state:=stDelim;
null:=true;
end;
else
state:=stText;
end;
stText:
case lptr^ of
',': begin
SetString(TmpStr,sptr,lptr-sptr);
Result:=Result+TmpStr;
state:=stDelim;
end;
end;
stQuote:
case lptr^ of
'"': begin
SetString(TmpStr,sptr,lptr-sptr);
Result:=Result+TmpStr;
inc(lptr);
if lptr^ <> '"' then state:=stDelim;
end;
end;
end;
inc(lptr);
end;
end;
end;
}
{
function TkbmCustomCSVStreamFormat.GetWord(var null:boolean):string;
label
L_exit;
var
sptr:PChar;
TmpStr:string;
l:integer;
begin
// Cut out next word.
Result:='';
// Check if parsing without quote.
if FCSVQuote=#0 then
begin
sptr:=lptr;
while (lptr<elptr) and (not (lptr^ in [FCSVFieldDelimiter,FCSVRecordDelimiter])) do inc(lptr);
l:=lptr-sptr;
if (lptr>elptr) then inc(l); // Allow for missing fieldseperator/recordseperator at end of line.
SetString(Result,sptr,l);
null:=(length(Result)<=0);
if (lptr<elptr) and (lptr^ in [FCSVFieldDelimiter,FCSVRecordDelimiter]) then inc(lptr);
end
else
begin
// Look for starting CSVQuote or CSVFieldDelimiter
while (lptr^ <> FCSVQuote) and (lptr^ <> FCSVFieldDelimiter) and (lptr^ <> FCSVRecordDelimiter) and (lptr<elptr) do inc(lptr);
if (lptr>=elptr) then exit;
if (lptr^ = FCSVFieldDelimiter) or (lptr^ = FCSVRecordDelimiter) then
begin
null:=true;
inc(lptr);
exit;
end
else null:=false;
inc(lptr);
while true do
begin
// Look for ending ".
sptr:=lptr;
while not (lptr^ = FCSVQuote) do
begin
if (lptr>=elptr) then goto L_exit;
inc(lptr);
end;
SetString(TmpStr,sptr,lptr-sptr);
Result:=Result+TmpStr;
inc(lptr);
// Is it a double "" or end of word ?.
if (lptr^ = FCSVQuote) then
begin
Result:=Result+FCSVQuote;
inc(lptr);
continue;
end;
L_exit:
inc(lptr);
break;
end;
end;
end;
}
procedure TkbmCustomCSVStreamFormat.BeforeLoad(ADataset:TkbmCustomMemTable);
begin
FDefLoaded:=false;
inherited;
// Allocate space for a buffer.
GetMem(buf,CSVBUFSIZE);
// Still nothing in the buffer to handle.
FDataset:=ADataset;
remaining_in_buf:=0;
StreamSize:=WorkStream.Size;
ProgressCnt:=0;
// Setup standard layout for data.
Ods:=DateSeparator;
Oms:=DecimalSeparator;
Ots:=TimeSeparator;
Oths:=ThousandSeparator;
Ocf:=CurrencyFormat;
Onf:=NegCurrFormat;
Osdf:=ShortDateFormat;
Ocs:=CurrencyString;
// Check if to load in local format.
if not (sfLoadLocalFormat in sfLocalFormat) then
begin
DateSeparator:='/';
TimeSeparator:=':';
ThousandSeparator:=',';
DecimalSeparator:='.';
ShortDateFormat:='dd/mm/yyyy';
CurrencyString:='';
CurrencyFormat:=0;
NegCurrFormat:=1;
end;
end;
procedure TkbmCustomCSVStreamFormat.AfterLoad(ADataset:TkbmCustomMemTable);
begin
DateSeparator:=Ods;
DecimalSeparator:=Oms;
TimeSeparator:=Ots;
ThousandSeparator:=Oths;
CurrencyFormat:=Ocf;
NegCurrFormat:=Onf;
ShortDateFormat:=Osdf;
CurrencyString:=Ocs;
FreeMem(buf);
inherited;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -