From: Christophe CURIS <christophe.cu...@free.fr>

The function did spend its time re-copying data and searching the
end of the read buffer, which is not really efficient.

The new code reads directly from file to the end of previous data,
avoiding unneccesary duplication, and keeps track of the end of
data to avoid searching it for next read.

Signed-off-by: Christophe CURIS <christophe.cu...@free.fr>
---
 WINGs/proplist.c | 43 +++++++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/WINGs/proplist.c b/WINGs/proplist.c
index beb209d..174edbe 100644
--- a/WINGs/proplist.c
+++ b/WINGs/proplist.c
@@ -1566,8 +1566,10 @@ WMPropList *WMReadPropListFromPipe(const char *command)
        FILE *file;
        WMPropList *plist;
        PLData *pldata;
-       char line[1024];
-       char *read_buf;
+       char *read_buf, *read_ptr;
+       size_t remain_size, line_size;
+       const size_t block_read_size = 4096;
+       const size_t block_read_margin = 512;
 
        file = popen(command, "r");
 
@@ -1576,28 +1578,33 @@ WMPropList *WMReadPropListFromPipe(const char *command)
                return NULL;
        }
 
-       pldata = (PLData *) wmalloc(sizeof(PLData));
-       pldata->ptr = NULL;
-       pldata->filename = command;
-       pldata->lineNumber = 1;
-
        /* read from file till EOF or OOM and fill proplist buffer*/
-       read_buf = NULL;
-       while (fgets(line, sizeof(line), file) != NULL) {
-               if (read_buf == NULL) {
-                       read_buf = wmalloc(strlen(line)+1);
-                       read_buf[0] = '\0';
-               } else {
-                       read_buf = wrealloc(read_buf,
-                           strlen(line) + strlen(read_buf) + 1);
+       remain_size = block_read_size;
+       read_buf = wmalloc(remain_size);
+       read_ptr = read_buf;
+       while (fgets(read_ptr, remain_size, file) != NULL) {
+               line_size = strlen(read_ptr);
+
+               remain_size -= line_size;
+               read_ptr += line_size;
+
+               if (remain_size < block_read_margin) {
+                       size_t read_length;
+
+                       read_length = read_ptr - read_buf;
+                       read_buf = wrealloc(read_buf, read_length + 
block_read_size);
+                       read_ptr = read_buf + read_length;
+                       remain_size = block_read_size;
                }
-
-               read_buf = strncat(read_buf, line, strlen(line));
        }
-       pldata->ptr = read_buf;
 
        pclose(file);
 
+       pldata = (PLData *) wmalloc(sizeof(PLData));
+       pldata->ptr = read_buf;
+       pldata->filename = command;
+       pldata->lineNumber = 1;
+
        plist = getPropList(pldata);
 
        if (getNonSpaceChar(pldata) != 0 && plist) {
-- 
2.0.0


-- 
To unsubscribe, send mail to wmaker-dev-unsubscr...@lists.windowmaker.org.

Reply via email to