home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacPerl 5.0.3 / MacPerl Source ƒ / MacPerl5 / MPPseudoFile.cp < prev    next >
Encoding:
Text File  |  1995-10-20  |  3.6 KB  |  187 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl                -    Standalone Perl
  3. File        :    MPPseudoFile.cp    -    Pseudo files for GUSI
  4. Author    :    Matthias Neeracher
  5. Language    :    MPW C/C++
  6. $Log: MPPseudoFile.cp,v $
  7. Revision 1.1  1994/02/27  23:05:08  neeri
  8. Initial revision
  9.  
  10. *********************************************************************/
  11.  
  12. #include <GUSIFile_P.h>
  13.  
  14. #include <ioctl.h>
  15. #include <sys/types.h>
  16. #include <Resources.h>
  17. #include <TextUtils.h>
  18.  
  19. extern "C" {
  20. #include "MPGlobals.h"
  21. }
  22.  
  23. #include "MPPseudoFile.h"
  24.  
  25. #define AF_PSEUDO 18
  26.  
  27. class MPPseudoSocket;                             // That's what this file's all about
  28.  
  29. class MPPseudoSocket : public Socket    {        
  30.     friend class MPPseudoSocketDomain;    
  31.     
  32.                     MPPseudoSocket(Handle hdl);
  33.                     
  34.     virtual         ~MPPseudoSocket();
  35.     
  36.     Handle        data;
  37.     long            readEnd;
  38.     long            readPtr;
  39. public:
  40.     virtual int    read(void * buffer, int buflen);
  41.     virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
  42.     virtual int    ioctl(unsigned int request, void *argp);
  43.     virtual long lseek(long offset, int whence);
  44. };    
  45.  
  46. class MPPseudoSocketDomain : public FileSocketDomain {
  47. public:
  48.     MPPseudoSocketDomain()    :    FileSocketDomain(AF_PSEUDO, true, false)    {    }
  49.     
  50.     virtual Boolean Yours(const GUSIFileRef & ref, Request request);
  51.     virtual Socket * open(const GUSIFileRef & ref, int oflag);
  52. };
  53.  
  54. MPPseudoSocketDomain    MPPseudoSockets;
  55.  
  56. #if !defined(powerc) && !defined(__powerc)
  57. #pragma segment MPPseudo
  58. #endif
  59.  
  60. /************************ MPPseudoSocket members ************************/
  61.  
  62. void InitPseudo()
  63. {
  64.     MPPseudoSockets.DontStrip();
  65. }
  66.  
  67. MPPseudoSocket::MPPseudoSocket(Handle hdl)
  68.     : data(hdl)
  69. {
  70.     readPtr    =    0;
  71.     readEnd    =    GetHandleSize(data);
  72. }
  73.  
  74. MPPseudoSocket::~MPPseudoSocket()
  75. {
  76.     DisposeHandle(data);
  77. }
  78.  
  79. int MPPseudoSocket::ioctl(unsigned int request, void *argp)
  80. {
  81.     switch (request)    {
  82.     case FIONREAD:
  83.         *(unsigned long *) argp    = readEnd - readPtr;
  84.         
  85.         return 0;
  86.     default:
  87.         return GUSI_error(EOPNOTSUPP);
  88.     }
  89. }
  90.  
  91. int MPPseudoSocket::read(void * buffer, int buflen)
  92. {
  93.     buflen = min(int(readEnd - readPtr), buflen);
  94.     
  95.     memcpy(buffer, (*data) + readPtr, buflen);
  96.     
  97.     readPtr += buflen;
  98.     
  99.     return buflen;
  100. }
  101.  
  102. int MPPseudoSocket::select(Boolean * canRead, Boolean * canWrite, Boolean * exception)
  103. {
  104.     int        goodies     =     0;
  105.         
  106.     if (canRead)
  107.         if (*canRead = readEnd > readPtr)
  108.             ++goodies;
  109.     
  110.     if (canWrite)
  111.         *canWrite = false;
  112.     
  113.     if (exception)
  114.         *exception = false;
  115.     
  116.     return goodies;
  117. }
  118.  
  119. long MPPseudoSocket::lseek(long offset, int whence)
  120. {
  121.     long    nuReadPtr;
  122.     
  123.     switch (whence) {
  124.     case SEEK_END:
  125.         nuReadPtr = readEnd + offset;
  126.         break;
  127.     case SEEK_CUR:
  128.         nuReadPtr = readPtr + offset;
  129.         break;
  130.     case SEEK_SET:
  131.         nuReadPtr = offset;
  132.         break;
  133.     default:
  134.         return GUSI_error(EINVAL);
  135.     }
  136.     
  137.     if (nuReadPtr > readEnd)
  138.         return GUSI_error(ESPIPE);
  139.     if (nuReadPtr < 0)
  140.         return GUSI_error(EINVAL);
  141.     
  142.     return readPtr = nuReadPtr;
  143. }
  144.  
  145. /********************* MPPseudoSocketDomain member **********************/
  146.  
  147. Boolean MPPseudoSocketDomain::Yours(const GUSIFileRef & ref, FileSocketDomain::Request)
  148. {
  149.     char      name[8];
  150.  
  151.     strncpy(name, ref.name+4, 6);
  152.     name[6] = 0;
  153.     
  154.     return equalstring(name, (char *) "pseudo", false, true);
  155. }
  156.  
  157. Socket * MPPseudoSocketDomain::open(const GUSIFileRef & ref, int flags)
  158. {
  159.     Socket *            sock = nil;
  160.  
  161.     if ((flags & O_ACCMODE) != O_RDONLY)
  162.         return (Socket *) GUSI_error_nil(EPERM);
  163.         
  164.     if (!ref.name[10]) {
  165.         sock = new MPPseudoSocket(gPseudoFile);
  166.         
  167.         gPseudoFile = nil;
  168.     } else {
  169.         short        res    =    CurResFile();
  170.         Handle    data;
  171.         
  172.         UseResFile(gScriptFile);
  173.         
  174.         data = getnamedresource('TEXT', (char *) ref.name+11);
  175.         
  176.         if (data) {
  177.             DetachResource(data);
  178.             
  179.             sock = new MPPseudoSocket(data); 
  180.         }
  181.         
  182.         UseResFile(res);
  183.     }
  184.  
  185.     return sock;
  186. }
  187.