8.1 Basicsocket Interface

ORIGIN '~beta/basiclib/basicsystemenv';
LIB_DEF 'processbasic' '../lib';

(*
 * COPYRIGHT
 *       Copyright (C) Mjolner Informatics 1995-97
 *       All rights reserved.
 *)
INCLUDE 'errorcallback';
INCLUDE 'commaddress';

--- systemlib:attributes ---
(* Used for timeouts *)
waitForever: (# exit -1 #);

(* Used to make it checkable whether something is uninitialized *)
assignGuard: (# assigned: @Boolean do true -> assigned #);

(* The number 127.0.0.1 by convention is 'this host' *)
localHost_IP_number: (# exit 2130706433 #);

BasicSocket: 
  (# <<SLOT socketlib:attributes>>;

     (* OPERATIONS
      * ==========
      *)

     (* do 'this' and 'other' wrap the same OS level connection? *)
     sameConnection: booleanValue
       (# other: ^basicSocket;
       enter other[]
       ...
       #);
     
     (* construct portable address for this connection *)
     getPortableAddress:
       (# addr: ^portablePortAddress;
       ...
       exit addr[]
       #);

     (* Initiator of socket communication. 
      * Pass 'host' and 'port' to 'connect' to connect 
      * to a passive socket to establish communication.
      * If you need to control the local port number, 
      * use firstLocalPort and lastLocalPort. These are then 
      * tried one at a time starting with first and ending 
      * with last. None of them can be zero.
      *)
     connect: open
       (# accessError:< loErrCB(# do INNER #);
          resourceError:< loErrCB(# do INNER #);
          addressError:< loErrCB(# do INNER #);
          refusedError:< loErrCB(# do INNER #);
          intrError:< loErrCB(# do INNER #);
          getHostError:< loErrCB(# do INNER #);
          firstLocalPort:<IntegerValue;
          lastLocalPort:<IntegerValue;
          aHost: ^Text;
          aPort: @Integer;
       enter (aHost[],aPort)
       ...
       #);
     
     (* provoke a timeout error in the current operation *)
     forceTimeout:< (# ... #);

     (* return timestamp of latest operation on this socket *)
     usageTimestamp:< integerValue
       (# ... #);
     
     (* return true iff no data is 
      * immediately available for reading 
      *)
     endOfDataPattern:
       (# error:< hiErrCB (* operation level error callback *)
            (#
            do INNER;
               (if value=errCB_initialValue then
                   (value,cleanup[])->this(basicSocket).error->value;
               if);
            #);
          loErrCB: errCB (* superpattern for 
                          * concrete error callbacks *)
            (#
            do INNER;
               (if value=errCB_initialValue then
                   (value,cleanup[])->error->value;
               if);
            #);
          connBrokenError:< loErrCB(# do INNER #);
          internalError:< loErrCB(# do INNER #);
          unknownError:< loErrCB(# do INNER #);
          value: @boolean;
       ...
       exit value
       #);

     (* Close socket completely. Any further operations are
      * disallowed and the other end gets EOS if it tries *)
     close: withIdle(# ... #);

     (* Close socket partially. closeRead makes further reads
      * at this end of the socket and further writes at
      * the other end fail with EOS. *)
     closeRead: (# ... #);
     
     (* Close socket partially. closeWrite makes further writes
      * at this end of the socket and further reads at
      * the other end fail with EOS. *)
     closeWrite: (# ... #);
     
     (* CALLBACKS
      * =========
      *)

     (* every local 'idle' executes this global one *)
     idle:< Object;

     (* socket level error callback *)
     error:< hiErrCB(# do INNER #);


     (* EXPLICIT SCHEDULING
      * ===================
      *)

     (* NB: don`t 'leave' a 'nonBlockingScope'. Use 'leaveNBScope'. *)
     nonBlockingScope: (# ... #);
     leaveNBScope: (# ... #);


     (* ATTRIBUTES
      * ==========
      *)

     host: @assignGuard(# t: @text; enter t exit t #);
     port: @assignGuard(# rep: @integer enter rep exit rep #);
     inetAddr: @assignGuard(# rep: @integer enter rep exit rep #);


     (* AUXILIARY PATTERNS
      * ==================
      *)

     withPE:
       (# error:< hiErrCB (* operation level error callback *)
            (#
            do INNER;
               (if value=errCB_initialValue then
                   (value,cleanup[])->this(basicSocket).error->value;
               if);
            #);
          loErrCB: errCB (* superpattern for 
                          * concrete error callbacks *)
            (#
            do INNER;
               (if value=errCB_initialValue then
                   (value,cleanup[])->error->value;
               if);
            #);
          timedOut:< loErrCB(# do INNER #);
          timedOutInTransfer:< loErrCB(# do INNER #);
          internalError:< loErrCB(# do INNER #);
          connBrokenError:< loErrCB(# do INNER #);
          usageError:< loErrCB(# do INNER #);
          unknownError:< loErrCB(# do INNER #);
          resourceError:< loErrCB(# do INNER #);
          badMsgError:< loErrCB(# do INNER #);
          timeout: @integer;
       enter timeout
       do INNER
       #);

     withIdle: withPE
       (# idle:< (# do INNER; this(basicSocket).idle #);
          blocking:<
            (# continue: (# do true->doContinue #);
               doContinue: @boolean;
            do INNER;
               (if not doContinue then leaveNBScope if);
               idle;
            #);
       do INNER
       #);

     open: withIdle(# ... #);
     init:< (# ... #);

     private: @...;
  #)


8.1 Basicsocket Interface
© 1994-2002 Mjølner Informatics
[Modified: Monday December 7th 1998 at 13:09]