@X @~
~V7 56 2 -5
~D10
~H                    MUSS
~
~
~D10
~H             LIB042E
~D10
~MMANCHESTER UNIVERSITY  -  CONFIDENTIAL
~
~
                                                            ISSUE 11~
~V9 -1
~P
~V9 1
~YLIB042E
~S~M~OLIBRARY IMPLEMENTATION DESCRIPTION
~S~M~OSection 4 Version 2E
~S~OSection 4.2E Positioning Operations
~S~O1. General Description
~BThis module provides facilities for positioning the input/output
pointers within a stream and for managing the physical buffering of
input/output documents.
~S1~O2. Interfaces
~
~
Library procedures~
   I.POS 89 BYTE POSITION~
   O.POS 89 BYTE POSITION~
   SET.I.POS (BYTE POSITION)~
   SET.O.POS (BYTE POSITION)~
   I.REC () BYTE POSITION~
   O.REC () BYTE POSITION~
   SET.I.REC (BYTE POSITION)~
   SET.O.REC (BYTE POSITION)~
~
Interface procedures~
   SET.BPOS (AREA, POSITION)~
   GET.BUFFER (AREA)
~S1~O2.1 Software Interface
~
~
1) SET.BPOS (Area, POSITION)
~BThis procedure set pointers for the specified position within a
stream and manages the physical buffering of the document, as
appropriate.  BYTE.PTR, PTR, PTR.START and PTR.END are set to
map the space in the document from the specified position to the
end of the record/buffer block.~
~
~
2) GET.BUFFER (AREA)
~BThis procedure allocates a buffer for use when accessing documents
held as X segments.
~S1~O3. Implementation
~S1~O3.1 Outline of Operation
~BNone.
~Y
~V9 -1
~P
~D15
~HFLOWCHARTS
~
~
~H                LIB042E
~V9 -1
~F
@TITLE LIB04(2E,11)

@COL 1S-2R

@FLOW 1-2

@BOX 1.0
POSITIONING OPERATIONS
@BOX 2.0
PROCEDURES IN SUB-SECTION:
   1 I POS
   2 O POS
   3 SET I POS
   4 SET O POS
   5 I REC
   6 O REC
   7 SET I REC
   8 SET O REC
   9 SET BPOS
   10 GET BUFFER
@BOX 1.1
:: POSITIONING OPERATIONS
@BOX 2.1
#LIB04.1
#LIB04.2
#LIB04.3
#LIB04.4
#LIB04.5
#LIB04.6
#LIB04.7
#LIB04.8
#LIB04.9
#LIB04.10
**IN -1
@END

@TITLE LIB04/1(2E,11)

@COL 1S

@BOX 1.0
POSITIONING OPERATION PSPECS
@BOX 1.1
LSPEC I.POS () / INTEGER32;
LSPEC O.POS () / INTEGER32;
LSPEC SET.IPOS (INTEGER32);
LSPEC SET.OPOS (INTEGER32);
LSPEC I.REC () / INTEGER32;
LSPEC O.REC () / INTEGER32;
LSPEC SET.IREC (INTEGER32);
LSPEC SET.OREC (INTEGER32);
PSPEC SET.BPOS (ADDR IO.CONTROL.AREA, INTEGER32);
PSPEC GET.BUFFER (INTEGER);
**IN -1
@END


@TITLE LIB04.1(2E,11)

@COL 1S-2R-3F

@FLOW 1-2-3

@BOX 1.0
I POS () POSITION
@BOX 2.0
RETURN BYTE POSITION
@BOX 3.0
END
@BOX 1.1
PROC I.POS;
@BOX 2.1
SELECT INPUT^;
PTR.START + PTR - REC.START - 4 => I.POS;
@BOX 3.1
END
@END


@TITLE LIB04.2(2E,11)

@COL 1S-2R-3F

@FLOW 1-2-3

@BOX 1.0
O POS () POSITION
@BOX 2.0
RETURN BYTE POSITION
@BOX 3.0
END
@BOX 1.1
PROC O.POS;
@BOX 2.1
SELECT OUTPUT^;
PTR.START + PTR - REC.START - 4 => O.POS;
@BOX 3.1
END
@END


@TITLE LIB04.3(2E,11)

@COL 1S-6T-4T-2R-3F
@COL 5R

@ROW 2-5

@FLOW 1-6NO-4NO-2-3
@FLOW 6YES-2
@FLOW 4YES-5-3

