note description: "Files viewed as persistent sequences of ASCII characters" library: "Free implementation of ELKS library" status: "See notice at end of class." legal: "See notice at end of class." date: "$Date: 2020-05-28 16:02:59 +0000 (Thu, 28 May 2020) $" revision: "$Revision: 104378 $" class PLAIN_TEXT_FILE inherit FILE rename index as position redefine make_with_name, make_with_path, is_plain_text end create make, make_with_name, make_with_path, make_open_read, make_open_write, make_open_append, make_open_read_write, make_create_read_write, make_open_read_append, make_open_temporary, make_open_temporary_with_prefix feature -- Initialization make_with_name (fn: READABLE_STRING_GENERAL) -- Create file object with fn as file name. do Precursor (fn) create last_string_32.make_empty end make_with_path (a_path: PATH) -- Create file object with a_path as path. do Precursor (a_path) create last_string_32.make_empty end feature -- Status report is_plain_text: BOOLEAN -- Is file reserved for text (character sequences)? (Yes) do Result := True end Support_storable: BOOLEAN = False -- Can medium be used to store an Eiffel structure? feature -- Output put_integer (i: INTEGER_32) -- Write ASCII value of i at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of putint and put_integer_32. do put_string_general (i.out) end putint (i: INTEGER_32) -- Write ASCII value of i at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_integer and put_integer_32. do put_string_general (i.out) end put_integer_32 (i: INTEGER_32) -- Write ASCII value of i at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_integer and putint. do put_string_general (i.out) end put_integer_64 (i: INTEGER_64) -- Write ASCII value of i at current position. do put_string_general (i.out) end put_integer_16 (i: INTEGER_16) -- Write ASCII value of i at current position. do put_string_general (i.out) end put_integer_8 (i: INTEGER_8) -- Write ASCII value of i at current position. do put_string_general (i.out) end put_natural_64 (i: NATURAL_64) -- Write ASCII value of i at current position. do put_string_general (i.out) end put_natural (i: NATURAL_32) -- Write ASCII value of i at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_natural_32. do put_string_general (i.out) end put_natural_32 (i: NATURAL_32) -- Write ASCII value of i at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_natural. do put_string_general (i.out) end put_natural_16 (i: NATURAL_16) -- Write ASCII value of i at current position. do put_string_general (i.out) end put_natural_8 (i: NATURAL_8) -- Write ASCII value of i at current position. do put_string_general (i.out) end put_boolean (b: BOOLEAN) -- Write ASCII value of b at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of putbool. do put_string_general (if b then True_string else False_string end) end putbool (b: BOOLEAN) -- Write ASCII value of b at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_boolean. do put_string_general (if b then True_string else False_string end) end put_real (r: REAL_32) -- Write ASCII value of r at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of putreal and put_real_32. do file_pr (file_pointer, r) end putreal (r: REAL_32) -- Write ASCII value of r at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_real and put_real_32. do file_pr (file_pointer, r) end put_real_32 (r: REAL_32) -- Write ASCII value of r at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_real and putreal. do file_pr (file_pointer, r) end put_double (d: REAL_64) -- Write ASCII value d at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of putdouble and put_real_64. do file_pd (file_pointer, d) end putdouble (d: REAL_64) -- Write ASCII value d at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_double and put_real_64. do file_pd (file_pointer, d) end put_real_64 (d: REAL_64) -- Write ASCII value d at current position. -- Was declared in PLAIN_TEXT_FILE as synonym of put_double and putdouble. do file_pd (file_pointer, d) end put_string_32 (s: READABLE_STRING_32) -- Write string s at current position. do put_string_general (s) end put_string_general (s: READABLE_STRING_GENERAL) -- Write string s at current position. require extendible: extendible non_void: s /= Void local str: STRING_8 utf32, utf8: ENCODING l_encoding: like encoding do l_encoding := encoding utf32 := {SYSTEM_ENCODINGS}.utf32; utf32.convert_to (l_encoding, s) if utf32.last_conversion_successful then str := utf32.last_converted_string_8 else utf8 := {SYSTEM_ENCODINGS}.utf8; utf32.convert_to (utf8, s) if utf32.last_conversion_successful then str := utf32.last_converted_string_8 if not utf8.same_as (l_encoding) then utf8.convert_to (l_encoding, str) if utf8.last_conversion_successful then str := utf8.last_converted_string_8 end end elseif s.is_valid_as_string_8 then str := s.to_string_8 else str := {UTF_CONVERTER}.string_32_to_utf_8_string_8 (s.as_string_32) end end put_string (str) end feature -- Input read_integer_64 -- Read the ASCII representation of a new 64-bit integer -- from file. Make result available in last_integer_64. do read_integer_with_no_type last_integer_64 := Ctoi_convertor.parsed_integer_64 end read_integer -- Read the ASCII representation of a new 32-bit integer -- from file. Make result available in last_integer. -- Was declared in PLAIN_TEXT_FILE as synonym of readint and read_integer_32. do read_integer_with_no_type last_integer := Ctoi_convertor.parsed_integer_32 end readint -- Read the ASCII representation of a new 32-bit integer -- from file. Make result available in last_integer. -- Was declared in PLAIN_TEXT_FILE as synonym of read_integer and read_integer_32. do read_integer_with_no_type last_integer := Ctoi_convertor.parsed_integer_32 end read_integer_32 -- Read the ASCII representation of a new 32-bit integer -- from file. Make result available in last_integer. -- Was declared in PLAIN_TEXT_FILE as synonym of read_integer and readint. do read_integer_with_no_type last_integer := Ctoi_convertor.parsed_integer_32 end read_integer_16 -- Read the ASCII representation of a new 16-bit integer -- from file. Make result available in last_integer_16. do read_integer_with_no_type last_integer_16 := Ctoi_convertor.parsed_integer_16 end read_integer_8 -- Read the ASCII representation of a new 8-bit integer -- from file. Make result available in last_integer_8. do read_integer_with_no_type last_integer_8 := Ctoi_convertor.parsed_integer_8 end read_natural_64 -- Read the ASCII representation of a new 64-bit natural -- from file. Make result available in last_natural_64. do read_integer_with_no_type last_natural_64 := Ctoi_convertor.parsed_natural_64 end read_natural -- Read the ASCII representation of a new 32-bit natural -- from file. Make result available in last_natural. -- Was declared in PLAIN_TEXT_FILE as synonym of read_natural_32. do read_integer_with_no_type last_natural := Ctoi_convertor.parsed_natural_32 end read_natural_32 -- Read the ASCII representation of a new 32-bit natural -- from file. Make result available in last_natural. -- Was declared in PLAIN_TEXT_FILE as synonym of read_natural. do read_integer_with_no_type last_natural := Ctoi_convertor.parsed_natural_32 end read_natural_16 -- Read the ASCII representation of a new 16-bit natural -- from file. Make result available in last_natural_16. do read_integer_with_no_type last_natural_16 := Ctoi_convertor.parsed_natural_16 end read_natural_8 -- Read the ASCII representation of a new 8-bit natural -- from file. Make result available in last_natural_8. do read_integer_with_no_type last_natural_8 := Ctoi_convertor.parsed_natural_8 end read_real -- Read the ASCII representation of a new real -- from file. Make result available in last_real. -- Was declared in PLAIN_TEXT_FILE as synonym of readreal and read_real_32. do last_real := file_gr (file_pointer) end readreal -- Read the ASCII representation of a new real -- from file. Make result available in last_real. -- Was declared in PLAIN_TEXT_FILE as synonym of read_real and read_real_32. do last_real := file_gr (file_pointer) end read_real_32 -- Read the ASCII representation of a new real -- from file. Make result available in last_real. -- Was declared in PLAIN_TEXT_FILE as synonym of read_real and readreal. do last_real := file_gr (file_pointer) end read_double -- Read the ASCII representation of a new double -- from file. Make result available in last_double. -- Was declared in PLAIN_TEXT_FILE as synonym of readdouble and read_real_64. do last_double := file_gd (file_pointer) end readdouble -- Read the ASCII representation of a new double -- from file. Make result available in last_double. -- Was declared in PLAIN_TEXT_FILE as synonym of read_double and read_real_64. do last_double := file_gd (file_pointer) end read_real_64 -- Read the ASCII representation of a new double -- from file. Make result available in last_double. -- Was declared in PLAIN_TEXT_FILE as synonym of read_double and readdouble. do last_double := file_gd (file_pointer) end read_to_string (a_string: STRING_8; pos, nb: INTEGER_32): INTEGER_32 -- Fill a_string, starting at position pos with at -- most nb characters read from current file. -- Return the number of characters actually read. do Result := file_gss (file_pointer, a_string.area.item_address (pos - 1), nb); a_string.reset_hash_codes end feature -- Unicode input last_string_32: STRING_32 -- Last unicode string read. read_unicode_line -- Read a line as STRING_32. local utf32: ENCODING do read_line utf32 := {SYSTEM_ENCODINGS}.utf32; encoding.convert_to (utf32, last_string) if encoding.last_conversion_successful then last_string_32.wipe_out; last_string_32.append (encoding.last_converted_string_32) end end feature -- Encoding encoding: ENCODING -- Associated encoding. do if attached internal_encoding as l_encoding then Result := l_encoding else Result := Default_encoding internal_encoding := Result end ensure encoding_not_void: Result /= Void end Default_encoding: ENCODING -- Default value for encoding. once Result := {SYSTEM_ENCODINGS}.utf8 ensure default_encoding_not_void: Result /= Void end set_encoding (enc: like encoding) -- Set associated encoding with enc. require enc_not_void: enc /= Void do internal_encoding := enc ensure encoding_set: encoding = enc end set_utf8_encoding -- Set encoding to UTF-8. do set_encoding ({SYSTEM_ENCODINGS}.utf8) ensure encoding_set: encoding = {SYSTEM_ENCODINGS}.utf8 end detect_encoding -- Detect and update encoding according to BOM detection. require is_open_read local pos: like position c1, c2, c3, c4: CHARACTER_8 do pos := position start if readable then read_character c1 := last_character inspect c1 when 'ï' then if readable then read_character c2 := last_character if c2 = '»' then if readable then read_character c3 := last_character if c3 = '¿' then set_utf8_encoding else back end end else back end end when 'ÿ' then if readable then read_character c2 := last_character if c2 = 'þ' then if readable then read_character c3 := last_character if readable then read_character c4 := last_character end if c3 = '%U' and c4 = '%U' then set_encoding (create {ENCODING}.make ({CODE_PAGE_CONSTANTS}.utf32_le)) else set_encoding (create {ENCODING}.make ({CODE_PAGE_CONSTANTS}.utf16_le)) back back end end else back end end when 'þ' then if readable then read_character c2 := last_character if c2 = 'ÿ' then set_encoding (create {ENCODING}.make ({CODE_PAGE_CONSTANTS}.utf16_be)) else back end end when '%U' then if readable then read_character c2 := last_character if c2 = '%U' then if readable then read_character c3 := last_character if c3 = 'þ' then if readable then read_character c4 := last_character if c4 = 'ÿ' then set_encoding (create {ENCODING}.make ({CODE_PAGE_CONSTANTS}.utf32_be)) else back end end else back end end else back end end else back end end if pos /= 0 then go (pos) end end put_encoding_bom -- Put Byte Order Mark (BOM) related to encoding. require is_open_write: is_open_write at_beginning: position = 0 local cp: READABLE_STRING_8 do cp := encoding.code_page if cp.is_case_insensitive_equal_general ({CODE_PAGE_CONSTANTS}.utf8) then put_character ('ï') put_character ('»') put_character ('¿') elseif cp.is_case_insensitive_equal_general ({CODE_PAGE_CONSTANTS}.utf16_le) then put_character ('ÿ') put_character ('þ') elseif cp.is_case_insensitive_equal_general ({CODE_PAGE_CONSTANTS}.utf16_be) then put_character ('þ') put_character ('ÿ') elseif cp.is_case_insensitive_equal_general ({CODE_PAGE_CONSTANTS}.utf32_le) then put_character ('ÿ') put_character ('þ') put_character ('%U') put_character ('%U') elseif cp.is_case_insensitive_equal_general ({CODE_PAGE_CONSTANTS}.utf32_be) then put_character ('%U') put_character ('%U') put_character ('þ') put_character ('ÿ') end end feature {NONE} -- Encoding internal_encoding: detachable ENCODING -- Internal value for encoding. feature {NONE} -- Implementation Ctoi_convertor: STRING_TO_INTEGER_CONVERTOR -- Convertor used to parse string to integer or natural once create Result.make; Result.set_leading_separators (Internal_leading_separators); Result.set_leading_separators_acceptable (True); Result.set_trailing_separators_acceptable (False) end Internal_leading_separators: STRING_8 = " %N%R%T" -- Characters that are considered as leading separators is_sequence_an_expected_numeric: BOOLEAN -- Is last number sequence read by read_number_sequence an expected numeric? read_number_sequence (convertor: STRING_TO_NUMERIC_CONVERTOR; conversion_type: INTEGER_32) -- Read a number sequence from current position and parse this -- sequence using convertor to see if it is a valid numeric. -- Set is_sequence_an_expected_numeric with True if it is valid. do convertor.reset (conversion_type) from is_sequence_an_expected_numeric := True until end_of_file or else not is_sequence_an_expected_numeric loop read_character if not end_of_file then convertor.parse_character (last_character) is_sequence_an_expected_numeric := convertor.parse_successful end end end read_integer_with_no_type -- Read a ASCII representation of number of type -- at current position. do read_number_sequence (Ctoi_convertor, {NUMERIC_INFORMATION}.type_no_limitation) if not is_sequence_an_expected_numeric then return_characters end end return_characters -- Return character(s) do if last_character = '%N' and {PLATFORM}.is_windows then back end back end file_gi (file: POINTER): INTEGER_32 -- Get an integer from file external "C signature (FILE *): EIF_INTEGER use %"eif_file.h%"" alias "eif_file_gi" end file_gr (file: POINTER): REAL_32 -- Read a real from file external "C signature (FILE *): EIF_REAL_32 use %"eif_file.h%"" alias "eif_file_gr" end file_gd (file: POINTER): REAL_64 -- Read a double from file external "C signature (FILE *): EIF_REAL_64 use %"eif_file.h%"" alias "eif_file_gd" end file_pi (file: POINTER; n: INTEGER_32) -- Put n to end of file. external "C signature (FILE *, EIF_INTEGER) use %"eif_file.h%"" alias "eif_file_pi" end file_pr (file: POINTER; r: REAL_32) -- Put r to end of file. external "C signature (FILE *, EIF_REAL_32) use %"eif_file.h%"" alias "eif_file_pr" end file_pd (file: POINTER; d: REAL_64) -- Put d to end of file. external "C signature (FILE *, EIF_REAL_64) use %"eif_file.h%"" alias "eif_file_pd" end invariant plain_text: is_plain_text note copyright: "Copyright (c) 1984-2020, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software 5949 Hollister Ave., Goleta, CA 93117 USA Telephone 805-685-1006, Fax 805-685-6869 Website http://www.eiffel.com Customer support http://support.eiffel.com ]" end -- class PLAIN_TEXT_FILE
Generated by ISE EiffelStudio