*copyc osd$default_pragmats
MODULE srm$convert_label;

{   This module contains those interfaces that convert the label to V1 format.
{ The label is converted only after it is found to be downward compatible.

?? PUSH (LISTEXT := ON) ??
*copyc fmc$unique_label_id
*copyc ame$attribute_validation_errors
*copyc ame$lfn_program_actions
*copyc fme$file_management_errors
*copyc amt$file_reference
*copyc amt$local_file_name
*copyc amt$path_name
*copyc fmt$basic_file_label
*copyc fmt$file_attribute_keys
*copyc fmt$label_headers
*copyc fmt$static_label_header
*copyc fmt$static_label_item
*copyc ost$status
?? POP ??
*copyc osp$set_status_abnormal
*copyc pfp$compute_checksum
*copyc srp$validate_compatibility
*copyc srv$static_label_attributes

?? TITLE := '[XDCL] srp$get_v1_label', EJECT ??

  PROCEDURE [XDCL] srp$get_v1_label (local_file_name: amt$local_file_name;
        current_label: SEQ ( * );
    VAR label_v1: ^SEQ ( * );
    VAR v1_label_allocated: boolean;
    VAR status: ost$status);

    VAR
      computed_checksum: integer,
      v1_label: ^SEQ ( * ),
      p_label: ^SEQ ( * ),
      p_label_header: ^fmt$static_label_header,
      p_label_v1_header: ^fmt$static_bam_label_header,
      p_stored_checksum: ^integer;

    status.normal := TRUE;

    v1_label := label_v1; {assign seq ptr to local variable}

    p_label := ^current_label;
    RESET p_label;
    NEXT p_stored_checksum IN p_label;
    IF p_stored_checksum = NIL THEN
      osp$set_status_abnormal (amc$access_method_id, ame$damaged_file_attributes,
            ' static label checksum', status);
      RETURN;
    IFEND;
    NEXT p_label_header IN p_label;
    IF p_label_header = NIL THEN
      osp$set_status_abnormal (amc$access_method_id,
            ame$damaged_file_attributes, ' p_label_header', status);
      RETURN;
    IFEND;
    pfp$compute_checksum (#LOC(p_label_header^), #SIZE (p_label^) -
          #SIZE (integer), computed_checksum);
    IF computed_checksum = p_stored_checksum^ THEN
      IF p_label_header^.unique_character = fmc$unique_label_id THEN
        srp$validate_compatibility (p_label, p_label_header, local_file_name,
              status);
        IF NOT status.normal THEN
          RETURN;
        IFEND;
        srp$convert_to_v1_label (p_label, p_label_header, v1_label, status);
        v1_label_allocated := TRUE;
      ELSE { unique character <> % }
        osp$set_status_abnormal (amc$access_method_id, ame$damaged_file_attributes,
              ' INVALID STATIC LABEL DETECTED in srp$get_v1_label', status);
        RETURN;
      IFEND;
    ELSE { computed_checksum <> p_stored_checksum; possible v1 label }
      RESET p_label;
      NEXT p_label_v1_header IN p_label;
      IF p_label_v1_header = NIL THEN
        osp$set_status_abnormal (amc$access_method_id, ame$damaged_file_attributes,
              ' p_label_v1_header NIL in srp$get_v1_label', status);
        RETURN;
      IFEND;
      IF p_label_v1_header^.name = 'BAM_STATIC_LABEL' THEN
        v1_label := p_label;
      ELSE
        osp$set_status_abnormal (amc$access_method_id, ame$damaged_file_attributes,
              ' INVALID LABEL DETECTED in srp$get_v1_label', status);
        RETURN;
      IFEND;
      v1_label_allocated := FALSE;
    IFEND;
  PROCEND srp$get_v1_label;

?? TITLE := '[INLINE] srp$convert_to_v1_label', EJECT ??

  PROCEDURE [INLINE] srp$convert_to_v1_label (label_p: ^SEQ ( * );
        p_label_header: ^fmt$static_label_header;
    VAR label_v1: ^SEQ ( * );
    VAR status: ost$status);

{ This converts any label to the V1 format }

    VAR
      p_label: ^SEQ ( * ),
      checksum_size: integer,
      job_label_header: ^fmt$job_label_header,
      current_job_info: ^SEQ ( * ),
      p_checksum: ^integer,
      static_label_header: ^fmt$static_bam_label_header,
      static_label_size: integer,
      v1_label: ^SEQ ( * ),
      v1_label_size: integer,
      v1_job_info: ^SEQ ( * ),
      v1_static_info: ^fmt$basic_file_label;

    v1_label := label_v1; {assign seq ptr to local variable}
    p_label := label_p;

    checksum_size := #SIZE (integer);
    static_label_size := #SIZE (fmt$basic_file_label);
    v1_label_size := static_label_size + checksum_size +
      #SIZE (fmt$static_bam_label_header) + checksum_size +
      #SIZE (fmt$job_label_header) + checksum_size;
    IF p_label_header^.job_routing_label_size > 0 THEN
      v1_label_size := v1_label_size + p_label_header^.job_routing_label_size +
        checksum_size;
    IFEND;
    ALLOCATE v1_label: [[REP v1_label_size OF cell]];
    IF v1_label = NIL THEN
      osp$set_status_abnormal (amc$access_method_id, fme$system_error,
            'FULL HEAP in srp$convert_to_v1_label', status);
      RETURN;
    IFEND;

    RESET v1_label;
    NEXT static_label_header IN v1_label;
    static_label_header^.name := 'BAM_STATIC_LABEL';
    static_label_header^.version := 1;
    static_label_header^.size := static_label_size;
    NEXT p_checksum IN v1_label;
    pfp$compute_checksum (#LOC (static_label_header^), #SIZE
          (fmt$static_bam_label_header), p_checksum^);

    NEXT v1_static_info IN v1_label;
    srp$convert_label_attributes (p_label, v1_static_info^, status);
    IF NOT status.normal THEN
      RETURN;
    IFEND;
    NEXT p_checksum IN v1_label;
    pfp$compute_checksum (#LOC (v1_static_info^), static_label_size,
          p_checksum^);

    NEXT job_label_header IN v1_label;
    job_label_header^.name := 'BAM_JOB_LABEL';
    job_label_header^.version := 1;
    job_label_header^.size := p_label_header^.job_routing_label_size;
    NEXT p_checksum IN v1_label;
    pfp$compute_checksum (#LOC (job_label_header^), #SIZE (fmt$job_label_header),
          p_checksum^);
    IF job_label_header^.size > 0 THEN
      NEXT v1_job_info: [[REP job_label_header^.size OF cell]] IN v1_label;
      NEXT current_job_info: [[REP p_label_header^.job_routing_label_size OF cell]]
        IN p_label;
      v1_job_info^ := current_job_info^;
      NEXT p_checksum IN v1_label;
      pfp$compute_checksum (#LOC (v1_job_info^), job_label_header^.size, p_checksum^);
    IFEND;

  PROCEND srp$convert_to_v1_label;

?? TITLE := '[XDCL] srp$convert_label_attributes', EJECT ??

  PROCEDURE [XDCL] srp$convert_label_attributes (p_label: ^SEQ ( * );
    VAR static_label_attributes: fmt$basic_file_label;
    VAR status: ost$status);

{ This converts a V2 label to the V1 types }

    VAR
      checksum: ^integer,
      header: ^fmt$static_label_header,
      attribute_key: fmt$file_attribute_keys,
      static_label: ^SEQ ( * ),
      static_label_item: ^fmt$static_label_item,
      ignore_path: amt$path_name,
      ignore_found: boolean,
      str: ^string ( * );

    PROCEDURE [INLINE] get_entry_point_reference (VAR name: pmt$program_name;
      VAR path: amt$file_reference);

      NEXT str: [static_label_item^.entry_point_name_length] IN static_label;
      name := str^;
      IF static_label_item^.entry_point_path_length > 0 THEN
        NEXT str: [static_label_item^.entry_point_path_length] IN static_label;
        path := str^;
      IFEND;
    PROCEND get_entry_point_reference;

    PROCEDURE [INLINE] get_name (VAR name: pmt$program_name);

      NEXT str: [static_label_item^.name_length] IN static_label;
      name := str^;
    PROCEND get_name;


    status.normal := TRUE;
    static_label_attributes := srv$static_label_attributes;

    IF p_label <> NIL THEN
      static_label := p_label;
      RESET static_label;
      NEXT checksum IN static_label;
      IF checksum = NIL THEN
        osp$set_status_abnormal (amc$access_method_id, ame$damaged_file_attributes,
              'BAD LABEL DETECTED in srp$convert_label_attributes', status);
        RETURN;
      IFEND;
      NEXT header IN static_label;
      IF header^. unique_character <> fmc$unique_label_id THEN
        osp$set_status_abnormal (amc$access_method_id, ame$damaged_file_attributes,
              'INVALID STATIC FILE LABEL DETECTED in srp$convert_label_attributes',
              status);
        RETURN;
      IFEND;
      static_label_attributes.existing_file := header^.file_previously_opened;
      IF header^. file_previously_opened THEN
        static_label_attributes.ring_attributes_source := header^.
              ring_attributes_source;
        static_label_attributes.ring_attributes := header^. ring_attributes;
      IFEND;
      IF header^. highest_attribute_present > 0 THEN
        FOR attribute_key := LOWERBOUND (header^. attribute_present) TO
              header^. highest_attribute_present DO
          CASE attribute_key OF
          = fmc$block_type =
            IF header^.attribute_present [fmc$block_type] THEN
              NEXT static_label_item: [fmc$block_type] IN static_label;
              static_label_attributes.block_type_source :=
                    static_label_item^.source;
              static_label_attributes.block_type := static_label_item^.
                    block_type;
            IFEND;
          = fmc$character_conversion =
            IF header^.attribute_present [fmc$character_conversion] THEN
              NEXT static_label_item: [fmc$character_conversion] IN static_label;
              static_label_attributes.character_conversion_source :=
                    static_label_item^.source;
              static_label_attributes.character_conversion := static_label_item^.
                    character_conversion;
            IFEND;
          = fmc$clear_space =
            IF header^.attribute_present [fmc$clear_space] THEN
              NEXT static_label_item: [fmc$clear_space] IN static_label;
              static_label_attributes.clear_space_source :=
                    static_label_item^.source;
              static_label_attributes.clear_space := static_label_item^.
                    clear_space;
            IFEND;
          = fmc$file_access_procedure =
            IF header^.attribute_present [fmc$file_access_procedure] THEN
              NEXT static_label_item: [fmc$file_access_procedure] IN static_label;
              static_label_attributes.file_access_procedure_source :=
                    static_label_item^.source;
              get_entry_point_reference (static_label_attributes.
                    file_access_procedure, ignore_path);
            IFEND;
          = fmc$file_contents =
            IF header^.attribute_present [fmc$file_contents] THEN
              NEXT static_label_item: [fmc$file_contents] IN static_label;
              static_label_attributes.file_contents_source :=
                    static_label_item^.source;
              get_name (static_label_attributes.file_contents);
            IFEND;
          = fmc$file_limit =
            IF header^.attribute_present [fmc$file_limit] THEN
              NEXT static_label_item: [fmc$file_limit] IN static_label;
              static_label_attributes.file_limit_source :=
                    static_label_item^.source;
              static_label_attributes.file_limit := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$file_organization =
            IF header^.attribute_present [fmc$file_organization] THEN
              NEXT static_label_item: [fmc$file_organization] IN static_label;
              static_label_attributes.file_organization_source :=
                    static_label_item^.source;
              static_label_attributes.file_organization := static_label_item^.
                    file_organization;
            IFEND;
          = fmc$file_processor =
            IF header^.attribute_present [fmc$file_processor] THEN
              NEXT static_label_item: [fmc$file_processor] IN static_label;
              static_label_attributes.file_processor_source :=
                    static_label_item^.source;
              get_name (static_label_attributes.file_processor);
            IFEND;
          = fmc$file_structure =
            IF header^.attribute_present [fmc$file_structure] THEN
              NEXT static_label_item: [fmc$file_structure] IN static_label;
              static_label_attributes.file_structure_source :=
                    static_label_item^.source;
              get_name (static_label_attributes.file_structure);
            IFEND;
          = fmc$forced_write =
            IF header^.attribute_present [fmc$forced_write] THEN
              NEXT static_label_item: [fmc$forced_write] IN static_label;
              static_label_attributes.forced_write_source :=
                    static_label_item^.source;
              static_label_attributes.forced_write := static_label_item^.
                    forced_write;
            IFEND;
          = fmc$internal_code =
            IF header^.attribute_present [fmc$internal_code] THEN
              NEXT static_label_item: [fmc$internal_code] IN static_label;
              static_label_attributes.internal_code_source :=
                    static_label_item^.source;
              static_label_attributes.internal_code := static_label_item^.
                    internal_code;
            IFEND;
          = fmc$label_type =
            IF header^.attribute_present [fmc$label_type] THEN
              NEXT static_label_item: [fmc$label_type] IN static_label;
              static_label_attributes.label_type_source :=
                    static_label_item^.source;
              static_label_attributes.label_type := static_label_item^.
                    label_type;
            IFEND;
          = fmc$line_number =
            IF header^.attribute_present [fmc$line_number] THEN
              NEXT static_label_item: [fmc$line_number] IN static_label;
              static_label_attributes.line_number_source :=
                    static_label_item^.source;
              static_label_attributes.line_number := static_label_item^.
                    line_number;
            IFEND;
          = fmc$max_block_length =
            IF header^.attribute_present [fmc$max_block_length] THEN
              NEXT static_label_item: [fmc$max_block_length] IN static_label;
              static_label_attributes.max_block_length_source :=
                    static_label_item^.source;
              static_label_attributes.max_block_length := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$max_record_length =
            IF header^.attribute_present [fmc$max_record_length] THEN
              NEXT static_label_item: [fmc$max_record_length] IN static_label;
              static_label_attributes.max_record_length_source :=
                    static_label_item^.source;
              static_label_attributes.max_record_length := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$min_block_length =
            IF header^.attribute_present [fmc$min_block_length] THEN
              NEXT static_label_item: [fmc$min_block_length] IN static_label;
              static_label_attributes.min_block_length_source :=
                    static_label_item^.source;
              static_label_attributes.min_block_length := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$min_record_length =
            IF header^.attribute_present [fmc$min_record_length] THEN
              NEXT static_label_item: [fmc$min_record_length] IN static_label;
              static_label_attributes.min_record_length_source :=
                    static_label_item^.source;
              static_label_attributes.min_record_length := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$padding_character =
            IF header^.attribute_present [fmc$padding_character] THEN
              NEXT static_label_item: [fmc$padding_character] IN static_label;
              static_label_attributes.padding_character_source :=
                    static_label_item^.source;
              static_label_attributes.padding_character := static_label_item^.
                    padding_character;
            IFEND;
          = fmc$page_format =
            IF header^.attribute_present [fmc$page_format] THEN
              NEXT static_label_item: [fmc$page_format] IN static_label;
              static_label_attributes.page_format_source :=
                    static_label_item^.source;
              static_label_attributes.page_format := static_label_item^.
                    page_format;
            IFEND;
          = fmc$page_length =
            IF header^.attribute_present [fmc$page_length] THEN
              NEXT static_label_item: [fmc$page_length] IN static_label;
              static_label_attributes.page_length_source :=
                    static_label_item^.source;
              static_label_attributes.page_length := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$page_width =
            IF header^.attribute_present [fmc$page_width] THEN
              NEXT static_label_item: [fmc$page_width] IN static_label;
              static_label_attributes.page_width_source :=
                    static_label_item^.source;
              static_label_attributes.page_width := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$preset_value =
            IF header^.attribute_present [fmc$preset_value] THEN
              NEXT static_label_item: [fmc$preset_value] IN static_label;
              static_label_attributes.preset_value_source :=
                    static_label_item^.source;
              static_label_attributes.preset_value := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$record_type =
            IF header^.attribute_present [fmc$record_type] THEN
              NEXT static_label_item: [fmc$record_type] IN static_label;
              static_label_attributes.record_type_source :=
                    static_label_item^.source;
              static_label_attributes.record_type := static_label_item^.
                    record_type;
            IFEND;
          = fmc$statement_identifier =
            IF header^.attribute_present [fmc$statement_identifier] THEN
              NEXT static_label_item: [fmc$statement_identifier] IN static_label;
              static_label_attributes.statement_identifier_source :=
                    static_label_item^.source;
              static_label_attributes.statement_identifier := static_label_item^.
                    statement_identifier;
            IFEND;
          = fmc$user_info =
            IF header^.attribute_present [fmc$user_info] THEN
              NEXT static_label_item: [fmc$user_info] IN static_label;
              static_label_attributes.user_info_source :=
                    static_label_item^.source;
              IF static_label_item^.user_info_present THEN
                NEXT str: [32] IN static_label;
                static_label_attributes.user_info := str^;
              IFEND;
            IFEND;
          = fmc$vertical_print_density =
            IF header^.attribute_present [fmc$vertical_print_density] THEN
              NEXT static_label_item: [fmc$vertical_print_density] IN static_label;
              static_label_attributes.vertical_print_density_source :=
                    static_label_item^.source;
              static_label_attributes.vertical_print_density := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$average_record_length =
            IF header^.attribute_present [fmc$average_record_length] THEN
              NEXT static_label_item: [fmc$average_record_length] IN static_label;
              static_label_attributes.average_record_length_source :=
                    static_label_item^.source;
              static_label_attributes.average_record_length := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$collate_table =
            IF header^.attribute_present [fmc$collate_table] THEN
              NEXT static_label_item: [fmc$collate_table] IN static_label;
              static_label_attributes.collate_table_source :=
                    static_label_item^.source;
              static_label_attributes.collate_table := static_label_item^.
                    collate_table;
            IFEND;
          = fmc$collate_table_name =
            IF header^.attribute_present [fmc$collate_table_name] THEN
              NEXT static_label_item: [fmc$collate_table_name] IN static_label;
              static_label_attributes.collate_table_name_source :=
                    static_label_item^.source;
              get_entry_point_reference (static_label_attributes.
                    collate_table_name, ignore_path);
            IFEND;
          = fmc$data_padding =
            IF header^.attribute_present [fmc$data_padding] THEN
              NEXT static_label_item: [fmc$data_padding] IN static_label;
              static_label_attributes.data_padding_source :=
                    static_label_item^.source;
              static_label_attributes.data_padding := static_label_item^.
                    data_padding;
            IFEND;
          = fmc$embedded_key =
            IF header^.attribute_present [fmc$embedded_key] THEN
              NEXT static_label_item: [fmc$embedded_key] IN static_label;
              static_label_attributes.embedded_key_source :=
                    static_label_item^.source;
              static_label_attributes.embedded_key := static_label_item^.
                    embedded_key;
            IFEND;
          = fmc$estimated_record_count =
            IF header^.attribute_present [fmc$estimated_record_count] THEN
              NEXT static_label_item: [fmc$estimated_record_count] IN static_label;
              static_label_attributes.estimated_record_count_source :=
                    static_label_item^.source;
              static_label_attributes.estimated_record_count := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$index_levels =
            IF header^.attribute_present [fmc$index_levels] THEN
              NEXT static_label_item: [fmc$index_levels] IN static_label;
              static_label_attributes.index_levels_source :=
                    static_label_item^.source;
              static_label_attributes.index_levels := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$index_padding =
            IF header^.attribute_present [fmc$index_padding] THEN
              NEXT static_label_item: [fmc$index_padding] IN static_label;
              static_label_attributes.index_padding_source :=
                    static_label_item^.source;
              static_label_attributes.index_padding := static_label_item^.
                    index_padding;
            IFEND;
          = fmc$key_length =
            IF header^.attribute_present [fmc$key_length] THEN
              NEXT static_label_item: [fmc$key_length] IN static_label;
              static_label_attributes.key_length_source :=
                    static_label_item^.source;
              static_label_attributes.key_length := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$key_position =
            IF header^.attribute_present [fmc$key_position] THEN
              NEXT static_label_item: [fmc$key_position] IN static_label;
              static_label_attributes.key_position_source :=
                    static_label_item^.source;
              static_label_attributes.key_position := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$key_type =
            IF header^.attribute_present [fmc$key_type] THEN
              NEXT static_label_item: [fmc$key_type] IN static_label;
              static_label_attributes.key_type_source :=
                    static_label_item^.source;
              static_label_attributes.key_type := static_label_item^.
                    key_type;
            IFEND;
          = fmc$record_limit =
            IF header^.attribute_present [fmc$record_limit] THEN
              NEXT static_label_item: [fmc$record_limit] IN static_label;
              static_label_attributes.record_limit_source :=
                    static_label_item^.source;
              static_label_attributes.record_limit := static_label_item^.
                    integer_value;
            IFEND;
          = fmc$records_per_block =
            IF header^.attribute_present [fmc$records_per_block] THEN
              NEXT static_label_item: [fmc$records_per_block] IN static_label;
              static_label_attributes.records_per_block_source :=
                    static_label_item^.source;
              static_label_attributes.records_per_block := static_label_item^.
                    integer_value;
            IFEND;
          ELSE
          CASEND;
        FOREND;
      IFEND;
    IFEND;

  PROCEND srp$convert_label_attributes;

MODEND srm$convert_label;

