]> granicus.if.org Git - recode/commitdiff
Add get_bytes and put_bytes
authorReuben Thomas <rrt@sc3d.org>
Tue, 23 Jan 2018 06:48:48 +0000 (06:48 +0000)
committerReuben Thomas <rrt@sc3d.org>
Tue, 23 Jan 2018 07:16:19 +0000 (07:16 +0000)
This allows transform_mere_copy to be made efficient in the case of writing
to buffer.

bootstrap.conf
src/recodext.h
src/task.c

index ac091caeddc68b709a2dc74eec9b74311092f6b3..639b0677d7698e6197f150d4822199f53b14d859 100644 (file)
@@ -1,4 +1,4 @@
-# bootstrap.conf (Recode) version 2018-01-22
+# bootstrap.conf (Recode) version 2018-01-23
 
 # This file is part of Recode.
 #
@@ -58,6 +58,7 @@ gnulib_modules='
         isatty
         localcharset
         manywarnings
+        minmax
         mkstemps
         pathmax
         pipe-posix
index b453d815a5187509a0f9106435075a2dbb5700a4..a96647d9fb739ae40a084c1276c3e44456a0e5c3 100644 (file)
@@ -682,7 +682,9 @@ const char *ucs2_to_rfc1345 (recode_ucs2);
 /* task.c.  */
 
 int get_byte (RECODE_SUBTASK);
-void put_byte (int, RECODE_SUBTASK);
+size_t get_bytes (RECODE_SUBTASK, char *, size_t);
+void put_byte (char, RECODE_SUBTASK);
+void put_bytes (const char *, size_t, RECODE_SUBTASK);
 bool recode_if_nogo (enum recode_error, RECODE_SUBTASK);
 bool transform_byte_to_byte (RECODE_SUBTASK);
 bool transform_byte_to_variable (RECODE_SUBTASK);
index 11fd977b4c8439bb2073308b9e65a87ef8f8a35a..ceabbdd53fec407a73b9ac22a3c31257ef28a1db 100644 (file)
 #include <sys/types.h>
 #include <sys/wait.h>
 
+#include "minmax.h"
 #include "xbinary-io.h"
 
 bool recode_interrupted = 0;   /* set by signal handler when some signal has been received */
 
-/* Buffer size used in transform_mere_copy.  */
-#define BUFFER_SIZE (16 * 1024)
 \f
 /* Input and output helpers.  */
 
 /*-------------------------------------------------------------------.
-| Read one byte from the input text of TASK, or EOF is none remain.  |
+| Read one byte from the input text of TASK, or EOF if none remain.  |
 `-------------------------------------------------------------------*/
 
 int
@@ -48,12 +47,32 @@ get_byte (RECODE_SUBTASK subtask)
     return (unsigned char) *subtask->input.cursor++;
 }
 
+/*-------------------------------------------------------------------.
+| Read N bytes from the input text of TASK into DATA; return number  |
+| of bytes read.                                                     |
+`-------------------------------------------------------------------*/
+
+size_t
+get_bytes (RECODE_SUBTASK subtask, char *data, size_t n)
+{
+  if (subtask->input.file)
+    return fread (data, 1, n, subtask->input.file);
+  else
+    {
+      size_t bytes_left = subtask->output.limit - subtask->output.cursor;
+      size_t bytes_to_copy = MIN (n, bytes_left);
+      memcpy (data, subtask->output.cursor, bytes_to_copy);
+      subtask->output.cursor += bytes_to_copy;
+      return bytes_to_copy;
+    }
+}
+
 /*-----------------------------------------.
 | Write BYTE on the output text for TASK.  |
 `-----------------------------------------*/
 
 void
-put_byte (int byte, RECODE_SUBTASK subtask)
+put_byte (char byte, RECODE_SUBTASK subtask)
 {
   if (subtask->output.file)
     {
@@ -61,23 +80,45 @@ put_byte (int byte, RECODE_SUBTASK subtask)
         recode_if_nogo (RECODE_SYSTEM_ERROR, subtask);
     }
   else if (subtask->output.cursor == subtask->output.limit)
-    {
-      RECODE_OUTER outer = subtask->task->request->outer;
-      size_t old_size = subtask->output.limit - subtask->output.buffer;
-      size_t new_size = old_size * 3 / 2 + 40;
-
-      if (REALLOC (subtask->output.buffer, new_size, char))
-       {
-         subtask->output.cursor = subtask->output.buffer + old_size;
-         subtask->output.limit = subtask->output.buffer + new_size;
-         *subtask->output.cursor++ = byte;
-       }
-      else
-        recode_if_nogo (RECODE_SYSTEM_ERROR, subtask);
-    }
+    put_bytes (&byte, 1, subtask);
   else
     *subtask->output.cursor++ = byte;
 }
