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.