This is MiscStringNEXTSTEP.m in view mode; [Download] [Up]
//
// MiscStringNEXTSTEP.m
// Written by Don Yacktman (c) 1993 by Don Yacktman.
// Version 1.95 All rights reserved.
// This notice may not be removed from this source code.
//
// This object is included in the MiscKit by permission from the author
// and its use is governed by the MiscKit license, found in the file
// "LICENSE.rtf" in the MiscKit distribution. Please refer to that file
// for a list of all applicable permissions and restrictions.
//
#import <misckit/MiscString.h>
#import <mach/mach_error.h>
@implementation MiscString(NEXTSTEP)
// This category includes methods to support various NEXTSTEP features,
// such as InterfaceBuilder (palettes), Distributed Objects (NXTransport),
// and object archiving.
- read:(NXTypedStream *)stream
{
int tempLength; char *tBuf;
[super read:stream];
// find out how much space we will need
NXReadType(stream, "i", &tempLength);
// note that -allocateBuffer:fromZone: will set _length for
// us -- it is important to not smash _length since it tracks
// the actual size of the current buffer! (See the notes for
// -allocateBuffer:fromZone: for more info on why no smashing.)
// Note that -allocateBuffer:fromZone: increments the buffer
// size by one, so we must pass it decremented so that we unarchive
// with a buffer of the same length as the original object.
[self allocateBuffer:(tempLength-1) fromZone:[self zone]]; // make sure
// we have a buffer and it is big enough.
// Get the string off the stream and into the buffer
NXReadType(stream, "*", &tBuf);
if (tBuf) strcpy(buffer, tBuf);
if (!tBuf && buffer) buffer[0] = '\0'; // NULL string?
// now make sure that we have the right length for the string stored.
if (buffer) length = strlen(buffer);
else length = 0;
// clean up and blow this joint
if (tBuf) free(tBuf);
return self;
}
- write:(NXTypedStream *)stream
{
[super write:stream];
// put the string and it's length on the stream. The length is sort
// of redundant, but this assures that the string really is like the
// one that was archived -- if the stored instance had an oversize
// buffer, then read will restore an oversize buffer. Of course,
// crud after the string won't be the same, so the new instance isn't
// quite the same, but...
NXWriteType(stream, "i", &_length);
NXWriteType(stream, "*", &buffer);
return self;
}
// NXTransport protocol implementation (next three methods):
- encodeUsing:(id <NXEncoding>)portal
{
[portal encodeData:&_length ofType:"i"]; // no longer used, remains for compatability reasons
[portal encodeData:&length ofType:"i"];
[portal encodeData:&buffer ofType:"*"];
return self;
}
- decodeUsing:(id <NXDecoding>)portal
{
int newLen;
[self freeString];
[portal decodeData:&newLen ofType:"i"]; // no longer used, remains for compatability reasons
// This is not necessary and causes a leak: [self allocateBuffer:newLen];
[portal decodeData:&length ofType:"i"];
[portal decodeData:&buffer ofType:"*"];
// Yes, I know I'm not supposed to fool with _length, but....
_length = length + 1; // it needs to be set properly and this ought to
// do the trick. Note that the bycopy object doesn't necessarily have
// a buffer as large as the original. We don't really care since they
// grow dynamically anyway and most strings passed through DO will end
// up being treated as constants anyway, so the trimming down is OK.
return self;
}
- encodeRemotelyFor:(NXConnection *)connection
freeAfterEncoding:(BOOL *)flagp isBycopy:(BOOL)isByCopy
{
if (isByCopy) {
*flagp = NO; // object will not be freed (ie, copy, not move)
return self; //encode object (copy it)
}
*flagp = NO;
// super will encode the proxy otherwise
return [super encodeRemotelyFor:connection
freeAfterEncoding:flagp isBycopy:isByCopy];
}
// RTF support
- (BOOL)isRTFText
{
if (![self cmp:"{\\rtf0" n:6]) return YES; //} rtf header/magic num
if (![self cmp:"{\\\\rtf0" n:7]) return YES; //} happens in .address files
return NO;
}
- (MiscString *)plainTextForRTF
{ // Donated by Darcy Brockbank and untested. Let's hope it works!
id text = [[Text alloc] init];
// text may have to go into a dummy window, or we could
// make a major hack and ask for the [[NXApp mainMenu] getFieldEditor...
vm_size_t allocSize = (strlen(buffer)+1) * sizeof(char);
char * tmp;
NXStream * stream;
MiscString * other = nil;
kern_return_t ret;
if (![self isRTFText]) return [self copy];
[text setText:""];
ret = (vm_allocate(task_self(), (vm_address_t *)&tmp, allocSize, TRUE));
if (ret != KERN_SUCCESS) {
mach_error("vm_allocate returned value of ", ret);
printf("Exiting with error.\n");
exit(-1);
}
strcpy(tmp,buffer);
stream = NXOpenMemory(tmp,allocSize,NX_READONLY);
[text readRichText:stream];
NXCloseMemory(stream,NX_TRUNCATEBUFFER);
ret = vm_deallocate(task_self(), (vm_address_t)tmp, allocSize);
if (ret != KERN_SUCCESS) {
mach_error("vm_deallocate returned value of ",ret);
printf("Exiting with error.\n");
exit(-1);
}
if ([text textLength]) {
int len = [text textLength];
char otherBuf[len + 1];
[text getSubstring:otherBuf start:0 length:len];
otherBuf[len]='\0';
other = [[MiscString alloc] initString:otherBuf];
}
[text free];
return other; // nil if we were unsuccessful
}
// Interface Builder support
- (const char *)getInspectorClassName { return "MiscStringInspector"; }
- (NXImage *)getIBImage { return [NXImage findImageNamed:"MiscStringObj"]; }
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.