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

📄 kbmmemcsvstreamformat.pas

📁 内存数据库控件源代码
💻 PAS
📖 第 1 页 / 共 4 页
字号:
                       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 + -