Browse Source

* PChar -> PansiChar

Michaël Van Canneyt 2 years ago
parent
commit
fdd26e6fca
1 changed files with 70 additions and 15 deletions
  1. 70 15
      packages/fcl-base/src/csvreadwrite.pp

+ 70 - 15
packages/fcl-base/src/csvreadwrite.pp

@@ -52,17 +52,21 @@ Type
 
 
   TCSVHandler = class(TPersistent)
   TCSVHandler = class(TPersistent)
   private
   private
+    function GetDelimiter: TCSVChar;
+    function GetLineEnding: String;
+    function GetQuoteChar: TCSVChar;
     procedure SetDelimiter(const AValue: TCSVChar);
     procedure SetDelimiter(const AValue: TCSVChar);
+    procedure SetLineEnding(AValue: String);
     procedure SetQuoteChar(const AValue: TCSVChar);
     procedure SetQuoteChar(const AValue: TCSVChar);
     procedure UpdateCachedChars;
     procedure UpdateCachedChars;
   protected
   protected
     // special chars
     // special chars
-    FDelimiter: TCSVChar;
-    FQuoteChar: TCSVChar;
-    FLineEnding: String;
+    FDelimiter: AnsiChar;
+    FQuoteChar: AnsiChar;
+    FLineEnding: AnsiString;
     // cached values to speed up special chars operations
     // cached values to speed up special chars operations
     FSpecialChars: TSysCharSet;
     FSpecialChars: TSysCharSet;
-    FDoubleQuote: String;
+    FDoubleQuote: AnsiString;
     // parser settings
     // parser settings
     FIgnoreOuterWhitespace: Boolean;
     FIgnoreOuterWhitespace: Boolean;
     // builder settings
     // builder settings
@@ -74,13 +78,13 @@ Type
     procedure Assign(ASource: TPersistent); override;
     procedure Assign(ASource: TPersistent); override;
     procedure AssignCSVProperties(ASource: TCSVHandler);
     procedure AssignCSVProperties(ASource: TCSVHandler);
     // Delimiter that separates the field, e.g. comma, semicolon, tab
     // Delimiter that separates the field, e.g. comma, semicolon, tab
-    property Delimiter: TCSVChar read FDelimiter write SetDelimiter;
+    property Delimiter: TCSVChar read GetDelimiter write SetDelimiter;
     // Character used to quote "problematic" data
     // Character used to quote "problematic" data
     // (e.g. with delimiters or spaces in them)
     // (e.g. with delimiters or spaces in them)
     // A common quotechar is "
     // A common quotechar is "
-    property QuoteChar: TCSVChar read FQuoteChar write SetQuoteChar;
+    property QuoteChar: TCSVChar read GetQuoteChar write SetQuoteChar;
     // String at the end of the line of data (e.g. CRLF)
     // String at the end of the line of data (e.g. CRLF)
-    property LineEnding: String read FLineEnding write FLineEnding;
+    property LineEnding: String read GetLineEnding write SetLineEnding;
     // Ignore whitespace between delimiters and field data
     // Ignore whitespace between delimiters and field data
     property IgnoreOuterWhitespace: Boolean read FIgnoreOuterWhitespace write FIgnoreOuterWhitespace;
     property IgnoreOuterWhitespace: Boolean read FIgnoreOuterWhitespace write FIgnoreOuterWhitespace;
     // Use quotes when outer whitespace is found
     // Use quotes when outer whitespace is found
@@ -106,14 +110,15 @@ Type
     // parser state
     // parser state
     EndOfFile: Boolean;
     EndOfFile: Boolean;
     EndOfLine: Boolean;
     EndOfLine: Boolean;
-    FCurrentChar: TCSVChar;
+    FCurrentChar: AnsiChar;
     FCurrentRow: Integer;
     FCurrentRow: Integer;
     FCurrentCol: Integer;
     FCurrentCol: Integer;
     FMaxColCount: Integer;
     FMaxColCount: Integer;
     // output buffers
     // output buffers
-    FCellBuffer: String;
-    FWhitespaceBuffer: String;
+    FCellBuffer: RawByteString;
+    FWhitespaceBuffer: RawByteString;
     procedure ClearOutput;
     procedure ClearOutput;
+    function GetCurrentCell: String;
     // basic parsing
     // basic parsing
     procedure SkipEndOfLine;
     procedure SkipEndOfLine;
     procedure SkipDelimiter;
     procedure SkipDelimiter;
@@ -140,7 +145,7 @@ Type
     // Current column (0 based); -1 if invalid/before beginning of file
     // Current column (0 based); -1 if invalid/before beginning of file
     property CurrentCol: Integer read FCurrentCol;
     property CurrentCol: Integer read FCurrentCol;
     // Data in current cell
     // Data in current cell
-    property CurrentCellText: String read FCellBuffer;
+    property CurrentCellText: String read GetCurrentCell;
     // The maximum number of columns found in the stream:
     // The maximum number of columns found in the stream:
     property MaxColCount: Integer read FMaxColCount;
     property MaxColCount: Integer read FMaxColCount;
     // Does the parser own the stream ? If true, a previous stream is freed when set or when parser is destroyed.
     // Does the parser own the stream ? If true, a previous stream is freed when set or when parser is destroyed.
