]> diplodocus.org Git - nmh/commitdiff
m_getfld() now supports interleaving calls with
authorDavid Levine <levinedl@acm.org>
Tue, 15 Jan 2013 02:58:56 +0000 (20:58 -0600)
committerDavid Levine <levinedl@acm.org>
Tue, 15 Jan 2013 02:58:56 +0000 (20:58 -0600)
fseek()/ftell().  Reverted the changes to uip/mhparse.c of
commit 484eb1003ae647e4b751e4d7829c7daf44fb99c9 because
they're no longer necessary.

sbr/m_getfld.c
uip/mhparse.c

index 4089bc7f936d9bebfb33e10ad77aa09ab13eb786..8c58108046cfad2fe65adf0381f8b87c62b01032 100644 (file)
@@ -244,28 +244,33 @@ static struct m_getfld_buffer {
     unsigned char *readpos;
     unsigned char *end;  /* One past the last character read in. */
     /* The following support tracking of the read position in the
-       input file so that callers can interleave m_getfld() calls with
-       ftell() and fseek().  bytes_read replaces the old m_getfld()
-       msg_count global. */
+       input file stream so that callers can interleave m_getfld()
+       calls with ftell() and fseek().  ytes_read replaces the old
+       m_getfld() msg_count global.  last_file_pos is stored when
+       leaving m_getfld()/m_unkown(), then checked on the next entry.
+       last_internal_pos is used to remember the position used
+       internally by m_getfld() (read_more(), actually). */
     off_t bytes_read;
-    off_t last_file_position;
+    off_t total_bytes_read;
+    off_t last_file_pos;
+    off_t last_internal_pos;
 } m;
 
 static void
 setup_buffer (FILE *iob, struct m_getfld_buffer *m) {
+    off_t pos = ftello (iob);
+
     /* Rely on Restriction that the first call to m_getfld (), etc.,
        is with the read position for the file stream set to 0. */
-    if (ftello (iob) == 0) {
+    if (pos == 0) {
        /* A new file stream, so reset the buffer state. */
        m->readpos = m->end = m->msg_buf;
-       m->last_file_position = ftello (iob);
+       m->total_bytes_read = 0;
+       m->last_file_pos = m->last_internal_pos = ftello (iob);
     } else {
-       off_t position = ftello (iob);
-
-       /* Compare current file position with last file position.  If
-          different, then caller must have called ftell(), so adjust
-          by the same amounmt. */
-       if (position - m->last_file_position != 0) {
+       /* If the current file stream position differs from the last one,
+          then caller must have called ftell(), so adjust. */
+       if (pos != m->last_file_pos) {
            size_t num_read;
 
            /* Opportunity for optimization here:  don't reread if the
@@ -274,15 +279,20 @@ setup_buffer (FILE *iob, struct m_getfld_buffer *m) {
            fseeko (iob, 0, SEEK_SET);
            do {
                num_read = fread (m->msg_buf, 1, MSG_INPUT_SIZE, iob);
-               position -= num_read;
-           } while (position > 0);
-           m->readpos = m->msg_buf + position + num_read;
+               pos -= num_read;
+           } while (pos > 0);
+           pos += num_read;
+           /* assert (ftello (iob) == pos); */
+           m->readpos = m->msg_buf + pos;
            m->end = m->msg_buf + num_read;
-
-           m->last_file_position = position;
+           m->last_internal_pos = m->last_file_pos = pos;
+           m->total_bytes_read = pos;
+       } else {
+           /* Restore the file position that we use for the input buffer. */
+           pos = m->last_internal_pos;
        }
 
-       fseeko (iob, position, SEEK_SET);
+       fseeko (iob, pos, SEEK_SET);
     }
 
     m->bytes_read = 0;
@@ -290,8 +300,13 @@ setup_buffer (FILE *iob, struct m_getfld_buffer *m) {
 
 static void
 update_input_filepos (struct m_getfld_buffer *m, FILE *iob) {
-    /* Need to fseek so that callers can use ftell (). */
-    m->last_file_position = ftello (iob);
+    /* Save the internal file position that we use for the input buffer. */
+    m->last_internal_pos = ftello (iob);
+
+    /* Set file stream position so that callers can use ftell (). */
+    m->total_bytes_read += m->bytes_read;
+    fseeko (iob, m->total_bytes_read, SEEK_SET);
+    m->last_file_pos = ftello (iob);
 }
 
 static size_t
@@ -473,7 +488,7 @@ m_getfld (int state, unsigned char name[NAMESZ], unsigned char *buf,
                    /* The last character read was '\n'.  m.bytes_read (and j)
                       include that, but it was not put into the name array
                       in the for loop above.  So subtract 1. */
-                   *bufsz = m.bytes_read - 1;  /* == j - 1 */
+                   *bufsz = --m.bytes_read;  /* == j - 1 */
                    update_input_filepos (&m, iob);
                    return BODY;
                }
index f5a5983adadc3b56d341c9efbc5ee0709f4143a2..ea5400e07ed2194fb50e84b37075e7ed9011de48 100644 (file)
@@ -262,7 +262,6 @@ get_content (FILE *in, char *file, int toplevel)
     char *np, *vp;
     CT ct;
     HF hp;
-    long filepos;
 
     /* allocate the content structure */
     if (!(ct = (CT) calloc (1, sizeof(*ct))))
@@ -270,7 +269,7 @@ get_content (FILE *in, char *file, int toplevel)
 
     ct->c_fp = in;
     ct->c_file = add (file, NULL);
-    ct->c_begin = (filepos = ftell (ct->c_fp)) + 1;
+    ct->c_begin = ftell (ct->c_fp) + 1;
 
     /*
      * Parse the header fields for this
@@ -283,7 +282,6 @@ get_content (FILE *in, char *file, int toplevel)
        case FLDPLUS:
        case FLDEOF:
            compnum++;
-           filepos += bufsz;
 
            /* get copies of the buffers */
            np = add (name, NULL);
@@ -301,20 +299,18 @@ get_content (FILE *in, char *file, int toplevel)
 
            /* continue, if this isn't the last header field */
            if (state != FLDEOF) {
-               ct->c_begin = filepos + 1;
+               ct->c_begin = ftell (in) + 1;
                continue;
            }
            /* else fall... */
 
        case BODY:
        case BODYEOF:
-           filepos += bufsz;
-           ct->c_begin = filepos - strlen (buf);
+           ct->c_begin = ftell (in) - strlen (buf);
            break;
 
        case FILEEOF:
-           filepos += bufsz;
-           ct->c_begin = filepos;
+           ct->c_begin = ftell (in);
            break;
 
        case LENERR: