emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: view/edit large files


From: Stefan Monnier
Subject: Re: view/edit large files
Date: Tue, 17 Feb 2009 14:23:32 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/23.0.90 (gnu/linux)

> While time values and file offsets can certainly be represented as
> floats under some constraints, I think it's an inelegant solution.

> This is the chance to have a clean design for support of large integers,
> since I or someone else will be modifying insert-file-contents anyhow.

Using floats has the major advantage that it only requires changes in
insert-file-contents (e.g. try the patch below).  Large integers can be
added as well, but it's a mostly orthogonal issue.


        Stefan


=== modified file 'src/fileio.c'
--- src/fileio.c        2009-02-11 20:00:50 +0000
+++ src/fileio.c        2009-02-17 19:21:59 +0000
@@ -3161,6 +3161,7 @@
   Lisp_Object old_Vdeactivate_mark = Vdeactivate_mark;
   int we_locked_file = 0;
   int deferred_remove_unwind_protect = 0;
+  off_t beg_offset, end_offset;
 
   if (current_buffer->base_buffer && ! NILP (visit))
     error ("Cannot do file visiting in an indirect buffer");
@@ -3268,12 +3269,12 @@
     }
 
   if (!NILP (beg))
-    CHECK_NUMBER (beg);
+    CHECK_NUMBER_OR_FLOAT (beg);
   else
     XSETFASTINT (beg, 0);
 
   if (!NILP (end))
-    CHECK_NUMBER (end);
+    CHECK_NUMBER_OR_FLOAT (end);
   else
     {
       if (! not_regular)
@@ -3408,6 +3409,8 @@
       set_coding_system = 1;
     }
 
+  beg_offset = FLOATP (beg) ? (off_t) XFLOAT_DATA (beg) : XINT (beg);
+  end_offset = FLOATP (end) ? (off_t) XFLOAT_DATA (end) : XINT (end);
   /* If requested, replace the accessible part of the buffer
      with the file contents.  Avoid replacing text at the
      beginning or end of the buffer that matches the file contents;
@@ -3438,9 +3441,9 @@
         give up on handling REPLACE in the optimized way.  */
       int giveup_match_end = 0;
 
-      if (XINT (beg) != 0)
+      if (beg_offset != 0)
        {
-         if (lseek (fd, XINT (beg), 0) < 0)
+         if (lseek (fd, beg_offset, 0) < 0)
            report_file_error ("Setting file position",
                               Fcons (orig_filename, Qnil));
        }
@@ -3487,7 +3490,7 @@
       immediate_quit = 0;
       /* If the file matches the buffer completely,
         there's no need to replace anything.  */
-      if (same_at_start - BEGV_BYTE == XINT (end))
+      if (same_at_start - BEGV_BYTE == end_offset - beg_offset)
        {
          emacs_close (fd);
          specpdl_ptr--;
@@ -3505,7 +3508,7 @@
          EMACS_INT total_read, nread, bufpos, curpos, trial;
 
          /* At what file position are we now scanning?  */
-         curpos = XINT (end) - (ZV_BYTE - same_at_end);
+         curpos = end_offset - (ZV_BYTE - same_at_end);
          /* If the entire file matches the buffer tail, stop the scan.  */
          if (curpos == 0)
            break;
@@ -3583,8 +3586,8 @@
            same_at_end += overlap;
 
          /* Arrange to read only the nonmatching middle part of the file.  */
-         XSETFASTINT (beg, XINT (beg) + (same_at_start - BEGV_BYTE));
-         XSETFASTINT (end, XINT (end) - (ZV_BYTE - same_at_end));
+         beg_offset += same_at_start - BEGV_BYTE;
+         end_offset -= ZV_BYTE - same_at_end;
 
          del_range_byte (same_at_start, same_at_end, 0);
          /* Insert from the file at the proper position.  */
@@ -3628,7 +3631,7 @@
       /* First read the whole file, performing code conversion into
         CONVERSION_BUFFER.  */
 
-      if (lseek (fd, XINT (beg), 0) < 0)
+      if (lseek (fd, beg_offset, 0) < 0)
        report_file_error ("Setting file position",
                           Fcons (orig_filename, Qnil));
 
@@ -3803,7 +3806,7 @@
     {
       register Lisp_Object temp;
 
-      total = XINT (end) - XINT (beg);
+      total = end_offset - beg_offset;
 
       /* Make sure point-max won't overflow after this insertion.  */
       XSETINT (temp, total);
@@ -3830,9 +3833,9 @@
   if (GAP_SIZE < total)
     make_gap (total - GAP_SIZE);
 
-  if (XINT (beg) != 0 || !NILP (replace))
+  if (beg_offset != 0 || !NILP (replace))
     {
-      if (lseek (fd, XINT (beg), 0) < 0)
+      if (lseek (fd, beg_offset, 0) < 0)
        report_file_error ("Setting file position",
                           Fcons (orig_filename, Qnil));
     }





reply via email to

[Prev in Thread] Current Thread [Next in Thread]