VERY VERY USEFUL FILE OPEN/DATA LOADING AND SAVE ROUTINES
****************************************************************
LOAD A HUGE ASCII TEXT WORD LIST INTO MEMORY...
const
{currently (20/01/98) the size of the dictionary file in bytes is
322811 so let's make the size of the array to store that data in
memory just a touch bigger shall we... also as of 20/01/98 there
are 36146 words in the dictionary too...}
bufSize = 350000;
{IN OBJECT/CLASS DECLARATION...}
private
{ Private declarations }
dictBuf: array[1..bufSize] of Char;
{AND THEN THE CRUCIAL PROCEDURE...}
procedure TForm1.LoadDictionary;
{low-level reading of 'dictionary' text file to minimise RAM usage...}
{put the whole file into the 'dictBuf' variable as one huge text stream}
var
dictFile: TextFile;
numLines: Integer;
ch: Char;
i: Integer;
begin
i := 1;
{associate a 'handle' variable with the file we want to open}
AssignFile(dictFile, 'DICT.ASC');
{open the dictionary file with the Reset procedure}
Reset(dictFile);
while (not Eof(DictFile)) do
begin
Read(dictFile, ch);
dictBuf[i] := ch;
Inc(i);
end;
CloseFile(dictFile);
end;
666****************************************************************
procedure TPerformanceDBMS.LoadData(redundant: Integer);
{use the inbuilt LoadFromFile() method of a TString object to load data,
and then put the data immediately into a string variable and hand it to
another function to convert that (text-format) data into SeatArray records}
var
tempString: String;
longText: TStrings;
begin
longText := TStringList.Create;
with UserInterface.OpenDialog do
begin
if UserInterface.OpenDialog.Execute then
begin
longText.LoadFromFile(UserInterface.OpenDialog.Filename);
tempString := longText[0];
if not CheckValidFile(tempString) then
begin
ShowMessage('This file is unusable. Either it is a corrupted data file or else it is not booking data at all');
end
else
begin
SeatBookings.StringToRecords(tempString);
end;
end; {if}
end; {with}
longText.Free;
end;
procedure TPerformanceDBMS.SaveData(redundant: Integer);
{here we call SeatBookings.RecordsToString() to convert records to text}
{and then we put that text into a TString type of object (that only exists}
{for the duration of the procedure) in order to take advantage of the inbuilt}
{SaveToFile() method of TString list objects...}
var
dateAndTime: String;
dataString: String;
userFilename: String;
longText: TStrings;
begin
userFilename := '';
longText := TStringList.Create;
dateAndTime := MakeOrEditBForm.DateLabel.Caption;
dateAndTime := MakeFileName(dateAndTime);
{append M for Matinee or E for Evening to dateAndTime}
if (MakeOrEditBForm.TimeLabel.Caption = 'Matinee') then
begin
dateAndTime := dateAndTime + 'M';
end
else if (MakeOrEditBForm.TimeLabel.Caption = 'Evening') then
begin
dateAndTime := dateAndTime + 'E';
end
else
begin
{the next line should NEVER execute...}
dateAndTime := 'DATETIME.BAD';
end;
dateAndTime := dateAndTime + '.TXT';
dateAndTime := UpperCase(dateAndTime);
UserInterface.SaveDialog.Filename := dateAndTime;
with UserInterface.SaveDialog do
begin
if UserInterface.SaveDialog.Execute then
begin
dataString := SeatBookings.RecordsToString(redundant);
longText.Add(dataString);
{code here ensures that when the user is presented with as 'Save' dialog}
{box, the 'proper' filename appears in the box by default. this filename}
{will include date/time info, as in 01JAN98M, BUT we also give the user}
{the opportunity to CHANGE that filename if they want to, so that after}
{setting the dialog box filename above, and then 'executing' the dialog}
{box, we can check in the next line to see if filename has a new value}
{and if it has, we must use the new one...}
userFilename := UserInterface.SaveDialog.Filename;
userFilename := UpperCase(userFilename);
longText.SaveToFile(userFilename);
end;
end;
longText.Free;
end;
******************************************************************************
HANDLING AN ASCII TEXT FILE IN COMMA-DELIMITED FORMAT...
SEE ALSO CROSSWORD PROGRAM, MAIN UNIT, WriteBLKFile() and ReadBLKFile() procedures
(they work well to write and save data in comma-delimited ASCII format WITH HEADER info)
procedure TSeatBookings.StringToRecords(dataString: String);
{parse out record data from the comma-delimited text file and place details}
{into SeatArray... records are in tuples of customer_name and booked...}
{and remember that performance date and performance time are the first two}
{fields in the text (which will have been loaded from disc)...}
var
redundant: Integer;
i,j,pos: Integer;
dateString, timeString: String;
thisField : String;
len,width: Integer;
row : Char;
column : Integer;
longString: string;
begin
len := Length(dataString);
i := 1;
j := 1;
pos := 1;
{firstly, extract the date and time...}
while not (dataString[i] = ',') do
begin
Inc(i);
if i >= len then Break;
end;
dateString := Copy(dataString, pos, i-pos);
{skip a comma by incrementing i...}
Inc(i);
pos := i;
while not (dataString[i] = ',') do
begin
Inc(i);
if i >= len then Break;
end;
timeString := Copy(dataString, pos, i-pos);
{skip a comma by incrementing i...}
Inc(i);
pos := i;
{and then extract the records proper...}
for row := 'A' to last_row do
begin
for column := 1 to last_column do
begin
pos := i;
while not (dataString[i] = ',') do
begin
Inc(i);
if i >= len then Break;
end;
thisField := Copy(dataString, pos, i-pos);
SeatArray[row,column].customer_name := thisField;
j := 1;
{re-initialise the thisField variable...}
{width := Length(thisField);}
{Delete(thisField,1,width);}
thisField := '';
{skip a comma by incrementing i...}
Inc(i);
pos := i;
while not (dataString[i] = ',') do
begin
Inc(i);
if i >= len then Break;
end;
thisField := Copy(dataString, pos, i-pos);
if thisField = 'T' then
SeatArray[row,column].booked := True;
if thisField = 'F' then
SeatArray[row,column].booked := False;
j := 1;
{re-initialise the thisField variable...}
thisField := '';
{skip a comma by incrementing i...}
Inc(i);
end; {for}
end; {for}
if not (dateString = '') then
begin
SetDate(dateString);
end;
if not (timeString = '') then
begin
SetTime(timeString);
end;
UserInterface.SetAllSeatColours(redundant);
end;
procedure TForm1.OpenButtonClick(Sender: TObject);
{open user-specified file but check that it's not too big}
var
TooBig : Boolean;
begin
TooBig := False;
with OpenDialog do
begin
if Execute then
begin
try
MainMemo.Lines.LoadFromFile(Filename);
except on EInvalidOperation do
TooBig := True;
end; {end try...except}
if TooBig = True then
begin
ShowMessage('This file is too large to load into the Text Editor');
end {if}
else
begin
HistoryList.Add(Filename);
Caption := 'Richards Text Editor - ' +
ExtractFilename(Filename);
SaveDialog.Filename := Filename;
Filename := '';
end; {else}
end; {if}
end; {with}
end;
procedure TForm1.SaveButtonClick(Sender: TObject);
{re-use this code elsewhere}
begin
if (SaveDialog.Filename = '') then
begin
with SaveDialog do
begin
if Execute then
begin
MainMemo.Lines.SaveToFile(Filename);
Caption := 'Richards Text Editor - ' +
ExtractFilename(Filename);
end; {if}
end; {with}
end {if}
else
begin
MainMemo.Lines.SaveToFile(SaveDialog.Filename);
end; {else}
end;
procedure TForm1.SaveAsButtonClick(Sender: TObject);
begin
with SaveDialog do
begin
if Execute then
begin
MainMemo.Lines.SaveToFile(Filename);
Caption := 'Richards Text Editor - ' +
ExtractFilename(Filename);
end;
end;
end;
function TForm1.GetWordsEnd: Integer;
var
len: Integer;
textEnd: Boolean;
begin
len := 1;
textEnd := False;
while ((textEnd = False) and (len < bufSize)) do
begin
if (((dictBuf[len] >= 'A') and (dictBuf[len] <= 'Z')) or
((dictBuf[len] >= 'a') and (dictBuf[len] <= 'z')) or
(dictBuf[len] = ',' )) then
begin
Inc(len);
end
else
begin
textEnd := True;
end;
end;
Result := len;
end;