home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 15 / BBS in a box XV-2.iso / Files II / Prog / M / MacPerl 4.13 source.sit / Perl Source ƒ / MacPerl / MPPseudoFile.cp < prev    next >
Encoding:
Text File  |  1994-02-27  |  3.6 KB  |  190 lines  |  [TEXT/MPS ]

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