+
+/*-----------------------------------------------------.
+| Write N bytes of DATA on the output text for TASK.   |
+`-----------------------------------------------------*/
+
+void
+put_bytes (const char *data, size_t n, RECODE_SUBTASK subtask)
+{
+  if (subtask->output.file)
+    {
+      if (fwrite (data, n, 1, subtask->output.file) != 1)
+        {
+          recode_perror (NULL, "fwrite ()");
+          recode_if_nogo (RECODE_SYSTEM_ERROR, subtask);
+        }
+    }
+  else {
+    if (subtask->output.cursor + n > subtask->output.limit)
+      {
+        RECODE_OUTER outer = subtask->task->request->outer;
+        size_t old_size = subtask->output.limit - subtask->output.buffer;
+        size_t new_size = old_size * 3 / 2 + 40 + n;
+
+        if (REALLOC (subtask->output.buffer, new_size, char))
+          {
+            subtask->output.cursor = subtask->output.buffer + old_size;
+            subtask->output.limit = subtask->output.buffer + new_size;
+          }
+        else
+          recode_if_nogo (RECODE_SYSTEM_ERROR, subtask);
+      }
+    memcpy (subtask->output.cursor, data, n);
+    subtask->output.cursor += n;
+  }
+}
 \f
 /* Error processing.  */
 
@@ -108,64 +149,26 @@ recode_if_nogo (enum recode_error new_error, RECODE_SUBTASK subtask)
 static void
 transform_mere_copy (RECODE_SUBTASK subtask)
 {
-  if (subtask->input.file && subtask->output.file)
+  if (subtask->input.file)
     {
-      /* File to file.  */
+      /* Reading from file.  */
 
-      char buffer[BUFFER_SIZE];
+      char buffer[BUFSIZ];
       size_t size;
 
-      while (size = fread (buffer, 1, BUFFER_SIZE, subtask->input.file),
-            size == BUFFER_SIZE)
-       if (fwrite (buffer, BUFFER_SIZE, 1, subtask->output.file) != 1)
-         {
-           recode_perror (NULL, "fwrite ()");
-           recode_if_nogo (RECODE_SYSTEM_ERROR, subtask);
-           return false;
-         }
+      while (size = get_bytes (subtask, buffer, BUFSIZ),
+            size == BUFSIZ)
+       put_bytes (buffer, BUFSIZ, subtask);
       if (size > 0)
-       if (fwrite (buffer, size, 1, subtask->output.file) != 1)
-         {
-           recode_perror (NULL, "fwrite ()");
-           recode_if_nogo (RECODE_SYSTEM_ERROR, subtask);
-           return false;
-         }
-    }
-  else if (subtask->input.file)
-    {
-      /* File to buffer.  */
-
-      int character;
-
-      /* FIXME: buy now, pay (optimise) only later.   */
-      while (character = get_byte (subtask), character != EOF)
-       put_byte (character, subtask);
-    }
-  else if (subtask->output.file)
-    {
-      /* Buffer to file.  */
-
-      if (subtask->input.cursor < subtask->input.limit)
-       if (fwrite (subtask->input.cursor,
-                   (unsigned) (subtask->input.limit - subtask->input.cursor),
-                   1, subtask->output.file)
-           != 1)
-         {
-           recode_perror (NULL, "fwrite ()");
-           recode_if_nogo (RECODE_SYSTEM_ERROR, subtask);
-           return false;
-         }
+       put_bytes (buffer, size, subtask);
     }
   else
-    {
-      /* Buffer to buffer.  */
+    /* Reading from buffer.  */
 
-      int character;
-
-      /* FIXME: buy now, pay (optimise) only later.  */
-      while (character = get_byte (subtask), character != EOF)
-       put_byte (character, subtask);
-    }
+    if (subtask->input.cursor < subtask->input.limit)
+      put_bytes (subtask->input.cursor,
+                 (unsigned) (subtask->input.limit - subtask->input.cursor),
+                 subtask);
 }
 
 /*--------------------------------------------------.