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.