csvdocument: added TCSVParser.MaxColCount property and more comments (patch by Reinier Olislagers)

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@2517 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
vvzh
2012-09-18 21:17:20 +00:00
parent 8fb214f590
commit 3111df6827

View File

@ -1,12 +1,13 @@
{ {
CSV Parser and Document classes. CSV Parser, Builder and Document classes.
Version 0.4 2011-05-10 Version 0.5 2012-09-20
Copyright (C) 2010-2011 Vladimir Zhirov <vvzh.home@gmail.com> Copyright (C) 2010-2012 Vladimir Zhirov <vvzh.home@gmail.com>
Contributors: Contributors:
Luiz Americo Pereira Camara Luiz Americo Pereira Camara
Mattias Gaertner Mattias Gaertner
Reinier Olislagers
This library is free software; you can redistribute it and/or modify it This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by under the terms of the GNU Library General Public License as published by
@ -82,6 +83,7 @@ type
property EqualColCountPerRow: Boolean read FEqualColCountPerRow write FEqualColCountPerRow; property EqualColCountPerRow: Boolean read FEqualColCountPerRow write FEqualColCountPerRow;
end; end;
// Sequential input from CSV stream
TCSVParser = class(TCSVHandler) TCSVParser = class(TCSVHandler)
private private
// fields // fields
@ -93,6 +95,7 @@ type
FCurrentChar: TCSVChar; FCurrentChar: TCSVChar;
FCurrentRow: Integer; FCurrentRow: Integer;
FCurrentCol: Integer; FCurrentCol: Integer;
FMaxColCount: Integer;
// output buffers // output buffers
FCellBuffer: String; FCellBuffer: String;
FWhitespaceBuffer: String; FWhitespaceBuffer: String;
@ -105,6 +108,7 @@ type
// complex parsing // complex parsing
procedure ParseCell; procedure ParseCell;
procedure ParseQuotedValue; procedure ParseQuotedValue;
// simple parsing
procedure ParseValue; procedure ParseValue;
public public
constructor Create; constructor Create;
@ -116,8 +120,11 @@ type
property CurrentRow: Integer read FCurrentRow; property CurrentRow: Integer read FCurrentRow;
property CurrentCol: Integer read FCurrentCol; property CurrentCol: Integer read FCurrentCol;
property CurrentCellText: String read FCellBuffer; property CurrentCellText: String read FCellBuffer;
// The maximum number of columns found in the stream:
property MaxColCount: Integer read FMaxColCount;
end; end;
// Sequential output to CSV stream
TCSVBuilder = class(TCSVHandler) TCSVBuilder = class(TCSVHandler)
private private
FOutputStream: TStream; FOutputStream: TStream;
@ -138,6 +145,7 @@ type
property DefaultOutputAsString: String read GetDefaultOutputAsString; property DefaultOutputAsString: String read GetDefaultOutputAsString;
end; end;
// Random access to CSV document. Reads entire document into memory.
TCSVDocument = class(TCSVHandler) TCSVDocument = class(TCSVHandler)
private private
FRows: TFPObjectList; FRows: TFPObjectList;
@ -321,6 +329,7 @@ begin
FWhitespaceBuffer := ''; FWhitespaceBuffer := '';
FCurrentRow := 0; FCurrentRow := 0;
FCurrentCol := -1; FCurrentCol := -1;
FMaxColCount := 0;
end; end;
procedure TCSVParser.SkipEndOfLine; procedure TCSVParser.SkipEndOfLine;
@ -449,13 +458,22 @@ begin
NextChar; NextChar;
end; end;
// Parses next cell; returns true if it could be parsed.
function TCSVParser.ParseNextCell: Boolean; function TCSVParser.ParseNextCell: Boolean;
var
LineColCount: Integer;
begin begin
if EndOfFile then if EndOfFile then
Exit(False); Exit(False);
// Handle line ending
if EndOfLine then if EndOfLine then
begin begin
// Having read the previous line, adjust column count if necessary:
LineColCount := FCurrentCol + 1;
if LineColCount > FMaxColCount then
FMaxColCount := LineColCount;
SkipEndOfLine; SkipEndOfLine;
if EndOfFile then if EndOfFile then
Exit(False); Exit(False);
@ -781,10 +799,14 @@ begin
Result := 0; Result := 0;
end; end;
// Returns maximum number of columns in the document
function TCSVDocument.GetMaxColCount: Integer; function TCSVDocument.GetMaxColCount: Integer;
var var
I, CC: Integer; I, CC: Integer;
begin begin
// While calling MaxColCount in TCSVParser could work,
// we'd need to adjust for any subsequent changes in
// TCSVDocument
Result := 0; Result := 0;
for I := 0 to RowCount - 1 do for I := 0 to RowCount - 1 do
begin begin