LCOV - code coverage report
Current view: top level - cmdline - stream.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 259 285 90.9 %
Date: 2017-11-06 22:14:04 Functions: 27 28 96.4 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2011 Andrea Mazzoleni
       3             :  *
       4             :  * This program is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 3 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * This program is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "portable.h"
      19             : 
      20             : #include "support.h"
      21             : #include "util.h"
      22             : #include "stream.h"
      23             : 
      24             : /****************************************************************************/
      25             : /* stream */
      26             : 
      27             : unsigned STREAM_SIZE = 64 * 1024;
      28             : 
      29        1838 : STREAM* sopen_read(const char* file)
      30             : {
      31             : #if HAVE_POSIX_FADVISE
      32             :         int ret;
      33             : #endif
      34        1838 :         STREAM* s = malloc_nofail(sizeof(STREAM));
      35             : 
      36        1838 :         s->handle_size = 1;
      37        1838 :         s->handle = malloc_nofail(sizeof(struct stream_handle));
      38             : 
      39        1838 :         pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file);
      40        1838 :         s->handle[0].f = open(file, O_RDONLY | O_BINARY | O_SEQUENTIAL);
      41        1838 :         if (s->handle[0].f == -1) {
      42          50 :                 free(s->handle);
      43          50 :                 free(s);
      44          50 :                 return 0;
      45             :         }
      46             : 
      47             : #if HAVE_POSIX_FADVISE
      48             :         /* advise sequential access */
      49        1788 :         ret = posix_fadvise(s->handle[0].f, 0, 0, POSIX_FADV_SEQUENTIAL);
      50        1788 :         if (ret == ENOSYS) {
      51           0 :                 log_fatal("WARNING! fadvise() is not supported in this platform. Performance may not be optimal!\n");
      52             :                 /* call is not supported, like in armhf, see posix_fadvise manpage */
      53           0 :                 ret = 0;
      54             :         }
      55        1788 :         if (ret != 0) {
      56             :                 /* LCOV_EXCL_START */
      57             :                 close(s->handle[0].f);
      58             :                 free(s->handle);
      59             :                 free(s);
      60             :                 errno = ret; /* posix_fadvise return the error code */
      61             :                 return 0;
      62             :                 /* LCOV_EXCL_STOP */
      63             :         }
      64             : #endif
      65             : 
      66        1788 :         s->buffer = malloc_nofail_test(STREAM_SIZE);
      67        1788 :         s->pos = s->buffer;
      68        1788 :         s->end = s->buffer;
      69        1788 :         s->state = STREAM_STATE_READ;
      70        1788 :         s->state_index = 0;
      71        1788 :         s->offset = 0;
      72        1788 :         s->offset_uncached = 0;
      73        1788 :         s->crc = 0;
      74        1788 :         s->crc_uncached = 0;
      75        1788 :         s->crc_stream = CRC_IV;
      76             : 
      77        1788 :         return s;
      78             : }
      79             : 
      80         167 : STREAM* sopen_multi_write(unsigned count)
      81             : {
      82             :         unsigned i;
      83             : 
      84         167 :         STREAM* s = malloc_nofail(sizeof(STREAM));
      85             : 
      86         167 :         s->handle_size = count;
      87         167 :         s->handle = malloc_nofail(count * sizeof(struct stream_handle));
      88             : 
      89        1307 :         for (i = 0; i < count; ++i)
      90        1140 :                 s->handle[i].f = -1;
      91             : 
      92         167 :         s->buffer = malloc_nofail_test(STREAM_SIZE);
      93         167 :         s->pos = s->buffer;
      94         167 :         s->end = s->buffer + STREAM_SIZE;
      95         167 :         s->state = STREAM_STATE_WRITE;
      96         167 :         s->state_index = 0;
      97         167 :         s->offset = 0;
      98         167 :         s->offset_uncached = 0;
      99         167 :         s->crc = 0;
     100         167 :         s->crc_uncached = 0;
     101         167 :         s->crc_stream = CRC_IV;
     102             : 
     103         167 :         return s;
     104             : }
     105             : 
     106        1140 : int sopen_multi_file(STREAM* s, unsigned i, const char* file)
     107             : {
     108             : #if HAVE_POSIX_FADVISE
     109             :         int ret;
     110             : #endif
     111             :         int f;
     112             : 
     113        1140 :         pathcpy(s->handle[i].path, sizeof(s->handle[i].path), file);
     114             : 
     115        1140 :         f = open(file, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_SEQUENTIAL, 0600);
     116        1140 :         if (f == -1) {
     117             :                 /* LCOV_EXCL_START */
     118             :                 return -1;
     119             :                 /* LCOV_EXCL_STOP */
     120             :         }
     121             : 
     122             : #if HAVE_POSIX_FADVISE
     123             :         /* advise sequential access */
     124        1140 :         ret = posix_fadvise(f, 0, 0, POSIX_FADV_SEQUENTIAL);
     125        1140 :         if (ret == ENOSYS) {
     126             :                 /* call is not supported, like in armhf, see posix_fadvise manpage */
     127           0 :                 ret = 0;
     128             :         }
     129        1140 :         if (ret != 0) {
     130             :                 /* LCOV_EXCL_START */
     131             :                 close(f);
     132             :                 errno = ret; /* posix_fadvise return the error code */
     133             :                 return -1;
     134             :                 /* LCOV_EXCL_STOP */
     135             :         }
     136             : #endif
     137             : 
     138        1140 :         s->handle[i].f = f;
     139             : 
     140        1140 :         return 0;
     141             : }
     142             : 
     143           0 : STREAM* sopen_write(const char* file)
     144             : {
     145           0 :         STREAM* s = sopen_multi_write(1);
     146             : 
     147           0 :         if (sopen_multi_file(s, 0, file) != 0) {
     148           0 :                 sclose(s);
     149           0 :                 return 0;
     150             :         }
     151             : 
     152           0 :         return s;
     153             : }
     154             : 
     155        1953 : int sclose(STREAM* s)
     156             : {
     157        1953 :         int fail = 0;
     158             :         unsigned i;
     159             : 
     160        1953 :         if (s->state == STREAM_STATE_WRITE) {
     161         167 :                 if (sflush(s) != 0) {
     162             :                         /* LCOV_EXCL_START */
     163             :                         fail = 1;
     164             :                         /* LCOV_EXCL_STOP */
     165             :                 }
     166             :         }
     167             : 
     168        4879 :         for (i = 0; i < s->handle_size; ++i) {
     169        2926 :                 if (close(s->handle[i].f) != 0) {
     170             :                         /* LCOV_EXCL_START */
     171             :                         fail = 1;
     172             :                         /* LCOV_EXCL_STOP */
     173             :                 }
     174             :         }
     175             : 
     176        1953 :         free(s->handle);
     177        1953 :         free(s->buffer);
     178        1953 :         free(s);
     179             : 
     180        1953 :         if (fail) {
     181             :                 /* LCOV_EXCL_START */
     182             :                 return -1;
     183             :                 /* LCOV_EXCL_STOP */
     184             :         }
     185             : 
     186        1953 :         return 0;
     187             : }
     188             : 
     189         254 : int shandle(STREAM* s)
     190             : {
     191         254 :         if (!s->handle_size) {
     192             :                 /* LCOV_EXCL_START */
     193             :                 return -1;
     194             :                 /* LCOV_EXCL_STOP */
     195             :         }
     196             : 
     197         254 :         return s->handle[0].f;
     198             : }
     199             : 
     200             : /**
     201             :  * Fill the read stream buffer.
     202             :  * \return 0 if at least on char is read, or EOF on error.
     203             :  */
     204      607128 : static int sfill(STREAM* s)
     205             : {
     206             :         ssize_t ret;
     207             : 
     208      607128 :         if (s->state != STREAM_STATE_READ) {
     209             :                 /* LCOV_EXCL_START */
     210             :                 return EOF;
     211             :                 /* LCOV_EXCL_STOP */
     212             :         }
     213             : 
     214      606068 :         ret = read(s->handle[0].f, s->buffer, STREAM_SIZE);
     215             : 
     216      606061 :         if (ret < 0) {
     217             :                 /* LCOV_EXCL_START */
     218             :                 s->state = STREAM_STATE_ERROR;
     219             :                 return EOF;
     220             :                 /* LCOV_EXCL_STOP */
     221             :         }
     222      606061 :         if (ret == 0) {
     223        1659 :                 s->state = STREAM_STATE_EOF;
     224        1659 :                 return EOF;
     225             :         }
     226             : 
     227             :         /* update the crc */
     228      604402 :         s->crc_uncached = s->crc;
     229      604402 :         s->crc = crc32c(s->crc, s->buffer, ret);
     230             : 
     231             :         /* update the offset */
     232      604397 :         s->offset_uncached = s->offset;
     233      604397 :         s->offset += ret;
     234             : 
     235      604397 :         s->pos = s->buffer;
     236      604397 :         s->end = s->buffer + ret;
     237             : 
     238      604397 :         return 0;
     239             : }
     240             : 
     241        1157 : int sdeplete(STREAM* s, unsigned char* last)
     242             : {
     243             :         /* last four bytes */
     244        1157 :         last[0] = 0;
     245        1157 :         last[1] = 0;
     246        1157 :         last[2] = 0;
     247        1157 :         last[3] = 0;
     248             : 
     249             :         while (1) {
     250             :                 /* increase the position up to 4 bytes before the end */
     251      308264 :                 if (s->pos + 4 <= s->end)
     252      148367 :                         s->pos = s->end - 4;
     253             : 
     254             :                 /* insert the last 4 bytes */
     255     1469818 :                 while (s->pos < s->end) {
     256      853290 :                         last[0] = last[1];
     257      853290 :                         last[1] = last[2];
     258      853290 :                         last[2] = last[3];
     259      853290 :                         last[3] = *s->pos++;
     260             :                 }
     261             : 
     262             :                 /* fill again the buffer until the end of the file */
     263      308264 :                 if (sfill(s) != 0) {
     264             :                         /* on error fail */
     265        1141 :                         if (serror(s)) {
     266             :                                 /* LCOV_EXCL_START */
     267             :                                 return EOF;
     268             :                                 /* LCOV_EXCL_STOP */
     269             :                         }
     270             : 
     271             :                         /* on EOF terminate */
     272        1141 :                         break;
     273             :                 }
     274      307107 :         }
     275             : 
     276        1141 :         return 0;
     277             : }
     278             : 
     279       39049 : int sflush(STREAM* s)
     280             : {
     281             :         ssize_t ret;
     282             :         ssize_t size;
     283             :         unsigned i;
     284             : 
     285       39049 :         if (s->state != STREAM_STATE_WRITE) {
     286             :                 /* LCOV_EXCL_START */
     287             :                 return EOF;
     288             :                 /* LCOV_EXCL_STOP */
     289             :         }
     290             : 
     291       39049 :         size = s->pos - s->buffer;
     292       39049 :         if (!size)
     293         151 :                 return 0;
     294             : 
     295      347023 :         for (i = 0; i < s->handle_size; ++i) {
     296      308125 :                 ret = write(s->handle[i].f, s->buffer, size);
     297             : 
     298      308125 :                 if (ret != size) {
     299             :                         /* LCOV_EXCL_START */
     300             :                         s->state = STREAM_STATE_ERROR;
     301             :                         s->state_index = i;
     302             :                         return EOF;
     303             :                         /* LCOV_EXCL_STOP */
     304             :                 }
     305             :         }
     306             : 
     307             :         /*
     308             :          * Update the crc *after* writing the data.
     309             :          *
     310             :          * This must be done after the file write,
     311             :          * to be able to detect memory errors on the buffer,
     312             :          * happening during the write.
     313             :          */
     314       38898 :         s->crc = crc32c(s->crc, s->buffer, size);
     315       38898 :         s->crc_uncached = s->crc;
     316             : 
     317             :         /* update the offset */
     318       38898 :         s->offset += size;
     319       38898 :         s->offset_uncached = s->offset;
     320             : 
     321       38898 :         s->pos = s->buffer;
     322             : 
     323       38898 :         return 0;
     324             : }
     325             : 
     326           1 : int64_t stell(STREAM* s)
     327             : {
     328           1 :         return s->offset_uncached + (s->pos - s->buffer);
     329             : }
     330             : 
     331        1689 : uint32_t scrc(STREAM*s)
     332             : {
     333        1689 :         return crc32c(s->crc_uncached, s->buffer, s->pos - s->buffer);
     334             : }
     335             : 
     336         167 : uint32_t scrc_stream(STREAM*s)
     337             : {
     338         167 :         return s->crc_stream ^ CRC_IV;
     339             : }
     340             : 
     341      298863 : int sgetc_uncached(STREAM* s)
     342             : {
     343             :         /* if at the end of the buffer, fill it */
     344      298863 :         if (s->pos == s->end && sfill(s) != 0)
     345        1578 :                 return EOF;
     346      297285 :         return *s->pos++;
     347             : }
     348             : 
     349        8196 : int sgettok(STREAM* f, char* str, int size)
     350             : {
     351        8196 :         char* i = str;
     352        8196 :         char* send = str + size;
     353             :         int c;
     354             : 
     355             :         while (1) {
     356       54612 :                 c = sgetc(f);
     357       54612 :                 if (c == EOF) {
     358         265 :                         break;
     359             :                 }
     360       54347 :                 if (c == ' ' || c == '\t') {
     361        7665 :                         sungetc(c, f);
     362        7665 :                         break;
     363             :                 }
     364       46682 :                 if (c == '\n') {
     365             :                         /* remove ending carrige return to support the Windows CR+LF format */
     366         266 :                         if (i != str && i[-1] == '\r')
     367           0 :                                 --i;
     368         266 :                         sungetc(c, f);
     369         266 :                         break;
     370             :                 }
     371             : 
     372       46416 :                 *i++ = c;
     373             : 
     374       46416 :                 if (i == send) {
     375             :                         /* LCOV_EXCL_START */
     376             :                         return -1;
     377             :                         /* LCOV_EXCL_STOP */
     378             :                 }
     379       46416 :         }
     380             : 
     381        8196 :         *i = 0;
     382             : 
     383        8196 :         return i - str;
     384             : }
     385             : 
     386    12810001 : int sread(STREAM* f, void* void_data, unsigned size)
     387             : {
     388    12810001 :         unsigned char* data = void_data;
     389             : 
     390             :         /* if there is enough space in memory */
     391    12810001 :         if (sptrlookup(f, size)) {
     392             :                 /* optimized version with all the data in memory */
     393    12783371 :                 unsigned char* pos = sptrget(f);
     394             : 
     395             :                 /* copy it */
     396   217709478 :                 while (size--)
     397   192142736 :                         *data++ = *pos++;
     398             : 
     399    12783371 :                 sptrset(f, pos);
     400             :         } else {
     401             :                 /* standard version using sgetc() */
     402     1385569 :                 while (size--) {
     403     1332309 :                         int c = sgetc(f);
     404     1332309 :                         if (c == EOF) {
     405             :                                 /* LCOV_EXCL_START */
     406             :                                 return -1;
     407             :                                 /* LCOV_EXCL_STOP */
     408             :                         }
     409             : 
     410     1332309 :                         *data++ = c;
     411             :                 }
     412             :         }
     413             : 
     414    12810001 :         return 0;
     415             : }
     416             : 
     417        5448 : int sgetline(STREAM* f, char* str, int size)
     418             : {
     419        5448 :         char* i = str;
     420        5448 :         char* send = str + size;
     421             :         int c;
     422             : 
     423             :         /* if there is enough data in memory */
     424        5448 :         if (sptrlookup(f, size)) {
     425             :                 /* optimized version with all the data in memory */
     426           0 :                 unsigned char* pos = sptrget(f);
     427             : 
     428             :                 while (1) {
     429           0 :                         c = *pos++;
     430           0 :                         if (c == '\n') {
     431             :                                 /* remove ending carrige return to support the Windows CR+LF format */
     432           0 :                                 if (i != str && i[-1] == '\r')
     433           0 :                                         --i;
     434           0 :                                 --pos;
     435           0 :                                 break;
     436             :                         }
     437             : 
     438           0 :                         *i++ = c;
     439             : 
     440           0 :                         if (i == send) {
     441             :                                 /* LCOV_EXCL_START */
     442             :                                 return -1;
     443             :                                 /* LCOV_EXCL_STOP */
     444             :                         }
     445           0 :                 }
     446             : 
     447           0 :                 sptrset(f, pos);
     448             :         } else {
     449             :                 while (1) {
     450      139951 :                         c = sgetc(f);
     451      139951 :                         if (c == EOF) {
     452             :                                 /* LCOV_EXCL_START */
     453             :                                 break;
     454             :                                 /* LCOV_EXCL_STOP */
     455             :                         }
     456      139951 :                         if (c == '\n') {
     457             :                                 /* remove ending carrige return to support the Windows CR+LF format */
     458        5448 :                                 if (i != str && i[-1] == '\r')
     459           0 :                                         --i;
     460        5448 :                                 sungetc(c, f);
     461        5448 :                                 break;
     462             :                         }
     463             : 
     464      134503 :                         *i++ = c;
     465             : 
     466      134503 :                         if (i == send) {
     467             :                                 /* LCOV_EXCL_START */
     468             :                                 return -1;
     469             :                                 /* LCOV_EXCL_STOP */
     470             :                         }
     471      134503 :                 }
     472             :         }
     473             : 
     474        5448 :         *i = 0;
     475             : 
     476        5448 :         return i - str;
     477             : }
     478             : 
     479        5407 : int sgetlasttok(STREAM* f, char* str, int size)
     480             : {
     481             :         int ret;
     482             : 
     483        5407 :         ret = sgetline(f, str, size);
     484        5407 :         if (ret < 0) {
     485             :                 /* LCOV_EXCL_START */
     486             :                 return ret;
     487             :                 /* LCOV_EXCL_STOP */
     488             :         }
     489             : 
     490       10814 :         while (ret > 0 && (str[ret - 1] == ' ' || str[ret - 1] == '\t'))
     491           0 :                 --ret;
     492             : 
     493        5407 :         str[ret] = 0;
     494             : 
     495        5407 :         return ret;
     496             : }
     497             : 
     498         266 : int sgetu32(STREAM* f, uint32_t* value)
     499             : {
     500             :         int c;
     501             : 
     502         266 :         c = sgetc(f);
     503         266 :         if (c >= '0' && c <= '9') {
     504             :                 uint32_t v;
     505             : 
     506         266 :                 v = c - '0';
     507             : 
     508         266 :                 c = sgetc(f);
     509         532 :                 while (c >= '0' && c <= '9') {
     510           0 :                         v *= 10;
     511           0 :                         v += c - '0';
     512           0 :                         c = sgetc(f);
     513             :                 }
     514             : 
     515         266 :                 *value = v;
     516             : 
     517         266 :                 sungetc(c, f);
     518         266 :                 return 0;
     519             :         } else {
     520             :                 /* LCOV_EXCL_START */
     521             :                 /* nothing read */
     522             :                 return -1;
     523             :                 /* LCOV_EXCL_STOP */
     524             :         }
     525             : }
     526             : 
     527    18666900 : int sgetb32(STREAM* f, uint32_t* value)
     528             : {
     529             :         uint32_t v;
     530             :         unsigned char b;
     531             :         unsigned char s;
     532             :         int c;
     533             : 
     534    18666900 :         v = 0;
     535    18666900 :         s = 0;
     536             : loop:
     537    36346607 :         c = sgetc(f);
     538    36346607 :         if (c == EOF) {
     539             :                 /* LCOV_EXCL_START */
     540             :                 return -1;
     541             :                 /* LCOV_EXCL_STOP */
     542             :         }
     543             : 
     544    36346607 :         b = (unsigned char)c;
     545    36346607 :         if ((b & 0x80) == 0) {
     546    17679707 :                 v |= (uint32_t)b << s;
     547    17679707 :                 s += 7;
     548    17679707 :                 if (s >= 32) {
     549             :                         /* LCOV_EXCL_START */
     550             :                         return -1;
     551             :                         /* LCOV_EXCL_STOP */
     552             :                 }
     553    17679707 :                 goto loop;
     554             :         }
     555             : 
     556    18666900 :         v |= (uint32_t)(b & 0x7f) << s;
     557             : 
     558    18666900 :         *value = v;
     559             : 
     560    18666900 :         return 0;
     561             : }
     562             : 
     563    10849135 : int sgetb64(STREAM* f, uint64_t* value)
     564             : {
     565             :         uint64_t v;
     566             :         unsigned char b;
     567             :         unsigned char s;
     568             :         int c;
     569             : 
     570    10849135 :         v = 0;
     571    10849135 :         s = 0;
     572             : loop:
     573    39665263 :         c = sgetc(f);
     574    39665263 :         if (c == EOF) {
     575             :                 /* LCOV_EXCL_START */
     576             :                 return -1;
     577             :                 /* LCOV_EXCL_STOP */
     578             :         }
     579             : 
     580    39665263 :         b = (unsigned char)c;
     581    39665263 :         if ((b & 0x80) == 0) {
     582    28816128 :                 v |= (uint64_t)b << s;
     583    28816128 :                 s += 7;
     584    28816128 :                 if (s >= 64) {
     585             :                         /* LCOV_EXCL_START */
     586             :                         return -1;
     587             :                         /* LCOV_EXCL_STOP */
     588             :                 }
     589    28816128 :                 goto loop;
     590             :         }
     591             : 
     592    10849135 :         v |= (uint64_t)(b & 0x7f) << s;
     593             : 
     594    10849135 :         *value = v;
     595             : 
     596    10849135 :         return 0;
     597             : }
     598             : 
     599         381 : int sgetble32(STREAM* f, uint32_t* value)
     600             : {
     601             :         unsigned char buf[4];
     602             : 
     603         381 :         if (sread(f, buf, 4) != 0) {
     604             :                 /* LCOV_EXCL_START */
     605             :                 return -1;
     606             :                 /* LCOV_EXCL_STOP */
     607             :         }
     608             : 
     609         381 :         *value = buf[0] | (uint32_t)buf[1] << 8 | (uint32_t)buf[2] << 16 | (uint32_t)buf[3] << 24;
     610             : 
     611         381 :         return 0;
     612             : }
     613             : 
     614     3877059 : int sgetbs(STREAM* f, char* str, int size)
     615             : {
     616             :         uint32_t len;
     617             : 
     618     3877059 :         if (sgetb32(f, &len) < 0) {
     619             :                 /* LCOV_EXCL_START */
     620             :                 return -1;
     621             :                 /* LCOV_EXCL_STOP */
     622             :         }
     623             : 
     624     3877059 :         if (len + 1 > (uint32_t)size) {
     625             :                 /* LCOV_EXCL_START */
     626             :                 return -1;
     627             :                 /* LCOV_EXCL_STOP */
     628             :         }
     629             : 
     630     3877058 :         str[len] = 0;
     631             : 
     632     3877058 :         return sread(f, str, (int)len);
     633             : }
     634             : 
     635    20725042 : int swrite(const void* void_data, unsigned size, STREAM* f)
     636             : {
     637    20725042 :         const unsigned char* data = void_data;
     638             : 
     639             :         /* if there is enough space in memory */
     640    20725042 :         if (sptrlookup(f, size)) {
     641             :                 /* optimized version with all the data in memory */
     642    20718864 :                 unsigned char* pos = sptrget(f);
     643             : 
     644             :                 /**
     645             :                  * Update the crc *before* writing the data in the buffer
     646             :                  *
     647             :                  * This must be done before the memory write,
     648             :                  * to be able to detect memory errors on the buffer,
     649             :                  * happening before we write it on the file.
     650             :                  */
     651    20718864 :                 f->crc_stream = crc32c_plain(f->crc_stream, data, size);
     652             : 
     653             :                 /* copy it */
     654   172990467 :                 while (size--)
     655   131552739 :                         *pos++ = *data++;
     656             : 
     657    20718864 :                 sptrset(f, pos);
     658             :         } else {
     659             :                 /* standard version using sputc() */
     660      202580 :                 while (size--) {
     661      190224 :                         if (sputc(*data++, f) != 0) {
     662             :                                 /* LCOV_EXCL_START */
     663             :                                 return -1;
     664             :                                 /* LCOV_EXCL_STOP */
     665             :                         }
     666             :                 }
     667             :         }
     668             : 
     669    20725042 :         return 0;
     670             : }
     671             : 
     672     9127415 : int sputb32(uint32_t value, STREAM* s)
     673             : {
     674             :         unsigned char b;
     675             :         unsigned char buf[16];
     676             :         unsigned i;
     677             : 
     678     9127415 :         i = 0;
     679             : loop:
     680    17834227 :         b = value & 0x7f;
     681    17834227 :         value >>= 7;
     682             : 
     683    17834227 :         if (value) {
     684     8706812 :                 buf[i++] = b;
     685     8706812 :                 goto loop;
     686             :         }
     687             : 
     688     9127415 :         buf[i++] = b | 0x80;
     689             : 
     690     9127415 :         return swrite(buf, i, s);
     691             : }
     692             : 
     693     5317120 : int sputb64(uint64_t value, STREAM* s)
     694             : {
     695             :         unsigned char b;
     696             :         unsigned char buf[16];
     697             :         unsigned i;
     698             : 
     699     5317120 :         i = 0;
     700             : loop:
     701    19434306 :         b = value & 0x7f;
     702    19434306 :         value >>= 7;
     703             : 
     704    19434306 :         if (value) {
     705    14117186 :                 buf[i++] = b;
     706    14117186 :                 goto loop;
     707             :         }
     708             : 
     709     5317120 :         buf[i++] = b | 0x80;
     710             : 
     711     5317120 :         return swrite(buf, i, s);
     712             : }
     713             : 
     714         167 : int sputble32(uint32_t value, STREAM* s)
     715             : {
     716             :         unsigned char buf[4];
     717             : 
     718         167 :         buf[0] = value & 0xFF;
     719         167 :         buf[1] = (value >> 8) & 0xFF;
     720         167 :         buf[2] = (value >> 16) & 0xFF;
     721         167 :         buf[3] = (value >> 24) & 0xFF;
     722             : 
     723         167 :         return swrite(buf, 4, s);
     724             : }
     725             : 
     726     1898005 : int sputbs(const char* str, STREAM* f)
     727             : {
     728     1898005 :         size_t len = strlen(str);
     729             : 
     730     1898005 :         if (sputb32(len, f) != 0) {
     731             :                 /* LCOV_EXCL_START */
     732             :                 return -1;
     733             :                 /* LCOV_EXCL_STOP */
     734             :         }
     735             : 
     736     1898005 :         return swrite(str, len, f);
     737             : }
     738             : 
     739             : #if HAVE_FSYNC
     740         151 : int ssync(STREAM* s)
     741             : {
     742             :         unsigned i;
     743             : 
     744        1163 :         for (i = 0; i < s->handle_size; ++i) {
     745        1012 :                 if (fsync(s->handle[i].f) != 0) {
     746             :                         /* LCOV_EXCL_START */
     747             :                         s->state = STREAM_STATE_ERROR;
     748             :                         s->state_index = i;
     749             :                         return -1;
     750             :                         /* LCOV_EXCL_STOP */
     751             :                 }
     752             :         }
     753             : 
     754         151 :         return 0;
     755             : }
     756             : #endif
     757             : 

Generated by: LCOV version 1.13