LCOV - code coverage report
Current view: top level - source3/lib - cbuf.c (source / functions) Hit Total Coverage
Test: coverage report for v4-17-test 1498b464 Lines: 0 163 0.0 %
Date: 2024-06-13 04:01:37 Functions: 0 18 0.0 %

          Line data    Source code
       1             : /*
       2             :  * Samba Unix/Linux SMB client library
       3             :  *
       4             :  * Copyright (C) Gregor Beck 2010
       5             :  *
       6             :  * This program is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * This program is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      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             : /**
      21             :  * @file   cbuf.c
      22             :  * @author Gregor Beck <gb@sernet.de>
      23             :  * @date   Aug 2010
      24             :  *
      25             :  * @brief  A talloced character buffer.
      26             :  *
      27             :  */
      28             : 
      29             : 
      30             : #include "replace.h"
      31             : #include "system/locale.h"
      32             : #include "cbuf.h"
      33             : #include <talloc.h>
      34             : #include <assert.h>
      35             : #include "lib/util/byteorder.h"
      36             : 
      37             : 
      38             : struct cbuf {
      39             :         char*  buf;
      40             :         size_t pos;
      41             :         size_t size;
      42             : };
      43             : 
      44             : 
      45           0 : cbuf* cbuf_clear(cbuf* b)
      46             : {
      47           0 :         cbuf_setpos(b, 0);
      48           0 :         return b;
      49             : }
      50             : 
      51           0 : cbuf* cbuf_new(const void* ctx)
      52             : {
      53           0 :         cbuf* s = talloc(ctx, cbuf);
      54           0 :         if (s == NULL)
      55           0 :                 return NULL;
      56           0 :         s->size = 32;
      57           0 :         s->buf  = (char *)talloc_size(s, s->size);
      58           0 :         if (s->size && (s->buf == NULL)) {
      59           0 :                 talloc_free(s);
      60           0 :                 return NULL;
      61             :         }
      62           0 :         return cbuf_clear(s);
      63             : }
      64             : 
      65           0 : cbuf* cbuf_copy(const cbuf* b)
      66             : {
      67           0 :         cbuf* s = talloc(talloc_parent(b), cbuf);
      68           0 :         if (s == NULL) {
      69           0 :                 return NULL;
      70             :         }
      71             : 
      72           0 :         s->buf = (char *)talloc_memdup(s, b->buf, b->size); /* only up to pos? */
      73             : 
      74             :         /* XXX shallow did not work, because realloc */
      75             :         /* fails with multiple references */
      76             :         /* s->buf = talloc_reference(s, b->buf); */
      77             : 
      78           0 :         if (s->buf == NULL) {
      79           0 :                 cbuf_delete(s);
      80           0 :                 return NULL;
      81             :         }
      82           0 :         s->size = b->size;
      83           0 :         s->pos  = b->pos;
      84           0 :         return s;
      85             : }
      86             : 
      87           0 : void cbuf_delete(cbuf* b)
      88             : {
      89           0 :         talloc_free(b);
      90           0 : }
      91             : 
      92             : #define SWAP(A,B,T) do {                        \
      93             :                 T tmp = A; A = B; B = tmp;      \
      94             :         } while(0)
      95             : 
      96             : 
      97           0 : void cbuf_swap(cbuf* b1, cbuf* b2)
      98             : {
      99           0 :         if (b1 == b2) {
     100           0 :                 return;
     101             :         }
     102           0 :         talloc_reparent(b1, b2, b1->buf);
     103           0 :         talloc_reparent(b2, b1, b2->buf);
     104           0 :         SWAP(b1->buf,  b2->buf, char*);
     105           0 :         SWAP(b1->pos,  b2->pos, size_t);
     106           0 :         SWAP(b1->size, b2->size, size_t);
     107             : }
     108             : 
     109             : 
     110             : 
     111           0 : cbuf* cbuf_takeover(cbuf* b1, cbuf* b2)
     112             : {
     113           0 :         talloc_reparent(b2, b1, b2->buf);
     114           0 :         b1->buf = b2->buf;
     115           0 :         b1->pos = b2->pos;
     116           0 :         b1->size = b2->size;
     117           0 :         cbuf_delete(b2);
     118           0 :         return b1;
     119             : }
     120             : 
     121           0 : cbuf* cbuf_swapptr(cbuf* b, char** ptr, size_t len)
     122             : {
     123           0 :         void* p = talloc_parent(*ptr);
     124           0 :         SWAP(b->buf, *ptr, char*);
     125           0 :         talloc_steal(b, b->buf);
     126           0 :         talloc_steal(p, *ptr);
     127           0 :         b->size = talloc_get_size(b->buf);
     128           0 :         b->pos  = (len == -1) ? strlen(b->buf) : len;
     129             : 
     130           0 :         assert(b->pos <= b->size);
     131           0 :         return b;
     132             : }
     133             : 
     134           0 : cbuf* cbuf_resize(cbuf* b, size_t size)
     135             : {
     136           0 :         char* save_buf = b->buf;
     137           0 :         b->buf = talloc_realloc(b, b->buf, char, size);
     138           0 :         if (b->buf == NULL) {
     139           0 :                 talloc_free(save_buf);
     140           0 :                 b->size = 0;
     141             :         } else {
     142           0 :                 b->size = size;
     143             :         }
     144           0 :         b->pos  = MIN(b->pos, b->size);
     145           0 :         return b->buf ? b : NULL;
     146             : }
     147             : 
     148           0 : char* cbuf_reserve(cbuf* b, size_t len)
     149             : {
     150           0 :         if(b->size < b->pos + len)
     151           0 :                 cbuf_resize(b, MAX(2*b->size, b->pos + len));
     152           0 :         return b->buf ? b->buf + b->pos : NULL;
     153             : }
     154             : 
     155           0 : int cbuf_puts(cbuf* b, const char* str, size_t len)
     156             : {
     157             :         char* dst;
     158             : 
     159           0 :         if (b == NULL)
     160           0 :                 return 0;
     161             : 
     162           0 :         if (len == -1) {
     163           0 :                 len=strlen(str);
     164             :         }
     165             : 
     166           0 :         dst = cbuf_reserve(b, len+1);
     167           0 :         if (dst == NULL)
     168           0 :                 return -1;
     169             : 
     170           0 :         memcpy(dst, str, len);
     171           0 :         dst[len] = '\0'; /* just to ease debugging */
     172             : 
     173           0 :         b->pos += len;
     174           0 :         assert(b->pos < b->size);
     175             : 
     176           0 :         return len;
     177             : }
     178             : 
     179           0 : int cbuf_putc(cbuf* b, char c) {
     180             :         char* dst;
     181             : 
     182           0 :         if (b == NULL)
     183           0 :                 return 0;
     184             : 
     185           0 :         dst = cbuf_reserve(b, 2);
     186           0 :         if (dst == NULL) {
     187           0 :                 return -1;
     188             :         }
     189             : 
     190           0 :         dst[0] = c;
     191           0 :         dst[1] = '\0'; /* just to ease debugging */
     192             : 
     193           0 :         b->pos++;
     194           0 :         assert(b->pos < b->size);
     195             : 
     196           0 :         return 1;
     197             : }
     198             : 
     199           0 : int cbuf_putdw(cbuf* b, uint32_t u) {
     200             :         char* dst;
     201             :         static const size_t LEN = sizeof(uint32_t);
     202             : 
     203           0 :         if (b == NULL)
     204           0 :                 return 0;
     205             : 
     206           0 :         dst = cbuf_reserve(b, LEN);
     207           0 :         if (dst == NULL) {
     208           0 :                 return -1;
     209             :         }
     210             : 
     211           0 :         SIVAL(dst, 0, u);
     212             : 
     213           0 :         b->pos += LEN;
     214           0 :         assert(b->pos <= b->size); /* no NULL termination*/
     215             : 
     216           0 :         return LEN;
     217             : }
     218             : 
     219           0 : size_t cbuf_getpos(const cbuf* b) {
     220           0 :         assert(b->pos <= b->size);
     221           0 :         return b->pos;
     222             : }
     223             : 
     224           0 : void cbuf_setpos(cbuf* b, size_t pos) {
     225           0 :         assert(pos <= b->size);
     226           0 :         b->pos = pos;
     227           0 :         if (pos < b->size)
     228           0 :                 b->buf[pos] = '\0'; /* just to ease debugging */
     229           0 : }
     230             : 
     231           0 : char* cbuf_gets(cbuf* b, size_t idx) {
     232           0 :         assert(idx <= b->pos);
     233             : 
     234           0 :         if (cbuf_reserve(b, 1) == NULL)
     235           0 :                 return NULL;
     236             : 
     237           0 :         b->buf[b->pos] = '\0';
     238           0 :         return b->buf + idx;
     239             : }
     240             : 
     241           0 : int cbuf_printf(cbuf* b, const char* fmt, ...)
     242             : {
     243             :         va_list args, args2;
     244             :         int len;
     245           0 :         char* dst = b->buf + b->pos;
     246           0 :         const int avail = b->size - b->pos;
     247           0 :         assert(avail >= 0);
     248             : 
     249           0 :         va_start(args, fmt);
     250           0 :         va_copy(args2, args);
     251             : 
     252           0 :         len = vsnprintf(dst, avail, fmt, args);
     253             : 
     254           0 :         if (len >= avail) {
     255           0 :                 dst = cbuf_reserve(b, len+1);
     256           0 :                 len = (dst != NULL) ? vsnprintf(dst, len+1, fmt, args2) : -1;
     257             :         }
     258             : 
     259           0 :         if (len > 0) {
     260           0 :                 b->pos += len;
     261             :         }
     262             : 
     263           0 :         va_end(args);
     264           0 :         va_end(args2);
     265           0 :         assert(b->pos <= b->size);
     266             : 
     267           0 :         return len;
     268             : }
     269             : 
     270           0 : int cbuf_print_quoted_string(cbuf* ost, const char* s)
     271             : {
     272           0 :         int n = 1;
     273           0 :         cbuf_putc(ost,'"');
     274             : 
     275             :         while(true) {
     276           0 :                 switch (*s) {
     277           0 :                 case '\0':
     278           0 :                         cbuf_putc(ost, '"');
     279           0 :                         return n+1;
     280             : 
     281           0 :                 case '"':
     282             :                 case '\\':
     283           0 :                         cbuf_putc(ost, '\\');
     284           0 :                         n++;
     285             : 
     286             :                         FALL_THROUGH;
     287           0 :                 default:
     288           0 :                         cbuf_putc(ost, *s);
     289           0 :                         n++;
     290             :                 }
     291           0 :                 s++;
     292             :         }
     293             : }
     294             : 
     295             : 
     296           0 : int cbuf_print_quoted(cbuf* ost, const char* s, size_t len)
     297             : {
     298           0 :         int n = 1;
     299             :         int ret;
     300           0 :         cbuf_reserve(ost, len+2);
     301             : 
     302           0 :         cbuf_putc(ost,'"');
     303             : 
     304           0 :         while(len--) {
     305           0 :                 switch (*s) {
     306           0 :                 case '"':
     307             :                 case '\\':
     308           0 :                         ret = cbuf_printf(ost, "\\%c", *s);
     309           0 :                         break;
     310           0 :                 default:
     311           0 :                         if (isprint(*s) && ((*s == ' ') || !isspace(*s))) {
     312           0 :                                 ret = cbuf_putc(ost, *s);
     313             :                         } else {
     314           0 :                                 ret = cbuf_printf(ost,
     315             :                                                   "\\%02x",
     316           0 :                                                   (unsigned char)*s);
     317             :                         }
     318             :                 }
     319           0 :                 s++;
     320           0 :                 if (ret == -1) {
     321           0 :                         return -1;
     322             :                 }
     323           0 :                 n += ret;
     324             :         }
     325           0 :         ret = cbuf_putc(ost,'"');
     326             : 
     327           0 :         return (ret == -1) ? -1 : (n + ret);
     328             : }

Generated by: LCOV version 1.13