Koryn's Units
Koryn Grant, Macintosh Developer



pascalflavouredmac picture

KGTextFiles

Author: Koryn Grant.
Copyright: 1998 Koryn Grant
Email: koryn@kagi.com
Date: 10 June 1998

Summary

KGTextFiles is an Object Pascal unit for CodeWarrior that implements a TextFileObject for easy access to a text file. It can handle text files in Mac, DOS or unix format and provides methods for reading the file, retrieving single lines of text as strings or text, searching for strings or text, appending strings or text and writing the text file. KGTextFiles requires MyAssertions from Peter Lewis' PNL Libraries, available from http://www.stairways.com/ .

Environment

Although KGTextFiles is provided as a unit, it is still environment-dependent. In particular, I use the Metrowerks scope keywords (public/protected/private) in object declarations.

Conditions of use

You may use KGTextFiles in any project you wish, provided that an acknowledgement is made in your application's AboutBox and ReadMe. A suitable acknowledgement would be

"YourApplication uses KGTextFiles, written by and copyright 1998 Koryn Grant."

Complimentary copies of any freeware, shareware or commercial applications that use KGTextFiles would be appreciated but are not required.

Unmodified copies of "KGTextFiles.p" may be freely distributed provided that they are accompanied by the file "About KGTextFiles". Modified copies may not be distributed without the author's permission.

Disclaimer: KGTextFiles is provided as is, with no warranties about its suitability for any purpose whatsoever.

How to use KGTextFiles

The procedure for using a TextFileObject to read a file is as follows:

  1. Initialise the TextFileObject.
  2. Give the TextFileObject the FSSpec of the file you wish it to read from.
  3. Tell the TextFileObject to read the file. This stores the file into a buffer in memory and sets up the internal data structures used by the access routines.
  4. Retrieve text by calls to the methods.

The procedure for using a TextFileObject to write a file is as follows:

  1. Initialise the TextFileObject.
  2. Clear the text buffer (only necessary if the text buffer has been used previously).
  3. Append strings or text to the buffer.
  4. Give the TextFileObject the FSSpec you wish it to write to.
  5. Tell the TextFileObject to write the file to the given FSSpec.

For further examples of how TextFileObjects can be used in an application, check out the source code to SlashMUD, available at http://www.ukc.ac.uk/IMS/maths/people/K.D.Grant/SlashMUD/ .

Most TextFileObject methods return error codes in the event that an error occurs. If the variable kTextFileDebugging is true additional checking is performed. Projects that include KGTextFiles can choose the setting of kTextFileDebugging by setting _KGTextFileDebugging_ to be 1 (true) or 0 (false). If _KGTextFileDebugging_ is not defined then kTextFileDebugging defaults to true.

KGTextFiles interface

Error codes:

kTextFileNoError = 0;
kTextFileOutOfMemoryError = 1;
kTextFileNoSuchLineError = 2;
kTextFileInvalidFileError = 3;
kTextFileAlreadyExistsError = 4;
kTextFileInternalError = 5;
kTextFileReadError = 6;
kTextFileEmptyTextError = 7;
kTextFileAppendError = 8;
kTextFileLongLineError = 9;
kTextFileLineNotFoundError = 10;

