This is TextFile.m in view mode; [Download] [Up]
/***********************************************************************\
Common class for accessing text files in all Convert programs
Copyright (C) 1993 David John Burrowes
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The author, David John Burrowes, can be reached at:
davidjohn@kira.net.netcom.com
David John Burrowes
1926 Ivy #10
San Mateo, CA 94403-1367
\***********************************************************************/
#import <streams/streams.h>
#import <stdio.h>
#import <string.h> // for strlen
#import "TextFile.h"
// We are assuming our superclass has already imported this. If not, you'll get an
// error below, indicating that this wont work (see LookAtNextCharacter
// #import <streams/streams.h>
@implementation TextFile
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: GetHexByte
// Parameters: none
// Returns: The byte corresponding to the hex values in the file
// Stores: error info
// The byte corresponding to the hex values in the file
// Description:
// This reads in a pair of hex difits, and returns their integer form (i.e reading
// '41' will be returned as the integer 65.
// *WARNING*:
// This assumes it is working as a subclass of a File object that is going to
// have a NXstream open.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Byte) GetHexByte
{
Integer theInt = 0;
Integer num;
[self ResetResults];
if (FileIsOpen == NO)
[self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to read from a closed file"];
else
{
num = NXScanf(TheFile, "%2x", &theInt);
if (num != 1)
[self StoreErrorCode: ERR_BADREAD AndText: "Unable to read a hex value"];
else
[self StoreErrorCode: ERR_OK AndText: "Got the byte just fine"];
}
[self StoreInteger: theInt];
return theInt;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: GetNumber
// Parameters: none
// Returns: The number read from the text file
// Stores: error info
// The number read from the text file
// Description:
// This reads in a series of characters, and converts them to a signed integer
// value.
// *WARNING*:
// This assumes it is working as a subclass of a File object that is going to
// have a NXstream open.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Integer) GetNumber
{
Integer theInt = 0;
Integer num;
[self ResetResults];
if (FileIsOpen == NO)
[self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to read from a closed file"];
else
{
num = NXScanf(TheFile, "%d", &theInt);
if (num != 1)
[self StoreErrorCode: ERR_BADREAD AndText: "Unable to read a hex value"];
else
[self StoreErrorCode: ERR_OK AndText: "Got the byte just fine"];
}
[self StoreInteger: theInt];
return theInt;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: GetCharacter:
// Parameters: none
// Returns: The character found
// Stores: error info
// The character found
// Description:
// This merely reads a character in from the file and returns it, unless an error
// occurrs. Note that if the file is open, our error results are those which
// Read:BytesInto: generates.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Character) GetCharacter
{
Character theBuffer = NullCharacter;
[self ResetResults];
if (FileIsOpen == NO)
[self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to read from a closed file"];
else
{
[self Read: 1 BytesInto: &theBuffer];
if ([self GetErrorCode] != ERR_OK)
{
[self StoreErrorCode: ERR_BADREAD AndText: "Read error. let's call it eof"];
FileLocation = fileAtEOF;
}
else
[self StoreErrorCode: ERR_OK AndText: "OK"];
}
[self StoreCharacter: theBuffer];
return theBuffer;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: LookAtNextCharacter
// Parameters: none
// Returns: The character found
// Stores: error info
// The character found
// Description:
// This locates the next character waiting to be read, and returns it without
// moving past it.
// *WARNING*:
// This assumes it is working as a subclass of a File object that is going to
// have a NXstream open that can do ungetting!!!!!!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- (Character) LookAtNextCharacter
{
Character theCharacter = NullCharacter;
[self ResetResults];
if (FileIsOpen == NO)
[self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to peek at a closed file"];
else
{
if (NXAtEOS(TheFile) == YES)
{
[self StoreErrorCode: ERR_BADREAD AndText: "Read error. let's call it eof"];
FileLocation = fileAtEOF;
}
else
{
//
// NeXT doesn't document what error codes these generate, very well..
//
theCharacter = NXGetc(TheFile);
NXUngetc(TheFile);
[self StoreErrorCode: ERR_OK AndText: "Read the character OK"];
}
}
[self StoreCharacter: theCharacter];
return theCharacter;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: UnGetCharacter
// Parameters: none
// Returns: none
// Stores: error info
// Description:
// Thgis simply ungets whatever the last character got was.
// (due to NeXT limitiations, you can't call this twice in a row to unget the last 2)
// *WARNING*:
// This assumes it is working as a subclass of a File object that is going to
// have a NXstream open that can do ungetting!!!!!!
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- UnGetCharacter
{
[self ResetResults];
if (FileIsOpen == NO)
[self StoreErrorCode: ERR_FILENOTOPEN AndText: "Unable to peek at a closed file"];
else
{
if (NXAtEOS(TheFile) == YES)
{
[self StoreErrorCode: ERR_BADREAD AndText: "Read error. let's call it eof"];
FileLocation = fileAtEOF;
}
else
{
//
// NeXT doesn't document what error codes these generate, very well..
//
NXUngetc(TheFile);
[self StoreErrorCode: ERR_OK AndText: "Ungot it ok"];
}
}
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: WriteText:
// Parameters: the line of text we are to write
// Returns: self
// Description:
// Writes the content6s of theLine out litterally, with no additional fiddling with.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- WriteText: (CString) theLine
{
[self Write: strlen(theLine) BytesFrom: (ByteString) theLine];
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: WriteTextLine:
// Parameters: the line of text we are to write
// Returns: self
// Description:
// This writes out the speciied text, and follows it with a newline.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- WriteTextLine: (CString) theLine
{
[self Write: strlen(theLine) BytesFrom: (ByteString) theLine];
[self Write: 1 BytesFrom: (ByteString) "\n"];
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: WriteTextUsing:WithFormat:
// Parameters: A buffer provided by the caller, a format, and N arguments to be written
// Returns: self
// Stores: nothing (bug)
// Description:
// This writes out a text string given variable arguments
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- WriteTextUsing: (CString) buffer WithFormat: (CString) format, ...;
{
va_list parameter_list;
va_start(parameter_list, format);
vsprintf(buffer, format, parameter_list); // doc implies this does a va_end
[self Write: strlen(buffer) BytesFrom: (ByteString) buffer];
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: AppendFrom:
// Parameters: Another file object (opened)
// Returns: self
// Stores: nothing (bug)
// Description:
// This is a crude little routine that simply takes a file, assumes it is open and in
// place, reads the whole file into memory, and then writs it out into itself.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- AppendFrom: sourceFile
{
Integer size;
ByteString buffer;
size = [sourceFile FileSize];
buffer = NewByteString(size);
[sourceFile MoveTo: 0];
[sourceFile Read: size BytesInto: buffer];
[self Write: size BytesFrom: buffer];
FreeByteString(buffer);
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: WriteInteger:
// Parameters:
// An integer
// Returns: self
// Stores: none explicitly (subcalls may)
// Description:
// This simply writes out an integer with a trailing space. ooh ahh.
// Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- WriteInteger: (Integer) theInt
{
CString temp = NewCString(15);
[self WriteTextUsing: temp WithFormat: "%d ", theInt];
FreeCString(temp);
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: WritePositiveInteger:
// Parameters:
// An integer
// Returns: self
// Stores: none explicitly (subcalls may)
// Description:
// This simply writes out a positive integer with a trailing space. yawn.
// Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- WritePositiveInteger: (PositiveInteger) theInt
{
CString temp = NewCString(15);
[self WriteTextUsing: temp WithFormat: "%u ", theInt];
FreeCString(temp);
return self;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Method: WriteReal:
// Parameters: A real number
// Returns: self
// Stores: none explicitly (subcalls may)
// Description:
// This simply writes out a Real number with a trailing space..
// Bugs:
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- WriteReal: (Real) theReal
{
CString temp = NewCString(31);
[self WriteTextUsing: temp WithFormat: "%.15f ", theReal];
FreeCString(temp);
return self;
}
@endThese are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.