annotate jansson/src/strbuffer.c @ 0:0047655db1aa

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