LCOV - code coverage report
Current view: top level - basicobjects - simplebuffer.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 56 58 96.6 %
Date: 2014-04-01 Functions: 10 10 100.0 %

          Line data    Source code
       1             : /*
       2             :     Simple buffer
       3             : 
       4             :     Basic buffer manipulation routines. Taken from ELAPI code.
       5             : 
       6             :     Copyright (C) Dmitri Pal <dpal@redhat.com> 2009 - 2010
       7             : 
       8             :     This program is free software; you can redistribute it and/or modify
       9             :     it under the terms of the GNU General Public License as published by
      10             :     the Free Software Foundation; either version 3 of the License, or
      11             :     (at your option) any later version.
      12             :     This program is distributed in the hope that it will be useful,
      13             :     but 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             :     You should have received a copy of the GNU General Public License
      17             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "config.h"
      21             : #include <errno.h>      /* for errors */
      22             : #include <stdlib.h>     /* for free() */
      23             : #include <unistd.h>     /* for write() */
      24             : #include <string.h>     /* for memcpy() */
      25             : 
      26             : #include "simplebuffer.h"
      27             : #include "trace.h"
      28             : 
      29             : /* End line string */
      30             : #define ENDLNSTR "\n"
      31             : 
      32             : /* Function to free buffer */
      33      200523 : void simplebuffer_free(struct simplebuffer *data)
      34             : {
      35             :     TRACE_FLOW_ENTRY();
      36             : 
      37      200523 :     if (data) {
      38      200523 :         free(data->buffer);
      39      200523 :         free(data);
      40             :     }
      41             : 
      42             :     TRACE_FLOW_EXIT();
      43      200523 : }
      44             : 
      45             : /* Allocate buffer structure */
      46      200523 : int simplebuffer_alloc(struct simplebuffer **data)
      47             : {
      48      200523 :     int error = EOK;
      49             : 
      50             :     TRACE_FLOW_ENTRY();
      51             : 
      52      200523 :     if (!data) {
      53             :         TRACE_ERROR_STRING("Invalid argument", "");
      54             :         error = EINVAL;
      55             :     }
      56             :     else {
      57      200523 :         *data = (struct simplebuffer *)calloc(1,
      58             :                                               sizeof(struct simplebuffer));
      59      200523 :         if (*data == NULL) {
      60             :             TRACE_ERROR_STRING("Failed to allocate memory", "");
      61             :             error = ENOMEM;
      62             :         }
      63      200523 :         else error = EOK;
      64             :     }
      65             : 
      66             :     TRACE_FLOW_RETURN(error);
      67      200523 :     return error;
      68             : }
      69             : 
      70             : 
      71             : /* Grow buffer */
      72     1477696 : int simplebuffer_grow(struct simplebuffer *data,
      73             :                       uint32_t len,
      74             :                       uint32_t block)
      75             : {
      76     1477696 :     int error = EOK;
      77     1477696 :     unsigned char *newbuf = NULL;
      78             : 
      79             :     TRACE_FLOW_ENTRY();
      80             : 
      81             :     TRACE_INFO_NUMBER("Current length: ", data->length);
      82             :     TRACE_INFO_NUMBER("Current size: ", data->size);
      83             :     TRACE_INFO_NUMBER("Length to have: ", len);
      84             :     TRACE_INFO_NUMBER("Increment length: ", block);
      85             : 
      86             :     /* Grow buffer if needed */
      87     3367788 :     while (data->length + len >= data->size) {
      88      412396 :         newbuf = realloc(data->buffer, data->size + block);
      89      412396 :         if (newbuf == NULL) {
      90             :             TRACE_ERROR_NUMBER("Error. Failed to allocate memory.", ENOMEM);
      91             :             return ENOMEM;
      92             :         }
      93      412396 :         data->buffer = newbuf;
      94      412396 :         data->size += block;
      95             :         TRACE_INFO_NUMBER("New size: ", data->size);
      96             :     }
      97             : 
      98             :     TRACE_INFO_NUMBER("Final size: ", data->size);
      99             :     TRACE_FLOW_RETURN(error);
     100             :     return error;
     101             : }
     102             : 
     103             : /* Function to add raw data to the end of the buffer.
     104             :  * Terminating 0 is not counted in length but appended
     105             :  * automatically.
     106             :  */
     107     1212401 : int simplebuffer_add_raw(struct simplebuffer *data,
     108             :                          void *data_in,
     109             :                          uint32_t len,
     110             :                          uint32_t block)
     111             : {
     112             : 
     113     1212401 :     int error = EOK;
     114             :     uint32_t size;
     115             : 
     116             :     TRACE_FLOW_ENTRY();
     117             : 
     118     1212401 :     size = len + 1;
     119     1212401 :     error = simplebuffer_grow(data, size,
     120             :                              ((block > size) ? block : size));
     121     1212401 :     if (error) {
     122             :         TRACE_ERROR_NUMBER("Failed to grow buffer.", error);
     123             :         return error;
     124             :     }
     125             : 
     126     1212401 :     memcpy(data->buffer + data->length, data_in, len);
     127     1212401 :     data->length += len;
     128     1212401 :     data->buffer[data->length] = '\0';
     129             : 
     130             :     TRACE_FLOW_EXIT();
     131     1212401 :     return error;
     132             : }
     133             : 
     134             : /* Function to add string to the end of the buffer. */
     135      265295 : int simplebuffer_add_str(struct simplebuffer *data,
     136             :                          const char *str,
     137             :                          uint32_t len,
     138             :                          uint32_t block)
     139             : {
     140             : 
     141      265295 :     int error = EOK;
     142             :     uint32_t size;
     143             : 
     144             :     TRACE_FLOW_ENTRY();
     145             : 
     146      265295 :     size = len + 1;
     147      265295 :     error = simplebuffer_grow(data, size,
     148             :                              ((block > size) ? block : size));
     149      265295 :     if (error) {
     150             :         TRACE_ERROR_NUMBER("Failed to grow buffer.", error);
     151             :         return error;
     152             :     }
     153             : 
     154      265295 :     memcpy(data->buffer + data->length, str, len);
     155      265295 :     data->length += len;
     156      265295 :     data->buffer[data->length] = '\0';
     157             : 
     158             :     TRACE_FLOW_EXIT();
     159      265295 :     return error;
     160             : }
     161             : 
     162             : /* Finction to add CR to the buffer */
     163      496878 : int simplebuffer_add_cr(struct simplebuffer *data)
     164             : {
     165      496878 :     int error = EOK;
     166      496878 :     char cr[] = ENDLNSTR;
     167             : 
     168             :     TRACE_FLOW_ENTRY();
     169             : 
     170      496878 :     error = simplebuffer_add_raw(data,
     171             :                                  (void *)cr,
     172             :                                  sizeof(ENDLNSTR) - 1,
     173             :                                  sizeof(ENDLNSTR));
     174             : 
     175             :     TRACE_FLOW_RETURN(error);
     176      496878 :     return error;
     177             : }
     178             : 
     179             : 
     180             : /* Function to write data synchroniusly */
     181         307 : int simplebuffer_write(int fd, struct simplebuffer *data, uint32_t *left)
     182             : {
     183             :     size_t res;
     184             :     int error;
     185             : 
     186             :     TRACE_FLOW_ENTRY();
     187             : 
     188             :     /* Write given number of bytes to the socket */
     189         614 :     res = write(fd,
     190         307 :                 data->buffer + (data->length - *left),
     191         307 :                 (size_t)(*left));
     192             : 
     193         307 :     if (res == -1) {
     194           0 :         error = errno;
     195             :         TRACE_ERROR_NUMBER("Write failed.", error);
     196           0 :         return error;
     197             :     }
     198             : 
     199         307 :     (*left) -= res;
     200             : 
     201             :     TRACE_FLOW_EXIT();
     202         307 :     return EOK;
     203             : }
     204             : 
     205             : /* Get buffer */
     206      263652 : const unsigned char *simplebuffer_get_buf(struct simplebuffer *data)
     207             : {
     208      263652 :     return data->buffer;
     209             : }
     210             : 
     211             : /* Get void buffer */
     212         245 : void *simplebuffer_get_vbuf(struct simplebuffer *data)
     213             : {
     214         245 :     return (void *)data->buffer;
     215             : }
     216             : 
     217             : 
     218             : /* Get length */
     219      264503 : uint32_t simplebuffer_get_len(struct simplebuffer *data)
     220             : {
     221      264503 :     return data->length;
     222             : }

Generated by: LCOV version 1.10