*DECK XDRSTR
USETEXT TEXTXDR
PROC XDRSTR (BUFFER, BUFPOS, STRING, STRLEN, OPERATION);
*CALL COPYRITE CDCNET - COPYRIGHT CONTROL DATA. 1992.
# TITLE XDRSTR CONVERT BETWEEN DISPLAY AND ASCII IN XDR FORMAT #
BEGIN # XDRSTR #
#
**** XDRSTR - CONVERT BETWEEN DISPLAY AND ASCII IN XDR FORMAT.
*
* THIS PROCEDURE WILL READ DATA OUT OF *BUFFER*, OR WRITE DATA INTO
* *BUFFER* DEPENDING ON THE *OPERATION* PARAMETER. THE DATA IN
* *BUFFER* IS IN ASCII CHARACTER XDR (EXTERNAL DATA REPRESENTATION)
* FORMAT, PACKED 7.5 CHARACTERS/CYBER WORD. THE FIRST 4 BYTES
* CONTAIN THE STRING LENGTH. IF THE LENGTH IS NOT A MULTIPLE OF
* BYTES, THEN 0 TO 3 BYTES OF ZEROS ARE ADDED TO THE MESSAGE TO MAKE
* THE NUMBER OF BYTES A MULTIPLE OF FOUR. STRING IS A ZERO BYTE
* TERMINATED STRING.
*
* PROC XDRSTR (BUFFER, BUFPOS, STRING, STRLEN, OPERATION)
*
* ENTRY BUFFER = INTEGER ARRAY PACKED 7.5 BYTES/WORD.
* BUFPOS = INDEX OF NEXT BYTE TO BE READ OR WRITTEN.
* STRING = DISPLAY CHARACTER ARRAY.
* OPERATION = EITHER *READ* FROM OR *WRITE* TO *BUFFER*.
*
* EXIT BUFFER = DATA READ OUT OR WRITTEN TO.
* BUFPOS = BYTE POSITION IN *BUFFER* AFTER OPERATION.
* STRING = CHARACTERS READ OUT OR WRITTEN TO.
* STRLEN = NUMBER OF CHARACTERS READ FROM *BUFFER* OR
* WRITTEN TO *BUFFER*.
*
* METHOD IF OPERATION IS *READ*, XDRINT IS CALLED TO DETERMINE THE
* VALUE OF *STRLEN*. *STRLEN* CHARACTERS ARE THEN READ FROM
* FROM *BUFFER*.
* IF THE OPERATION IS *WRITE*, CHARACTERS ARE WRITTEN TO
* *STRING* UNTIL A ZERO BYTE IS ENCOUNTERED. WHEN THE ZERO
* BYTE IS ENCOUNTERED, *STRLEN* IS DETERMINED AND WRITTEN
* TO THE BEGINNING OF THE STRING IN *BUFFER*.
* *BUFPOS* IS UPDATED TO THE NEXT READ/WRITE BYTE POSITION.
* THE ARITHMETIC MODULO BASE 60 FUNCTION IS PERFORMED ON
* *BUFPOS* MULTIPLIED BY EIGHT TO DETERMINE THE BIT
* POSITION WITHIN BUFFER. IF THE POSITION IS 56, THE
* BYTE IS SPLIT ACROSS TWO WORDS. THE CHARACTERS IN
* *BUFFER* ARE 7-BIT ASCII CHARACTERS TERMINATED WITH A
* ZERO BYTE, THE CHARACTERS IN STRING ARE IN DISPLAY CODE.
* IF CONVERTING ASCII TO DISPLAY, THE ASCII INTEGER VALUE
* IS THE OFFSET INTO THE ASCII TO DISPLAY CONVERSION ARRAY.
* IF CONVERTING DISPLAY TO ASCII, THE DISPLAY INTEGER VALUE
* IS USED TO DETERMINE THE WORD AND BIT OFFSET INTO THE
* DISPLAY TO ASCII ARRAY.
* THE CALLER IS RESPONSIBLE FOR MAKING SURE THAT THE
* DESTINATION ARRAY IS LARGE ENOUGH TO HOLD THE NUMBER
* OF VALUES SPECIFIED.
*
#
#
**** PROC XDRSTR - XREF LIST
#
XREF
BEGIN
PROC XDRBYTE; # CONVERT BYTE TO XDR DATA #
PROC XDRINT; # CONVERT INTEGER TO XDR DATA #
END
#
**
#
DEF CHARNUL$ # 0 #; # NULL CHARACTER #
ARRAY BUFFER [0:0] S(1); # ARRAY OF DATA, 7.5 BYTES/WORD #
ITEM BUF$WRD U(00,00,60); # WORD REFERENCE #
ITEM BUFPOS I; # CUR BYTE POSITION IN BUFFER #
ARRAY STRING [0:0] S(240);
ITEM STR$CHAR C(00,00,240); # CHARACTER REFERENCE #
ITEM STRLEN I; # NUMBER OF CHARS TO BE PROCESSD#
ITEM OPERATION S:XDROPER; # OPERATION TO PERFORM ON BUFFER#
ITEM ARRAYBIT I; # BIT OFFSET INTO *DACONVER* WRD#
ITEM ARRAYWRD I; # WORD OFFSET INTO *DACONVER* #
ITEM BITPOS I; # BIT POSITION IN BUFFER #
ITEM INDEX I; # NUMBER OF CHARACTERS READ #
ITEM LENPOS I; # STRING LENGTH POSITION IN BUF #
ITEM SRCHAR I; # INPUT SOURCE CHARACTER #
ITEM WORDPOS I; # WORD POSITION IN BUFFER #
ITEM ZEROBYTE I; # NUMBER OF ZERO BYTES TO ADD #
#
**** ARRAY THAT DEFINES THE ASCII TO DISPLAY CODE CONVERSION TABLE
#
ARRAY ADCONVER [00:12] S(1);
BEGIN # ASCII TO DISPLAY CONVERSION #
ITEM AD$CHAR C(00,00,127); # CHARACTER REFERENCE #
ITEM AD$WORD U(00,00,60) =
[O"00000000000000000000", # 00,01,02,03,04,05,06,07,08,09 #
O"00000000000000000000", # 0A,0B,0C,0D,0E,0F,10,11,12,13 #
O"00000000000000000000", # 14,15,16,17,18,19,1A,1B,1C,1D #
O"00005566646053636770", # 1E,1F,20,21,22,23,24,25,26,27 #
O"51524745564657503334", # 28,29,2A,2B,2C,2D,2E,2F,30,31 #
O"35363740414243440077", # 32,33,34,35,36,37,38,39,3A,3B #
O"72547371740102030405", # 3C,3D,3E,3F,40,41,42,43,44,45 #
O"06071011121314151617", # 46,47,48,49,4A,4B,4C,4D,4E,4F #
O"20212223242526273031", # 50,51,52,53,54,55,56,57,58,59 #
O"32617562766500010203", # 5A,5B,5C,5D,5E,5F,60,61,62,63 #
O"04050607101112131415", # 64,65,66,67,68,69,6A,6B,6C,6D #
O"16172021222324252627", # 6E,6F,70,71,72,73,74,75,76,77 #
O"30313200000000000000"]; # 78,79,7A,7B,7C,7D,7E,7F #
END
#
**** ARRAYS THAT DEFINES THE DISPLAY TO ASCII CONVERSION
#
ARRAY DACONVER [00:12] S(1);
BEGIN # DISPLAY TO ASCII CONVERSION #
ITEM DA$WORD U(00,00,60) =
[X"03A041042043044", # 00,01,02,03,04 : A B C D #
X"045046047048049", # 05,06,07,10,11 E F G H I #
X"04A04B04C04D04E", # 12,13,14,15,16 J K L M N #
X"04F050051052053", # 17,20,21,22,23 O P Q R S #
X"054055056057058", # 24,25,26,27,30 T U V W X #
X"05905A030031032", # 31,32,33,34,35 Y Z 0 1 2 #
X"033034035036037", # 36,37,40,41,42 3 4 5 6 7 #
X"03803902B02D02A", # 43,44,45,46,47 8 9 + - * #
X"02F02802902403D", # 50,51,52,53,54 / ( ) $ = #
X"02002C02E02305B", # 55,56,57,60,61 , . PD [ #
X"05D02502205F021", # 62,63,64,65,66 ] % " _ ! #
X"02602703F03C03E", # 67,70,71,72,73 & ' ? < > #
X"04005C05E03B000"]; # 74,75,76,77 AT \ CF SC #
END
CONTROL EJECT;
#
**** START MAIN PROCEDURE
#
SWITCH OPER$:XDROPER OPER$READ:READ,
OPER$WRITE:WRITE;
GOTO OPER$ [OPERATION];
BEGIN # OPERATION TYPE #
OPER$READ:
INDEX = 1; # READ/WRITE ONE INTEGER #
XDRINT (BUFFER, BUFPOS, STRLEN, INDEX, OPERATION);
ZEROBYTE = XDRMODU (STRLEN, 4);
IF ZEROBYTE NQ 0
THEN
BEGIN # ACTUAL NUMBER OF ZERO BYTES #
ZEROBYTE = 4 - ZEROBYTE;
END
BITPOS = XDRMODU (BUFPOS * 8, 60);# INITIAL BIT POSITION IN BUF#
WORDPOS = (BUFPOS * 2) / 15; # INITIAL WORD INDEX WITHIN BUF #
FOR INDEX = 0 STEP 1 UNTIL (STRLEN - 1)
DO
BEGIN # LOOP THROUGH REQUESTED CHARS #
IF BITPOS EQ 56
THEN
BEGIN # BYTE SPLIT BETWEEN WORDS #
SRCHAR = B<56,4>BUF$WRD [WORDPOS] * 16 +
B<0,4>BUF$WRD [WORDPOS +1];
WORDPOS = WORDPOS + 1;
BITPOS = 4;
END
ELSE
BEGIN # BYTE IN SINGLE CM WORD #
SRCHAR = B<BITPOS,8>BUF$WRD [WORDPOS];
BITPOS = BITPOS + 8;
IF BITPOS GQ 60
THEN
BEGIN
BITPOS = 0;
WORDPOS = WORDPOS + 1;
END
END
SRCHAR = SRCHAR LAN X"7F"; # MASK UPPER BIT, ONLY 127 CHARS#
C<INDEX,1>STR$CHAR [0] = C<SRCHAR,1>AD$CHAR [0];
END # LOOP THROUGH REQUESTED CHARS #
BUFPOS = BUFPOS + STRLEN + ZEROBYTE;# NEXT READ POSITION #
C<STRLEN,1>STR$CHAR [0] = CHARNUL$;
GOTO OPER$END;
OPER$WRITE:
LENPOS = BUFPOS;
BUFPOS = BUFPOS + 4;
BITPOS = XDRMODU (BUFPOS * 8, 60);# INITIAL BIT POSITION IN BUF#
WORDPOS = (BUFPOS * 2) / 15; # INITIAL WORD INDEX WITHIN BUF #
SRCHAR = C<0,1>STR$CHAR [0]; # DISPLAY CHAR TO CONVERT #
FOR STRLEN = 1 STEP 1
WHILE SRCHAR NQ CHARNUL$
DO
BEGIN # LOOP THROUGH REQUESTED CHARS #
ARRAYWRD = SRCHAR / 5; # WORD OFFSET IN *DACONVER* #
ARRAYBIT = XDRMODU (SRCHAR * 12, 60) + 4; # BIT OFFSET IN WRD#
IF BITPOS EQ 56
THEN
BEGIN # BYTE SPLIT BETWEEN WORDS #
B<56,4>BUF$WRD [WORDPOS] = B<ARRAYBIT,4>DA$WORD [ARRAYWRD];
B<0,4>BUF$WRD [WORDPOS + 1] =
B<ARRAYBIT + 4,4>DA$WORD [ARRAYWRD];
WORDPOS = WORDPOS + 1;
BITPOS = 4;
END
ELSE
BEGIN # BYTE IN SINGLE CM WORD #
B<BITPOS,8>BUF$WRD [WORDPOS] =
B<ARRAYBIT,8>DA$WORD [ARRAYWRD];
BITPOS = BITPOS + 8;
IF BITPOS GQ 60
THEN
BEGIN
BITPOS = 0;
WORDPOS = WORDPOS + 1;
END
END
SRCHAR = C<STRLEN,1>STR$CHAR [0];# DISPLAY CHAR TO CONVERT #
END # LOOP THROUGH REQUESTED CHARS #
INDEX = 1;
STRLEN = STRLEN - 1;
XDRINT (BUFFER, LENPOS, STRLEN, INDEX, OPERATION);
BUFPOS = BUFPOS + STRLEN; # NEXT BUFFER LOCATION #
ZEROBYTE = XDRMODU (STRLEN, 4);
IF ZEROBYTE NQ 0
THEN
BEGIN # ACTUAL NUMBER OF ZERO BYTES #
ZEROBYTE = 4 - ZEROBYTE;
END
XDRBYTE (BUFFER, BUFPOS, ADCONVER, ZEROBYTE, XDROPER"WRITE");
GOTO OPER$END;
END # OPERATION TYPE #
OPER$END:
RETURN; # RETURN TO CALLER #
END # XDRSTR #
TERM
*WEOR