diff --git a/Headers/gnustep/base/BinaryCStream.h b/Headers/gnustep/base/BinaryCStream.h new file mode 100644 index 000000000..b7567f447 --- /dev/null +++ b/Headers/gnustep/base/BinaryCStream.h @@ -0,0 +1,35 @@ +/* Interface for GNU Objective-C binary stream object for use serializing + Copyright (C) 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Written: Jan 1996 + + This file is part of the GNU Objective C Class 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. + */ + +#ifndef __BinaryCStream_h_OBJECTS_INCLUDE +#define __BinaryCStream_h_OBJECTS_INCLUDE + +#include +#include +#include + +@interface BinaryCStream : CStream + +@end + +#endif /* __BinaryCStream_h_OBJECTS_INCLUDE */ diff --git a/Headers/gnustep/base/CStream.h b/Headers/gnustep/base/CStream.h new file mode 100644 index 000000000..8ea585ae2 --- /dev/null +++ b/Headers/gnustep/base/CStream.h @@ -0,0 +1,55 @@ +/* Interface for GNU Objective-C stream object for use in archiving + Copyright (C) 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Written: Jan 1996 + + This file is part of the GNU Objective C Class 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. + */ + +#ifndef __CStream_h_OBJECTS_INCLUDE +#define __CStream_h_OBJECTS_INCLUDE + +#include +#include +#include + +@interface CStream : Stream +{ + Stream *stream; + int format_version; + int indentation; +} + +/* These are standard ways to create a new CStream from a Stream + that is open for reading. + It reads the CStream signature at the beginning of the file, and + automatically creates the appropriate subclass of CStream with + the correct format version. */ ++ cStreamReadingFromFile: (id ) filename; ++ cStreamReadingFromStream: (id ) stream; + +/* These are standard ways to create a new CStream with a Stream + that is open for writing. */ +- initForWritingToFile: (id ) filename; +- initForWritingToStream: (id ) stream; ++ cStreamWritingToStream: (id ) stream; ++ cStreamWritingToFile: (id ) filename; + +@end + +#endif /* __CStream_h_OBJECTS_INCLUDE */ diff --git a/Headers/gnustep/base/CStreaming.h b/Headers/gnustep/base/CStreaming.h new file mode 100644 index 000000000..5190fdd9b --- /dev/null +++ b/Headers/gnustep/base/CStreaming.h @@ -0,0 +1,56 @@ +/* Protocol for GNU Objective C byte streams that can code C types and indentn + Copyright (C) 1995, 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Date: April 1995 + + This file is part of the GNU Objective C Class 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. + */ + +#ifndef __CStreaming_h__OBJECTS_INCLUDE +#define __CStreaming_h__OBJECTS_INCLUDE + +#include +#include + +@protocol CStreaming + +- (void) encodeValueOfCType: (const char*) type + at: (const void*) d + withName: (id ) name; + +- (void) decodeValueOfCType: (const char*) type + at: (void*) d + withName: (id *) namePtr; + +- (void) encodeName: (id ) name; +- (void) decodeName: (id *) name; + +- (void) encodeIndent; +- (void) decodeIndent; + +- (void) encodeUnindent; +- (void) decodeUnindent; + +- (id ) stream; + ++ (int) defaultFormatVersion; + +@end + +#endif /* __CStreaming_h__OBJECTS_INCLUDE */ + diff --git a/Headers/gnustep/base/TextCStream.h b/Headers/gnustep/base/TextCStream.h new file mode 100644 index 000000000..3cc6e30ae --- /dev/null +++ b/Headers/gnustep/base/TextCStream.h @@ -0,0 +1,35 @@ +/* Interface for GNU Objective-C text stream object for use serializing + Copyright (C) 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Written: Jan 1996 + + This file is part of the GNU Objective C Class 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. + */ + +#ifndef __TextCStream_h_OBJECTS_INCLUDE +#define __TextCStream_h_OBJECTS_INCLUDE + +#include +#include +#include + +@interface TextCStream : CStream + +@end + +#endif /* __TextCStream_h_OBJECTS_INCLUDE */ diff --git a/Source/BinaryCStream.m b/Source/BinaryCStream.m new file mode 100644 index 000000000..b9ebd3d9c --- /dev/null +++ b/Source/BinaryCStream.m @@ -0,0 +1,339 @@ +/* Implementation of GNU Objective-C binary stream object for use serializing + Copyright (C) 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Written: Jan 1996 + + This file is part of the GNU Objective C Class 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 + +#define DEFAULT_FORMAT_VERSION 0 + +@implementation BinaryCStream + + +/* For debugging */ + +static BOOL debug_binary_coder; + ++ setDebugging: (BOOL)f +{ + debug_binary_coder = f; + return self; +} + ++ debugStderrCoder +{ + static id c = nil; + + if (!c) + c = [[TextCStream alloc] + initForWritingToStream: [StdioStream standardError]]; + return c; +} + +- (void) encodeName: (id ) name +{ + if (debug_binary_coder) + [[[self class] debugStderrCoder] + encodeName:name]; +} + + + +/* Encoding/decoding C values */ + +- (void) encodeValueOfCType: (const char*)type + at: (const void*)d + withName: (id ) name +{ + unsigned char size; + + if (debug_binary_coder) + { + [[[self class] debugStderrCoder] + encodeValueOfCType:type + at:d + withName:name]; + } + assert(type); + assert(*type != '@'); + assert(*type != '^'); + assert(*type != ':'); + assert(*type != '{'); + assert(*type != '['); + + /* A fairly stupid, inefficient binary encoding. This could use + some improvement. For instance, we could compress the sign + information and the type information. + It could probably also use some portability fixes. */ + [stream writeByte:*type]; + size = objc_sizeof_type(type); + [stream writeByte:size]; + switch (*type) + { + case _C_CHARPTR: + { + int length = strlen(*(char**)d); + [self encodeValueOfCType:@encode(int) + at:&length withName:@"BinaryCoder char* length"]; + [stream writeBytes:*(char**)d length:length]; + break; + } + + case _C_CHR: +#ifndef __CHAR_UNSIGNED__ + if (*(char*)d < 0) + [stream writeByte:1]; + else +#endif + [stream writeByte:0]; + case _C_UCHR: + [stream writeByte:*(unsigned char*)d]; + break; + + case _C_SHT: + if (*(short*)d < 0) + [stream writeByte:1]; + else + [stream writeByte:0]; + case _C_USHT: + { + unsigned char *buf = alloca(size); + short s = *(short*)d; + int count = size; + if (s < 0) s = -s; + for (; count--; s >>= 8) + buf[count] = (char) (s % 0x100); + [stream writeBytes:buf length:size]; + break; + } + + case _C_INT: + if (*(int*)d < 0) + [stream writeByte:1]; + else + [stream writeByte:0]; + case _C_UINT: + { + unsigned char *buf = alloca(size); + int s = *(int*)d; + int count = size; + if (s < 0) s = -s; + for (; count--; s >>= 8) + buf[count] = (char) (s % 0x100); + [stream writeBytes:buf length:size]; + break; + } + + case _C_LNG: + if (*(long*)d < 0) + [stream writeByte:1]; + else + [stream writeByte:0]; + case _C_ULNG: + { + unsigned char *buf = alloca(size); + long s = *(long*)d; + int count = size; + if (s < 0) s = -s; + for (; count--; s >>= 8) + buf[count] = (char) (s % 0x100); + [stream writeBytes:buf length:size]; + break; + } + + /* Two quickie kludges to make archiving of floats and doubles work */ + case _C_FLT: + { + char buf[64]; + char *s = buf; + sprintf(buf, "%f", *(float*)d); + [self encodeValueOfCType:@encode(char*) + at:&s withName:@"BinaryCoder float"]; + break; + } + case _C_DBL: + { + char buf[64]; + char *s = buf; + sprintf(buf, "%f", *(double*)d); + [self encodeValueOfCType:@encode(char*) + at:&s withName:@"BinaryCoder double"]; + break; + } + default: + [self error:"Unrecognized Type %s", type]; + } +} + +- (void) decodeValueOfCType: (const char*)type + at: (void*)d + withName: (id *)namePtr +{ + char encoded_type; + unsigned char encoded_size; + unsigned char encoded_sign = 0; + + assert(type); + assert(*type != '@'); + assert(*type != '^'); + assert(*type != ':'); + assert(*type != '{'); + assert(*type != '['); + + [stream readByte:&encoded_type]; + if (encoded_type != *type + && !((encoded_type=='c' || encoded_type=='C') + && (*type=='c' || *type=='C'))) + [self error:"Expected type \"%c\", got type \"%c\"", *type, encoded_type]; + [stream readByte:&encoded_size]; + switch (encoded_type) + { + case _C_CHARPTR: + { + int length; + [self decodeValueOfCType:@encode(int) + at:&length withName:NULL]; + OBJC_MALLOC(*(char**)d, char, length+1); + [stream readBytes:*(char**)d length:length]; + (*(char**)d)[length] = '\0'; + break; + } + + case _C_CHR: + [stream readByte:&encoded_sign]; + case _C_UCHR: + [stream readByte:(unsigned char*)d]; + if (encoded_sign) + *(char*)d = *(char*)d * -1; + break; + + case _C_SHT: + [stream readByte:&encoded_sign]; + case _C_USHT: + { + unsigned char *buf = alloca(encoded_size); + int i; + short s = 0; + [stream readBytes:buf length:encoded_size]; + for (i = 0; i < sizeof(short); i++) + { + s <<= 8; + s += buf[i]; + } + if (encoded_sign) + s = -s; + *(short*)d = s; + break; + } + + case _C_INT: + [stream readByte:&encoded_sign]; + case _C_UINT: + { + unsigned char *buf = alloca(encoded_size); + int i; + int s = 0; + [stream readBytes:buf length:encoded_size]; + for (i = 0; i < sizeof(int); i++) + { + s <<= 8; + s += buf[i]; + } + if (encoded_sign) + s = -s; + *(int*)d = s; + break; + } + + case _C_LNG: + [stream readByte:&encoded_sign]; + case _C_ULNG: + { + unsigned char *buf = alloca(encoded_size); + int i; + long s = 0; + [stream readBytes:buf length:encoded_size]; + for (i = 0; i < sizeof(long); i++) + { + s <<= 8; + s += buf[i]; + } + if (encoded_sign) + s = -s; + *(long*)d = s; + break; + } + + /* Two quickie kludges to make archiving of floats and doubles work */ + case _C_FLT: + { + char *buf; + [self decodeValueOfCType:@encode(char*) at:&buf withName:NULL]; + if (sscanf(buf, "%f", (float*)d) != 1) + [self error:"expected float, got %s", buf]; + (*objc_free)(buf); + break; + } + case _C_DBL: + { + char *buf; + [self decodeValueOfCType:@encode(char*) at:&buf withName:NULL]; + if (sscanf(buf, "%lf", (double*)d) != 1) + [self error:"expected double, got %s", buf]; + (*objc_free)(buf); + break; + } + default: + [self error:"Unrecognized Type %s", type]; + } + + if (debug_binary_coder) + { + [[[self class] debugStderrCoder] + encodeValueOfCType:type + at:d + withName:@"decoding unnamed"]; + } +} + + +/* Returning default format version. */ + ++ (int) defaultFormatVersion +{ + return DEFAULT_FORMAT_VERSION; +} + +- (void) decodeName: (id *)n +{ +#if 1 + *n = nil; +#else + *n = [[[NSString alloc] init] autorelease]; +#endif +} + +@end + diff --git a/Source/CStream.m b/Source/CStream.m new file mode 100644 index 000000000..4af0ce3fc --- /dev/null +++ b/Source/CStream.m @@ -0,0 +1,231 @@ +/* Implementation of GNU Objective-C class for streaming C types and indentatn + Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Date: July 1994 + + This file is part of the GNU Objective C Class 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 + +id CStreamSignatureMalformedException = @"CStreamSignatureMalformedException"; +id CStreamSignatureMismatchException = @"CStreamSignatureMismatchException"; + +@implementation CStream + + +/* Encoding/decoding C values */ + +- (void) encodeValueOfCType: (const char*) type + at: (const void*) d + withName: (id ) name; +{ + [self subclassResponsibility:_cmd]; +} + +- (void) decodeValueOfCType: (const char*) type + at: (void*) d + withName: (id *) namePtr; +{ + [self subclassResponsibility:_cmd]; +} + + +/* Signature methods. */ + +#define SIGNATURE_FORMAT_STRING \ +@"GNU Objective C Class Library %s version %d\n" + +- (void) writeSignature +{ + /* Careful: the string should not contain newlines. */ + [stream writeFormat: SIGNATURE_FORMAT_STRING, + object_get_class_name(self), + format_version]; +} + ++ (void) readSignatureFromStream: s + getClassname: (char *) name + formatVersion: (int*) version +{ + int got; + + got = [s readFormat: SIGNATURE_FORMAT_STRING, + name, version]; + if (got != 2) + [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; +} + +- initForReadingFromStream: (id ) s + formatVersion: (int)version +{ + [self _initWithStream: s + formatVersion: version]; + 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"]; + } + } + 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] + _initWithStream: s + formatVersion: version]; + return [new_cstream autorelease]; +} + ++ cStreamReadingFromFile: (id ) filename +{ + return [self cStreamReadingFromStream: + [StdioStream streamWithFilename: filename fmode: "r"]]; +} + +/* This is a designated initializer for writing. */ +- initForWritingToStream: (id ) s + formatVersion: (int)version +{ + [self _initWithStream: s + formatVersion: version]; + [self writeSignature]; + return self; +} + +- initForWritingToStream: (id ) s +{ + [self initForWritingToStream: s + formatVersion: [[self class] defaultFormatVersion]]; +} + +- initForWritingToFile: (id ) file +{ + return [self initForWritingToStream: + [StdioStream streamWithFilename: file fmode: "w"]]; +} + ++ cStreamWritingToStream: (id ) s +{ + return [[[self alloc] initForWritingToStream: s] + autorelease]; +} + ++ cStreamWritingToFile: (id ) filename; +{ + return [[[self alloc] initForWritingToFile: filename] + autorelease]; +} + + +/* Encoding/decoding indentation */ + +- (void) encodeIndent +{ + /* Do nothing */ +} + +- (void) encodeUnindent +{ + /* Do nothing */ +} + +- (void) decodeIndent +{ + /* Do nothing */ +} + +- (void) decodeUnindent +{ + /* Do nothing */ +} + +- (void) encodeName: (id ) n +{ + /* Do nothing */ +} + +- (void) decodeName: (id *) 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 diff --git a/Source/TextCStream.m b/Source/TextCStream.m new file mode 100644 index 000000000..126410b85 --- /dev/null +++ b/Source/TextCStream.m @@ -0,0 +1,381 @@ +/* Implementation of GNU Objective-C text stream object for use serializing + Copyright (C) 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Written: Jan 1996 + + This file is part of the GNU Objective C Class 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 + +#define DEFAULT_FORMAT_VERSION 0 + +static BOOL debug_textcoder = NO; + +@implementation TextCStream + + +/* Encoding/decoding C values */ + +#define XSTR(s) STR(s) +#define STR(s) #s + +#define ATXSTR(s) ATSTR(s) +#define ATSTR(s) @#s + +#define ROUND(V, A) \ + ({ typeof(V) __v=(V); typeof(A) __a=(A); \ + __a*((__v+__a-1)/__a); }) + +#define ENCODER_FORMAT(TYPE, CONVERSION) \ +@"%*s<%s> (" ATXSTR(TYPE) @") = %" ATXSTR(CONVERSION) @"\n" + +- (void) encodeValueOfCType: (const char*) type + at: (const void*) d + withName: (id ) name; +{ + if (!name) + name = @""; + switch (*type) + { + case _C_LNG: + [stream writeFormat:@"%*s<%@> (long) = %ld\n", + indentation, "", name, *(long*)d]; + break; + case _C_ULNG: + [stream writeFormat:@"%*s<%@> (unsigned long) = %lu\n", + indentation, "", name, *(unsigned long*)d]; + break; + case _C_INT: + [stream writeFormat:@"%*s<%@> (int) = %d\n", + indentation, "", name, *(int*)d]; + break; + case _C_UINT: + [stream writeFormat:@"%*s<%@> (unsigned int) = %u\n", + indentation, "", name, *(unsigned int*)d]; + break; + case _C_SHT: + [stream writeFormat:@"%*s<%@> (short) = %d\n", + indentation, "", name, (int)*(short*)d]; + break; + case _C_USHT: + [stream writeFormat:@"%*s<%@> (unsigned short) = %u\n", + indentation, "", name, (unsigned)*(unsigned short*)d]; + break; + case _C_CHR: + [stream writeFormat:@"%*s<%@> (char) = %c (0x%x)\n", + indentation, "", name, *(char*)d, (unsigned)*(char*)d]; + break; + case _C_UCHR: + [stream writeFormat:@"%*s<%@> (unsigned char) = 0x%x\n", + indentation, "", name, (unsigned)*(unsigned char*)d]; + break; + case _C_FLT: + [stream writeFormat:@"%*s<%@> (float) = %g\n", + indentation, "", name, *(float*)d]; + break; + case _C_DBL: + [stream writeFormat:@"%*s<%@> (double) = %g\n", + indentation, "", name, *(double*)d]; + break; + case _C_CHARPTR: + [stream writeFormat:@"%*s<%@> (char*) = \"%s\"\n", + indentation, "", name, *(char**)d]; + break; + case _C_ARY_B: + { + int len = atoi (type+1); /* xxx why +1 ? */ + int offset; + + while (isdigit(*++type)); + offset = objc_sizeof_type(type); + [self encodeName:name]; + [self encodeIndent]; + while (len-- > 0) + { + /* Change this so we don't re-write type info every time. */ + [self encodeValueOfCType:type + at:d + withName:@"array component"]; + ((char*)d) += offset; + } + [self encodeUnindent]; + break; + } + case _C_STRUCT_B: + { + int acc_size = 0; + int align; + + while (*type != _C_STRUCT_E && *type++ != '='); /* skip "=" */ + [self encodeName:name]; + [self encodeIndent]; + while (*type != _C_STRUCT_E) + { + align = objc_alignof_type (type); /* pad to alignment */ + acc_size = ROUND (acc_size, align); + [self encodeValueOfCType:type + at:((char*)d)+acc_size + withName:@"structure component"]; + acc_size += objc_sizeof_type (type); /* add component size */ + type = objc_skip_typespec (type); /* skip component */ + } + [self encodeUnindent]; + break; + } + case _C_PTR: + [self error:"Cannot encode pointers"]; + break; +#if 0 /* No, don't know how far to recurse */ + [self encodeValueOfObjCType:type+1 at:*(char**)d withName:name]; + break; +#endif + default: + [self error:"type %s not implemented", type]; + } +} + +#define DECODER_FORMAT(TYPE, CONVERSION) \ +@" <%a[^>]> (" ATXSTR(TYPE) @") = %" ATXSTR(CONVERSION) @" \n" + +#define DECODE_ERROR(TYPE) [self error:"bad format decoding " XSTR(TYPE)] + +#define DECODE_DEBUG(TYPE, CONVERSION) \ +if (debug_textcoder) \ + [[StdioStream standardError] writeFormat: \ + @"got <%s> (%s) %" ATXSTR(CONVERSION) @"\n", \ + tmpname, \ + XSTR(TYPE), *(TYPE*)d]; + +- (void) decodeValueOfCType: (const char*) type + at: (void*) d + withName: (id *) namePtr; +{ + char *tmpname; + + assert (d); + switch (*type) + { + case _C_LNG: + if ([stream readFormat: DECODER_FORMAT(long,l), + &tmpname, (long*)d] != 2) + DECODE_ERROR(long); + DECODE_DEBUG(long, l); + break; + case _C_ULNG: + if ([stream readFormat:DECODER_FORMAT(unsigned long, lu), + &tmpname, (unsigned long*)d] != 2) + DECODE_ERROR(unsigned long); + DECODE_DEBUG(unsigned long, lu); + break; + case _C_INT: + if ([stream readFormat:DECODER_FORMAT(int, d), + &tmpname, (int*)d] != 2) + DECODE_ERROR(int); + DECODE_DEBUG(int, d); + break; + case _C_UINT: + if ([stream readFormat:DECODER_FORMAT(unsigned int,u), + &tmpname, (unsigned int*)d] != 2) + DECODE_ERROR(unsigned int); + DECODE_DEBUG(unsigned int, u); + break; + case _C_SHT: + if ([stream readFormat:DECODER_FORMAT(short,hd), + &tmpname, (short*)d] != 2) + DECODE_ERROR(short); + DECODE_DEBUG(short, d); + break; + case _C_USHT: + if ([stream readFormat:DECODER_FORMAT(unsigned short,hu), + &tmpname, (unsigned short*)d] != 2) + DECODE_ERROR(unsigned short); + DECODE_DEBUG(unsigned short, u); + break; + case _C_CHR: + { + unsigned tmp; + if ([stream readFormat:@" <%a[^>]> (char) = %*c (%x) \n", + &tmpname, &tmp] != 2) + DECODE_ERROR(char); + *(char*)d = (char)tmp; + DECODE_DEBUG(char, c); + break; + } + case _C_UCHR: + { + unsigned tmp; + if ([stream readFormat:DECODER_FORMAT(unsigned char,x), + &tmpname, &tmp] != 2) + DECODE_ERROR(unsigned char); + *(unsigned char*)d = (unsigned char)tmp; + DECODE_DEBUG(unsigned char, c); + break; + } + case _C_FLT: + if ([stream readFormat:DECODER_FORMAT(float,f), + &tmpname, (float*)d] != 2) + DECODE_ERROR(float); + DECODE_DEBUG(float, f); + break; + case _C_DBL: + if ([stream readFormat:DECODER_FORMAT(double,lf), + &tmpname, (double*)d] != 2) + DECODE_ERROR(double); + DECODE_DEBUG(double, f); + break; + case _C_CHARPTR: + if ([stream readFormat:@" <%a[^>]> (char*) = \"%a[^\"]\" \n", + &tmpname, (char**)d] != 2) + DECODE_ERROR(char*); + DECODE_DEBUG(char*, s); + break; + case _C_ARY_B: + { + /* xxx Do we need to allocate space, just like _C_CHARPTR ? */ + int len = atoi(type+1); + int offset; + [self decodeName:namePtr]; + [self decodeIndent]; + while (isdigit(*++type)); + offset = objc_sizeof_type(type); + while (len-- > 0) + { + [self decodeValueOfCType:type + at:d + withName:namePtr]; + ((char*)d) += offset; + } + [self decodeUnindent]; + break; + } + case _C_STRUCT_B: + { + /* xxx Do we need to allocate space just like char* ? No. */ + int acc_size = 0; + int align; + while (*type != _C_STRUCT_E && *type++ != '='); /* skip "=" */ + [self decodeName:namePtr]; + [self decodeIndent]; /* xxx insert [self decodeName:] */ + while (*type != _C_STRUCT_E) + { + align = objc_alignof_type (type); /* pad to alignment */ + acc_size = ROUND (acc_size, align); + [self decodeValueOfCType:type + at:((char*)d)+acc_size + withName:namePtr]; + acc_size += objc_sizeof_type (type); /* add component size */ + type = objc_skip_typespec (type); /* skip component */ + } + [self decodeUnindent]; + break; + } + case _C_PTR: + [self error:"Cannot decode pointers"]; + break; +#if 0 /* No, don't know how far to recurse */ + OBJC_MALLOC(*(void**)d, void*, 1); + [self decodeValueOfObjCType:type+1 at:*(char**)d withName:namePtr]; + break; +#endif + default: + [self error:"type %s not yet implemented", type]; + } + if (namePtr) + *namePtr = [NSString stringWithCStringNoCopy: tmpname]; + else + (*objc_free) (tmpname); +} + + +/* Encoding/decoding indentation */ + +- (void) encodeIndent +{ + [stream writeFormat: @"%*s {\n", indentation, ""]; + indentation += 2; +} + +- (void) encodeUnindent +{ + indentation -= 2; + [stream writeFormat: @"%*s }\n", indentation, ""]; +} + +- (void) decodeIndent +{ + id line; + const char *lp; + + line = [stream readLine]; + lp = [line cStringNoCopy]; + while (*lp == ' ') lp++; + if (*lp != '{') + [self error:"bad indent format, got \"%s\"", line]; +} + +- (void) decodeUnindent +{ + id line; + const char *lp; + + line = [stream readLine]; + lp = [line cStringNoCopy]; + while (*lp == ' ') lp++; + if (*lp != '}') + [self error:"bad unindent format, got \"%s\"", line]; +} + +- (void) encodeName: (id ) n +{ + if (n) + [stream writeFormat:@"%*s<%@>\n", indentation, "", n]; + else + [stream writeFormat:@"%*s\n", indentation, ""]; +} + +- (void) decodeName: (id *) name +{ + const char *n; + if (name) + { + if ([stream readFormat: @" <%a[^>]> \n", &n] != 1) + [self error:"bad format"]; + *name = [NSString stringWithCStringNoCopy: n + freeWhenDone: YES]; + if (debug_textcoder) + fprintf(stderr, "got name <%s>\n", *n); + } + else + { + [stream readFormat: @" <%*[^>]> \n"]; + } +} + + +/* Returning default format version. */ + ++ (int) defaultFormatVersion +{ + return DEFAULT_FORMAT_VERSION; +} + +@end diff --git a/Source/objects/BinaryCStream.h b/Source/objects/BinaryCStream.h new file mode 100644 index 000000000..b7567f447 --- /dev/null +++ b/Source/objects/BinaryCStream.h @@ -0,0 +1,35 @@ +/* Interface for GNU Objective-C binary stream object for use serializing + Copyright (C) 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Written: Jan 1996 + + This file is part of the GNU Objective C Class 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. + */ + +#ifndef __BinaryCStream_h_OBJECTS_INCLUDE +#define __BinaryCStream_h_OBJECTS_INCLUDE + +#include +#include +#include + +@interface BinaryCStream : CStream + +@end + +#endif /* __BinaryCStream_h_OBJECTS_INCLUDE */ diff --git a/Source/objects/CStream.h b/Source/objects/CStream.h new file mode 100644 index 000000000..8ea585ae2 --- /dev/null +++ b/Source/objects/CStream.h @@ -0,0 +1,55 @@ +/* Interface for GNU Objective-C stream object for use in archiving + Copyright (C) 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Written: Jan 1996 + + This file is part of the GNU Objective C Class 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. + */ + +#ifndef __CStream_h_OBJECTS_INCLUDE +#define __CStream_h_OBJECTS_INCLUDE + +#include +#include +#include + +@interface CStream : Stream +{ + Stream *stream; + int format_version; + int indentation; +} + +/* These are standard ways to create a new CStream from a Stream + that is open for reading. + It reads the CStream signature at the beginning of the file, and + automatically creates the appropriate subclass of CStream with + the correct format version. */ ++ cStreamReadingFromFile: (id ) filename; ++ cStreamReadingFromStream: (id ) stream; + +/* These are standard ways to create a new CStream with a Stream + that is open for writing. */ +- initForWritingToFile: (id ) filename; +- initForWritingToStream: (id ) stream; ++ cStreamWritingToStream: (id ) stream; ++ cStreamWritingToFile: (id ) filename; + +@end + +#endif /* __CStream_h_OBJECTS_INCLUDE */ diff --git a/Source/objects/CStreaming.h b/Source/objects/CStreaming.h new file mode 100644 index 000000000..5190fdd9b --- /dev/null +++ b/Source/objects/CStreaming.h @@ -0,0 +1,56 @@ +/* Protocol for GNU Objective C byte streams that can code C types and indentn + Copyright (C) 1995, 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Date: April 1995 + + This file is part of the GNU Objective C Class 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. + */ + +#ifndef __CStreaming_h__OBJECTS_INCLUDE +#define __CStreaming_h__OBJECTS_INCLUDE + +#include +#include + +@protocol CStreaming + +- (void) encodeValueOfCType: (const char*) type + at: (const void*) d + withName: (id ) name; + +- (void) decodeValueOfCType: (const char*) type + at: (void*) d + withName: (id *) namePtr; + +- (void) encodeName: (id ) name; +- (void) decodeName: (id *) name; + +- (void) encodeIndent; +- (void) decodeIndent; + +- (void) encodeUnindent; +- (void) decodeUnindent; + +- (id ) stream; + ++ (int) defaultFormatVersion; + +@end + +#endif /* __CStreaming_h__OBJECTS_INCLUDE */ + diff --git a/Source/objects/TextCStream.h b/Source/objects/TextCStream.h new file mode 100644 index 000000000..3cc6e30ae --- /dev/null +++ b/Source/objects/TextCStream.h @@ -0,0 +1,35 @@ +/* Interface for GNU Objective-C text stream object for use serializing + Copyright (C) 1996 Free Software Foundation, Inc. + + Written by: R. Andrew McCallum + Written: Jan 1996 + + This file is part of the GNU Objective C Class 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. + */ + +#ifndef __TextCStream_h_OBJECTS_INCLUDE +#define __TextCStream_h_OBJECTS_INCLUDE + +#include +#include +#include + +@interface TextCStream : CStream + +@end + +#endif /* __TextCStream_h_OBJECTS_INCLUDE */