/[svn]/liblscp/trunk/src/common.c
ViewVC logotype

Contents of /liblscp/trunk/src/common.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 125 - (show annotations) (download)
Mon Jun 14 21:04:04 2004 UTC (19 years, 9 months ago) by capela
File MIME type: text/plain
File size: 9282 byte(s)
* Added support for the new LIST commands (draft v.08).

1 // client.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21 *****************************************************************************/
22
23 #include "common.h"
24
25 #include <ctype.h>
26
27
28 // Chunk size magic:
29 // LSCP_SPLIT_CHUNK1 = 2 ^ LSCP_SPLIT_CHUNK2
30 #define LSCP_SPLIT_CHUNK1 4
31 #define LSCP_SPLIT_CHUNK2 2
32 // Chunk size legal calculator.
33 #define LSCP_SPLIT_SIZE(n) ((((n) >> LSCP_SPLIT_CHUNK2) + 1) << LSCP_SPLIT_CHUNK2)
34
35
36 //-------------------------------------------------------------------------
37 // General utility functions.
38
39 // Trimming left spaces...
40 char *lscp_ltrim ( char *psz )
41 {
42 while (isspace(*psz))
43 psz++;
44 return psz;
45 }
46
47 // Unquote an in-split string.
48 char *lscp_unquote ( char **ppsz, int dup )
49 {
50 char chQuote;
51 char *psz = *ppsz;
52
53 while (isspace(*psz))
54 ++psz;
55 if (*psz == '\"' || *psz == '\'') {
56 chQuote = *psz++;
57 while (isspace(*psz))
58 ++psz;
59 if (dup)
60 psz = strdup(psz);
61 *ppsz = psz;
62 if (*ppsz) {
63 while (**ppsz && **ppsz != chQuote)
64 ++(*ppsz);
65 if (**ppsz) {
66 while (isspace(*(*ppsz - 1)) && *ppsz > psz)
67 --(*ppsz);
68 *(*ppsz)++ = (char) 0;
69 }
70 }
71 }
72 else if (dup) {
73 psz = strdup(psz);
74 *ppsz = psz;
75 }
76
77 return psz;
78 }
79
80
81 // Custom tokenizer.
82 char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )
83 {
84 char *pszToken;
85
86 if (pchBuffer == NULL)
87 pchBuffer = *ppch;
88
89 pchBuffer += strspn(pchBuffer, pszSeps);
90 if (*pchBuffer == '\0')
91 return NULL;
92
93 pszToken = pchBuffer;
94 pchBuffer = strpbrk(pszToken, pszSeps);
95 if (pchBuffer == NULL) {
96 *ppch = strchr(pszToken, '\0');
97 } else {
98 *pchBuffer = '\0';
99 *ppch = pchBuffer + 1;
100 while (**ppch && strchr(pszSeps, **ppch))
101 (*ppch)++;
102 }
103
104 return pszToken;
105 }
106
107
108 // Split a comma separated string into a null terminated array of strings.
109 char **lscp_szsplit_create ( const char *pszCsv, const char *pszSeps )
110 {
111 char *pszHead, *pch;
112 int iSize, i, j, cchSeps;
113 char **ppszSplit, **ppszNewSplit;
114
115 // Initial size is one chunk away.
116 iSize = LSCP_SPLIT_CHUNK1;
117 // Allocate and split...
118 ppszSplit = (char **) malloc(iSize * sizeof(char *));
119 if (ppszSplit == NULL)
120 return NULL;
121
122 // Make a copy of the original string.
123 i = 0;
124 pszHead = (char *) pszCsv;
125 if ((ppszSplit[i++] = lscp_unquote(&pszHead, 1)) == NULL) {
126 free(ppszSplit);
127 return NULL;
128 }
129
130 // Go on for it...
131 cchSeps = strlen(pszSeps);
132 while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {
133 // Pre-advance to next item.
134 pszHead = pch + cchSeps;
135 // Trim and null terminate current item.
136 while (isspace(*(pch - 1)) && pch > ppszSplit[0])
137 --pch;
138 *pch = (char) 0;
139 // Make it official.
140 ppszSplit[i++] = lscp_unquote(&pszHead, 0);
141 // Do we need to grow?
142 if (i >= iSize) {
143 // Yes, but only grow in chunks.
144 iSize += LSCP_SPLIT_CHUNK1;
145 // Allocate and copy to new split array.
146 ppszNewSplit = (char **) malloc(iSize * sizeof(char *));
147 if (ppszNewSplit) {
148 for (j = 0; j < i; j++)
149 ppszNewSplit[j] = ppszSplit[j];
150 free(ppszSplit);
151 ppszSplit = ppszNewSplit;
152 }
153 }
154 }
155
156 // NULL terminate split array.
157 for ( ; i < iSize; i++)
158 ppszSplit[i] = NULL;
159
160 return ppszSplit;
161 }
162
163
164 // Free allocated memory of a legal null terminated array of strings.
165 void lscp_szsplit_destroy ( char **ppszSplit )
166 {
167 // Our split string is always the first item, if any.
168 if (ppszSplit && ppszSplit[0])
169 free(ppszSplit[0]);
170 // Now free the array itself.
171 if (ppszSplit)
172 free(ppszSplit);
173 }
174
175
176 #ifdef LSCP_SZSPLIT_COUNT
177
178 // Return the number of items of a null terminated array of strings.
179 int lscp_szsplit_count ( char **ppszSplit )
180 {
181 int i = 0;
182 while (ppszSplit && ppszSplit[i])
183 i++;
184 return i;
185 }
186
187 // Return the allocated number of items of a splitted string array.
188 int lscp_szsplit_size ( char **ppszSplit )
189 {
190 return LSCP_SPLIT_SIZE(lscp_szsplit_count(ppszSplit));
191 }
192
193 #endif // LSCP_SZSPLIT_COUNT
194
195
196 // Split a comma separated string into a -1 terminated array of positive integers.
197 int *lscp_isplit_create ( const char *pszCsv, const char *pszSeps )
198 {
199 char *pchHead, *pch;
200 int iSize, i, j, cchSeps;
201 int *piSplit, *piNewSplit;
202
203 // Initial size is one chunk away.
204 iSize = LSCP_SPLIT_CHUNK1;
205 // Allocate and split...
206 piSplit = (int *) malloc(iSize * sizeof(int));
207 if (piSplit == NULL)
208 return NULL;
209
210 // Make a copy of the original string.
211 i = 0;
212 pchHead = (char *) pszCsv;
213 if ((piSplit[i++] = atoi(pchHead)) < 0) {
214 free(piSplit);
215 return NULL;
216 }
217
218 // Go on for it...
219 cchSeps = strlen(pszSeps);
220 while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {
221 // Pre-advance to next item.
222 pchHead = pch + cchSeps;
223 // Make it official.
224 piSplit[i++] = atoi(pchHead);
225 // Do we need to grow?
226 if (i >= iSize) {
227 // Yes, but only grow in chunks.
228 iSize += LSCP_SPLIT_CHUNK1;
229 // Allocate and copy to new split array.
230 piNewSplit = (int *) malloc(iSize * sizeof(int));
231 if (piNewSplit) {
232 for (j = 0; j < i; j++)
233 piNewSplit[j] = piSplit[j];
234 free(piSplit);
235 piSplit = piNewSplit;
236 }
237 }
238 }
239
240 // NULL terminate split array.
241 for ( ; i < iSize; i++)
242 piSplit[i] = -1;
243
244 return piSplit;
245 }
246
247
248 // Destroy a integer splitted array.
249 void lscp_isplit_destroy ( int *piSplit )
250 {
251 if (piSplit)
252 free(piSplit);
253 }
254
255
256 #ifdef LSCP_ISPLIT_COUNT
257
258 // Compute a string list valid item count.
259 int lscp_isplit_count ( int *piSplit )
260 {
261 int i = 0;
262 while (piSplit && piSplit[i] >= 0)
263 i++;
264 return i;
265 }
266
267 // Compute a string list size.
268 int lscp_isplit_size ( int *piSplit )
269 {
270 return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
271 }
272
273 #endif // LSCP_ISPLIT_COUNT
274
275
276 //-------------------------------------------------------------------------
277 // Engine info struct helper functions.
278
279 void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
280 {
281 pEngineInfo->description = NULL;
282 pEngineInfo->version = NULL;
283 }
284
285 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
286 {
287 if (pEngineInfo->description)
288 free(pEngineInfo->description);
289 if (pEngineInfo->version)
290 free(pEngineInfo->version);
291
292 lscp_engine_info_init(pEngineInfo);
293 }
294
295
296 //-------------------------------------------------------------------------
297 // Channel info struct helper functions.
298
299 void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
300 {
301 pChannelInfo->engine_name = NULL;
302 pChannelInfo->audio_device = 0;
303 pChannelInfo->audio_channels = 0;
304 pChannelInfo->audio_routing = NULL;
305 pChannelInfo->instrument_file = NULL;
306 pChannelInfo->instrument_nr = 0;
307 pChannelInfo->midi_device = 0;
308 pChannelInfo->midi_port = 0;
309 pChannelInfo->midi_channel = 0;
310 pChannelInfo->volume = 0.0;
311 }
312
313 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
314 {
315 if (pChannelInfo->engine_name)
316 free(pChannelInfo->engine_name);
317 if (pChannelInfo->audio_routing)
318 lscp_szsplit_destroy(pChannelInfo->audio_routing);
319 if (pChannelInfo->instrument_file)
320 free(pChannelInfo->instrument_file);
321
322 lscp_channel_info_init(pChannelInfo);
323 }
324
325
326 //-------------------------------------------------------------------------
327 // Driver info struct functions.
328
329 void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
330 {
331 pDriverInfo->description = NULL;
332 pDriverInfo->version = NULL;
333 pDriverInfo->parameters = NULL;
334 }
335
336 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
337 {
338 if (pDriverInfo->description)
339 free(pDriverInfo->description);
340 if (pDriverInfo->version)
341 free(pDriverInfo->version);
342 lscp_szsplit_destroy(pDriverInfo->parameters);
343
344 lscp_driver_info_init(pDriverInfo);
345 }
346
347
348 // end of common.c

  ViewVC Help
Powered by ViewVC