@BOX 1.0
SET I POS (BYTE.POS)
@BOX 2.0
SET POINTER TO
REQUIRED BYTE POSITION
@BOX 3.0
END
@BOX 4.0
INVALID POSITION?
@BOX 5.0
ENTER TRAP (6, 10)
INVALID POSITION SPECIFIED
@BOX 6.0
START OF RECORD REQUIRED?
@BOX 1.1
PROC SET.I.POS (POS);
SELECT INPUT^;
@BOX 2.1
SET.BPOS (INPUT, REC.START + 4 + POS);
@BOX 3.1
END
@BOX 4.1
IF POS < 0 OR
   REC.START + 4 + POS > REC.END
@BOX 5.1
ENTER.TRAP (6, 10);
@BOX 6.1
IF POS = 0
@END


@TITLE LIB04.4(2E,11)

@COL 1S-6T-4T-2R-3F
@COL 5R

@ROW 2-5

@FLOW 1-6NO-4NO-2-3
@FLOW 6YES-2
@FLOW 4YES-5-3

@BOX 1.0
SET O POS (BYTE.POS)
@BOX 2.0
SET POINTER TO
REQUIRED BYTE POSITION
@BOX 3.0
END
@BOX 4.0
INVALID POSITION SPECIFIED?
@BOX 5.0
ENTER TRAP (6, 10)
INVALID POSITION SPECIFIED
@BOX 6.0
START OF RECORD REQUIRED?
@BOX 1.1
PROC SET.O.POS (POS);
SELECT OUTPUT^;
@BOX 2.1
SET.BPOS (OUTPUT, REC.START + 4 + POS);
@BOX 3.1
END
@BOX 4.1
IF POS < 0 OR
   REC.START + 4 + POS > REC.END
@BOX 5.1
ENTER.TRAP (6, 10);
@BOX 6.1
IF POS = 0
@END


@TITLE LIB04.5(2E,11)

@COL 1S-2R-3F

@FLOW 1-2-3

@BOX 1.0
I REC () POSITION
@BOX 2.0
RETURN BYTE POSITION
OF START OF RECORD
@BOX 3.0
END
@BOX 1.1
PROC I.REC;
@BOX 2.1
REC.START OF INPUT^ => I.REC;
@BOX 3.1
END
@END





@TITLE LIB04.6(2E,11)

@COL 1S-2R-3F

@FLOW 1-2-3

@BOX 1.0
O REC () POSITION
@BOX 2.0
RETURN BYTE POSITION
OF START OF RECORD
@BOX 3.0
END
@BOX 1.1
PROC O.REC;
@BOX 2.1
REC.START OF OUTPUT^ => O.REC;
@BOX 3.1
END
@END




@TITLE LIB04.7(2E,11)

@COL 1S-2R-3F

@FLOW 1-2-3

@BOX 1.0
SET I REC (BYTE POS)
@BOX 2.0
SET POINTER TO
REQUIRED BYTE POSITION
@BOX 3.0
END
@BOX 1.1
PROC SET.IREC (POS);
@BOX 2.1
SELECT INPUT^;
POS => REC.START => PREV.REC;
POS + 4 => REC.END;
SET.BPOS (INPUT, POS);
IN.BIN (4) + 4 + REC.START => REC.END;
SET.BPOS (INPUT, POS + 4);
@BOX 3.1
END
@END



@TITLE LIB04.8(2E,11)

@COL 1S-2R-3F

@FLOW 1-2-3

@BOX 1.0
SET O REC (BYTE POS)
@BOX 2.0
SET POINTER TO
REQUIRED BYTE POSITION
@BOX 3.0
END
@BOX 1.1
PROC SET.OREC (POS);
@BOX 2.1
SELECT OUTPUT^;
IF POS => REC.START => PREV.REC > SECTION.SIZE THEN
   POS => SECTION.SIZE;
FI
MAX.SECTION.SIZE => REC.END;
SET.BPOS (OUTPUT, POS + 4);
@BOX 3.1
END
@END

@TITLE LIB04.9(2E,11)

@COL 1S-12T-3T-4T-5R-6R-7R-10N-8F
@COL 13R-9R-11N

@ROW 3-13

@FLOW 1-12NO-3X SEGMENT-4NO-5-6-7-10-8
@FLOW 12YES-13-11-10
@FLOW 3SEGMENT-9-11-10
@FLOW 4YES-7

