?? TITLE := 'NOS/VE:  BASIC ACCESS METHOD, TASK SERVICES' ??
MODULE bam$trailing_char_delimited_fap;
?? RIGHT := 110 ??

?? NEWTITLE := '    Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc amc$condition_code_limits
*copyc bac$minimum_open_ring
*copyc osd$virtual_address
*copyc ame$access_validation_errors
*copyc ame$conflicting_access_level
*copyc ame$device_class_validation
*copyc ame$fap_validation_errors
*copyc ame$file_organization_errors
*copyc ame$get_program_actions
*copyc ame$get_validation_errors
*copyc ame$improper_file_id
*copyc ame$improper_random_access
*copyc ame$improper_wsl
*copyc ame$open_validation_errors
*copyc ame$put_program_actions
*copyc ame$put_validation_errors
*copyc ame$ring_validation_errors
*copyc ame$skip_program_actions
*copyc ame$skip_validation_errors
*copyc ame$unimplemented_request
*copyc fme$file_management_errors
*copyc ife$error_codes
*copyc amt$fap_declarations
*copyc bat$block_header
*copyc bat$block_manager_descriptor
*copyc bat$block_position
*copyc bat$global_file_information
*copyc bat$task_file_table
*copyc ost$caller_identifier
?? POP ??
*copyc pmf$job_mode
*copyc amp$set_file_instance_abnormal
*copyc baf$task_file_entry_p
*copyc bap$close
*copyc bap$fetch
*copyc bap$fetch_access_information
*copyc bap$get_segment_pointer
*copyc bap$set_segment_eoi
*copyc bap$set_segment_position
*copyc bap$store
*copyc bap$write_modified_pages
*copyc mmp$set_segment_length
*copyc osp$set_status_abnormal
*copyc bav$task_file_table
*copyc fmv$global_file_information
*copyc i#move
?? OLDTITLE ??
?? NEWTITLE := 'BAP$TRAILING_CHAR_DELIMITED_FAP', EJECT ??

  PROCEDURE [XDCL, #GATE] bap$trailing_char_delimited_fap
    (    file_identifier: amt$file_identifier;
         call_block: amt$call_block;
         layer_number: amt$fap_layer_number;
     VAR status: ost$status);

    CONST
      error_text = 'BAP$TRAILING_CHAR_DELIMITED_FAP - ',
      max_scan_size = 256, { current maximum scan length }
      trailing_char_length_constant = 1;

    TYPE
      set_of_char = set of char;

    VAR
      at_eoi: boolean,
      caller_id: ost$caller_identifier,
      data_ptr: ^cell,
      delimiting_char_set: set_of_char,
      delimiter_ptr: ^char,
      file_byte_address: amt$file_byte_address,
      file_instance: ^bat$task_file_entry,
      found_delimiter: boolean,
      record_info: bat$record_info,
      scan_byte_address: amt$file_byte_address,
      scan_max: 0 .. max_scan_size,
      scan_size: amt$working_storage_length,
      scan_string: ^string (max_scan_size),
      scanned_piece_size: amt$working_storage_length,
      skip_count: amt$skip_count,
      trailing_char_length: integer;

?? NEWTITLE := 'ROLLBACK_PROCEDURE', EJECT ??

    PROCEDURE rollback_procedure
      (    condition_status: ost$status);

      status := condition_status;
      file_instance^.rollback_procedure := NIL;
      EXIT bap$trailing_char_delimited_fap; {----->

    PROCEND rollback_procedure;

?? OLDTITLE ??
?? NEWTITLE := '[inline] GET_NEXT', EJECT ??

    PROCEDURE [INLINE] get_next;

      IF file_instance^.access_level <> amc$record THEN
        amp$set_file_instance_abnormal (file_identifier, ame$conflicting_access_level, call_block.operation,
              error_text, status);
        RETURN; {----->
      IFEND;

*copy bai$validate_read_access
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

*copy bai$get_record_info
      IF (record_info.file_position = amc$mid_record) AND (file_instance^.private_read_information = NIL) AND
            (file_instance^.global_file_information^.last_access_operation = amc$put_partial_req) THEN

{ Must have been left mid_record by a put_partial.  EOI needs updating.
        record_info.file_position := amc$eor;
        update_eoi;
      IFEND;

      IF record_info.file_position = amc$mid_record THEN
{ Move to start of next record.
        scan_to_delimiting_char;

{ Scanned_length includes the delimiter.
        record_info.current_byte_address := scan_byte_address;
      IFEND;

*copy bai$get_eoi_check

      IF NOT at_eoi THEN
{ Locate eor.
*copy   bai$scan_to_delimiting_char

        data_ptr := #ADDRESS (osc$min_ring, #SEGMENT (file_instance^.file_pva),
              record_info.current_byte_address);
        record_info.bor_address := record_info.current_byte_address;

        IF call_block.getn.working_storage_length < scan_byte_address - record_info.current_byte_address -
              trailing_char_length THEN
          record_info.record_length := call_block.getn.working_storage_length;
          record_info.file_position := amc$mid_record;
          record_info.current_byte_address := record_info.current_byte_address + record_info.record_length;
        ELSE { getting a full record }
          record_info.record_length := scan_byte_address - record_info.current_byte_address -
                trailing_char_length;
          record_info.file_position := amc$eor;
          record_info.current_byte_address := scan_byte_address;
        IFEND;

{ Move data to user's working_storage_area.

        i#move (data_ptr, call_block.getn.working_storage_area, record_info.record_length);
      ELSE { at eoi }
        record_info.bor_address := record_info.current_byte_address;
        record_info.record_length := 0;
      IFEND; { NOT at eoi }

*copy bai$save_record_info

      call_block.getn.file_position^ := record_info.file_position;
      call_block.getn.transfer_count^ := record_info.record_length;
      call_block.getn.byte_address^ := record_info.bor_address;

    PROCEND get_next;
?? OLDTITLE ??
?? NEWTITLE := '[inline] PUT_NEXT', EJECT ??

    PROCEDURE [INLINE] put_next;

      IF file_instance^.access_level <> amc$record THEN
        amp$set_file_instance_abnormal (file_identifier, ame$conflicting_access_level, call_block.operation,
              error_text, status);
        RETURN; {----->
      IFEND;

*copy bai$validate_write_access
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

    /main_code_put_next/
      BEGIN
        record_info := file_instance^.global_file_information^.positioning_info.record_info;

{ Not necessary to add delimiter if mid_record since all put_partials will
{ write a temporary delimiter.

        record_info.bor_address := record_info.current_byte_address;

{ Check to make sure we do not go over the 2 GB file limit.
        IF file_instance^.global_file_information^.file_limit <
              record_info.current_byte_address + call_block.putn.working_storage_length +
              trailing_char_length_constant THEN
          amp$set_file_instance_abnormal (file_identifier, ame$put_beyond_file_limit, call_block.operation,
                error_text, status);
          EXIT /main_code_put_next/; {----->
        IFEND;

{ Write data to file.
        data_ptr := #ADDRESS (osc$min_ring, #SEGMENT (file_instance^.file_pva),
              record_info.current_byte_address);
        i#move (call_block.putn.working_storage_area, data_ptr, call_block.putn.working_storage_length);

{ Write trailing_character_delimiter
        delimiter_ptr := #ADDRESS (osc$min_ring, #SEGMENT (data_ptr), #OFFSET (data_ptr) +
              call_block.putn.working_storage_length);
        delimiter_ptr^ := file_instance^.global_file_information^.record_delimiting_character;

        record_info.current_byte_address := record_info.current_byte_address +
              call_block.putn.working_storage_length + trailing_char_length_constant;
        record_info.file_position := amc$eor;
        record_info.record_length := call_block.putn.working_storage_length;

*copy   bai$update_eoi

        file_instance^.instance_of_open_modified := TRUE;
      END /main_code_put_next/;

      file_instance^.global_file_information^.positioning_info.record_info := record_info;
      IF call_block.operation = amc$put_next_req THEN
        call_block.putn.byte_address^ := record_info.bor_address;
      IFEND;

    PROCEND put_next;
?? OLDTITLE ??
?? NEWTITLE := '[inline] GET_PARTIAL', EJECT ??

    PROCEDURE [INLINE] get_partial;

      IF file_instance^.access_level <> amc$record THEN
        amp$set_file_instance_abnormal (file_identifier, ame$conflicting_access_level, call_block.operation,
              error_text, status);
        RETURN; {----->
      IFEND;

*copy bai$validate_read_access
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

      IF (call_block.getp.skip_option < LOWERVALUE (amt$skip_option)) OR
            (call_block.getp.skip_option > UPPERVALUE (amt$skip_option)) THEN
        amp$set_file_instance_abnormal (file_identifier, ame$improper_skip_option, call_block.operation,
              error_text, status);
        RETURN; {----->
      IFEND;

*copy bai$get_record_info

      IF (record_info.file_position = amc$mid_record) AND (file_instance^.private_read_information = NIL) AND
            (file_instance^.global_file_information^.last_access_operation = amc$put_partial_req) THEN

{ Must have been left mid_record by a put_partial.  EOI needs updating.

        record_info.file_position := amc$eor;
        update_eoi;
      IFEND;

      IF (record_info.file_position = amc$mid_record) AND (call_block.getp.skip_option = amc$skip_to_eor) THEN
        scan_to_delimiting_char;
        record_info.current_byte_address := scan_byte_address;
        record_info.file_position := amc$eor;
      IFEND;

*copy bai$get_eoi_check

      IF NOT at_eoi THEN
{ Locate delimiter.
        data_ptr := #ADDRESS (osc$min_ring, #SEGMENT (file_instance^.file_pva),
              record_info.current_byte_address);
*copy   bai$scan_to_delimiting_char

        IF record_info.file_position <> amc$mid_record THEN
          record_info.bor_address := record_info.current_byte_address;
        IFEND;

        IF call_block.getp.working_storage_length < scan_byte_address - record_info.current_byte_address -
              trailing_char_length THEN
          record_info.record_length := call_block.getp.working_storage_length;
          record_info.file_position := amc$mid_record;
          record_info.current_byte_address := record_info.current_byte_address + record_info.record_length;
        ELSE { getting a full record }
          record_info.record_length := scan_byte_address - record_info.current_byte_address -
                trailing_char_length;
          record_info.file_position := amc$eor;
          record_info.current_byte_address := scan_byte_address;
        IFEND;

        i#move (data_ptr, call_block.getp.working_storage_area, record_info.record_length);

{ Get transfer count before resetting record_length to sum of transfer counts.
        call_block.getp.transfer_count^ := record_info.record_length;

{ Remember that record_length is the sum of get_partial transfer_counts.
        IF record_info.file_position = amc$eor THEN
          record_info.record_length := record_info.current_byte_address - record_info.bor_address -
                trailing_char_length;
        ELSE
          record_info.record_length := record_info.current_byte_address - record_info.bor_address;
        IFEND;
      ELSE { at eoi }
        record_info.record_length := 0;
        call_block.getp.transfer_count^ := record_info.record_length;
      IFEND;

*copy bai$save_record_info

      call_block.getp.file_position^ := record_info.file_position;
      call_block.getp.record_length^ := record_info.record_length;
      call_block.getp.byte_address^ := record_info.bor_address;

    PROCEND get_partial;
?? OLDTITLE ??
?? NEWTITLE := '[inline] PUT_PARTIAL', EJECT ??

    PROCEDURE [INLINE] put_partial;

      IF file_instance^.access_level <> amc$record THEN
        amp$set_file_instance_abnormal (file_identifier, ame$conflicting_access_level, call_block.operation,
              error_text, status);
        RETURN; {----->
      IFEND;

*copy bai$validate_write_access
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

      IF (call_block.putp.term_option < LOWERVALUE (amt$term_option)) OR
            (call_block.putp.term_option > UPPERVALUE (amt$term_option)) THEN
        amp$set_file_instance_abnormal (file_identifier, ame$improper_term_option, call_block.operation,
              error_text, status);
        RETURN; {----->
      IFEND;

    /main_code_put_partial/
      BEGIN
        record_info := file_instance^.global_file_information^.positioning_info.record_info;

{ Figure out if starting or continuing a record.
        CASE call_block.putp.term_option OF
        = amc$start =
          IF (record_info.file_position = amc$mid_record) AND
                (file_instance^.global_file_information^.last_access_operation = amc$put_partial_req) THEN

{ Terminate_last record before starting new record.

            update_eoi;
          IFEND;
          record_info.bor_address := record_info.current_byte_address;
          record_info.file_position := amc$mid_record;

        = amc$continue =
          IF record_info.file_position <> amc$mid_record THEN
            amp$set_file_instance_abnormal (file_identifier, ame$improper_continue, call_block.operation, ' ',
                  status);
            EXIT /main_code_put_partial/; {----->
          IFEND;

          IF (record_info.file_position = amc$mid_record) AND
                (file_instance^.global_file_information^.last_access_operation = amc$put_partial_req) THEN

{ Must skip backwards over the temporary delimiter.
            record_info.current_byte_address := record_info.current_byte_address -
                  trailing_char_length_constant;
          IFEND;

        = amc$terminate =
          IF record_info.file_position = amc$mid_record THEN
            IF file_instance^.global_file_information^.last_access_operation = amc$put_partial_req THEN

{ Must skip backwards over the temporary delimiter.
              record_info.current_byte_address := record_info.current_byte_address -
                    trailing_char_length_constant;
            IFEND;
          ELSE
            record_info.bor_address := record_info.current_byte_address;
          IFEND;
          record_info.file_position := amc$eor;
        ELSE
        CASEND;

{ Check to make sure we do not go over the 2 GB file limit.
        IF file_instance^.global_file_information^.file_limit <
              record_info.current_byte_address + call_block.putn.working_storage_length +
              trailing_char_length_constant THEN
          amp$set_file_instance_abnormal (file_identifier, ame$put_beyond_file_limit, call_block.operation,
                error_text, status);
          EXIT /main_code_put_partial/; {----->
        IFEND;

        data_ptr := #ADDRESS (osc$min_ring, #SEGMENT (file_instance^.file_pva),
              record_info.current_byte_address);
        i#move (call_block.putn.working_storage_area, data_ptr, call_block.putn.working_storage_length);

{ Write trailing_character_delimiter. Delimiter will be temporary if the
{ record is continued. This guarantees a delimiter at eoi.

        delimiter_ptr := #ADDRESS (osc$min_ring, #SEGMENT (data_ptr), #OFFSET (data_ptr) +
              call_block.putn.working_storage_length);
        delimiter_ptr^ := file_instance^.global_file_information^.record_delimiting_character;

        record_info.current_byte_address := record_info.current_byte_address +
              call_block.putp.working_storage_length + trailing_char_length_constant;
        record_info.record_length := record_info.current_byte_address - record_info.bor_address -
              trailing_char_length_constant;

        IF call_block.putp.term_option = amc$terminate THEN
*copy     bai$update_eoi
        IFEND;

        file_instance^.instance_of_open_modified := TRUE;
      END /main_code_put_partial/;

      file_instance^.global_file_information^.positioning_info.record_info := record_info;
      call_block.putp.byte_address^ := record_info.bor_address;

    PROCEND put_partial;
?? OLDTITLE ??
?? NEWTITLE := '[inline] SKIP', EJECT ??

    PROCEDURE [INLINE] skip;

      IF file_instance^.access_level <> amc$record THEN
        amp$set_file_instance_abnormal (file_identifier, ame$conflicting_access_level, call_block.operation,
              error_text, status);
        RETURN; {----->
      ELSEIF NOT (pfc$read IN file_instance^.instance_attributes.dynamic_label.access_mode) THEN
        amp$set_file_instance_abnormal (file_identifier, ame$skip_requires_read_perm, call_block.operation,
              error_text, status);
        RETURN; {----->
      ELSEIF call_block.skp.unit <> amc$skip_record THEN
        amp$set_file_instance_abnormal (file_identifier, ame$improper_skip_unit, call_block.operation,
              error_text, status);
        RETURN; {----->
      IFEND;

*copy bai$get_record_info
      IF (record_info.file_position = amc$mid_record) AND (file_instance^.private_read_information = NIL) AND
            (file_instance^.global_file_information^.last_access_operation = amc$put_partial_req) THEN

{ Must have been left mid_record by a put_partial.  EOI needs updating.
        record_info.file_position := amc$eor;
        update_eoi;
      IFEND;

      skip_count := call_block.skp.count;

      CASE call_block.skp.direction OF
      = amc$forward =
        IF record_info.file_position = amc$mid_record THEN
          scan_to_delimiting_char;
          record_info.current_byte_address := scan_byte_address;
          record_info.file_position := amc$eor;
        ELSE
          scan_byte_address := record_info.current_byte_address;
        IFEND;
        IF skip_count > 0 THEN
          WHILE (skip_count > 0) AND (scan_byte_address < file_instance^.global_file_information^.
                eoi_byte_address) DO
*copy       bai$scan_to_delimiting_char
            skip_count := skip_count - 1;
            record_info.current_byte_address := scan_byte_address;
          WHILEND;
          IF (scan_byte_address = file_instance^.global_file_information^.eoi_byte_address) AND
                (skip_count <> 0) THEN
            record_info.file_position := amc$eoi;
            amp$set_file_instance_abnormal (file_identifier, ame$skip_encountered_eoi, amc$skip_req,
                  'RECORDS', status);
          ELSE
            record_info.file_position := amc$eor;
          IFEND;
        IFEND;

      = amc$backward =
        scan_byte_address := record_info.current_byte_address;
        IF record_info.file_position = amc$mid_record THEN

{ Always position to beginning of current record.
{ Remember that mid_record position is after a temporary delimiter.
          backscan_to_delimiting_char;
          record_info.file_position := amc$eor;

        ELSEIF scan_byte_address > 0 THEN

{ Back up over the delimiting_char in preparation to finding start of the
{ next record.  Note that it is NOT necessary to check for a missing
{ delimiting character at the end of the file.  If the file is at EOI and the
{ final delimiter is missing, it is NOT NECESSARY to back up, but it doesn't
{ alter the result if it is done.

          scan_byte_address := scan_byte_address - trailing_char_length_constant;
        IFEND;

        IF skip_count > 0 THEN
          WHILE (skip_count > 0) AND (scan_byte_address <> 0) DO
            backscan_to_delimiting_char;
            skip_count := skip_count - 1;
          WHILEND;

{ Will be positioned after the delimiting_char or at boi.
          IF scan_byte_address = 0 THEN
            IF skip_count = 0 THEN
              record_info.file_position := amc$eor;
            ELSE
              record_info.file_position := amc$boi;
              amp$set_file_instance_abnormal (file_identifier, ame$skip_encountered_boi, amc$skip_req,
                    'RECORDS', status);
            IFEND;
          ELSE
            record_info.file_position := amc$eor;
            scan_byte_address := scan_byte_address + 1;
          IFEND;
        IFEND;
      CASEND;

      record_info.bor_address := scan_byte_address;
      record_info.current_byte_address := scan_byte_address;

*copy bai$save_record_info

      file_instance^.residual_skip_count := skip_count;
      call_block.skp.file_position^ := record_info.file_position;

    PROCEND skip;
?? OLDTITLE ??
?? NEWTITLE := '[inline] SEEK_DIRECT', EJECT ??

    PROCEDURE [INLINE] seek_direct;

      IF file_instance^.access_level <> amc$record THEN
        amp$set_file_instance_abnormal (file_identifier, ame$conflicting_access_level, call_block.operation,
              error_text, status);
        RETURN; {----->
      IFEND;

*copy bai$seek_validation
      IF NOT status.normal THEN
        RETURN; {----->
      IFEND;

*copy bai$get_record_info
      IF (record_info.file_position = amc$mid_record) AND (file_instance^.private_read_information = NIL) AND
            (file_instance^.global_file_information^.last_access_operation = amc$put_partial_req) THEN

{ Must have been left mid_record by a put_partial.  EOI needs updating.
        record_info.file_position := amc$eor;
        update_eoi;
      IFEND;

      IF (record_info.current_byte_address = file_byte_address) THEN
        IF record_info.file_position = amc$mid_record THEN

{ Seek must position to a record boundary or it is an error.

          amp$set_file_instance_abnormal (file_identifier, ame$improper_seek_address, call_block.operation,
                error_text, status);
        IFEND;

{ IF the seek is to the address the file is already at then it is a no-op.

        RETURN; {----->
      IFEND;

      IF (file_byte_address > 0) AND (file_byte_address < file_instance^.global_file_information^.
            eoi_byte_address) AND ((file_instance^.instance_attributes.static_label.file_organization =
            amc$sequential) OR ((file_instance^.instance_attributes.static_label.file_organization =
            amc$byte_addressable) AND (call_block.operation = amc$get_direct_req))) THEN
        delimiter_ptr := #ADDRESS (osc$min_ring, #SEGMENT (file_instance^.file_pva), file_byte_address - 1);
        IF delimiter_ptr^ <> file_instance^.global_file_information^.record_delimiting_character THEN

{ Seek must position to a record boundary or it is an error.

          amp$set_file_instance_abnormal (file_identifier, ame$improper_seek_address, call_block.operation,
                error_text, status);
          RETURN; {----->
        IFEND;
      IFEND;

      record_info.current_byte_address := file_byte_address;
      record_info.file_position := amc$eor;

*copy bai$save_record_info

    PROCEND seek_direct;
?? OLDTITLE ??
?? NEWTITLE := 'BACKSCAN_TO_DELIMITING_CHAR', EJECT ??

    PROCEDURE backscan_to_delimiting_char;

{ This code scans backwards until it finds boi or a delimiter, and assumes that
{ the scan_byte_address starts and ends on a delimiter if one is found.

      found_delimiter := FALSE;
      scan_max := max_scan_size;

      WHILE (scan_byte_address >= 1) AND (NOT found_delimiter) DO
        IF scan_byte_address < max_scan_size THEN
          scan_max := scan_byte_address;
        IFEND;

        scan_string := #ADDRESS (osc$min_ring, #SEGMENT (file_instance^.file_pva),
              scan_byte_address - scan_max);

      /backscan_loop/
        FOR scanned_piece_size := scan_max DOWNTO 1 DO
          IF scan_string^ (scanned_piece_size) = file_instance^.global_file_information^.
                record_delimiting_character THEN
            found_delimiter := TRUE;
            EXIT /backscan_loop/; {----->
          IFEND;
        FOREND /backscan_loop/;

{ Note: Scanned_piece_size is really the unscanned piece size in this usage.
{       Indexing a string starts from 1, but offsets in file start from 0,
{       so scanned_piece_size must be decremented to get true file offset.

        scan_byte_address := (scan_byte_address - scan_max) + (scanned_piece_size - 1);

      WHILEND;

    PROCEND backscan_to_delimiting_char;
?? OLDTITLE ??
?? NEWTITLE := 'SCAN_TO_DELIMITING_CHAR', EJECT ??

    PROCEDURE scan_to_delimiting_char;

*copy bai$scan_to_delimiting_char

    PROCEND scan_to_delimiting_char;
?? OLDTITLE ??
?? NEWTITLE := 'UPDATE_EOI', EJECT ??

    PROCEDURE update_eoi;

*copy bai$update_eoi

    PROCEND update_eoi;
?? OLDTITLE ??
?? NEWTITLE := 'TERMINATE_RECORD', EJECT ??

    PROCEDURE terminate_record;

      IF (file_instance^.private_read_information = NIL) AND
            (file_instance^.global_file_information^.positioning_info.record_info.file_position =
            amc$mid_record) AND (file_instance^.global_file_information^.last_access_operation =
            amc$put_partial_req) THEN

{ Must have been left mid_record by a put_partial.  EOI needs updating.

        record_info := file_instance^.global_file_information^.positioning_info.record_info;
        update_eoi;
        file_instance^.global_file_information^.positioning_info.record_info := record_info;
      IFEND;

    PROCEND terminate_record;
?? OLDTITLE ??
?? EJECT ??

    #CALLER_ID (caller_id);
    status.normal := TRUE;

  /process_fap_request/
    BEGIN
      file_instance := baf$task_file_entry_p (file_identifier);
      IF file_instance = NIL THEN
        osp$set_status_abnormal (amc$access_method_id, ame$improper_file_id, error_text, status);
        RETURN; {----->
      IFEND;

      delimiting_char_set := $set_of_char [file_instance^.global_file_information^.
            record_delimiting_character];

      file_instance^.rollback_procedure := ^rollback_procedure;
      CASE call_block.operation OF
      = amc$get_next_req =
        get_next;
      = amc$put_next_req =
        put_next;
      = amc$get_partial_req =
        get_partial;
      = amc$put_partial_req =
        put_partial;
      = amc$open_req =
        ;
      = amc$close_req =
        terminate_record;
        bap$close (file_identifier, status);
        EXIT /process_fap_request/; {----->
      = amc$rewind_req =
        terminate_record;
*copy   bai$rewind
      = amc$seek_direct_req =
        file_byte_address := call_block.seekd.byte_address;
        seek_direct;
      = amc$get_direct_req =
        file_byte_address := call_block.getd.byte_address;
        seek_direct;
        IF NOT status.normal THEN
          IF status.condition = ame$position_beyond_eoi THEN
            status.condition := ame$input_after_eoi;
          IFEND;
        ELSE
          get_next;
        IFEND;
      = amc$put_direct_req =
        file_byte_address := call_block.putd.byte_address;
        seek_direct;
        IF status.normal THEN
          put_next;
        IFEND;
      = amc$skip_req =
        skip;
      = amc$fetch_access_information_rq =
        bap$fetch_access_information (file_identifier, call_block, layer_number, status);
        EXIT /process_fap_request/; {----->
      = amc$fetch_req =
        bap$fetch (file_identifier, call_block, layer_number, status);
        EXIT /process_fap_request/; {----->
      = amc$get_segment_pointer_req =
        bap$get_segment_pointer (file_identifier, call_block, layer_number, status);
      = amc$set_segment_eoi_req =
        bap$set_segment_eoi (file_identifier, call_block, layer_number, status);
      = amc$set_segment_position_req =
        bap$set_segment_position (file_identifier, call_block, layer_number, status);
      = amc$replace_req, amc$write_end_partition_req =
        amp$set_file_instance_abnormal (file_identifier, ame$unsupported_operation, call_block.operation,
              error_text, status);
      = amc$store_req =
        bap$store (file_identifier, call_block, layer_number, status);
      = amc$write_tape_mark_req, amc$close_volume_req =
        amp$set_file_instance_abnormal (file_identifier, ame$improper_device_class, call_block.operation,
              'MASS_STORAGE', status);
      = amc$flush_req =
        bap$write_modified_pages (file_instance, file_identifier, status);
      = ifc$fetch_terminal_req, ifc$store_terminal_req =
        IF pmf$job_mode () = jmc$batch THEN
          osp$set_status_abnormal (ifc$interactive_facility_id, ife$current_job_not_interactive,
                'FETCH/STORE_TERMINAL_REQ', status);
        ELSE
          amp$set_file_instance_abnormal (file_identifier, ame$improper_device_class, call_block.operation,
                'MASS STORAGE', status);
        IFEND;

      ELSE { NO CASE }
        amp$set_file_instance_abnormal (file_identifier, ame$unimplemented_request, call_block.operation,
              ' for sequential or byte addressable files', status);
      CASEND;

      IF file_instance^.private_read_information = NIL THEN
        IF status.normal THEN
          file_instance^.global_file_information^.error_status := 0;
        ELSE
          file_instance^.global_file_information^.error_status := status.condition;
        IFEND;
        file_instance^.global_file_information^.last_access_operation := call_block.operation;
      ELSE
        IF status.normal THEN
          file_instance^.private_read_information^.error_status := 0;
        ELSE
          file_instance^.private_read_information^.error_status := status.condition;
        IFEND;
        file_instance^.private_read_information^.last_access_operation := call_block.operation;
      IFEND;
    END /process_fap_request/;

    file_instance^.rollback_procedure := NIL;

  PROCEND bap$trailing_char_delimited_fap;
?? OLDTITLE ??
MODEND bam$trailing_char_delimited_fap;
