xref: /trueos/contrib/jansson/src/strbuffer.c (revision 47b2a07a74bf982bec730c936e92feeef05c7575)
1 /*
2  * Copyright (c) 2009-2014 Petri Lehtinen <petri@digip.org>
3  *
4  * Jansson is free software; you can redistribute it and/or modify
5  * it under the terms of the MIT license. See LICENSE for details.
6  */
7 
8 #ifndef _GNU_SOURCE
9 #define _GNU_SOURCE
10 #endif
11 
12 #include <stdlib.h>
13 #include <string.h>
14 #include "jansson_private.h"
15 #include "strbuffer.h"
16 
17 #define STRBUFFER_MIN_SIZE  16
18 #define STRBUFFER_FACTOR    2
19 #define STRBUFFER_SIZE_MAX  ((size_t)-1)
20 
strbuffer_init(strbuffer_t * strbuff)21 int strbuffer_init(strbuffer_t *strbuff)
22 {
23     strbuff->size = STRBUFFER_MIN_SIZE;
24     strbuff->length = 0;
25 
26     strbuff->value = jsonp_malloc(strbuff->size);
27     if(!strbuff->value)
28         return -1;
29 
30     /* initialize to empty */
31     strbuff->value[0] = '\0';
32     return 0;
33 }
34 
strbuffer_close(strbuffer_t * strbuff)35 void strbuffer_close(strbuffer_t *strbuff)
36 {
37     if(strbuff->value)
38         jsonp_free(strbuff->value);
39 
40     strbuff->size = 0;
41     strbuff->length = 0;
42     strbuff->value = NULL;
43 }
44 
strbuffer_clear(strbuffer_t * strbuff)45 void strbuffer_clear(strbuffer_t *strbuff)
46 {
47     strbuff->length = 0;
48     strbuff->value[0] = '\0';
49 }
50 
strbuffer_value(const strbuffer_t * strbuff)51 const char *strbuffer_value(const strbuffer_t *strbuff)
52 {
53     return strbuff->value;
54 }
55 
strbuffer_steal_value(strbuffer_t * strbuff)56 char *strbuffer_steal_value(strbuffer_t *strbuff)
57 {
58     char *result = strbuff->value;
59     strbuff->value = NULL;
60     return result;
61 }
62 
strbuffer_append(strbuffer_t * strbuff,const char * string)63 int strbuffer_append(strbuffer_t *strbuff, const char *string)
64 {
65     return strbuffer_append_bytes(strbuff, string, strlen(string));
66 }
67 
strbuffer_append_byte(strbuffer_t * strbuff,char byte)68 int strbuffer_append_byte(strbuffer_t *strbuff, char byte)
69 {
70     return strbuffer_append_bytes(strbuff, &byte, 1);
71 }
72 
strbuffer_append_bytes(strbuffer_t * strbuff,const char * data,size_t size)73 int strbuffer_append_bytes(strbuffer_t *strbuff, const char *data, size_t size)
74 {
75     if(size >= strbuff->size - strbuff->length)
76     {
77         size_t new_size;
78         char *new_value;
79 
80         /* avoid integer overflow */
81         if (strbuff->size > STRBUFFER_SIZE_MAX / STRBUFFER_FACTOR
82             || size > STRBUFFER_SIZE_MAX - 1
83             || strbuff->length > STRBUFFER_SIZE_MAX - 1 - size)
84             return -1;
85 
86         new_size = max(strbuff->size * STRBUFFER_FACTOR,
87                        strbuff->length + size + 1);
88 
89         new_value = jsonp_malloc(new_size);
90         if(!new_value)
91             return -1;
92 
93         memcpy(new_value, strbuff->value, strbuff->length);
94 
95         jsonp_free(strbuff->value);
96         strbuff->value = new_value;
97         strbuff->size = new_size;
98     }
99 
100     memcpy(strbuff->value + strbuff->length, data, size);
101     strbuff->length += size;
102     strbuff->value[strbuff->length] = '\0';
103 
104     return 0;
105 }
106 
strbuffer_pop(strbuffer_t * strbuff)107 char strbuffer_pop(strbuffer_t *strbuff)
108 {
109     if(strbuff->length > 0) {
110         char c = strbuff->value[--strbuff->length];
111         strbuff->value[strbuff->length] = '\0';
112         return c;
113     }
114     else
115         return '\0';
116 }
117