This is IMediaD.m in view mode; [Download] [Up]
// // IMediaD is an abstract superclass. It supports instance variables and // methods for media classes such as ITiffD, ISndD, IEpsD. The embedded // graphic objects in a rich Text object references a media object. It is the // media object that provides the image that is displayed by the embedded // graphic object and performs the double click action. Multiple embedded // graphic objects may reference the same media object. In the default // read/write methods provided by IMediaD the stream, tar stream and // pasteboard representations are identical. the tar stream representation // was orginally meant to support a special compressed representation. This // however is at present only done for text data. Tar stream representation // is used to post data to the NNTP server. // // A Media Class must implement these class methods: // // + (NXAtom)rtfControlWord - returns the RTF control word eg "MMtiff" // + (NXAtom)fileExtension - returns the file extension eg "tiff" // + (NXAtom)pasteboardType - returns the pasteboard type // eg NXTIFFPboardtype // // A Media Class must implement these instance methods: // - initWithKey:(char *)pathName // - (BOOL)readFromFile:(const char *)pathName // This method maps the file into a stream which the receiver will // own. Then [self readFromStream:] is called. // - (BOOL)readFromPasteboard:(Pasteboard *)pasteboard // This method maps the pasteboard data into a stream which the // receiver will own. Then [self readFromStream:] is called. // - (NXImage *)image // This method returns the image to be displayed in the document. // This method must be defined in the media subclass. // - setReferenceCount:(int)newCount // - (int)referenceCount // The number of embedded objects in the document that references // this media object. // - (int)incrementReferenceCount // - (int)decrementReferenceCount // - (BOOL)readFromStream:(NXStream *)inStream // This method first copies the stream if the receiver does not own // the stream. Then the stream is read. The implementation in // IMediaD only does the copying of the stream the actual reading // must be defined in the media subclass. // - (BOOL)readFromTarStream:(NXStream *)tarStream // This is implemented as [self readFromStream:]. Override this // implementation if the media class has a different representation // for the tar format. For example, the ITextD class uses a // special compressed format when it writes to a tar stream. // - (void)writeToTarStream:(NXStream *)tarStream // This is implemented as [self writeFromStream:]. Override this // implementation if the media class has a different representation // for the tar format. // - (void)writeToStream:(NXStream *)outStream // This method copies the stream owned by the receiver to outStream. // (A more efficient implementation should just assign the stream // pointer.) // - free // - performDoubleClickAction:sender // This method does nothing in IMediaD's implementation. // // IMediaD provides default methods for most of the above. Only these // instance methods must be implemented by the media subclass // - (BOOL)readFromStream:(NXStream *)inStream // The subclass implementation of this method should super // the IMediaD implementation first. This will copy inStream if // the receiver does not own inStream; IMediaD uses this method // is to read tar streams and pasteboard data, also. You must // implement your own methods if you have special tar stream // or pasteboard representations. // - (NXImage *)image // - performDoubleClickAction:sender // This method need not be implemented if there is no double click // action. // // Please make an entry in Tables.c for each new media class. #import "IMediaD.h" #import <appkit/Application.h> #import <appkit/Listener.h> #import <appkit/Speaker.h> #import <objc/hashtable.h> #import <sys/param.h> #import <sys/types.h> #import <sys/stat.h> #import <mach.h> #import <libc.h> @implementation IMediaD + getFileIconFor:(Class)Media { char path[256]; int fd; char *data; int length; int flag; NXStream *iconStream; NXImage *icon; sprintf(path, "/tmp/x.%.248s", [(id)Media fileExtension]); if ((fd = open(path, O_WRONLY | O_CREAT)) != -1) { close(fd); } [[NXApp appSpeaker] setSendPort:NXPortFromName(NX_WORKSPACEREQUEST, NULL)]; [[NXApp appSpeaker] getFileIconFor:path TIFF:&data TIFFLength:&length ok:&flag]; unlink(path); if (flag == YES) { iconStream = NXOpenMemory(data, length, NX_READONLY); icon = [[NXImage alloc] initFromStream:iconStream]; NXCloseMemory(iconStream, NX_FREEBUFFER); } else { // ## REWRITE! ## should provide a default icon icon = nil; } [(id)Media setIcon:icon]; return(self); } - initWithKey:(char *)pathName { const char *fileName; [super init]; if ((fileName = rindex(pathName, '/')) == 0) { fileName = pathName; } else { ++fileName; } key = NXCopyStringBufferFromZone(fileName, [self zone]); stream = NULL; count = 0; return self; } - (BOOL)readFromFile:(const char *)pathName { if ((stream = NXMapFile(pathName, NX_READONLY)) != NULL) { if ([self readFromStream:stream] == YES) { return(YES); } else { NXCloseMemory(stream, NX_FREEBUFFER); stream = NULL; return(NO); } } else { return(NO); } } - (BOOL)readFromPasteboard:(Pasteboard *)pasteboard { char *data; int length; if ([pasteboard readType:[[self class] pasteboardType] data:&data length:&length] != nil) { if ((stream = NXOpenMemory(data, length, NX_READONLY)) != NULL) { if ([self readFromStream:stream] == YES) { return(YES); } else { NXCloseMemory(stream, NX_FREEBUFFER); stream = NULL; return(NO); } } else { return(NO); } } else { return(NO); } } - (NXImage *)image { /* defined in subclasses */ return nil; } - setReferenceCount:(int)newCount { count = newCount; return self; } - (int)referenceCount { return count; } - (int)incrementReferenceCount { return(++count); } - (int)decrementReferenceCount { return(--count); } - (int)size { return size; } - (BOOL)readFromTarStream:(NXStream *)tarStream { return([self readFromStream:tarStream]); } - (void)writeToTarStream:(NXStream *)tarStream { [self writeToStream:tarStream]; } - (BOOL)readFromStream:(NXStream *)inStream { char *data; int len, maxLen; NXSeek(inStream, (long)0, NX_FROMEND); size = NXTell(inStream); NXSeek(inStream, (long)0, NX_FROMSTART); // Do we own this stream? if (inStream != stream) { // No. Make a copy that we will own. if (stream != NULL) { NXCloseMemory(stream, NX_FREEBUFFER); } NXGetMemoryBuffer(inStream, &data, &len, &maxLen); stream = NXOpenMemory(NULL, 0, NX_READWRITE); NXWrite(stream, data, size); NXSeek(stream, (long)0, NX_FROMSTART); } return(YES); /* actual read is defined in subclasses */ } - (void)writeToStream:(NXStream *)outStream { char *data; int len, maxLen; // ## REWRITE! ## really should just assign NXStream pointers instead // Just copy the in stream which we should own if (stream != NULL) { NXGetMemoryBuffer(stream, &data, &len, &maxLen); NXWrite(outStream, data, size); } } - free { int len, maxlen; char *buffer; /* may be redefined in subclasses */ if (stream != NULL) { NXGetMemoryBuffer(stream, &buffer, &len, &maxlen); NXCloseMemory(stream, NX_FREEBUFFER); // vm_deallocate(task_self(), buffer, maxlen); } return([super free]); } - performDoubleClickAction:sender { /* may be redefined in subclasses */ // images should return nil; media objects that are not just images // i.e, icons should return self. return(nil); } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.