/* Implementation of GNU Objective-C class for streaming C types and indentatn Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc. Written by: Andrew Kachites McCallum Date: July 1994 This file is part of the GNUstep Base Library. 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. */ #include #include #include #include #include #include /* for SIGNATURE_FORMAT_STRING */ #include #include id CStreamSignatureMalformedException = @"CStreamSignatureMalformedException"; id CStreamSignatureMismatchException = @"CStreamSignatureMismatchException"; @implementation CStream /* Encoding/decoding C values */ - (void) encodeValueOfCType: (const char*) type at: (const void*) d withName: (NSString*) name; { [self subclassResponsibility:_cmd]; } - (void) decodeValueOfCType: (const char*) type at: (void*) d withName: (NSString* *) namePtr; { [self subclassResponsibility:_cmd]; } /* Signature methods. */ - (void) writeSignature { /* Careful: the string should not contain newlines. */ [stream writeFormat: SIGNATURE_FORMAT_STRING, STRINGIFY(GNUSTEP_BASE_PACKAGE_NAME), GNUSTEP_BASE_MAJOR_VERSION, GNUSTEP_BASE_MINOR_VERSION, GNUSTEP_BASE_SUBMINOR_VERSION, object_get_class_name(self), format_version]; } + (void) readSignatureFromStream: s getClassname: (char *) name formatVersion: (int*) version { int got; char package_name[64]; int major_version; int minor_version; int subminor_version; got = [s readFormat: SIGNATURE_FORMAT_STRING, &(package_name[0]), &major_version, &minor_version, &subminor_version, name, version]; if (got != 6) [NSException raise:CStreamSignatureMalformedException format: @"CStream found a malformed signature"]; } /* Initialization methods */ /* This is the hidden designated initializer. Do not call it yourself. */ - _initWithStream: (id ) s formatVersion: (int)version { [super init]; [s retain]; stream = s; format_version = version; indentation = 0; return self; } /* This is the designated initializer for reading. */ - _initForReadingFromPostSignatureStream: (id )s withFormatVersion: (int)version { [self _initWithStream: s formatVersion: version]; return self; } - initForReadingFromStream: (id ) s withFormatVersion: (int)version { [self notImplemented: _cmd]; /* xxx Why this condition? -mccallum */ 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"]; } [self _initForReadingFromPostSignatureStream: s withFormatVersion: version]; } return self; } + cStreamReadingFromStream: (id ) 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] _initForReadingFromPostSignatureStream: s withFormatVersion: version]; return [new_cstream autorelease]; } + cStreamReadingFromFile: (NSString*) filename { return [self cStreamReadingFromStream: [StdioStream streamWithFilename: filename fmode: "r"]]; } /* This is a designated initializer for writing. */ - initForWritingToStream: (id ) s withFormatVersion: (int)version { [self _initWithStream: s formatVersion: version]; [self writeSignature]; return self; } - initForWritingToStream: (id ) s { return [self initForWritingToStream: s withFormatVersion: [[self class] defaultFormatVersion]]; } - initForWritingToFile: (NSString*) file { return [self initForWritingToStream: [StdioStream streamWithFilename: file fmode: "w"]]; } + cStreamWritingToStream: (id ) s { return [[[self alloc] initForWritingToStream: s] autorelease]; } + cStreamWritingToFile: (NSString*) filename; { return [[[self alloc] initForWritingToFile: filename] autorelease]; } /* Encoding/decoding indentation */ - (void) encodeWithName: (NSString*) name 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); } - (void) decodeWithName: (NSString* *)name 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); } - (void) encodeIndent { /* Do nothing */ } - (void) encodeUnindent { /* Do nothing */ } - (void) decodeIndent { /* Do nothing */ } - (void) decodeUnindent { /* Do nothing */ } - (void) encodeName: (NSString*) n { /* Do nothing */ } - (void) decodeName: (NSString* *) name { /* Do nothing */ } /* Access to the underlying stream. */ - (id ) stream { return stream; } /* Deallocation. */ - (void) dealloc { [stream release]; [super dealloc]; } /* Returning default format version. */ + (int) defaultFormatVersion { [self subclassResponsibility:_cmd]; return 0; } @end