home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / MacPerl 5.0.3 / MacPerl Source ƒ / Perl5 / MemoryStream.cp < prev    next >
Encoding:
Text File  |  1995-05-09  |  3.9 KB  |  194 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Standalone Perl
  3. File        :    MPConsole.cp    -    Console interface for GUSI
  4. Author    :    Matthias Neeracher
  5. Language    :    MPW C/C++
  6.  
  7. $Log: MPConsole.cp,v $
  8. *********************************************************************/
  9.  
  10. #include <GUSIFile_P.h>
  11.  
  12. #include <stdio.h>
  13. #include <ioctl.h>
  14.  
  15. class MemSocket : public Socket    {        
  16.     friend class MemSocketDomain;    
  17.     
  18.                     MemSocket(Handle data);
  19.                     
  20.     virtual         ~MemSocket();
  21.     
  22.     Handle        data;
  23.     long            maxData;
  24.     long            readPtr;
  25.     MemSocket *    next;
  26. public:
  27.     virtual int    read(void * buffer, int buflen);
  28.     virtual int write(void * buffer, int buflen);
  29.     virtual int select(Boolean * canRead, Boolean * canWrite, Boolean * exception);
  30.     virtual int    ioctl(unsigned int request, void *argp);
  31. };    
  32.  
  33. class MemSocketDomain : public FileSocketDomain {
  34.     friend class MemSocket;
  35.     
  36.     MemSocket * first;
  37.     Handle        nextLookup;
  38. public:
  39.     MemSocketDomain();
  40.     
  41.     virtual Boolean Yours(const GUSIFileRef & ref, Request request);
  42.     virtual Socket * open(const GUSIFileRef & ref, int oflag);
  43.     
  44.     MemSocket * Lookup(Handle hand);
  45. };
  46.  
  47. static Handle                     StdSockets[3];
  48. static MemSocketDomain         MemSockets;
  49.  
  50. extern "C" void InstallMemConsole(Handle input, Handle output, Handle error)
  51. {
  52.     StdSockets[0] = input;
  53.     StdSockets[1] = output;
  54.     StdSockets[2] = error;
  55.  
  56.     freopen("dev:stdin", "r", stdin);
  57.     freopen("dev:stdout", "w", stdout);
  58.     freopen("dev:stderr", "w", stderr); 
  59. }
  60.  
  61. /************************ MemSocket members ************************/
  62.  
  63. MemSocket::MemSocket(Handle data)
  64.     : data(data), maxData(GetHandleSize(data)), readPtr(0), next(nil)
  65. {
  66. }
  67.  
  68. MemSocket::~MemSocket()
  69. {
  70.     for (int i = 0; i<3; ++i)
  71.         if (StdSockets[i] == data)
  72.             StdSockets[i] = nil;
  73. }
  74.  
  75. int MemSocket::ioctl(unsigned int request, void *argp)
  76. {
  77.     switch (request)    {
  78.     case FIONREAD:
  79.         *(unsigned long *) argp    = maxData - readPtr;
  80.         
  81.         return 0;
  82.     default:
  83.         return GUSI_error(EOPNOTSUPP);
  84.     }
  85. }
  86.  
  87. int MemSocket::read(void * buffer, int buflen)
  88. {
  89.     buflen = min(buflen, maxData - readPtr);
  90.     HLock(data);
  91.     memcpy(buffer, *data+readPtr, buflen);
  92.     HUnlock(data);
  93.     readPtr += buflen;
  94.     
  95.     return buflen;
  96. }
  97.  
  98. int MemSocket::write(void * buffer, int buflen)
  99. {
  100.     if (PtrAndHand(buffer, data, buflen))
  101.         return GUSI_error(ENOMEM);
  102.     
  103.     maxData += buflen;
  104.     
  105.     return buflen;
  106. }
  107.  
  108. int MemSocket::select(Boolean * canRead, Boolean * canWrite, Boolean *)
  109. {
  110.     int        goodies     =     0;
  111.         
  112.     if (canRead) {
  113.         *canRead = true;
  114.         ++goodies;
  115.     }    
  116.     
  117.     if (canWrite) {
  118.         *canWrite = true;
  119.         ++goodies;
  120.     }    
  121.     
  122.     return goodies;
  123. }
  124.  
  125. /********************* MemSocketDomain members **********************/
  126.  
  127. #if !defined(powerc) && !defined(__powerc)
  128. #pragma force_active on
  129. #endif
  130.  
  131. MemSocketDomain::MemSocketDomain()
  132.     :    FileSocketDomain(AF_UNSPEC, true, false)
  133. {
  134. }
  135.  
  136. Boolean MemSocketDomain::Yours(const GUSIFileRef & ref, FileSocketDomain::Request request)
  137. {
  138.     if (ref.spec || (request != willOpen))
  139.         return false;
  140.     
  141.     if (
  142.             (ref.name[4] | 0x20) == 's'
  143.         && (ref.name[5] | 0x20) == 't' 
  144.         && (ref.name[6] | 0x20) == 'd'
  145.     ) 
  146.         switch (ref.name[7] | 0x20) {
  147.         case 'i':
  148.             return     (ref.name[8] | 0x20) == 'n' 
  149.                     && (nextLookup = StdSockets[0]) != nil;
  150.         case 'o':
  151.             return    (ref.name[8] | 0x20) == 'u' 
  152.                     && (ref.name[9] | 0x20) == 't' 
  153.                     && (nextLookup = StdSockets[1]) != nil;
  154.         case 'e':
  155.             return     (ref.name[8] | 0x20) == 'r' 
  156.                     && (ref.name[9] | 0x20) == 'r' 
  157.                     && (nextLookup = StdSockets[2]) != nil;
  158.         default:
  159.             return false;
  160.         }
  161.     else if (!strncmp(ref.name+4, "Handle", 6)) {
  162.         char * end;
  163.         
  164.         switch (ref.name[10]) {
  165.         case 0:
  166.             return false;
  167.         case ':':
  168.             nextLookup = (Handle) strtoul(ref.name+11, &end, 0);
  169.             
  170.             return end > ref.name+11 && !*end;
  171.         }
  172.     }
  173.     
  174.     return false;
  175. }
  176.  
  177. Socket * MemSocketDomain::open(const GUSIFileRef &, int)
  178. {
  179.     return Lookup(nextLookup);
  180. }
  181.  
  182. MemSocket * MemSocketDomain::Lookup(Handle hand)
  183. {
  184.     MemSocket * sock = first;
  185.     
  186.     while (sock)
  187.         if (sock->data == hand)
  188.             return sock;
  189.         else
  190.             sock = sock->next;
  191.     
  192.     return new MemSocket(hand);
  193. }
  194.