1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
/*-------------------------------------------------------------------------
*
* stringinfo.c--
* These are routines that can be used to write informations to a string,
* without having to worry about string lengths, space allocation etc.
* Ideally the interface should look like the file i/o interface,
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/lib/stringinfo.c,v 1.1.1.1 1996/07/09 06:21:29 scrappy Exp $
*
*-------------------------------------------------------------------------
*/
#include <string.h>
#include "postgres.h"
#include "nodes/pg_list.h"
#include "lib/stringinfo.h"
#include "utils/elog.h"
#include "utils/palloc.h"
/*---------------------------------------------------------------------
* makeStringInfo
*
* Create a StringInfoData & return a pointer to it.
*
*---------------------------------------------------------------------
*/
StringInfo
makeStringInfo()
{
StringInfo res;
long size;
res = (StringInfo) palloc(sizeof(StringInfoData));
if (res == NULL) {
elog(WARN, "makeStringInfo: Out of memory!");
}
size = 100;
res->data = palloc(size);
if (res->data == NULL) {
elog(WARN,
"makeStringInfo: Out of memory! (%ld bytes requested)", size);
}
res->maxlen = size;
res->len = 0;
/*
* NOTE: we must initialize `res->data' to the empty string because
* we use 'strcat' in 'appendStringInfo', which of course it always
* expects a null terminated string.
*/
res->data[0] = '\0';
return(res);
}
/*---------------------------------------------------------------------
* appendStringInfo
*
* append to the current 'StringInfo' a new string.
* If there is not enough space in the current 'data', then reallocate
* some more...
*
* NOTE: if we reallocate space, we pfree the old one!
*---------------------------------------------------------------------
*/
void
appendStringInfo(StringInfo str, char *buffer)
{
int buflen, newlen;
char *s;
Assert((str!=NULL));
/*
* do we have enough space to append the new string?
* (don't forget to count the null string terminating char!)
* If no, then reallocate some more.
*/
buflen = strlen(buffer);
if (buflen + str->len >= str->maxlen-1) {
/*
* how much more space to allocate ?
* Let's say double the current space...
* However we must check if this is enough!
*/
newlen = 2 * str->len;
while (buflen + str->len >= newlen-1) {
newlen = 2 * newlen;
}
/*
* allocate enough space.
*/
s = palloc(newlen);
if (s==NULL) {
elog(WARN,
"appendStringInfo: Out of memory (%d bytes requested)",
newlen);
}
memmove(s, str->data, str->len+1);
pfree(str->data);
str->maxlen = newlen;
str->data = s;
}
/*
* OK, we have enough space now, append 'buffer' at the
* end of the string & update the string length.
* NOTE: this is a text string (i.e. printable characters)
* so 'strcat' will do the job (no need to use 'bcopy' et all...)
*/
(void) strcat(str->data, buffer);
str->len += buflen;
}
|