@BOX 1.0
SET BPOS (AREA, POS)
@BOX 3.0
SEGMENT OR X SEGMENT?
@BOX 4.0
POSITION IN EXISTING BLOCK?
@BOX 5.0
SECURE BUFFER BLOCK
IF OUTPUT STREAM
@BOX 6.0
COPY REQUIRED BLOCK
INTO BUFFER
@BOX 7.0
POSITION STREAM AT
SPECIFIED POS
@BOX 8.0
END
@BOX 9.0
POSITION STREAM AT
SPECIFIED POS
@BOX 12.0
SHORT MESSAGE?
@BOX 13.0
POSITION STREAM IN
SHORT MESSAGE
@BOX 1.1
PROC SET.BPOS (AREA, POS);
INTEGER BLK;
SELECT AREA^;
POS => PTR.START;
0 => PTR;
REC.END - POS => PTR.END;
@BOX 3.1
IF SEG.STATUS & %40 = 0
@BOX 4.1
POS ->> SYS14.PAGE.SHIFT => BLK;
IF BLK = BLOCK
@BOX 5.1
IF MODE & OUT /= 0 AND
   BLOCK >= 0 THEN
   COPY.BLOCK (IO.CONTROL.SEG, BUF + IO.BUFFER.BLOCK, SEG, BLOCK);
FI
@BOX 6.1
COPY.BLOCK (SEG, BLK => BLOCK, IO.CONTROL.SEG, BUF + IO.BUFFER.BLOCK);
@BOX 7.1
SYS14.PAGE.MASK &> POS;
SYS14.PAGE.SIZE - POS => PTR.END;
IF PTR.START + PTR.END > REC.END THEN
   REC.END - PTR.START => PTR.END;
FI
MAKE (LOGICAL8, PTR.END,
   BUF <<- SYS14.PAGE.SHIFT + IO.BUFFER.VA + POS) => BYTE.PTR;
@BOX 8.1
END
@BOX 9.1
MAKE (LOGICAL8, PTR.END,
   SEG <<- SYS14.SEG.SHIFT + POS) => BYTE.PTR;
@BOX 12.1
IF HDR /= 0
@BOX 13.1
MAKE (LOGICAL8, PTR.END,
   BYTE (^MESSAGE) + POS) => BYTE.PTR;
@END


@TITLE LIB04.10(2E,11)

@COL 1S-2T-3T-4R-5R-6R-7F

@FLOW 1-2NO-3NO-4-5-6-7
@FLOW 2YES-7
@FLOW 3YES-7

@BOX 1.0
GET BUFFER (STREAM, AREA)
@BOX 2.0
BUFFER NOT REQUIRED?
@BOX 3.0
IS BUFFER ALREADY ALLOCATED
FOR THIS STREAM?
@BOX 4.0
SELECT BUFFER TO USE
@BOX 5.0
SECURE PREVIOUS BUFFER
IF NECESSARY
@BOX 6.0
GET NEW BLOCK
@BOX 7.0
END
@BOX 1.1
PROC GET.BUFFER (AREA);
INTEGER OLD.AREA;
@BOX 2.1
SELECT IO.CONTROL [AREA];
IF MODE & DEFINED = 0
   OR SEG = 0 OR SEG.STATUS & %40 = 0
@BOX 3.1
IF BUF >= 0
@BOX 4.1
NEXT.BUF:
IF 1 +> BUF.PTR = NO.OF.BUFFERS THEN
   0 => BUF.PTR;
FI
IF BUFFER [BUF.PTR] => OLD.AREA /= NO.OF.STREAMS AND
   [OLD.AREA = I.STREAM [CURRENT.IN] OR
   OLD.AREA = O.STREAM [CURRENT.OUT]] , -> NEXT.BUF;
@BOX 5.1
IF OLD.AREA /= NO.OF.STREAMS THEN
   -1 => BUF OF IO.CONTROL [OLD.AREA];
   IF MODE OF IO.CONTROL [OLD.AREA] & OUT /= 0 THEN
      COPY.BLOCK (IO.CONTROL.SEG, BUF.PTR + IO.BUFFER.BLOCK,
         SEG OF IO.CONTROL [OLD.AREA],
         BLOCK OF IO.CONTROL [OLD.AREA]);
   FI
FI
@BOX 6.1
AREA => BUFFER [BUF.PTR];
BUF.PTR => BUF;
IF HDR = 0 THEN
   COPY.BLOCK (SEG, BLOCK, IO.CONTROL.SEG, BUF.PTR + IO.BUFFER.BLOCK);
   MAKE (LOGICAL8, SIZE (BYTE.PTR), BUF.PTR <<- SYS14.PAGE.SHIFT + IO.BUFFER.VA
      + (BYTE (BYTE.PTR) & SYS14.PAGE.MASK)) => BYTE.PTR;
FI
@BOX 7.1
END
@END


