//  Procedure to call the ring PS.MAP service.  The arguments given are as
//  follows:
//
//      name         string      name to be mapped
//      fromdomain   string      name of source domain
//      todomain     string      name of target domain
//      result       pointer     pointer to result buffer 
//      length       number      size of result buffer in bytes
//
//  The following headers are assumed:
//
//      GET "LIBHDR"
//      GET "RINGHDR"
//
//  This is the Z80 BCPL version.


LET ringmap( name, fromdomain, todomain, result, length )  =  VALOF
$(
//  Routine to call the PS.MAP service, mapping the name "name" from the
//  "fromdomain" to the "todomain".  The result is stored in "result".

    LET txbuff  =  VEC max.ssp.size
    LET rxbuff  =  VEC max.ssp.size

    LET ln      =  name % 0
    LET lf      =  fromdomain % 0
    LET lt      =  todomain % 0
    
    LET toff    =  bb.ssp.args * bytesperringword
    LET roff    =  bb.ssp.args * bytesperringword

    LET off     =  toff
    LET oft     =  off + lf + 1
    LET ofn     =  oft + lt + 1
    LET total   =  ofn + ln + 1
    
    LET txsize  =  (total + 1)/bytesperringword  -  bb.ssp.type
    LET rxsize  =  max.ssp.size

    //  First, check that the transmission block is long enough to take the
    //  strings given to us.
    
    IF  txsize > max.ssp.size  THEN
    $(
        //  The user is mucking us about by giving us strings that are
        //  too long.  Off with his head!
        
        result2  :=  #XA001
        
        RESULTIS  FALSE
    $)

    //  The transmission buffer is large enough, so we can copy the strings
    //  across into it.

    FOR  i = 0  TO  lf  DO  txbuff % (off + i)  :=  fromdomain % i
    FOR  i = 0  TO  lt  DO  txbuff % (oft + i)  :=  todomain % i
    FOR  i = 0  TO  ln  DO  txbuff % (ofn + i)  :=  name % i

    //  Now call the map service to do the mapping.  If the SSP fails, then
    //  return the error value.

    txbuff!bb.ssp.length  :=  txsize
    rxbuff!bb.ssp.length  :=  rxsize

    UNLESS  ssp( "PS.MAP", txbuff, rxbuff )  DO  RESULTIS  FALSE

    //  We have been given a result by the map service, but is the block given
    //  to us by the user large enough to hold it.
    
    IF  rxbuff % roff  >  length  THEN
    $(
        //  The block given to us by the user isn't long enough.  Set the
        //  return code appropriately, and return.
        
        result2  :=  #XA001
        
        RESULTIS  FALSE
    $)
    
    //  Otherwise, we can copy the result given to us from the reply block
    //  into the user's buffer.

    FOR  i = 0  TO  rxbuff % roff  DO  result % i  :=  rxbuff % (roff + i)

    RESULTIS  TRUE
$)


