8.4 Commaddress Interface

ORIGIN '~beta/basiclib/betaenv';
LIB_DEF 'processaddress' '../lib';

(*
 * COPYRIGHT
 *       Copyright (C) Mjolner Informatics 1994-97
 *       All rights reserved.
 *)

BODY 'private/commaddressbody';

(* CONTENTS
 * ========
 *
 * Defines patterns for representing communication addresses.
 *
 * The most abstract pattern, portableCommAddress, models a
 * portable communication address. This specifies the address
 * of a single destination or the address(es) of a group of
 * destinations.
 *
 * The patterns portableMultiAddress and portablePortAddress
 * specialize portableCommAddress into concrete patterns for
 * the multiple-destination case and one-destination case,
 * respectively.
 *
 * The pattern concretePortAddress and its specializations
 * represent non-portable, protocol specific communication
 * port addresses. These are kept in portableCommAddresses
 * and selected according to protocol specifications, given
 * as protocolSpec objects.
 * 
 * As a best-fit addition, there are also some patterns
 * to aid the process of looking up TCP/IP hosts, getting the
 * hostname of this machine, etc.
 * 
 *)

--- lib:attributes ---
(* Reliability
 * ===========
 *
 * Used to specify the reliability proporties
 * required for a transfer (in a protocolSpec).
 * The proporties are additive. 
 *)

