?? NEWTITLE := 'NOS/VE :  BASIC ACCESS METHOD' ??
MODULE amm$fetch;
?? RIGHT := 110 ??

*copyc amh$also

?? NEWTITLE := 'Global Declarations Referenced By This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc amc$condition_code_limits
*copyc ame$improper_file_id
*copyc amt$call_block
*copyc amt$fap_layer_number
*copyc amt$fap_pointer
?? POP ??
*copyc baf$task_file_entry_p
*copyc osp$set_status_abnormal
?? OLDTITLE ??
?? NEWTITLE := '  [XDCL] AMP$FETCH', EJECT ??

*copyc amh$fetch

  PROCEDURE [XDCL, #GATE] amp$fetch ALIAS 'amxftch'
    (    file_identifier: amt$file_identifier;
     VAR file_attributes: amt$fetch_attributes;
     VAR status: ost$status);

    CONST
      interface_name = 'AMP$FETCH',
      fap_layer_number = 0;

    VAR
      call_block: amt$call_block,
      file_instance_p: ^bat$task_file_entry;

?? NEWTITLE := 'P$GET_DEVICE_CLASSES', EJECT ??

{ GET_DEVICE_CLASSES will fill the sets INPUT_DEVICE_CLASSES and OUTPUT_
{ DEVICE_CLASSES if the subject file is a connected file.  If INPUT_DEVICE_
{ CLASSES is specified, this procedure will follow the path of most recently
{ connected files.  If OUTPUT_DEVICE_CLASSES is specified, GET_OUTPUT_DEVICE_
{ CLASSES, (defined below) will be called recursivly to find the device class
{ of all files connected directly or indirectly to the subject file.

    PROCEDURE p$get_device_classes
      (    call_block: amt$call_block,
           file_identifer: amt$file_identifier,
           file_instance_p: ^bat$task_file_entry;
       VAR status: ost$status);

      VAR
        current_file_identifier: amt$file_identifier,
        current_file_instance_p: ^bat$task_file_entry,
        entry_p: ^amt$fetch_item,
        i: integer,
        target_defined: boolean;

?? NEWTITLE := 'P$GET_OUTPUT_DEVICE_CLASSES', EJECT ??

      PROCEDURE p$get_output_device_classes
        (    file_id: amt$file_identifier;
             entry_p: ^amt$fetch_item;
         VAR status: ost$status);

        VAR
          current_file_id: amt$file_identifier,
          current_file_instance_p: ^bat$task_file_entry;

        current_file_id := file_id;
        WHILE TRUE DO
          current_file_instance_p := baf$task_file_entry_p (current_file_identifier);
          IF current_file_instance_p = NIL THEN
            osp$set_status_abnormal (amc$access_method_id, ame$improper_file_id, interface_name, status);
            RETURN; {----->
          IFEND;

          entry_p^.output_device_classes := entry_p^.output_device_classes +
                $rmt$device_classes [current_file_instance_p^.device_class];
          IF (current_file_instance_p^.device_class = rmc$connected_file_device) AND
                (current_file_instance_p^.first_target.defined) THEN
            p$get_output_device_classes (current_file_instance_p^.first_target.file_identifier, entry_p,
                  status);
          IFEND;
          IF NOT current_file_instance_p^.next_target.defined THEN
            RETURN; {----->
          IFEND;
          current_file_id := current_file_instance_p^.next_target.file_identifier;
        WHILEND;

      PROCEND p$get_output_device_classes;
?? OLDTITLE ??
?? EJECT ??
      FOR i := LOWERBOUND (call_block.fetch.file_attributes^)
            TO UPPERBOUND (call_block.fetch.file_attributes^) DO
        entry_p := ^call_block.fetch.file_attributes^ [i];

        IF (entry_p^.key = amc$output_device_classes) THEN
          entry_p^.output_device_classes := $rmt$device_classes [];
          p$get_output_device_classes (file_identifier, entry_p, status);
          IF NOT status.normal THEN
            RETURN; {----->
          IFEND;

        ELSEIF (entry_p^.key = amc$input_device_classes) THEN
          entry_p^.input_device_classes := $rmt$device_classes [];
          current_file_identifier := file_identifier;
          REPEAT
            current_file_instance_p := baf$task_file_entry_p (current_file_identifier);
            IF current_file_instance_p = NIL THEN
              osp$set_status_abnormal (amc$access_method_id, ame$improper_file_id, interface_name, status);
              RETURN; {----->
            IFEND;

            entry_p^.input_device_classes := entry_p^.input_device_classes +
                  $rmt$device_classes [current_file_instance_p^.device_class];
            target_defined := (current_file_instance_p^.device_class = rmc$connected_file_device) AND
                  (current_file_instance_p^.first_target.defined);
            IF target_defined THEN
              current_file_identifier := current_file_instance_p^.first_target.file_identifier;
            IFEND;
          UNTIL NOT target_defined;

        ELSEIF entry_p^.key = amc$device_class THEN
          entry_p^.device_class := file_instance_p^.device_class;
        IFEND;
      FOREND;

    PROCEND p$get_device_classes;
?? OLDTITLE ??
?? EJECT ??

    status.normal := TRUE;
    file_instance_p := baf$task_file_entry_p (file_identifier);
    IF file_instance_p = NIL THEN
      osp$set_status_abnormal (amc$access_method_id, ame$improper_file_id, interface_name, status);
      RETURN; {----->
    IFEND;

    call_block.operation := amc$fetch_req;
    call_block.fetch.file_attributes := ^file_attributes;
    file_instance_p^.fap_control_information.first_fap.access_method^
          (file_identifier, call_block, fap_layer_number, status);

    IF file_instance_p^.device_class = rmc$connected_file_device THEN
      p$get_device_classes (call_block, file_identifier, file_instance_p, status);
    IFEND;

    IF NOT status.normal THEN
      IF (file_instance_p^.instance_attributes.dynamic_label.error_exit_procedure <> NIL) THEN
        file_instance_p^.instance_attributes.dynamic_label.error_exit_procedure^ (file_identifier, status);
      IFEND;
    IFEND;

  PROCEND amp$fetch;
?? OLDTITLE ??
MODEND amm$fetch;
