1818#include "cs_priv.h"
1919#include "utils.h"
2020
21+ static size_t SStream_remaining (SStream * ss )
22+ {
23+ assert (ss );
24+ if (ss -> index >= SSTREAM_BUF_LEN ) {
25+ ss -> index = SSTREAM_BUF_LEN - 1 ;
26+ ss -> buffer [ss -> index ] = '\0' ;
27+ return 0 ;
28+ }
29+ return SSTREAM_BUF_LEN - ss -> index - 1 ;
30+ }
31+
32+ static void SStream_concat_raw (SStream * ss , const char * s , size_t len )
33+ {
34+ size_t remaining = SStream_remaining (ss );
35+ if (len > remaining ) {
36+ len = remaining ;
37+ }
38+ if (len > 0 ) {
39+ memcpy (ss -> buffer + ss -> index , s , len );
40+ ss -> index += len ;
41+ }
42+ ss -> buffer [ss -> index ] = '\0' ;
43+ }
44+
45+ static void SStream_concat1_raw (SStream * ss , char c )
46+ {
47+ if (SStream_remaining (ss ) == 0 ) {
48+ return ;
49+ }
50+ ss -> buffer [ss -> index ] = c ;
51+ ss -> index ++ ;
52+ ss -> buffer [ss -> index ] = '\0' ;
53+ }
54+
55+ static void SStream_close_markup (SStream * ss )
56+ {
57+ if (ss -> markup_stream && ss -> prefixed_by_markup ) {
58+ SStream_concat1_raw (ss , '>' );
59+ }
60+ }
61+
2162void SStream_Init (SStream * ss )
2263{
2364 assert (ss );
@@ -177,19 +218,9 @@ void SStream_concat0(SStream *ss, const char *s)
177218 SSTREAM_RETURN_IF_CLOSED (ss );
178219 if (s [0 ] == '\0' )
179220 return ;
180- unsigned int len = (unsigned int )strlen (s );
181-
182- SSTREAM_OVERFLOW_CHECK (ss , len );
183221
184- memcpy (ss -> buffer + ss -> index , s , len );
185- ss -> index += len ;
186- ss -> buffer [ss -> index ] = '\0' ;
187- if (ss -> markup_stream && ss -> prefixed_by_markup ) {
188- SSTREAM_OVERFLOW_CHECK (ss , 1 );
189- ss -> buffer [ss -> index ] = '>' ;
190- ss -> index += 1 ;
191- ss -> buffer [ss -> index ] = '\0' ;
192- }
222+ SStream_concat_raw (ss , s , strlen (s ));
223+ SStream_close_markup (ss );
193224#else
194225 ss -> buffer [ss -> index ] = '\0' ;
195226#endif
@@ -206,16 +237,8 @@ void SStream_concat1(SStream *ss, const char c)
206237 if (c == '\0' )
207238 return ;
208239
209- SSTREAM_OVERFLOW_CHECK (ss , 1 );
210-
211- ss -> buffer [ss -> index ] = c ;
212- ss -> index ++ ;
213- ss -> buffer [ss -> index ] = '\0' ;
214- if (ss -> markup_stream && ss -> prefixed_by_markup ) {
215- SSTREAM_OVERFLOW_CHECK (ss , 1 );
216- ss -> buffer [ss -> index ] = '>' ;
217- ss -> index ++ ;
218- }
240+ SStream_concat1_raw (ss , c );
241+ SStream_close_markup (ss );
219242#else
220243 ss -> buffer [ss -> index ] = '\0' ;
221244#endif
@@ -231,21 +254,25 @@ void SStream_concat(SStream *ss, const char *fmt, ...)
231254 SSTREAM_RETURN_IF_CLOSED (ss );
232255 va_list ap ;
233256 int ret ;
257+ size_t remaining = SStream_remaining (ss );
258+ if (remaining == 0 ) {
259+ return ;
260+ }
234261
235262 va_start (ap , fmt );
236263 ret = cs_vsnprintf (ss -> buffer + ss -> index ,
237- sizeof ( ss -> buffer ) - ( ss -> index + 1 ) , fmt , ap );
264+ remaining + 1 , fmt , ap );
238265 va_end (ap );
239266 if (ret < 0 ) {
267+ ss -> buffer [ss -> index ] = '\0' ;
240268 return ;
241269 }
242- SSTREAM_OVERFLOW_CHECK (ss , ret );
243- ss -> index += ret ;
244- if (ss -> markup_stream && ss -> prefixed_by_markup ) {
245- SSTREAM_OVERFLOW_CHECK (ss , 1 );
246- ss -> buffer [ss -> index ] = '>' ;
247- ss -> index += 1 ;
270+ if ((size_t )ret > remaining ) {
271+ ss -> index += remaining ;
272+ } else {
273+ ss -> index += (size_t )ret ;
248274 }
275+ SStream_close_markup (ss );
249276#else
250277 ss -> buffer [ss -> index ] = '\0' ;
251278#endif
0 commit comments