]> arthur.barton.de Git - netatalk.git/blob - libatalk/bstring/bstradd.c
Fix compiler diagnostics
[netatalk.git] / libatalk / bstring / bstradd.c
1 /*
2   $Id: bstradd.c,v 1.1.2.1 2010-02-01 10:56:08 franklahm Exp $
3   Copyright (c) 2010 Frank Lahm <franklahm@gmail.com>
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 */
15
16 /*!
17  * @file
18  * Additional functions for bstrlib
19  */
20
21 #include <stdio.h>
22 #include <stddef.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27
28 #include <atalk/bstrlib.h>
29
30 /* Optionally include a mechanism for debugging memory */
31
32 #if defined(MEMORY_DEBUG) || defined(BSTRLIB_MEMORY_DEBUG)
33 #include "memdbg.h"
34 #endif
35
36 #ifndef bstr__alloc
37 #define bstr__alloc(x) malloc (x)
38 #endif
39
40 #ifndef bstr__free
41 #define bstr__free(p) free (p)
42 #endif
43
44 #ifndef bstr__realloc
45 #define bstr__realloc(p,x) realloc ((p), (x))
46 #endif
47
48 #ifndef bstr__memcpy
49 #define bstr__memcpy(d,s,l) memcpy ((d), (s), (l))
50 #endif
51
52 #ifndef bstr__memmove
53 #define bstr__memmove(d,s,l) memmove ((d), (s), (l))
54 #endif
55
56 #ifndef bstr__memset
57 #define bstr__memset(d,c,l) memset ((d), (c), (l))
58 #endif
59
60 #ifndef bstr__memcmp
61 #define bstr__memcmp(d,c,l) memcmp ((d), (c), (l))
62 #endif
63
64 #ifndef bstr__memchr
65 #define bstr__memchr(s,c,l) memchr ((s), (c), (l))
66 #endif
67
68 /*************************************************************************
69  * Stuff for making bstrings referencing c-strings
70  ************************************************************************/
71
72 /*!
73  * @brief Create a bstring referencing "str"
74  *
75  * This is usefull if a well know code path uses string, often doing strlen on string.
76  * By converting to bstring which carries the strlen, the repeated computation can be avoided.
77  */
78 bstring brefcstr (char *str) {
79     bstring b;
80     size_t j;
81
82         if (str == NULL)
83         return NULL;
84         j = strlen(str);
85
86         b = (bstring)bstr__alloc(sizeof(struct tagbstring));
87         if (NULL == b)
88         return NULL;
89
90         b->slen = (int) j;
91     b->mlen = -1;
92     b->data = (unsigned char *)str;
93
94         return b;
95 }
96
97 /*!
98  * @brief Free up the bstring, WITHOUT freeing the pointed to c-string!
99  */
100 int bunrefcstr (bstring b) {
101         if (b == NULL || b->slen < 0 || b->mlen > 0 || b->data == NULL)
102                 return BSTR_ERR;
103
104         /* In case there is any stale usage, there is one more chance to 
105            notice this error. */
106
107         b->slen = -1;
108         b->mlen = -__LINE__;
109         b->data = NULL;
110
111         bstr__free (b);
112         return BSTR_OK;
113 }
114
115 /*************************************************************************
116  * stuff for bstrList
117  ************************************************************************/
118
119 /*!
120  * @brief Create an empty list with preallocated storage for at least 'min' members
121  */
122 struct bstrList *bstrListCreateMin(int min)
123 {
124     struct bstrList *sl = NULL;
125
126     if ((sl = bstrListCreate()) == NULL)
127         return NULL;
128
129     if ((bstrListAlloc(sl, min)) != BSTR_OK) {
130         bstrListDestroy(sl);
131         return NULL;
132     }
133
134     return sl;
135 }
136
137 /*!
138  * @brief Push a bstring to the end of a list
139  */
140 int bstrListPush(struct bstrList *sl, bstring bs)
141 {
142     if (sl->qty == sl->mlen) {
143         if ((bstrListAlloc(sl, sl->qty + 1)) != BSTR_OK)
144             return BSTR_ERR;
145     }
146
147     sl->entry[sl->qty] = bs;
148     sl->qty++;
149     return BSTR_OK;
150 }
151
152 /*!
153  * @brief Pop a bstring from the end of a list
154  */
155 bstring bstrListPop(struct bstrList *sl)
156 {
157     return NULL;
158 }
159
160 /*!
161  * @brief Inverse bjoin
162  */
163 bstring bjoinInv(const struct bstrList * bl, const_bstring sep) {
164     bstring b;
165     int i, j, c, v;
166
167     if (bl == NULL || bl->qty < 0)
168         return NULL;
169     if (sep != NULL && (sep->slen < 0 || sep->data == NULL))
170         return NULL;
171
172     for (i = 0, c = 1; i < bl->qty; i++) {
173         v = bl->entry[i]->slen;
174         if (v < 0)
175             return NULL;/* Invalid input */
176         c += v;
177         if (c < 0)
178             return NULL;/* Wrap around ?? */
179     }
180
181     if (sep != NULL)
182         c += (bl->qty - 1) * sep->slen;
183
184     b = (bstring) bstr__alloc (sizeof (struct tagbstring));
185     if (NULL == b)
186         return NULL; /* Out of memory */
187     b->data = (unsigned char *) bstr__alloc (c);
188     if (b->data == NULL) {
189         bstr__free (b);
190         return NULL;
191     }
192
193     b->mlen = c;
194     b->slen = c-1;
195
196     for (i = bl->qty - 1, c = 0, j = 0; i >= 0; i--, j++) {
197         if (j > 0 && sep != NULL) {
198             bstr__memcpy (b->data + c, sep->data, sep->slen);
199             c += sep->slen;
200         }
201         v = bl->entry[i]->slen;
202         bstr__memcpy (b->data + c, bl->entry[i]->data, v);
203         c += v;
204     }
205     b->data[c] = (unsigned char) '\0';
206     return b;
207 }