commRely_dontcare:   (# exit 0 #);
commRely_loss:       (# exit 2 #); (* packets are not lost *)
commRely_dup:        (# exit 4 #); (* packets are not duplicated *)
commRely_order:      (# exit 8 #); (* packets arrive 
                                    * in correct order *)
commRely_contents:   (# exit 16 #); (* corrupt data unlikely 
                                     * (e.g. checksum) *)

commRely_unreliable: (# exit 1 #); (* ensures none of the above *)
commRely_reliable:   (# exit 31 #); (* ensure loss, dup, 
                                     * order & contents *)


(* Type of connection protocol
 * ===========================
 *
 * OS level category of connection. An implementation
 * level description of an individual connection
 * managed by a connectionPool. Weird numbers chosen
 * to make data containing these constants recognizable
 * in a raw communication dump.
 *)

commProtocol_dontcare:   (# exit 0 #);
commProtocol_tcp:        (# exit 72301 #); (* TCP/IP *)
commProtocol_udp:        (# exit 72302 #); (* UDP/IP *)
commProtocol_unix:       (# exit 72303 #); (* UNIX domain 
                                            * (socket as file) *)
commProtocol_ppc:        (# exit 72304 #); (* Mac PPC ToolBox *)
commProtocol_mem:        (# exit 72305 #); (* Shared memory buffer *)

(* Mnemonic names of the protocols *)
commProtName_tcp:        (# exit 'TCP' #);
commProtName_udp:        (# exit 'UDP' #);
commProtName_unix:       (# exit 'UNIX' #);
commProtName_ppc:        (# exit 'PPC' #);
commProtName_mem:        (# exit 'MEM' #);


(* Specification of connection requirements
 * ========================================
 *
 * Used to package spec. of requirements to a communication
 * transfer, and then given to a portablePortAddress, which
 * will use it when choosing an appropriate channel.
 *)
protocolSpec:
  (#
     cType: @integer; (* one of 'commProtocol_.*'
                       * dontcare is default *)
     rType: @integer; (* one of 'commRely_.*'
                       * dontcare is default *)
     (* bandwidth/r-rr-rra/etc *)
  enter (cType, rType)
  exit cType
  #);


(* Portable communication address
 * ==============================
 *
 * Specifies identity of an abstract communication address.
 * This pattern is abstract, and no instances of it are
 * expected to exist. The patterns portableMultiAddress and
 * portablePortAddress are non-abstract specializations.
 *
 * Any portableCommAddress is able to express its value
 * in textual form, by 'asText'.
 * 
 * Tell a portableCommAddress what proporties are required
 * of the communications associated with it by entering
 * a protocolSpec object. This affects its choice of
 * concrete communication port(s) in subsequent
 * communications.
 *)
portableCommAddress:
  (#
     init:< Object;
     asText: @asTextPattern;

     (* private *)
     asTextPattern:< (# t: ^text do INNER exit t[] #);
     enterSpec: @...;
     private: @...;
  enter enterSpec
  #);


(* Portable communication address constructor
 * ==========================================
 *
 * Function. Takes a text value, which is expected to have
 * been produced by some instance X of a specialization of
 * portableCommAddress using its 'asText'. Returns an object
 * with the same value as X.
 *
 * Problems are reported by invoking 'parseError'. The 
 * application will then terminate with an exception,
 * unless you furtherbind parseError to leave it.
 *)
portableCommAddressFromText:
  (# 
     parseError:<
       (# msg: ^text;
       enter msg[]
       ...
       #);
     txt: ^text;
     addr: ^portableCommAddress;
     <<SLOT portableCommAddressFromTextLib:attributes>>;
  enter txt[]
  ...
  exit addr[]
  #);


(* Portable multicast address
 * ==========================
 *
 * Specifies identities of the members of a group of
 * communication destinations.
 *
 * The group can be built from scratch or enhanced
 * by 'insert'ing members. It can be reduced by
 * 'delete'ing members. 
 *)
portableMultiAddress: portableCommAddress
  (#
     init::< (# ... #);

     insert:
       (# addr: ^portablePortAddress;
       enter addr[]
       ...
       #);

     delete:
       (# addr: ^portablePortAddress;
       enter addr[]
       ...
       #);
     
     (* private *)
     asTextPattern::< (# ... #);
     private2: @...;
  #);


(* Portable communication port address
 * ===================================
 *
 * Specifies identity of one logical communication destination.
 * A logical destination corresponds to a number of concrete
 * communication ports, represented by instances of
 * specializations of concretePortAddress.
 *
 * A portablePortAddress can be built from scratch by
 * by 'insert'ing such instances. Only one concrete address
 * is allowed for each known type - inserting a second instance
 * overrides the previously inserted one. 
 *)
portablePortAddress: portableCommAddress
  (#
     insert:
       (# addr: ^concretePortAddress;
          addrHasUnknownType:< exception;
       enter addr[]
       ...
       #);
     delete:
       (# prot: @integer; (* one of 'commProtocol_.*' *)
          addrHasUnknownType:< exception;
       enter prot
       ...
       #);
     getTcpPort:
       (# addr: ^tcpPortAddress;
       ...
       exit addr[] (* NONE if not present *)
       #);
     getUdpPort:
       (# addr: ^udpPortAddress;
       ...
       exit addr[] (* NONE if not present *)
       #);
     getUnixPort:
       (# addr: ^unixPortAddress;
       ...
       exit addr[] (* NONE if not present *)
       #);
     getPpcPort:
       (# addr: ^ppcPortAddress;
       ...
       exit addr[] (* NONE if not present *)
       #);
     getMemPort:
       (# addr: ^memPortAddress;
       ...
       exit addr[] (* NONE if not present *)
       #);

     (* private *)
     asTextPattern::< (# ... #);
     private2: @...;
  #);


(* Concrete communication port address
 * ===================================
 *
 * Abstract superpattern for specifying the address
 * of a concrete communication port, such as a UN*X
 * stream socket, a Mac PPC ToolBox session, a shared
 * memory buffer etc.
 *
 * Is able to express its value textually with 'asText',
 * and to characterize its communication protocol
 * with 'commType'. 
 *)
concretePortAddress:
  (#
     asText: @asTextPattern;
     asTextPattern:< (# t: ^text do INNER exit t[] #);
     
     protocol:< integerValue; (* one of 'commProtocol_.*' *)
     protName:< (# t: ^text do &text[] -> t[]; INNER exit t[] #);
     conformsTo: BooleanValue
       (# p: @integer;
       enter p
       ...
       #);
     private: @...;
  #);


(* Unix communication port address types
 * =====================================
 *
 * The pattern unixAbstractPortAddress captures similarities
 * between TCP and UDP ports, represented by
 * tcpPortAddress and udpPortAddress. 
 *
 * The pattern unixPortAddress represents an AF_UNIX address
 * family socket, i.e. it appears as a name in some directory,
 * just like a file. 
 * 
 * NB: The tcpPortAddress also fits a MacTCP port.
 *)
unixAbstractPortAddress: concretePortAddress
  (#
     inetAddr: @integer;
     portNo: @integer;
     asTextPattern::< (# ... #);
  #);

tcpPortAddress: unixAbstractPortAddress
  (#
     protocol::< (# do commProtocol_tcp -> value #);
     protName::< (# do commProtName_tcp -> t #);
  #);

udpPortAddress: unixAbstractPortAddress
  (#
     protocol::< (# do commProtocol_udp -> value #);
     protName::< (# do commProtName_udp -> t #);
  #);

unixPortAddress: concretePortAddress
  (#
     asTextPattern::< (# ... #);
     pathName: @text;
     protocol::< (# do commProtocol_unix -> value #);
     protName::< (# do commProtName_unix -> t #);
  #);


(* Mac communication port address
 * ==============================
 *
 * Represents a PPC ToolBox session.
 *)
ppcPortAddress: concretePortAddress
  (#
     host: @text;
     portNo: @integer;
     sessionId: @integer;
     asTextPattern::< (# ... #);
     protocol::< (# do commProtocol_ppc -> value #);
     protName::< (# do commProtName_ppc -> t #);
  #);


(* Shared memory buffer port address
 * =================================
 * 
 * Corresponding communication support NOT IMPLEMENTED.
 * Could be very fast, perhaps for communicating within
 * one process, using the same source code as for remote
 * communication.
 *)
memPortAddress: concretePortAddress
  (#
     bufferID: @integer; (* !!! This may have to change *)
     asTextPattern::< (# ... #);
     protocol::< (# do commProtocol_mem -> value #);
     protName::< (# do commProtName_mem -> t #);
  #);


(* IPv4 Miscellaneous address conversions *)

(* Look up the IPv4 address of a given host. *)
gethostbyname:
  (#
     notfound:< Exception;
     name: ^Text;     
     inadr: @Integer; 
  enter name[]
  ...
  exit inadr
  #);

(* Look up the name of a given IPv4 address. *)
gethostbyaddr:
  (#
     notfound:< Exception;
     name: ^Text;
     inadr: @Integer;
  enter inadr
     ...
  exit name[]
  #);

(* Find the name and IPv4 address of this host. *)
thisHost:
  (# name: ^Text;
     inadr: @Integer;
     err: @Integer; (* Private *)
     ...
  exit (name[], inadr)
  #)


8.4 Commaddress Interface
© 1994-2002 Mjølner Informatics
[Modified: Tuesday March 7th 2000 at 20:17]