home *** CD-ROM | disk | FTP | other *** search
Text File | 1995-05-09 | 3.9 KB | 194 lines | [TEXT/MPS ] |
- /*********************************************************************
- Project : MacPerl - Standalone Perl
- File : MPConsole.cp - Console interface for GUSI
- Author : Matthias Neeracher
- Language : MPW C/C++
-
- $Log: MPConsole.cp,v $
- *********************************************************************/
-
- #include <GUSIFile_P.h>
-
- #include <stdio.h>
- #include <ioctl.h>
-
- class MemSocket : public Socket {
- friend class MemSocketDomain;
-
- MemSocket(Handle data);
-
- virtual ~MemSocket();
-
- Handle data;
- long maxData;
- long readPtr;
- MemSocket * next;
- public:
- virtual int read(void * buffer, int buflen);
- virtual int write(void * buffer, int buflen);
- virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
- virtual int ioctl(unsigned int request, void *argp);
- };
-
- class MemSocketDomain : public FileSocketDomain {
- friend class MemSocket;
-
- MemSocket * first;
- Handle nextLookup;
- public:
- MemSocketDomain();
-
- virtual Boolean Yours(const GUSIFileRef & ref, Request request);
- virtual Socket * open(const GUSIFileRef & ref, int oflag);
-
- MemSocket * Lookup(Handle hand);
- };
-
- static Handle StdSockets[3];
- static MemSocketDomain MemSockets;
-
- extern "C" void InstallMemConsole(Handle input, Handle output, Handle error)
- {
- StdSockets[0] = input;
- StdSockets[1] = output;
- StdSockets[2] = error;
-
- freopen("dev:stdin", "r", stdin);
- freopen("dev:stdout", "w", stdout);
- freopen("dev:stderr", "w", stderr);
- }
-
- /************************ MemSocket members ************************/
-
- MemSocket::MemSocket(Handle data)
- : data(data), maxData(GetHandleSize(data)), readPtr(0), next(nil)
- {
- }
-
- MemSocket::~MemSocket()
- {
- for (int i = 0; i<3; ++i)
- if (StdSockets[i] == data)
- StdSockets[i] = nil;
- }
-
- int MemSocket::ioctl(unsigned int request, void *argp)
- {
- switch (request) {
- case FIONREAD:
- *(unsigned long *) argp = maxData - readPtr;
-
- return 0;
- default:
- return GUSI_error(EOPNOTSUPP);
- }
- }
-
- int MemSocket::read(void * buffer, int buflen)
- {
- buflen = min(buflen, maxData - readPtr);
- HLock(data);
- memcpy(buffer, *data+readPtr, buflen);
- HUnlock(data);
- readPtr += buflen;
-
- return buflen;
- }
-
- int MemSocket::write(void * buffer, int buflen)
- {
- if (PtrAndHand(buffer, data, buflen))
- return GUSI_error(ENOMEM);
-
- maxData += buflen;
-
- return buflen;
- }
-
- int MemSocket::select(Boolean * canRead, Boolean * canWrite, Boolean *)
- {
- int goodies = 0;
-
- if (canRead) {
- *canRead = true;
- ++goodies;
- }
-
- if (canWrite) {
- *canWrite = true;
- ++goodies;
- }
-
- return goodies;
- }
-
- /********************* MemSocketDomain members **********************/
-
- #if !defined(powerc) && !defined(__powerc)
- #pragma force_active on
- #endif
-
- MemSocketDomain::MemSocketDomain()
- : FileSocketDomain(AF_UNSPEC, true, false)
- {
- }
-
- Boolean MemSocketDomain::Yours(const GUSIFileRef & ref, FileSocketDomain::Request request)
- {
- if (ref.spec || (request != willOpen))
- return false;
-
- if (
- (ref.name[4] | 0x20) == 's'
- && (ref.name[5] | 0x20) == 't'
- && (ref.name[6] | 0x20) == 'd'
- )
- switch (ref.name[7] | 0x20) {
- case 'i':
- return (ref.name[8] | 0x20) == 'n'
- && (nextLookup = StdSockets[0]) != nil;
- case 'o':
- return (ref.name[8] | 0x20) == 'u'
- && (ref.name[9] | 0x20) == 't'
- && (nextLookup = StdSockets[1]) != nil;
- case 'e':
- return (ref.name[8] | 0x20) == 'r'
- && (ref.name[9] | 0x20) == 'r'
- && (nextLookup = StdSockets[2]) != nil;
- default:
- return false;
- }
- else if (!strncmp(ref.name+4, "Handle", 6)) {
- char * end;
-
- switch (ref.name[10]) {
- case 0:
- return false;
- case ':':
- nextLookup = (Handle) strtoul(ref.name+11, &end, 0);
-
- return end > ref.name+11 && !*end;
- }
- }
-
- return false;
- }
-
- Socket * MemSocketDomain::open(const GUSIFileRef &, int)
- {
- return Lookup(nextLookup);
- }
-
- MemSocket * MemSocketDomain::Lookup(Handle hand)
- {
- MemSocket * sock = first;
-
- while (sock)
- if (sock->data == hand)
- return sock;
- else
- sock = sock->next;
-
- return new MemSocket(hand);
- }
-