from __future__ import annotations from typing import Final magic: Final = ( b"\x00\x00\x00\x00\x00\x00\x00\x00" + b"\x00\x00\x00\x00\xc2\xea\x81\x60" + b"\xb3\x14\x11\xcf\xbd\x92\x08\x00" + b"\x09\xc7\x31\x8c\x18\x1f\x10\x11" ) align_1_checker_value: Final = b"3" align_1_offset: Final = 32 align_1_length: Final = 1 align_1_value: Final = 4 u64_byte_checker_value: Final = b"3" align_2_offset: Final = 35 align_2_length: Final = 1 align_2_value: Final = 4 endianness_offset: Final = 37 endianness_length: Final = 1 platform_offset: Final = 39 platform_length: Final = 1 encoding_offset: Final = 70 encoding_length: Final = 1 dataset_offset: Final = 92 dataset_length: Final = 64 file_type_offset: Final = 156 file_type_length: Final = 8 date_created_offset: Final = 164 date_created_length: Final = 8 date_modified_offset: Final = 172 date_modified_length: Final = 8 header_size_offset: Final = 196 header_size_length: Final = 4 page_size_offset: Final = 200 page_size_length: Final = 4 page_count_offset: Final = 204 page_count_length: Final = 4 sas_release_offset: Final = 216 sas_release_length: Final = 8 sas_server_type_offset: Final = 224 sas_server_type_length: Final = 16 os_version_number_offset: Final = 240 os_version_number_length: Final = 16 os_maker_offset: Final = 256 os_maker_length: Final = 16 os_name_offset: Final = 272 os_name_length: Final = 16 page_bit_offset_x86: Final = 16 page_bit_offset_x64: Final = 32 subheader_pointer_length_x86: Final = 12 subheader_pointer_length_x64: Final = 24 page_type_offset: Final = 0 page_type_length: Final = 2 block_count_offset: Final = 2 block_count_length: Final = 2 subheader_count_offset: Final = 4 subheader_count_length: Final = 2 page_type_mask: Final = 0x0F00 # Keep "page_comp_type" bits page_type_mask2: Final = 0xF000 | page_type_mask page_meta_type: Final = 0x0000 page_data_type: Final = 0x0100 page_mix_type: Final = 0x0200 page_amd_type: Final = 0x0400 page_meta2_type: Final = 0x4000 page_comp_type: Final = 0x9000 page_meta_types: Final = [page_meta_type, page_meta2_type] subheader_pointers_offset: Final = 8 truncated_subheader_id: Final = 1 compressed_subheader_id: Final = 4 compressed_subheader_type: Final = 1 text_block_size_length: Final = 2 row_length_offset_multiplier: Final = 5 row_count_offset_multiplier: Final = 6 col_count_p1_multiplier: Final = 9 col_count_p2_multiplier: Final = 10 row_count_on_mix_page_offset_multiplier: Final = 15 column_name_pointer_length: Final = 8 column_name_text_subheader_offset: Final = 0 column_name_text_subheader_length: Final = 2 column_name_offset_offset: Final = 2 column_name_offset_length: Final = 2 column_name_length_offset: Final = 4 column_name_length_length: Final = 2 column_data_offset_offset: Final = 8 column_data_length_offset: Final = 8 column_data_length_length: Final = 4 column_type_offset: Final = 14 column_type_length: Final = 1 column_format_text_subheader_index_offset: Final = 22 column_format_text_subheader_index_length: Final = 2 column_format_offset_offset: Final = 24 column_format_offset_length: Final = 2 column_format_length_offset: Final = 26 column_format_length_length: Final = 2 column_label_text_subheader_index_offset: Final = 28 column_label_text_subheader_index_length: Final = 2 column_label_offset_offset: Final = 30 column_label_offset_length: Final = 2 column_label_length_offset: Final = 32 column_label_length_length: Final = 2 rle_compression: Final = b"SASYZCRL" rdc_compression: Final = b"SASYZCR2" compression_literals: Final = [rle_compression, rdc_compression] # Incomplete list of encodings, using SAS nomenclature: # http://support.sas.com/documentation/cdl/en/nlsref/61893/HTML/default/viewer.htm#a002607278.htm encoding_names: Final = { 29: "latin1", 20: "utf-8", 33: "cyrillic", 60: "wlatin2", 61: "wcyrillic", 62: "wlatin1", 90: "ebcdic870", } class SASIndex: row_size_index: Final = 0 column_size_index: Final = 1 subheader_counts_index: Final = 2 column_text_index: Final = 3 column_name_index: Final = 4 column_attributes_index: Final = 5 format_and_label_index: Final = 6 column_list_index: Final = 7 data_subheader_index: Final = 8 subheader_signature_to_index: Final = { b"\xF7\xF7\xF7\xF7": SASIndex.row_size_index, b"\x00\x00\x00\x00\xF7\xF7\xF7\xF7": SASIndex.row_size_index, b"\xF7\xF7\xF7\xF7\x00\x00\x00\x00": SASIndex.row_size_index, b"\xF7\xF7\xF7\xF7\xFF\xFF\xFB\xFE": SASIndex.row_size_index, b"\xF6\xF6\xF6\xF6": SASIndex.column_size_index, b"\x00\x00\x00\x00\xF6\xF6\xF6\xF6": SASIndex.column_size_index, b"\xF6\xF6\xF6\xF6\x00\x00\x00\x00": SASIndex.column_size_index, b"\xF6\xF6\xF6\xF6\xFF\xFF\xFB\xFE": SASIndex.column_size_index, b"\x00\xFC\xFF\xFF": SASIndex.subheader_counts_index, b"\xFF\xFF\xFC\x00": SASIndex.subheader_counts_index, b"\x00\xFC\xFF\xFF\xFF\xFF\xFF\xFF": SASIndex.subheader_counts_index, b"\xFF\xFF\xFF\xFF\xFF\xFF\xFC\x00": SASIndex.subheader_counts_index, b"\xFD\xFF\xFF\xFF": SASIndex.column_text_index, b"\xFF\xFF\xFF\xFD": SASIndex.column_text_index, b"\xFD\xFF\xFF\xFF\xFF\xFF\xFF\xFF": SASIndex.column_text_index, b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFD": SASIndex.column_text_index, b"\xFF\xFF\xFF\xFF": SASIndex.column_name_index, b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF": SASIndex.column_name_index, b"\xFC\xFF\xFF\xFF": SASIndex.column_attributes_index, b"\xFF\xFF\xFF\xFC": SASIndex.column_attributes_index, b"\xFC\xFF\xFF\xFF\xFF\xFF\xFF\xFF": SASIndex.column_attributes_index, b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFC": SASIndex.column_attributes_index, b"\xFE\xFB\xFF\xFF": SASIndex.format_and_label_index, b"\xFF\xFF\xFB\xFE": SASIndex.format_and_label_index, b"\xFE\xFB\xFF\xFF\xFF\xFF\xFF\xFF": SASIndex.format_and_label_index, b"\xFF\xFF\xFF\xFF\xFF\xFF\xFB\xFE": SASIndex.format_and_label_index, b"\xFE\xFF\xFF\xFF": SASIndex.column_list_index, b"\xFF\xFF\xFF\xFE": SASIndex.column_list_index, b"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF": SASIndex.column_list_index, b"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE": SASIndex.column_list_index, } # List of frequently used SAS date and datetime formats # http://support.sas.com/documentation/cdl/en/etsug/60372/HTML/default/viewer.htm#etsug_intervals_sect009.htm # https://github.com/epam/parso/blob/master/src/main/java/com/epam/parso/impl/SasFileConstants.java sas_date_formats: Final = ( "DATE", "DAY", "DDMMYY", "DOWNAME", "JULDAY", "JULIAN", "MMDDYY", "MMYY", "MMYYC", "MMYYD", "MMYYP", "MMYYS", "MMYYN", "MONNAME", "MONTH", "MONYY", "QTR", "QTRR", "NENGO", "WEEKDATE", "WEEKDATX", "WEEKDAY", "WEEKV", "WORDDATE", "WORDDATX", "YEAR", "YYMM", "YYMMC", "YYMMD", "YYMMP", "YYMMS", "YYMMN", "YYMON", "YYMMDD", "YYQ", "YYQC", "YYQD", "YYQP", "YYQS", "YYQN", "YYQR", "YYQRC", "YYQRD", "YYQRP", "YYQRS", "YYQRN", "YYMMDDP", "YYMMDDC", "E8601DA", "YYMMDDN", "MMDDYYC", "MMDDYYS", "MMDDYYD", "YYMMDDS", "B8601DA", "DDMMYYN", "YYMMDDD", "DDMMYYB", "DDMMYYP", "MMDDYYP", "YYMMDDB", "MMDDYYN", "DDMMYYC", "DDMMYYD", "DDMMYYS", "MINGUO", ) sas_datetime_formats: Final = ( "DATETIME", "DTWKDATX", "B8601DN", "B8601DT", "B8601DX", "B8601DZ", "B8601LX", "E8601DN", "E8601DT", "E8601DX", "E8601DZ", "E8601LX", "DATEAMPM", "DTDATE", "DTMONYY", "DTMONYY", "DTWKDATX", "DTYEAR", "TOD", "MDYAMPM", )