home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-02-27 | 3.6 KB | 190 lines | [TEXT/MPS ] |
- /*********************************************************************
- Project : MacPerl - Standalone Perl
- File : MPPseudoFile.cp - Pseudo files for GUSI
- Author : Matthias Neeracher
- File : MPPseudoLanguage : MPW C/C++
- File : MPPseudo
- File : MPPseudo$Log: MPPseudoFile.cp,v $
- File : MPPseudoRevision 1.1 1994/02/27 23:05:08 neeri
- File : MPPseudoInitial revision
- File : MPPseudo
- *********************************************************************/
-
- #include "GUSI_P.h"
-
- #include <ioctl.h>
- #include <sys/types.h>
- #include <Resources.h>
- #include <TextUtils.h>
-
- extern "C" {
- #include "MPGlobals.h"
- }
-
- #define AF_PSEUDO 18
-
- class MPPseudoSocket; // That's what this file's all about
-
- class MPPseudoSocket : public Socket {
- friend class MPPseudoSocketDomain;
-
- MPPseudoSocket(Handle hdl);
-
- virtual ~MPPseudoSocket();
-
- Handle data;
- long readEnd;
- long readPtr;
- public:
- virtual int read(void * buffer, int buflen);
- virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
- virtual int ioctl(unsigned int request, void *argp);
- virtual long lseek(long offset, int whence);
- };
-
- class MPPseudoSocketDomain : public DeviceSocketDomain {
- public:
- MPPseudoSocketDomain() : DeviceSocketDomain(AF_PSEUDO) { }
-
- virtual Socket * open(const char * filename, int oflag);
- };
-
- MPPseudoSocketDomain MPPseudoSockets;
-
- #pragma segment MPPseudo
-
- /************************ MPPseudoSocket members ************************/
-
- MPPseudoSocket::MPPseudoSocket(Handle hdl)
- : data(hdl)
- {
- readPtr = 0;
- readEnd = GetHandleSize(data);
- }
-
- MPPseudoSocket::~MPPseudoSocket()
- {
- DisposeHandle(data);
- }
-
- int MPPseudoSocket::ioctl(unsigned int request, void *argp)
- {
- switch (request) {
- case FIONREAD:
- *(unsigned long *) argp = readEnd - readPtr;
-
- return 0;
- default:
- return GUSI_error(EOPNOTSUPP);
- }
- }
-
- int MPPseudoSocket::read(void * buffer, int buflen)
- {
- buflen = min(int(readEnd - readPtr), buflen);
-
- memcpy(buffer, (*data) + readPtr, buflen);
-
- readPtr += buflen;
-
- return buflen;
- }
-
- int MPPseudoSocket::select(Boolean * canRead, Boolean * canWrite, Boolean * exception)
- {
- int goodies = 0;
-
- if (canRead)
- if (*canRead = readEnd > readPtr)
- ++goodies;
-
- if (canWrite)
- *canWrite = false;
-
- if (exception)
- *exception = false;
-
- return goodies;
- }
-
- long MPPseudoSocket::lseek(long offset, int whence)
- {
- long nuReadPtr;
-
- switch (whence) {
- case SEEK_END:
- nuReadPtr = readEnd + offset;
- break;
- case SEEK_CUR:
- nuReadPtr = readPtr + offset;
- break;
- case SEEK_SET:
- nuReadPtr = offset;
- break;
- default:
- return GUSI_error(EINVAL);
- }
-
- if (nuReadPtr > readEnd)
- return GUSI_error(ESPIPE);
- if (nuReadPtr < 0)
- return GUSI_error(EINVAL);
-
- return readPtr = nuReadPtr;
- }
-
- /********************* MPPseudoSocketDomain member **********************/
-
- #pragma force_active on
-
- Socket * MPPseudoSocketDomain::open(const char * filename, int flags)
- {
- Socket * sock = nil;
- char title[256];
- Boolean nudoc = false;
-
- strncpy(title, filename, 6);
- title[6] = 0;
-
- if (equalstring(title, (char *) "Pseudo", false, true)) {
- switch (filename[6]) {
- case ':':
- ++filename;
- case 0:
- filename += 6;
- break;
- default:
- goto nope;
- }
-
- if (flags & ~O_BINARY)
- return (Socket *) GUSI_error_nil(EPERM);
-
- if (!*filename) {
- sock = new MPPseudoSocket(gPseudoFile);
-
- gPseudoFile = nil;
- } else {
- short res = CurResFile();
- Handle data;
-
- UseResFile(gScriptFile);
-
- data = getnamedresource('TEXT', (char *) filename);
-
- if (data) {
- DetachResource(data);
-
- sock = new MPPseudoSocket(data);
- }
-
- UseResFile(res);
- }
-
- return sock;
- }
-
- nope:
- return (Socket *) TryNextDevice;
- }
-