@@ -193,6 +198,28 @@ const
   WhitespaceChars = [HTAB, SPACE];
   WhitespaceChars = [HTAB, SPACE];
   LineEndingChars = [CR, LF];
   LineEndingChars = [CR, LF];
 
 
+Procedure AppendStr(Var Dest : RawByteString; Src : RawByteString); inline;
+
+begin
+  Dest:=Dest+Src;
+end;
+
+procedure RemoveTrailingChars(VAR S: RawByteString; const CSet: TSysCharset);
+
+VAR I,J: LONGINT;
+
+Begin
+ I:=Length(S);
+ IF (I>0) Then
+  Begin
+   J:=I;
+   While (j>0) and (S[J] IN CSet) DO DEC(J);
+   IF J<>I Then
+    SetLength(S,J);
+  End;
+End;
+
+
 // The following implementation of ChangeLineEndings function originates from
 // The following implementation of ChangeLineEndings function originates from
 // Lazarus CodeTools library by Mattias Gaertner. It was explicitly allowed
 // Lazarus CodeTools library by Mattias Gaertner. It was explicitly allowed
 // by Mattias to relicense it under modified LGPL and include into CsvDocument.
 // by Mattias to relicense it under modified LGPL and include into CsvDocument.
@@ -261,6 +288,21 @@ end;
 
 
 { TCSVHandler }
 { TCSVHandler }
 
 
+function TCSVHandler.GetDelimiter: TCSVChar;
+begin
+  Result:=FDelimiter;
+end;
+
+function TCSVHandler.GetLineEnding: String;
+begin
+  Result:=UTF8Decode(FLineEnding);
+end;
+
+function TCSVHandler.GetQuoteChar: TCSVChar;
+begin
+  Result:=FQuoteChar;
+end;
+
 procedure TCSVHandler.SetDelimiter(const AValue: TCSVChar);
 procedure TCSVHandler.SetDelimiter(const AValue: TCSVChar);
 begin
 begin
   if FDelimiter <> AValue then
   if FDelimiter <> AValue then
@@ -270,6 +312,11 @@ begin
   end;
   end;
 end;
 end;
 
 
+procedure TCSVHandler.SetLineEnding(AValue: String);
+begin
+  FLineEnding:=UTF8ENcode(AValue)
+end;
+
 procedure TCSVHandler.SetQuoteChar(const AValue: TCSVChar);
 procedure TCSVHandler.SetQuoteChar(const AValue: TCSVChar);
 begin
 begin
   if FQuoteChar <> AValue then
   if FQuoteChar <> AValue then
@@ -327,6 +374,11 @@ begin
   FMaxColCount := 0;
   FMaxColCount := 0;
 end;
 end;
 
 
+function TCSVParser.GetCurrentCell: String;
+begin
+  Result:=FCellBuffer
+end;
+
 procedure TCSVParser.SkipEndOfLine;
 procedure TCSVParser.SkipEndOfLine;
 begin
 begin
   // treat LF+CR as two linebreaks, not one
   // treat LF+CR as two linebreaks, not one
@@ -350,7 +402,7 @@ end;
 
 
 procedure TCSVParser.NextChar;
 procedure TCSVParser.NextChar;
 begin
 begin
-  if FSourceStream.Read(FCurrentChar, CsvCharSize) < CsvCharSize then
+  if FSourceStream.Read(FCurrentChar, SizeOf(FCurrentChar)) < SizeOf(FCurrentChar) then
   begin
   begin
     FCurrentChar := #0;
     FCurrentChar := #0;
     EndOfFile := True;
     EndOfFile := True;
@@ -544,10 +596,13 @@ end;
 procedure TCSVBuilder.AppendStringToStream(const AString: String; AStream: TStream);
 procedure TCSVBuilder.AppendStringToStream(const AString: String; AStream: TStream);
 var
 var
   StrLen: Integer;
   StrLen: Integer;
+  S : AnsiString;
+
 begin
 begin
-  StrLen := Length(AString);
+  S:=aString;
+  StrLen := Length(S);
   if StrLen > 0 then
   if StrLen > 0 then
-    AStream.WriteBuffer(AString[1], StrLen);
+    AStream.WriteBuffer(S[1], StrLen);
 end;
 end;
 
 
 function TCSVBuilder.QuoteCSVString(const AValue: String): String;
 function TCSVBuilder.QuoteCSVString(const AValue: String): String;
@@ -622,7 +677,7 @@ var
   CellValue: String;
   CellValue: String;
 begin
 begin
   if FNeedLeadingDelimiter then
   if FNeedLeadingDelimiter then
-    FOutputStream.WriteBuffer(FDelimiter, CsvCharSize);
+    FOutputStream.WriteBuffer(FDelimiter, SizeOf(FDelimiter));
 
 
   CellValue := ChangeLineEndings(AValue, FLineEnding);
   CellValue := ChangeLineEndings(AValue, FLineEnding);
   CellValue := QuoteCSVString(CellValue);
   CellValue := QuoteCSVString(CellValue);