LCOV - code coverage report
Current view: top level - ogr/ogrsf_frmts/geojson/libjson - printbuf.c (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 48 71 67.6 %
Date: 2024-05-06 11:10:03 Functions: 6 7 85.7 %

          Line data    Source code
       1             : /*
       2             :  * $Id: printbuf.c,v 1.5 2006/01/26 02:16:28 mclark Exp $
       3             :  *
       4             :  * Copyright (c) 2004, 2005 Metaparadigm Pte. Ltd.
       5             :  * Michael Clark <michael@metaparadigm.com>
       6             :  *
       7             :  * This library is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the MIT license. See COPYING for details.
       9             :  *
      10             :  *
      11             :  * Copyright (c) 2008-2009 Yahoo! Inc.  All rights reserved.
      12             :  * The copyrights to the contents of this file are licensed under the MIT License
      13             :  * (http://www.opensource.org/licenses/mit-license.php)
      14             :  */
      15             : 
      16             : #include "config.h"
      17             : 
      18             : #include <limits.h>
      19             : #include <stdio.h>
      20             : #include <stdlib.h>
      21             : #include <string.h>
      22             : 
      23             : #include "cpl_string.h"
      24             : 
      25             : #ifdef HAVE_STDARG_H
      26             : #include <stdarg.h>
      27             : #else /* !HAVE_STDARG_H */
      28             : #error Not enough var arg support!
      29             : #endif /* HAVE_STDARG_H */
      30             : 
      31             : #include "debug.h"
      32             : #include "printbuf.h"
      33             : 
      34             : static int printbuf_extend(struct printbuf *p, int min_size);
      35             : 
      36       30670 : struct printbuf *printbuf_new(void)
      37             : {
      38             :   struct printbuf *p;
      39             : 
      40       30670 :   p = (struct printbuf *)calloc(1, sizeof(struct printbuf));
      41       30670 :   if (!p)
      42           0 :     return NULL;
      43       30670 :   p->size = 32;
      44       30670 :   p->bpos = 0;
      45       30670 :   if (!(p->buf = (char *)malloc(p->size)))
      46             :   {
      47           0 :     free(p);
      48           0 :     return NULL;
      49             :   }
      50       30670 :   p->buf[0] = '\0';
      51       30670 :   return p;
      52             : }
      53             : 
      54             : /**
      55             :  * Extend the buffer p so it has a size of at least min_size.
      56             :  *
      57             :  * If the current size is large enough, nothing is changed.
      58             :  *
      59             :  * Note: this does not check the available space!  The caller
      60             :  *  is responsible for performing those calculations.
      61             :  */
      62       28312 : static int printbuf_extend(struct printbuf *p, int min_size)
      63             : {
      64             :   char *t;
      65             :   int new_size;
      66             : 
      67       28312 :   if (p->size >= min_size)
      68        6897 :     return 0;
      69             :   /* Prevent signed integer overflows with large buffers. */
      70       21415 :   if (min_size > INT_MAX - 8)
      71           0 :     return -1;
      72       21415 :   if (p->size > INT_MAX / 2)
      73           0 :     new_size = min_size + 8;
      74             :   else {
      75       21415 :     new_size = p->size * 2;
      76       21415 :     if (new_size < min_size + 8)
      77         550 :       new_size = min_size + 8;
      78             :   }
      79             : #ifdef PRINTBUF_DEBUG
      80             :   MC_DEBUG("printbuf_memappend: realloc "
      81             :            "bpos=%d min_size=%d old_size=%d new_size=%d\n",
      82             :            p->bpos, min_size, p->size, new_size);
      83             : #endif /* PRINTBUF_DEBUG */
      84       21415 :   if (!(t = (char *)realloc(p->buf, new_size)))
      85           0 :     return -1;
      86       21415 :   p->size = new_size;
      87       21415 :   p->buf = t;
      88       21415 :   return 0;
      89             : }
      90             : 
      91      844453 : int printbuf_memappend(struct printbuf *p, const char *buf, int size)
      92             : {
      93             :   /* Prevent signed integer overflows with large buffers. */
      94      844453 :   if (size > INT_MAX - p->bpos - 1)
      95           0 :     return -1;
      96      844453 :   if (p->size <= p->bpos + size + 1)
      97             :   {
      98       27351 :     if (printbuf_extend(p, p->bpos + size + 1) < 0)
      99           0 :       return -1;
     100             :   }
     101      844453 :   memcpy(p->buf + p->bpos, buf, size);
     102      844453 :   p->bpos += size;
     103      844453 :   p->buf[p->bpos] = '\0';
     104      844453 :   return size;
     105             : }
     106             : 
     107       82007 : int printbuf_memset(struct printbuf *pb, int offset, int charvalue, int len)
     108             : {
     109             :   int size_needed;
     110             : 
     111       82007 :   if (offset == -1)
     112       82007 :     offset = pb->bpos;
     113             :   /* Prevent signed integer overflows with large buffers. */
     114       82007 :   if (len > INT_MAX - offset)
     115           0 :     return -1;
     116       82007 :   size_needed = offset + len;
     117       82007 :   if (pb->size < size_needed)
     118             :   {
     119         961 :     if (printbuf_extend(pb, size_needed) < 0)
     120           0 :       return -1;
     121             :   }
     122             : 
     123       82007 :   memset(pb->buf + offset, charvalue, len);
     124       82007 :   if (pb->bpos < size_needed)
     125       79299 :     pb->bpos = size_needed;
     126             : 
     127       82007 :   return 0;
     128             : }
     129             : 
     130             : /* Use CPLVASPrintf for portability issues */
     131           0 : int sprintbuf(struct printbuf *p, const char *msg, ...)
     132             : {
     133             :   va_list ap;
     134             :   char *t;
     135             :   int size, ret;
     136             : 
     137             :   /* user stack buffer first */
     138           0 :   va_start(ap, msg);
     139           0 :   size = CPLVASPrintf(&t, msg, ap);
     140           0 :   va_end(ap);
     141           0 :   if( size == -1 )
     142           0 :       return -1;
     143             : 
     144           0 :   if (strcmp(msg, "%f") == 0)
     145             :   {
     146           0 :       char* pszComma = strchr(t, ',');
     147           0 :       if (pszComma)
     148           0 :           *pszComma = '.';
     149             :   }
     150             : 
     151           0 :   ret = printbuf_memappend(p, t, size);
     152           0 :   CPLFree(t);
     153           0 :   return ret;
     154             : }
     155             : 
     156     2872830 : void printbuf_reset(struct printbuf *p)
     157             : {
     158     2872830 :   p->buf[0] = '\0';
     159     2872830 :   p->bpos = 0;
     160     2872830 : }
     161             : 
     162     2807380 : void printbuf_free(struct printbuf *p)
     163             : {
     164     2807380 :   if (p)
     165             :   {
     166       30670 :     free(p->buf);
     167       30670 :     free(p);
     168             :   }
     169     2807380 : }

Generated by: LCOV version 1.14