1996-01-24 14:09:55 +00:00
|
|
|
|
/* Implementation of GNU Objective-C class for streaming C types and indentatn
|
1997-01-12 18:49:08 +00:00
|
|
|
|
Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
|
1996-01-24 14:09:55 +00:00
|
|
|
|
|
1996-04-17 20:17:45 +00:00
|
|
|
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
1996-01-24 14:09:55 +00:00
|
|
|
|
Date: July 1994
|
|
|
|
|
|
1996-05-12 00:56:10 +00:00
|
|
|
|
This file is part of the GNUstep Base Library.
|
1996-01-24 14:09:55 +00:00
|
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
|
|
This library 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
|
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
|
License along with this library; if not, write to the Free
|
|
|
|
|
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
|
*/
|
|
|
|
|
|
1996-04-17 15:34:35 +00:00
|
|
|
|
#include <gnustep/base/preface.h>
|
1996-04-17 15:23:00 +00:00
|
|
|
|
#include <gnustep/base/CStream.h>
|
|
|
|
|
#include <gnustep/base/NSString.h>
|
|
|
|
|
#include <gnustep/base/StdioStream.h>
|
|
|
|
|
#include <gnustep/base/CoderPrivate.h> /* for SIGNATURE_FORMAT_STRING */
|
1996-01-24 14:09:55 +00:00
|
|
|
|
#include <Foundation/NSException.h>
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
|
|
id CStreamSignatureMalformedException = @"CStreamSignatureMalformedException";
|
|
|
|
|
id CStreamSignatureMismatchException = @"CStreamSignatureMismatchException";
|
|
|
|
|
|
|
|
|
|
@implementation CStream
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Encoding/decoding C values */
|
|
|
|
|
|
|
|
|
|
- (void) encodeValueOfCType: (const char*) type
|
|
|
|
|
at: (const void*) d
|
1996-11-24 17:30:39 +00:00
|
|
|
|
withName: (NSString*) name;
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
[self subclassResponsibility:_cmd];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) decodeValueOfCType: (const char*) type
|
|
|
|
|
at: (void*) d
|
1996-11-24 17:30:39 +00:00
|
|
|
|
withName: (NSString* *) namePtr;
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
[self subclassResponsibility:_cmd];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Signature methods. */
|
|
|
|
|
|
|
|
|
|
- (void) writeSignature
|
|
|
|
|
{
|
|
|
|
|
/* Careful: the string should not contain newlines. */
|
|
|
|
|
[stream writeFormat: SIGNATURE_FORMAT_STRING,
|
1996-04-17 18:59:34 +00:00
|
|
|
|
STRINGIFY(GNUSTEP_BASE_PACKAGE_NAME),
|
|
|
|
|
GNUSTEP_BASE_MAJOR_VERSION,
|
|
|
|
|
GNUSTEP_BASE_MINOR_VERSION,
|
|
|
|
|
GNUSTEP_BASE_SUBMINOR_VERSION,
|
1996-01-24 14:09:55 +00:00
|
|
|
|
object_get_class_name(self),
|
|
|
|
|
format_version];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ (void) readSignatureFromStream: s
|
|
|
|
|
getClassname: (char *) name
|
|
|
|
|
formatVersion: (int*) version
|
|
|
|
|
{
|
|
|
|
|
int got;
|
1996-03-06 13:51:48 +00:00
|
|
|
|
char package_name[64];
|
|
|
|
|
int major_version;
|
|
|
|
|
int minor_version;
|
|
|
|
|
int subminor_version;
|
1996-01-24 14:09:55 +00:00
|
|
|
|
|
|
|
|
|
got = [s readFormat: SIGNATURE_FORMAT_STRING,
|
1996-03-06 13:51:48 +00:00
|
|
|
|
&(package_name[0]),
|
|
|
|
|
&major_version,
|
|
|
|
|
&minor_version,
|
|
|
|
|
&subminor_version,
|
|
|
|
|
name,
|
|
|
|
|
version];
|
|
|
|
|
if (got != 6)
|
1996-01-24 14:09:55 +00:00
|
|
|
|
[NSException raise:CStreamSignatureMalformedException
|
|
|
|
|
format: @"CStream found a malformed signature"];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Initialization methods */
|
|
|
|
|
|
|
|
|
|
/* This is the hidden designated initializer. Do not call it yourself. */
|
|
|
|
|
- _initWithStream: (id <Streaming>) s
|
|
|
|
|
formatVersion: (int)version
|
|
|
|
|
{
|
|
|
|
|
[super init];
|
|
|
|
|
[s retain];
|
|
|
|
|
stream = s;
|
|
|
|
|
format_version = version;
|
|
|
|
|
indentation = 0;
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
1997-01-12 18:49:08 +00:00
|
|
|
|
/* This is the designated initializer for reading. */
|
|
|
|
|
- _initForReadingFromPostSignatureStream: (id <Streaming>)s
|
|
|
|
|
withFormatVersion: (int)version
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
[self _initWithStream: s
|
1996-01-25 16:54:14 +00:00
|
|
|
|
formatVersion: version];
|
1997-01-12 18:49:08 +00:00
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- initForReadingFromStream: (id <Streaming>) s
|
|
|
|
|
withFormatVersion: (int)version
|
|
|
|
|
{
|
|
|
|
|
[self notImplemented: _cmd];
|
|
|
|
|
/* xxx Why this condition? -mccallum */
|
1996-01-24 14:09:55 +00:00
|
|
|
|
if ([stream streamPosition] != 0)
|
|
|
|
|
{
|
|
|
|
|
char name[128]; /* max class name length. */
|
|
|
|
|
int version;
|
|
|
|
|
[[self class] readSignatureFromStream: stream
|
|
|
|
|
getClassname: name
|
|
|
|
|
formatVersion: &version];
|
|
|
|
|
if (!strcmp(name, object_get_class_name(self))
|
|
|
|
|
|| version != format_version)
|
|
|
|
|
{
|
|
|
|
|
[NSException raise: CStreamSignatureMismatchException
|
|
|
|
|
format: @"CStream found a mismatched signature"];
|
|
|
|
|
}
|
1997-01-12 18:49:08 +00:00
|
|
|
|
[self _initForReadingFromPostSignatureStream: s
|
|
|
|
|
withFormatVersion: version];
|
1996-01-24 14:09:55 +00:00
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ cStreamReadingFromStream: (id <Streaming>) s
|
|
|
|
|
{
|
|
|
|
|
char name[128]; /* Maximum class name length. */
|
|
|
|
|
int version;
|
|
|
|
|
id new_cstream;
|
|
|
|
|
|
|
|
|
|
[self readSignatureFromStream: s
|
|
|
|
|
getClassname: name
|
|
|
|
|
formatVersion: &version];
|
|
|
|
|
new_cstream = [[objc_lookup_class(name) alloc]
|
1997-01-12 18:49:08 +00:00
|
|
|
|
_initForReadingFromPostSignatureStream: s
|
|
|
|
|
withFormatVersion: version];
|
1996-01-24 14:09:55 +00:00
|
|
|
|
return [new_cstream autorelease];
|
|
|
|
|
}
|
|
|
|
|
|
1996-11-24 17:30:39 +00:00
|
|
|
|
+ cStreamReadingFromFile: (NSString*) filename
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
return [self cStreamReadingFromStream:
|
|
|
|
|
[StdioStream streamWithFilename: filename fmode: "r"]];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* This is a designated initializer for writing. */
|
|
|
|
|
- initForWritingToStream: (id <Streaming>) s
|
1996-01-25 16:54:14 +00:00
|
|
|
|
withFormatVersion: (int)version
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
[self _initWithStream: s
|
1996-01-25 16:54:14 +00:00
|
|
|
|
formatVersion: version];
|
1996-01-24 14:09:55 +00:00
|
|
|
|
[self writeSignature];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- initForWritingToStream: (id <Streaming>) s
|
|
|
|
|
{
|
1996-03-18 13:41:30 +00:00
|
|
|
|
return [self initForWritingToStream: s
|
|
|
|
|
withFormatVersion: [[self class] defaultFormatVersion]];
|
1996-01-24 14:09:55 +00:00
|
|
|
|
}
|
|
|
|
|
|
1996-11-24 17:30:39 +00:00
|
|
|
|
- initForWritingToFile: (NSString*) file
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
return [self initForWritingToStream:
|
|
|
|
|
[StdioStream streamWithFilename: file fmode: "w"]];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
+ cStreamWritingToStream: (id <Streaming>) s
|
|
|
|
|
{
|
|
|
|
|
return [[[self alloc] initForWritingToStream: s]
|
|
|
|
|
autorelease];
|
|
|
|
|
}
|
|
|
|
|
|
1996-11-24 17:30:39 +00:00
|
|
|
|
+ cStreamWritingToFile: (NSString*) filename;
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
return [[[self alloc] initForWritingToFile: filename]
|
|
|
|
|
autorelease];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Encoding/decoding indentation */
|
|
|
|
|
|
1996-11-24 17:30:39 +00:00
|
|
|
|
- (void) encodeWithName: (NSString*) name
|
1996-01-24 15:06:04 +00:00
|
|
|
|
valuesOfCTypes: (const char *) types, ...
|
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
[self encodeName: name];
|
|
|
|
|
va_start (ap, types);
|
|
|
|
|
while (*types)
|
|
|
|
|
{
|
|
|
|
|
[self encodeValueOfCType: types
|
|
|
|
|
at: va_arg(ap, void*)
|
|
|
|
|
withName: NULL];
|
|
|
|
|
types = objc_skip_typespec (types);
|
|
|
|
|
}
|
|
|
|
|
va_end (ap);
|
|
|
|
|
}
|
|
|
|
|
|
1996-11-24 17:30:39 +00:00
|
|
|
|
- (void) decodeWithName: (NSString* *)name
|
1996-01-24 15:06:04 +00:00
|
|
|
|
valuesOfCTypes: (const char *)types, ...
|
|
|
|
|
{
|
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
|
|
[self decodeName: name];
|
|
|
|
|
va_start (ap, types);
|
|
|
|
|
while (*types)
|
|
|
|
|
{
|
|
|
|
|
[self decodeValueOfCType: types
|
|
|
|
|
at: va_arg (ap, void*)
|
|
|
|
|
withName: NULL];
|
|
|
|
|
types = objc_skip_typespec (types);
|
|
|
|
|
}
|
|
|
|
|
va_end (ap);
|
|
|
|
|
}
|
|
|
|
|
|
1996-01-24 14:09:55 +00:00
|
|
|
|
- (void) encodeIndent
|
|
|
|
|
{
|
|
|
|
|
/* Do nothing */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) encodeUnindent
|
|
|
|
|
{
|
|
|
|
|
/* Do nothing */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) decodeIndent
|
|
|
|
|
{
|
|
|
|
|
/* Do nothing */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) decodeUnindent
|
|
|
|
|
{
|
|
|
|
|
/* Do nothing */
|
|
|
|
|
}
|
|
|
|
|
|
1996-11-24 17:30:39 +00:00
|
|
|
|
- (void) encodeName: (NSString*) n
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
/* Do nothing */
|
|
|
|
|
}
|
|
|
|
|
|
1996-11-24 17:30:39 +00:00
|
|
|
|
- (void) decodeName: (NSString* *) name
|
1996-01-24 14:09:55 +00:00
|
|
|
|
{
|
|
|
|
|
/* Do nothing */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Access to the underlying stream. */
|
|
|
|
|
|
|
|
|
|
- (id <Streaming>) stream
|
|
|
|
|
{
|
|
|
|
|
return stream;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Deallocation. */
|
|
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
|
{
|
|
|
|
|
[stream release];
|
|
|
|
|
[super dealloc];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Returning default format version. */
|
|
|
|
|
|
|
|
|
|
+ (int) defaultFormatVersion
|
|
|
|
|
{
|
|
|
|
|
[self subclassResponsibility:_cmd];
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|