home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / MacPerl 5.1.3 / Mac_Perl_513_src / MacPerl5 / MPPseudoFile.cp < prev    next >
Encoding:
Text File  |  1996-04-22  |  3.6 KB  |  189 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. #undef open
  26.  
  27. #define AF_PSEUDO 18
  28.  
  29. class MPPseudoSocket;                             // That's what this file's all about
  30.  
  31. class MPPseudoSocket : public Socket    {        
  32.     friend class MPPseudoSocketDomain;    
  33.     
  34.                     MPPseudoSocket(Handle hdl);
  35.                     
  36.     virtual         ~MPPseudoSocket();
  37.     
  38.     Handle        data;
  39.     long            readEnd;
  40.     long            readPtr;
  41. public:
  42.     virtual int    read(void * buffer, int buflen);
  43.     virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
  44.     virtual int    ioctl(unsigned int request, void *argp);
  45.     virtual long lseek(long offset, int whence);
  46. };    
  47.  
  48. class MPPseudoSocketDomain : public FileSocketDomain {
  49. public:
  50.     MPPseudoSocketDomain()    :    FileSocketDomain(AF_PSEUDO, true, false)    {    }
  51.     
  52.     virtual Boolean Yours(const GUSIFileRef & ref, Request request);
  53.     virtual Socket * open(const GUSIFileRef & ref, int oflag);
  54. };
  55.  
  56. MPPseudoSocketDomain    MPPseudoSockets;
  57.  
  58. #if !defined(powerc) && !defined(__powerc)
  59. #pragma segment MPPseudo
  60. #endif
  61.  
  62. /************************ MPPseudoSocket members ************************/
  63.  
  64. void InitPseudo()
  65. {
  66.     MPPseudoSockets.DontStrip();
  67. }
  68.  
  69. MPPseudoSocket::MPPseudoSocket(Handle hdl)
  70.     : data(hdl)
  71. {
  72.     readPtr    =    0;
  73.     readEnd    =    GetHandleSize(data);
  74. }
  75.  
  76. MPPseudoSocket::~MPPseudoSocket()
  77. {
  78.     DisposeHandle(data);
  79. }
  80.  
  81. int MPPseudoSocket::ioctl(unsigned int request, void *argp)
  82. {
  83.     switch (request)    {
  84.     case FIONREAD:
  85.         *(unsigned long *) argp    = readEnd - readPtr;
  86.         
  87.         return 0;
  88.     default:
  89.         return GUSI_error(EOPNOTSUPP);
  90.     }
  91. }
  92.  
  93. int MPPseudoSocket::read(void * buffer, int buflen)
  94. {
  95.     buflen = min(int(readEnd - readPtr), buflen);
  96.     
  97.     memcpy(buffer, (*data) + readPtr, buflen);
  98.     
  99.     readPtr += buflen;
  100.     
  101.     return buflen;
  102. }
  103.  
  104. int MPPseudoSocket::select(Boolean * canRead, Boolean * canWrite, Boolean * exception)
  105. {
  106.     int        goodies     =     0;
  107.         
  108.     if (canRead)
  109.         if (*canRead = readEnd > readPtr)
  110.             ++goodies;
  111.     
  112.     if (canWrite)
  113.         *canWrite = false;
  114.     
  115.     if (exception)
  116.         *exception = false;
  117.     
  118.     return goodies;
  119. }
  120.  
  121. long MPPseudoSocket::lseek(long offset, int whence)
  122. {
  123.     long    nuReadPtr;
  124.     
  125.     switch (whence) {
  126.     case SEEK_END:
  127.         nuReadPtr = readEnd + offset;
  128.         break;
  129.     case SEEK_CUR:
  130.         nuReadPtr = readPtr + offset;
  131.         break;
  132.     case SEEK_SET:
  133.         nuReadPtr = offset;
  134.         break;
  135.     default:
  136.         return GUSI_error(EINVAL);
  137.     }
  138.     
  139.     if (nuReadPtr > readEnd)
  140.         return GUSI_error(ESPIPE);
  141.     if (nuReadPtr < 0)
  142.         return GUSI_error(EINVAL);
  143.     
  144.     return readPtr = nuReadPtr;
  145. }
  146.  
  147. /********************* MPPseudoSocketDomain member **********************/
  148.  
  149. Boolean MPPseudoSocketDomain::Yours(const GUSIFileRef & ref, FileSocketDomain::Request)
  150. {
  151.     char      name[8];
  152.  
  153.     strncpy(name, ref.name+4, 6);
  154.     name[6] = 0;
  155.     
  156.     return equalstring(name, (char *) "pseudo", false, true);
  157. }
  158.  
  159. Socket * MPPseudoSocketDomain::open(const GUSIFileRef & ref, int flags)
  160. {
  161.     Socket *            sock = nil;
  162.  
  163.     if ((flags & O_ACCMODE) != O_RDONLY)
  164.         return (Socket *) GUSI_error_nil(EPERM);
  165.         
  166.     if (!ref.name[10]) {
  167.         sock = new MPPseudoSocket(gPseudoFile);
  168.         
  169.         gPseudoFile = nil;
  170.     } else {
  171.         short        res    =    CurResFile();
  172.         Handle    data;
  173.         
  174.         UseResFile(gScriptFile);
  175.         
  176.         data = getnamedresource('TEXT', (char *) ref.name+11);
  177.         
  178.         if (data) {
  179.             DetachResource(data);
  180.             
  181.             sock = new MPPseudoSocket(data); 
  182.         }
  183.         
  184.         UseResFile(res);
  185.     }
  186.  
  187.     return sock;
  188. }
  189.