+ struct string input;
+ struct line_reader *reader = line_reader_for_file (file->encoding, file->file_name, O_RDONLY);
+ if (reader == NULL)
+ {
+ msg_error (errno, _("Could not open `%s'"),
+ file->file_name);
+ return false;
+ }
+
+ ds_init_empty (&input);
+ file->lines = xnmalloc (MAX_PREVIEW_LINES, sizeof *file->lines);
+ for (; file->line_cnt < MAX_PREVIEW_LINES; file->line_cnt++)
+ {
+ ds_clear (&input);
+ if (!line_reader_read (reader, &input, MAX_LINE_LEN + 1)
+ || ds_length (&input) > MAX_LINE_LEN)
+ {
+ if (line_reader_eof (reader))
+ break;
+ else if (line_reader_error (reader))
+ msg (ME, _("Error reading `%s': %s"),
+ file->file_name, strerror (line_reader_error (reader)));
+ else
+ msg (ME, _("Failed to read `%s', because it contains a line "
+ "over %d bytes long and therefore appears not to be "
+ "a text file."),
+ file->file_name, MAX_LINE_LEN);
+ line_reader_close (reader);
+ destroy_file (ia);
+ ds_destroy (&input);
+ return false;
+ }
+
+ ds_init_cstr (&file->lines[file->line_cnt],
+ recode_string ("UTF-8", line_reader_get_encoding (reader),
+ ds_cstr (&input), ds_length (&input)));
+ }
+ ds_destroy (&input);
+
+ if (file->line_cnt == 0)
+ {
+ msg (ME, _("`%s' is empty."), file->file_name);
+ line_reader_close (reader);
+ destroy_file (ia);
+ return false;
+ }
+
+
+ /* Estimate the number of lines in the file. */
+ if (file->line_cnt < MAX_PREVIEW_LINES)
+ {
+ file->total_lines = file->line_cnt;
+ file->total_is_exact = true;
+ }
+ else
+ {
+ struct stat s;
+ off_t position = line_reader_tell (reader);
+ if (fstat (line_reader_fileno (reader), &s) == 0 && position > 0)
+ {
+ file->total_lines = (double) file->line_cnt / position * s.st_size;
+ file->total_is_exact = false;
+ }
+ else
+ {
+ file->total_lines = 0;
+ file->total_is_exact = true;
+ }
+ }
+
+ line_reader_close (reader);
+ }