diff options
Diffstat (limited to 'packages/fcl-base/src/csvreadwrite.pp')
-rw-r--r-- | packages/fcl-base/src/csvreadwrite.pp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/packages/fcl-base/src/csvreadwrite.pp b/packages/fcl-base/src/csvreadwrite.pp index 4c68f151ff..32f195d411 100644 --- a/packages/fcl-base/src/csvreadwrite.pp +++ b/packages/fcl-base/src/csvreadwrite.pp @@ -92,12 +92,16 @@ Type { TCSVParser } + TCSVByteOrderMark = (bomNone, bomUTF8, bomUTF16LE, bomUTF16BE); + TCSVParser = class(TCSVHandler) private FFreeStream: Boolean; // fields FSourceStream: TStream; FStrStreamWrapper: TStringStream; + FBOM: TCSVByteOrderMark; + FDetectBOM: Boolean; // parser state EndOfFile: Boolean; EndOfLine: Boolean; @@ -140,6 +144,10 @@ Type 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. Property FreeStream : Boolean Read FFreeStream Write FFreeStream; + // Return BOM found in file + property BOM: TCSVByteOrderMark read FBOM; + // Detect whether a BOM marker is present. If set to True, then BOM can be used to see what BOM marker there was. + property DetectBOM: Boolean read FDetectBOM write FDetectBOM default false; end; // Sequential output to CSV stream @@ -441,9 +449,32 @@ begin end; procedure TCSVParser.ResetParser; +var + b: packed array[0..2] of byte; + n: Integer; begin ClearOutput; FSourceStream.Seek(0, soFromBeginning); + if FDetectBOM then + begin + FSourceStream.ReadBuffer(b[0], 3); + if (b[0] = $EF) and (b[1] = $BB) and (b[2] = $BF) then begin + FBOM := bomUTF8; + n := 3; + end else + if (b[0] = $FE) and (b[1] = $FF) then begin + FBOM := bomUTF16BE; + n := 2; + end else + if (b[0] = $FF) and (b[1] = $FE) then begin + FBOM := bomUTF16LE; + n := 2; + end else begin + FBOM := bomNone; + n := 0; + end; + FSourceStream.Seek(n, soFromBeginning); + end; EndOfFile := False; NextChar; end; |