Menu

[r3166]: / trunk / Src / UMainDBFileReader.pas  Maximize  Restore  History

Download this file

151 lines (132 with data), 4.3 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
{
* This Source Code Form is subject to the terms of the Mozilla Public License,
* v. 2.0. If a copy of the MPL was not distributed with this file, You can
* obtain one at http://mozilla.org/MPL/2.0/
*
* Copyright (C) 2005-2012, Peter Johnson (www.delphidabbler.com).
*
* $Rev$
* $Date$
*
* Implements class that can read files from main database using correct
* encoding.
}
unit UMainDBFileReader;
interface
uses
// Delphi
SysUtils,
// Project
UEncodings, UIStringList;
type
/// <summary>
/// Loads files from main database, taking into account file encoding.
/// </summary>
/// <remarks>
/// All files in database folder are assumed to have the same encoding. Only
/// one file is tested.
/// </remarks>
TMainDBFileReader = class(TObject)
strict private
var
/// <summary>Encoding to use when reading text files.</summary>
fEncoding: TEncoding;
/// <summary>
/// Detects encoding used by specified file.
/// </summary>
/// <param name="FileName">string [in] Name of file.</param>
/// <returns>Required TEncoding instance. Callers should free this instance
/// if it not a standard encoding.</returns>
/// <remarks>
/// Main database files created by CodeSnip v3 and earlier use the Default
/// encoding while those created by v4 use UTF-8 files that have the UTF-8
/// preamble.
/// </remarks>
function GetFileEncoding(const FileName: string): TEncoding;
public
/// <summary>
/// Object constructor. Sets up object to use encoding used for given
/// specimen file.
/// </summary>
constructor Create(const SpecimenFile: string);
/// <summary>
/// Object destructor. Tears down object.
/// </summary>
destructor Destroy; override;
/// <summary>
/// Reads all text from a text file using known encoding.
/// </summary>
/// <param name="FileName">string [in] Name of text file to read.</param>
/// <returns>String containing contents of file.</returns>
function ReadAllText(const FileName: string): string;
/// <summary>
/// Reads all lines from a text file using known encoding.
/// </summary>
/// <param name="FileName">string [in] Name of text file to read.</param>
/// <returns>IStringList object containing lines from file.</returns>
function ReadAllStrings(const FileName: string): IStringList;
end;
implementation
uses
// Delphi
Classes,
// Project
UIOUtils;
{ TMainDBFileReader }
constructor TMainDBFileReader.Create(const SpecimenFile: string);
begin
inherited Create;
fEncoding := GetFileEncoding(SpecimenFile);
end;
destructor TMainDBFileReader.Destroy;
begin
TEncodingHelper.FreeEncoding(fEncoding);
inherited;
end;
function TMainDBFileReader.GetFileEncoding(const FileName: string): TEncoding;
/// Checks if two byte arrays are equal.
function BytesMatch(const BA1, BA2: TBytes): Boolean;
var
I: Integer;
begin
if Length(BA1) <> Length(BA2) then
Exit(False);
for I := 0 to Pred(Length(BA1)) do
if BA1[I] <> BA2[I] then
Exit(False);
Result := True;
end;
var
FS: TFileStream; // stream onto file
Buffer: TBytes; // buffer containing first few bytes of file
UTF8Preamble: TBytes; // bytes of UTF-8 preamble
begin
UTF8Preamble := TEncoding.UTF8.GetPreamble;
Assert(Length(UTF8Preamble) > 0,
ClassName + '.GetFileEncoding: UTF-8 preamble has zero length');
FS := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
try
if FS.Size >= Length(UTF8Preamble) then
begin
// read first few bytes of file to see if they match UTF-8 preamble
SetLength(Buffer, Length(UTF8Preamble));
FS.ReadBuffer(Pointer(Buffer)^, Length(Buffer));
if BytesMatch(Buffer, UTF8Preamble) then
Exit(TEncoding.UTF8);
end;
finally
FS.Free;
end;
Result := TEncoding.Default;
end;
function TMainDBFileReader.ReadAllStrings(const FileName: string): IStringList;
begin
Result := TIStringList.Create(
TFileIO.ReadAllLines(FileName, fEncoding, True)
);
end;
function TMainDBFileReader.ReadAllText(const FileName: string): string;
begin
Result := TFileIO.ReadAllText(FileName, fEncoding, True);
end;
end.
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.