TextFileObject = object
	{ Private data fields. }
	private FileSpec : FSSpec;               { FSSpec for the file. }
	private TextBuffer : TextHandle;         { Buffer for the file's text. }
	private LineInfo : LineBreakHandle;      { Array pointing to the beginning of lines. }
	private TextLength : SInt32;             { Number of characters in the text. }
	private TextLines : SInt32;              { Number of lines of text. }
	private LineBreakStyle : SInt16;         { Mac (CR), unix (LF) or DOS (CR/LF). }
	private Name : Str255;                   { The name of the text file. }
	
	{ Methods. }
	procedure Initialise;
	procedure Finished;
	function  ReadFile : SInt16;
	function  WriteFile : SInt16;
	procedure CountNumberOfLines;
	procedure SetUpLineInfo;
	procedure SetFileSpec(theFSSpec : FSSpec);
	function  GetFileSpec : FSSpec;
	function  GetNumberOfLines : SInt32;
	function  GetLineLength(theIndex : SInt32; var lineLength : SInt32) : SInt16;
	function  GetLineNumber(theIndex : SInt32; var theLine : TextHandle) : SInt16;
	function  GetLineAsString(theIndex : SInt32; var theString : Str255) : SInt16;
	function  GetLineContainingString(searchString : ConstStr255Param; var lineNumber : SInt32) : SInt16;
	function  GetMatchingLine(searchString : ConstStr255Param; var lineNumber : SInt32) : SInt16;
	function  ConvertOffsetToLineNumber(findOffset : SInt32; var returnLine : SInt32) : SInt16;
	function  GetNumberOfMatches(searchText : TextHandle; var returnMatches : SInt32) : SInt16;
	procedure ClearTextBuffer;
	function  AppendText(theText : TextHandle) : SInt16;
	function  AppendString(theString : Str255) : SInt16;
	procedure GetName(var theName : Str255);
	end;
		{ of TextFileObject }

TextFileObject methods

procedure Initialise;

Initialises the internal data structures.

procedure Finished;

Disposes of memory used by the TextFileObject and the object itself. After calling this method all references to the TextFileObject are invalid.

function ReadFile : SInt16;

This method reads the data fork of the TextFileObject's FSSpec (which must be set via a call to SetFileSpec before calling ReadFile) into a buffer in memory. The file is closed after being read into memory

Result codes:

function WriteFile : SInt16;

This method is a request for the TextFileObject to write the contents of its text buffer to its associated FSSpec.

Result codes:

procedure CountNumberOfLines;

This method is used internally to calculate the number of lines of text in the file and determine which style of line break (Mac/DOS/unix) the file uses. Under normal circumstances there is no need to call this method directly.

procedure SetUpLineInfo;

This method is used internally to set up data structures that hold information about the position and length of the lines of text. Under normal circumstances there is no need to call this method directly.

procedure SetFileSpec(theFSSpec : FSSpec);

This method associates the given FSSpec with the TextFileObject, and should be called before ReadFile or WriteFile.

function GetFileSpec : FSSpec;

This method returns the FSSpec currently associated with the TextFileObject.

function GetNumberOfLines : SInt32;

This method returns the number of lines of text in the text file. Its primary use is in for-loops where you wish to iterate over the lines of text.

function GetLineLength(theIndex : SInt32; var lineLength : SInt32) : SInt16;

This method puts the size of the line indexed by theIndex in the variable lineLength, and returns an error code.

Result codes:

function GetLineNumber(theIndex : SInt32; var theLine : TextHandle) : SInt16;

This method puts the line referred to by theIndex in theLine as a handle to text. theLine is allocated by GetLineNumber. It is the responsibility of the caller to dispose of it.

Result codes:

function GetLineAsString(theIndex : SInt32; var theString : Str255) : SInt16;

This method is essentially the same as GetLineNumber, except that it returns the desired line as a string rather than a handle to text (if possible).

Result codes are as for GetLineNumber, plus:

function GetLineContainingString(searchString : ConstStr255Param; var lineNumber : SInt32; startLine : SInt32) : SInt16;

This method looks for a line that contains the searchString, beginning at the given startLine. If found, the lineNumber of the desired string is returned in lineNumber.

Result codes:

function GetMatchingLine(searchString : ConstStr255Param; var lineNumber : SInt32; startLine : SInt32) : SInt16;

This method is essentially the same as GetLineContainingString, except that it looks for a line that contains only the searchString. Internally it adds an appropriate end-of-line delimiter to the searchString and calls GetLineContainingString with this new string.

Result codes are as for GetLineContainingString.

function ConvertOffsetToLineNumber(findOffset : SInt32; var returnLine : SInt32) : SInt16;

This method is used internally to convert the findOffset, an offset from the beginning of the text buffer, into the line number of the line containing that offset. On normal completion returnLine contains the desired line number. The search uses information about the lines gathered when the file was read and excludes end-of-line delimiters. Thus the search will fail if findOffset refers to an end-of-line delimiter. The line number is found by a binary search, with a counter that triggers an emergency exit when it reaches the total number of lines of text (i.e. when findOffset refers to an end-of-line delimiter). Under normal circumstances there is no need to call this method directly.

Result codes:

function GetNumberOfMatches(searchText : TextHandle; var returnMatches : SInt32) : SInt16;

This method searches the TextFileObject's text buffer for the text referenced by the TextHandle, puts the number of matches in returnMatches and returns an error code.

Result codes:

procedure ClearTextBuffer;

This method disposes of the TextFileObject's text buffer.

function AppendText(theText : TextHandle) : SInt16;

This method appends the given text to the TextFileObject's text buffer. If the text buffer does not exist, it is created.

Result codes:

function AppendString(theString : Str255) : SInt16;

This method appends the given string plus an appropriate end-of-line delimiter to the TextFileObject's text buffer. If the text buffer does not exist, it is created.

Result codes:

procedure GetName(var theName : Str255);

This method returns the name of the text file in theName.

Credits

KGTextFiles uses MyAssertions by Peter N Lewis.

Download KGTextFiles



Copyright ©1998 Koryn Grant.