"Fossies" - the Fresh Open Source Software Archive 
Member "sarg-2.4.0/stringbuffer.c" (30 Jan 2017, 4839 Bytes) of package /linux/privat/sarg-2.4.0.tar.gz:
As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style:
standard) with prefixed line numbers and
code folding option.
Alternatively you can here
view or
download the uninterpreted source code file.
For more information about "stringbuffer.c" see the
Fossies "Dox" file reference documentation.
1 /*
2 * SARG Squid Analysis Report Generator http://sarg.sourceforge.net
3 * 1998, 2015
4 *
5 * SARG donations:
6 * please look at http://sarg.sourceforge.net/donations.php
7 * Support:
8 * http://sourceforge.net/projects/sarg/forums/forum/363374
9 * ---------------------------------------------------------------------
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
24 *
25 */
26 /*!\file
27 \brief Efficient? strings storage
28
29 Store strings in a globaly allocated memory to avoid memory waste and
30 memory fragmentation.
31 */
32
33 #include "include/conf.h"
34 #include "include/stringbuffer.h"
35
36 //! Default size of the string buffer (I hope it fits inside one memory page).
37 #define STRINGBUFFER_SIZE (4096-sizeof(struct StringBufferStruct))
38
39 /*!
40 * \brief String storage data.
41 *
42 * Strings are concatenated in fixed size buffers. The buffers are linked
43 * in a list. New buffers are added as the previous buffers are filled.
44 */
45 struct StringBufferStruct
46 {
47 //! Next buffer in the chained list.
48 StringBufferObject Next;
49 //! How many buffer bytes are left.
50 int BytesLeft;
51 //! Where the strings are stored.
52 char *Buffer;
53 };
54
55 /*!
56 * Create an object to store constant strings.
57 *
58 * \return The created object or NULL if it failed.
59 */
60 StringBufferObject StringBuffer_Create(void)
61 {
62 StringBufferObject SObj;
63
64 SObj=(StringBufferObject)calloc(1,sizeof(*SObj));
65 if (!SObj) return(NULL);
66 return(SObj);
67 }
68
69 /*!
70 * Destroy the object created by StringBuffer_Create().
71 *
72 * Any string pointer to the destroyed object becomes invalid.
73 *
74 * \param SPtr A pointer to the object created by StringBuffer_Create().
75 * The pointer is reset to NULL before the functrion returns to prevent
76 * subsequent use of the freed pointer.
77 */
78 void StringBuffer_Destroy(StringBufferObject *SPtr)
79 {
80 StringBufferObject SObj;
81 StringBufferObject Next;
82
83 if (!SPtr || !*SPtr) return;
84 SObj=*SPtr;
85 *SPtr=NULL;
86
87 while (SObj)
88 {
89 Next=SObj->Next;
90 if (SObj->Buffer) free(SObj->Buffer);
91 free(SObj);
92 SObj=Next;
93 }
94 }
95
96 /*!
97 * Store a string in an existing buffer.
98 */
99 static char *StringBuffer_StoreInBuffer(StringBufferObject SObj,const char *String,int Length)
100 {
101 int Start=0;
102
103 if (SObj->Buffer)
104 {
105 Start=STRINGBUFFER_SIZE-SObj->BytesLeft;
106 }
107 else if (Length>=STRINGBUFFER_SIZE)
108 {
109 SObj->BytesLeft=Length+1;
110 SObj->Buffer=malloc(SObj->BytesLeft);
111 }
112 else
113 {
114 SObj->BytesLeft=STRINGBUFFER_SIZE;
115 SObj->Buffer=malloc(SObj->BytesLeft);
116 }
117 if (!SObj->Buffer) return(NULL);
118 strncpy(SObj->Buffer+Start,String,Length);
119 SObj->Buffer[Start+Length]='\0';
120 SObj->BytesLeft-=Length+1;
121 return(SObj->Buffer+Start);
122 }
123
124 /*!
125 * Add a string to the buffer. Duplicate strings are not merged.
126 * Each call to this function stores one copy of the string.
127 *
128 * \param SObj The string buffer object.
129 * \param String The string to store.
130 * \param Length The length of the string.
131 *
132 * \return The pointer to the stored string or NULL if the function
133 * failed. The returned string may be altered or truncated but not
134 * appended to.
135 */
136 char *StringBuffer_StoreLength(StringBufferObject SObj,const char *String,int Length)
137 {
138 StringBufferObject SLast;
139 char *Ptr;
140
141 if (!SObj) return(NULL);
142
143 // find a suitable buffer
144 SLast=NULL;
145 while (SObj)
146 {
147 if (!SObj->Buffer || Length<SObj->BytesLeft)
148 {
149 return(StringBuffer_StoreInBuffer(SObj,String,Length));
150 }
151 SLast=SObj;
152 SObj=SObj->Next;
153 }
154
155 // create a new buffer
156 SObj=(StringBufferObject)calloc(1,sizeof(*SObj));
157 if (!SObj) return(NULL);
158 Ptr=StringBuffer_StoreInBuffer(SObj,String,Length);
159 if (!Ptr)
160 {
161 free(SObj);
162 return(NULL);
163 }
164 SLast->Next=SObj;
165 return(Ptr);
166 }
167
168 /*!
169 * Add a string to the buffer. Duplicate strings are not merged.
170 * Each call to this function stores one copy of the string.
171 *
172 * \param SObj The string buffer object.
173 * \param String The string to store.
174 *
175 * \return The pointer to the stored string or NULL if the function
176 * failed. The returned string may be altered or truncated but not
177 * appended to.
178 */
179 char *StringBuffer_Store(StringBufferObject SObj,const char *String)
180 {
181 return(StringBuffer_StoreLength(SObj,String,strlen(String)));
182 }