boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

__buffered_read.c (3046B)


      1 /* -*-comment-start: "//";comment-end:""-*-
      2  * GNU Mes --- Maxwell Equations of Software
      3  * Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
      4  *
      5  * This file is part of GNU Mes.
      6  *
      7  * GNU Mes is free software; you can redistribute it and/or modify it
      8  * under the terms of the GNU General Public License as published by
      9  * the Free Software Foundation; either version 3 of the License, or (at
     10  * your option) any later version.
     11  *
     12  * GNU Mes is distributed in the hope that it will be useful, but
     13  * WITHOUT ANY WARRANTY; without even the implied warranty of
     14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  * GNU General Public License for more details.
     16  *
     17  * You should have received a copy of the GNU General Public License
     18  * along with GNU Mes.  If not, see <http://www.gnu.org/licenses/>.
     19  */
     20 
     21 #include <mes/lib.h>
     22 #include <stdlib.h>
     23 #include <string.h>
     24 
     25 #if !__MESC__
     26 #define __READ_BUFFER_MAX 128
     27 int __read_buffer_max;
     28 #else /* FIXME: We want bin/mes-mescc's x86-linux sha256sum to stay the same. */
     29 #define __READ_BUFFER_MAX 100
     30 #define __read_buffer_max 100
     31 #endif
     32 
     33 struct __read_buffer
     34 {
     35   ssize_t size;
     36   char string[__READ_BUFFER_MAX];
     37 };
     38 
     39 struct __read_buffer *__read_cache = 0;
     40 
     41 void
     42 __buffered_read_init (int filedes)
     43 {
     44   if (!__read_cache)
     45     {
     46       __read_cache = (struct __read_buffer *) malloc (sizeof (struct __read_buffer) * __FILEDES_MAX);
     47 #if !__MESC__
     48       __read_buffer_max = __READ_BUFFER_MAX;
     49       char *p = getenv ("MES_READ_BUFFER");
     50       if (p)
     51         {
     52           __read_buffer_max = atoi (p);
     53           if (__read_buffer_max < 0)
     54             __read_buffer_max = 0;
     55           if (__read_buffer_max > __READ_BUFFER_MAX)
     56             __read_buffer_max = __READ_BUFFER_MAX;
     57         }
     58 #endif
     59     }
     60 }
     61 
     62 size_t
     63 __buffered_read_clear (int filedes)
     64 {
     65   __buffered_read_init (filedes);
     66   size_t size = __read_cache[filedes].size;
     67   __read_cache[filedes].size = 0;
     68   return size;
     69 }
     70 
     71 ssize_t
     72 __buffered_read (int filedes, void *buffer, size_t size)
     73 {
     74   size_t todo = size;
     75   __buffered_read_init (filedes);
     76   struct __read_buffer *cache = &__read_cache[filedes];
     77   char *p = buffer;
     78   if (!cache->size && size > __read_buffer_max)
     79     return _read (filedes, buffer, size);
     80   while (cache->size > 0 && todo)
     81     {
     82       todo--;
     83       *p++ = cache->string[__read_buffer_max - cache->size--];
     84     }
     85   if (todo)
     86     {
     87 #if !__MESC__
     88       if (todo > __read_buffer_max)
     89         return size - todo + _read (filedes, p, todo);
     90       if (__mes_debug () > 4)
     91         {
     92           eputs ("__buffered_read: ");
     93           eputs (itoa (__read_buffer_max));
     94           eputs ("\n");
     95         }
     96 #endif
     97       ssize_t bytes = _read (filedes, cache->string, __read_buffer_max);
     98       if (bytes < 0)
     99         return -1;
    100       if (bytes)
    101         {
    102           cache->size = bytes;
    103           if (bytes < __read_buffer_max)
    104             memmove (cache->string + __read_buffer_max - bytes, cache->string, bytes);
    105           return size - todo + __buffered_read (filedes, p, todo);
    106         }
    107     }
    108   return size - todo;
    109 }