1 /* Copyright (c) 2003 Canna Project. All rights reserved.
2  *
3  * Permission to use, copy, modify, distribute and sell this software
4  * and its documentation for any purpose is hereby granted without
5  * fee, provided that the above copyright notice appear in all copies
6  * and that both that copyright notice and this permission notice
7  * appear in supporting documentation, and that the name of the
8  * author and contributors not be used in advertising or publicity
9  * pertaining to distribution of the software without specific, written
10  * prior permission.  The author and contributors no representations
11  * about the suitability of this software for any purpose.  It is
12  * provided "as is" without express or implied warranty.
13  *
14  * THE AUTHOR AND CONTRIBUTORS DISCLAIMS ALL WARRANTIES WITH REGARD TO
15  * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
16  * FITNESS, IN NO EVENT SHALL THE AUTHOR AND CONTRIBUTORS BE LIABLE FOR
17  * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
18  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
19  * CONTRACT, NEGLIGENCE OR OTHER TORTUOUS ACTION, ARISING OUT OF OR IN
20  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21  */
22 
23 #include "cannaconf.h"
24 #include "ccompat.h"
25 #include "RKindep/strops.h"
26 
27 RCSID("$Id: strops.c,v 1.2 2003/09/06 13:59:33 aida_s Exp $");
28 
29 void
RkiStrbuf_init(sb)30 RkiStrbuf_init(sb)
31 RkiStrbuf *sb;
32 {
33   sb->sb_buf = sb->sb_curr = sb->sb_end = NULL;
34 }
35 
36 void
RkiStrbuf_destroy(sb)37 RkiStrbuf_destroy(sb)
38 RkiStrbuf *sb;
39 {
40   free(sb->sb_buf);
41 }
42 
43 void
RkiStrbuf_clear(sb)44 RkiStrbuf_clear(sb)
45 RkiStrbuf *sb;
46 {
47   free(sb->sb_buf);
48   sb->sb_buf = sb->sb_curr = sb->sb_end = NULL;
49 }
50 
51 int
RkiStrbuf_reserve(sb,size)52 RkiStrbuf_reserve(sb, size)
53 RkiStrbuf *sb;
54 size_t size;
55 {
56   size_t oldsize = sb->sb_end - sb->sb_buf, newsize;
57   size_t used = sb->sb_curr - sb->sb_buf;
58   char *tmp;
59   if (used + size < oldsize)
60     return 0;
61   newsize = oldsize ? (oldsize * 2 + size) : (size < 20) ? 20 : size;
62   tmp = realloc(sb->sb_buf, newsize);
63   if (!tmp)
64     return -1;
65   sb->sb_buf = tmp;
66   sb->sb_curr = tmp + used;
67   sb->sb_end = tmp + newsize;
68   return 0;
69 }
70 
71 int
RkiStrbuf_term(sb)72 RkiStrbuf_term(sb)
73 RkiStrbuf *sb;
74 {
75   if (sb->sb_curr && !*sb->sb_curr)
76     return 0; /* already terminated */
77   if (RKI_STRBUF_RESERVE(sb, 1))
78     return -1;
79   *sb->sb_curr++ = '\0';
80   return 0;
81 }
82 
83 void
RkiStrbuf_pack(sb)84 RkiStrbuf_pack(sb)
85 RkiStrbuf *sb;
86 {
87   size_t used = sb->sb_curr - sb->sb_buf;
88   char *tmp;
89   tmp = realloc(sb->sb_buf, used);
90   if (!tmp)
91     return;
92   sb->sb_buf = tmp;
93   sb->sb_curr = sb->sb_end = tmp + used;
94 }
95 
96 int
RkiStrbuf_add(sb,src)97 RkiStrbuf_add(sb, src)
98 RkiStrbuf *sb;
99 const char *src;
100 {
101   return RkiStrbuf_addmem(sb, src, strlen(src));
102 }
103 
104 int
RkiStrbuf_addmem(sb,src,size)105 RkiStrbuf_addmem(sb, src, size)
106 RkiStrbuf *sb;
107 const void *src;
108 size_t size;
109 {
110   if (RKI_STRBUF_RESERVE(sb, size))
111     return -1;
112   memcpy(sb->sb_curr, src, size);
113   sb->sb_curr += size;
114   return 0;
115 }
116 
117 int
RkiStrbuf_addch(sb,ch)118 RkiStrbuf_addch(sb, ch)
119 RkiStrbuf *sb;
120 int ch;
121 {
122   return RKI_STRBUF_ADDCH(sb, ch);
123 }
124 
125 /* vim: set sw=2: */
126