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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 952 - (hide annotations) (download)
Tue Nov 28 22:46:32 2006 UTC (17 years, 4 months ago) by capela
File MIME type: text/plain
File size: 27295 byte(s)
Code cleanup; preparations for 0.4.1 release (hopefully).

1 capela 144 // common.c
2 capela 103 //
3     /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API
5 capela 869 Copyright (C) 2004-2006, rncbc aka Rui Nuno Capela. All rights reserved.
6 capela 103
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 capela 921 You should have received a copy of the GNU General Public License along
18     with this program; if not, write to the Free Software Foundation, Inc.,
19     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 capela 103
21     *****************************************************************************/
22    
23     #include "common.h"
24    
25     #include <ctype.h>
26    
27    
28 capela 158 // Split chunk size magic:
29     // LSCP_SPLIT_CHUNK1 := 2 ^ LSCP_SPLIT_CHUNK2
30 capela 103 #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 capela 132 // Local client request executive.
38 capela 103
39 capela 132 // Result buffer internal settler.
40     void lscp_client_set_result ( lscp_client_t *pClient, char *pszResult, int iErrno )
41     {
42 capela 952 if (pClient->pszResult)
43     free(pClient->pszResult);
44     pClient->pszResult = NULL;
45 capela 132
46 capela 952 pClient->iErrno = iErrno;
47 capela 132
48 capela 952 if (pszResult)
49     pClient->pszResult = strdup(lscp_ltrim(pszResult));
50 capela 132 }
51    
52 capela 253
53     // The common client receiver executive.
54     lscp_status_t lscp_client_recv ( lscp_client_t *pClient, char *pchBuffer, int *pcchBuffer, int iTimeout )
55 capela 132 {
56 capela 952 fd_set fds; // File descriptor list for select().
57     int fd, fdmax; // Maximum file descriptor number.
58     struct timeval tv; // For specifying a timeout value.
59     int iSelect; // Holds select return status.
60 capela 253
61 capela 952 lscp_status_t ret = LSCP_FAILED;
62 capela 253
63 capela 952 if (pClient == NULL)
64     return ret;
65 capela 253
66 capela 952 // Prepare for waiting on select...
67     fd = (int) pClient->cmd.sock;
68     FD_ZERO(&fds);
69     FD_SET((unsigned int) fd, &fds);
70     fdmax = fd;
71 capela 253
72 capela 952 // Use the timeout select feature...
73     if (iTimeout < 1)
74     iTimeout = pClient->iTimeout;
75     if (iTimeout >= 1000) {
76     tv.tv_sec = iTimeout / 1000;
77     iTimeout -= tv.tv_sec * 1000;
78     }
79     else tv.tv_sec = 0;
80     tv.tv_usec = iTimeout * 1000;
81 capela 253
82 capela 952 // Wait for event...
83     iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);
84     if (iSelect > 0 && FD_ISSET(fd, &fds)) {
85     // May recv now...
86     *pcchBuffer = recv(pClient->cmd.sock, pchBuffer, *pcchBuffer, 0);
87     if (*pcchBuffer > 0)
88     ret = LSCP_OK;
89     else if (*pcchBuffer < 0)
90     lscp_socket_perror("lscp_client_recv: recv");
91     else if (*pcchBuffer == 0) {
92     // Damn, server probably disconnected,
93     // we better free everything down here.
94     lscp_socket_agent_free(&(pClient->evt));
95     lscp_socket_agent_free(&(pClient->cmd));
96     // Fake a result message.
97     ret = LSCP_QUIT;
98     }
99     } // Check if select has timed out.
100     else if (iSelect == 0)
101     ret = LSCP_TIMEOUT;
102     else
103     lscp_socket_perror("lscp_client_recv: select");
104 capela 253
105 capela 952 return ret;
106 capela 253 }
107    
108    
109     // The main client requester call executive.
110 capela 948 lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery, int iResult )
111 capela 253 {
112 capela 952 int cchQuery;
113     char achBuffer[LSCP_BUFSIZ];
114     int cchBuffer;
115     const char *pszSeps = ":[]";
116     char *pszBuffer;
117     char *pszToken;
118     char *pch;
119     int iErrno;
120     char *pszResult;
121     int cchResult;
122    
123     lscp_status_t ret = LSCP_FAILED;
124    
125     if (pClient == NULL)
126     return ret;
127    
128     iErrno = -1;
129     cchResult = 0;
130     pszResult = NULL;
131     pszBuffer = NULL;
132    
133     // Check if command socket socket is still valid.
134     if (pClient->cmd.sock == INVALID_SOCKET) {
135     pszResult = "Connection closed or no longer valid";
136     lscp_client_set_result(pClient, pszResult, iErrno);
137     return ret;
138     }
139    
140     // Check if last transaction has timed out, in which case
141     // we'll retry wait and flush for some pending garbage...
142     if (pClient->iTimeoutCount > 0) {
143     // We'll hope to get rid of timeout trouble...
144     pClient->iTimeoutCount = 0;
145     cchBuffer = sizeof(achBuffer);
146     ret = lscp_client_recv(pClient, achBuffer, &cchBuffer, pClient->iTimeout);
147     if (ret != LSCP_OK) {
148     // Things seems to be unresolved. Fake a result message.
149     iErrno = (int) ret;
150     pszResult = "Failure during flush timeout operation";
151     lscp_client_set_result(pClient, pszResult, iErrno);
152     return ret;
153     }
154     }
155    
156     // Send data, and then, wait for the result...
157     cchQuery = strlen(pszQuery);
158     if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {
159     lscp_socket_perror("lscp_client_call: send");
160     pszResult = "Failure during send operation";
161     lscp_client_set_result(pClient, pszResult, iErrno);
162     return ret;
163     }
164    
165     // Keep receiving while result is not the expected one:
166     // single-line result (iResult = 0) : one single CRLF ends the receipt;
167     // multi-line result (iResult > 0) : one "." followed by a last CRLF;
168    
169     while (pszResult == NULL) {
170    
171     // Wait for receive event...
172     cchBuffer = sizeof(achBuffer) - 1;
173     ret = lscp_client_recv(pClient, achBuffer, &cchBuffer, pClient->iTimeout);
174    
175     switch (ret) {
176    
177     case LSCP_OK:
178     // Always force the result to be null terminated.
179     achBuffer[cchBuffer] = (char) 0;
180     // Check if the response it's an error or warning message.
181     if (strncasecmp(achBuffer, "WRN:", 4) == 0)
182     ret = LSCP_WARNING;
183     else if (strncasecmp(achBuffer, "ERR:", 4) == 0)
184     ret = LSCP_ERROR;
185     // So we got a result...
186     if (ret == LSCP_OK) {
187     // Reset errno in case of success.
188     iErrno = 0;
189     // Is it a special successful response?
190     if (iResult < 1 && strncasecmp(achBuffer, "OK[", 3) == 0) {
191     // Parse the OK message, get the return string under brackets...
192     pszToken = lscp_strtok(achBuffer, pszSeps, &(pch));
193     if (pszToken)
194     pszResult = lscp_strtok(NULL, pszSeps, &(pch));
195     } else {
196     // It can be specially long response...
197     cchResult += sizeof(achBuffer);
198     pszResult = malloc(cchResult + 1);
199     pszResult[0] = (char) 0;
200     if (pszBuffer) {
201     strcat(pszResult, pszBuffer);
202     free(pszBuffer);
203     }
204     strcat(pszResult, achBuffer);
205     pszBuffer = pszResult;
206     pszResult = NULL;
207     // Check for correct end-of-transmission...
208     // Depending whether its single or multi-line we'll
209     // flag end-of-transmission...
210     cchBuffer = strlen(pszBuffer);
211     if (cchBuffer >= 2
212     && pszBuffer[cchBuffer - 1] == '\n'
213     && pszBuffer[cchBuffer - 2] == '\r'
214     && (iResult < 1 || (cchBuffer >= 3
215     && pszBuffer[cchBuffer - 3] == '.'))) {
216     // Get rid of the trailing dot and CRLF anyway...
217     while (cchBuffer > 0 && (
218     pszBuffer[cchBuffer - 1] == '\r' ||
219     pszBuffer[cchBuffer - 1] == '\n' ||
220     pszBuffer[cchBuffer - 1] == '.'))
221     cchBuffer--;
222     pszBuffer[cchBuffer] = (char) 0;
223     pszResult = pszBuffer;
224     }
225     }
226     // The result string is now set to the command response, if any.
227     } else {
228     // Parse the error/warning message, skip first colon...
229     pszToken = lscp_strtok(achBuffer, pszSeps, &(pch));
230     if (pszToken) {
231     // Get the error number...
232     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
233     if (pszToken) {
234     iErrno = atoi(pszToken);
235     // And make the message text our final result.
236     pszResult = lscp_strtok(NULL, pszSeps, &(pch));
237     }
238     }
239     // The result string is set to the error/warning message text.
240     }
241     break;
242    
243     case LSCP_TIMEOUT:
244     // We have trouble...
245     pClient->iTimeoutCount++;
246     // Fake a result message.
247     pszResult = "Timeout during receive operation";
248     iErrno = (int) ret;
249     break;
250    
251     case LSCP_QUIT:
252     // Fake a result message.
253     pszResult = "Server terminated the connection";
254     iErrno = (int) ret;
255     break;
256    
257     case LSCP_FAILED:
258     default:
259     // What's down?
260     pszResult = "Failure during receive operation";
261     break;
262     }
263     }
264    
265     // Make the result official...
266     lscp_client_set_result(pClient, pszResult, iErrno);
267    
268     // Free long-buffer, if any...
269     if (pszBuffer)
270     free(pszBuffer);
271    
272     return ret;
273 capela 132 }
274    
275    
276     //-------------------------------------------------------------------------
277     // Other general utility functions.
278    
279 capela 103 // Trimming left spaces...
280     char *lscp_ltrim ( char *psz )
281     {
282 capela 952 while (isspace(*psz))
283     psz++;
284     return psz;
285 capela 103 }
286    
287     // Unquote an in-split string.
288     char *lscp_unquote ( char **ppsz, int dup )
289     {
290 capela 952 char chQuote;
291     char *psz = *ppsz;
292 capela 103
293 capela 952 while (isspace(*psz))
294     ++psz;
295     if (*psz == '\"' || *psz == '\'') {
296     chQuote = *psz++;
297     while (isspace(*psz))
298     ++psz;
299     if (dup)
300     psz = strdup(psz);
301     *ppsz = psz;
302     if (*ppsz) {
303     while (**ppsz && **ppsz != chQuote)
304     ++(*ppsz);
305     if (**ppsz) {
306     while (isspace(*(*ppsz - 1)) && *ppsz > psz)
307     --(*ppsz);
308     *(*ppsz)++ = (char) 0;
309     }
310     }
311     }
312     else if (dup) {
313     psz = strdup(psz);
314     *ppsz = psz;
315     }
316 capela 103
317 capela 952 return psz;
318 capela 103 }
319    
320 capela 180 // Unquote and make a duplicate of an in-split string.
321     void lscp_unquote_dup ( char **ppszDst, char **ppszSrc )
322     {
323 capela 952 // Free desteny string, if already there.
324     if (*ppszDst)
325     free(*ppszDst);
326     *ppszDst = NULL;
327     // Unquote and duplicate.
328     if (*ppszSrc)
329     *ppszDst = lscp_unquote(ppszSrc, 1);
330 capela 180 }
331 capela 103
332 capela 180
333 capela 103 // Custom tokenizer.
334     char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )
335     {
336 capela 952 char *pszToken;
337 capela 103
338 capela 952 if (pchBuffer == NULL)
339     pchBuffer = *ppch;
340 capela 103
341 capela 952 pchBuffer += strspn(pchBuffer, pszSeps);
342     if (*pchBuffer == '\0')
343     return NULL;
344 capela 103
345 capela 952 pszToken = pchBuffer;
346     pchBuffer = strpbrk(pszToken, pszSeps);
347     if (pchBuffer == NULL) {
348     *ppch = strchr(pszToken, '\0');
349     } else {
350     *pchBuffer = '\0';
351     *ppch = pchBuffer + 1;
352     while (**ppch && strchr(pszSeps, **ppch))
353     (*ppch)++;
354     }
355 capela 103
356 capela 952 return pszToken;
357 capela 103 }
358    
359    
360     // Split a comma separated string into a null terminated array of strings.
361     char **lscp_szsplit_create ( const char *pszCsv, const char *pszSeps )
362     {
363 capela 952 char *pszHead, *pch;
364     int iSize, i, j, cchSeps;
365     char **ppszSplit, **ppszNewSplit;
366 capela 103
367 capela 952 // Initial size is one chunk away.
368     iSize = LSCP_SPLIT_CHUNK1;
369     // Allocate and split...
370     ppszSplit = (char **) malloc(iSize * sizeof(char *));
371     if (ppszSplit == NULL)
372     return NULL;
373 capela 103
374 capela 952 // Make a copy of the original string.
375     i = 0;
376     pszHead = (char *) pszCsv;
377     if ((ppszSplit[i++] = lscp_unquote(&pszHead, 1)) == NULL) {
378     free(ppszSplit);
379     return NULL;
380     }
381 capela 103
382 capela 952 // Go on for it...
383     cchSeps = strlen(pszSeps);
384     while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {
385     // Pre-advance to next item.
386     pszHead = pch + cchSeps;
387     // Trim and null terminate current item.
388     while (isspace(*(pch - 1)) && pch > ppszSplit[0])
389     --pch;
390     *pch = (char) 0;
391     // Make it official.
392     ppszSplit[i] = lscp_unquote(&pszHead, 0);
393     // Do we need to grow?
394     if (++i >= iSize) {
395     // Yes, but only grow in chunks.
396     iSize += LSCP_SPLIT_CHUNK1;
397     // Allocate and copy to new split array.
398     ppszNewSplit = (char **) malloc(iSize * sizeof(char *));
399     if (ppszNewSplit) {
400     for (j = 0; j < i; j++)
401     ppszNewSplit[j] = ppszSplit[j];
402     free(ppszSplit);
403     ppszSplit = ppszNewSplit;
404     }
405     }
406     }
407 capela 103
408 capela 952 // NULL terminate split array.
409     for ( ; i < iSize; i++)
410     ppszSplit[i] = NULL;
411 capela 103
412 capela 952 return ppszSplit;
413 capela 103 }
414    
415    
416     // Free allocated memory of a legal null terminated array of strings.
417     void lscp_szsplit_destroy ( char **ppszSplit )
418     {
419 capela 952 // Our split string is always the first item, if any.
420     if (ppszSplit && ppszSplit[0])
421     free(ppszSplit[0]);
422     // Now free the array itself.
423     if (ppszSplit)
424     free(ppszSplit);
425 capela 103 }
426    
427    
428     #ifdef LSCP_SZSPLIT_COUNT
429    
430     // Return the number of items of a null terminated array of strings.
431     int lscp_szsplit_count ( char **ppszSplit )
432     {
433 capela 952 int i = 0;
434     while (ppszSplit && ppszSplit[i])
435     i++;
436     return i;
437 capela 103 }
438    
439     // Return the allocated number of items of a splitted string array.
440     int lscp_szsplit_size ( char **ppszSplit )
441     {
442 capela 952 return LSCP_SPLIT_SIZE(lscp_szsplit_count(ppszSplit));
443 capela 103 }
444    
445     #endif // LSCP_SZSPLIT_COUNT
446    
447    
448 capela 125 // Split a comma separated string into a -1 terminated array of positive integers.
449     int *lscp_isplit_create ( const char *pszCsv, const char *pszSeps )
450     {
451 capela 952 char *pchHead, *pch;
452     int iSize, i, j, cchSeps;
453     int *piSplit, *piNewSplit;
454 capela 125
455 capela 952 // Get it clean first.
456     pchHead = lscp_ltrim((char *) pszCsv);
457     if (*pchHead == (char) 0)
458     return NULL;
459 capela 415
460 capela 952 // Initial size is one chunk away.
461     iSize = LSCP_SPLIT_CHUNK1;
462     // Allocate and split...
463     piSplit = (int *) malloc(iSize * sizeof(int));
464     if (piSplit == NULL)
465     return NULL;
466 capela 125
467 capela 952 // Make a copy of the original string.
468     i = 0;
469     if ((piSplit[i++] = atoi(pchHead)) < 0) {
470     free(piSplit);
471     return NULL;
472     }
473 capela 125
474 capela 952 // Go on for it...
475     cchSeps = strlen(pszSeps);
476     while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {
477     // Pre-advance to next item.
478     pchHead = pch + cchSeps;
479     // Make it official.
480     piSplit[i] = atoi(pchHead);
481     // Do we need to grow?
482     if (++i >= iSize) {
483     // Yes, but only grow in chunks.
484     iSize += LSCP_SPLIT_CHUNK1;
485     // Allocate and copy to new split array.
486     piNewSplit = (int *) malloc(iSize * sizeof(int));
487     if (piNewSplit) {
488     for (j = 0; j < i; j++)
489     piNewSplit[j] = piSplit[j];
490     free(piSplit);
491     piSplit = piNewSplit;
492     }
493     }
494     }
495 capela 125
496 capela 952 // NULL terminate split array.
497     for ( ; i < iSize; i++)
498     piSplit[i] = -1;
499 capela 125
500 capela 952 return piSplit;
501 capela 125 }
502    
503    
504     // Destroy a integer splitted array.
505     void lscp_isplit_destroy ( int *piSplit )
506     {
507 capela 952 if (piSplit)
508     free(piSplit);
509 capela 125 }
510    
511    
512     #ifdef LSCP_ISPLIT_COUNT
513    
514     // Compute a string list valid item count.
515     int lscp_isplit_count ( int *piSplit )
516     {
517 capela 952 int i = 0;
518     while (piSplit && piSplit[i] >= 0)
519     i++;
520     return i;
521 capela 125 }
522    
523     // Compute a string list size.
524     int lscp_isplit_size ( int *piSplit )
525     {
526 capela 952 return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
527 capela 125 }
528    
529     #endif // LSCP_ISPLIT_COUNT
530    
531    
532 capela 158 // Split a string into a null terminated array of parameter items.
533     lscp_param_t *lscp_psplit_create ( const char *pszCsv, const char *pszSeps1, const char *pszSeps2 )
534     {
535 capela 952 char *pszHead, *pch;
536     int iSize, i, j, cchSeps1, cchSeps2;
537     lscp_param_t *ppSplit, *ppNewSplit;
538 capela 158
539 capela 952 pszHead = strdup(pszCsv);
540     if (pszHead == NULL)
541     return NULL;
542 capela 158
543 capela 952 iSize = LSCP_SPLIT_CHUNK1;
544     ppSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
545     if (ppSplit == NULL) {
546     free(pszHead);
547     return NULL;
548     }
549 capela 158
550 capela 952 cchSeps1 = strlen(pszSeps1);
551     cchSeps2 = strlen(pszSeps2);
552 capela 158
553 capela 952 i = 0;
554     while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {
555     ppSplit[i].key = pszHead;
556     pszHead = pch + cchSeps1;
557     *pch = (char) 0;
558     ppSplit[i].value = lscp_unquote(&pszHead, 0);
559     if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {
560     pszHead = pch + cchSeps2;
561     *pch = (char) 0;
562     }
563     if (++i >= iSize) {
564     iSize += LSCP_SPLIT_CHUNK1;
565     ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
566     if (ppNewSplit) {
567     for (j = 0; j < i; j++) {
568     ppNewSplit[j].key = ppSplit[j].key;
569     ppNewSplit[j].value = ppSplit[j].value;
570     }
571     free(ppSplit);
572     ppSplit = ppNewSplit;
573     }
574     }
575     }
576 capela 158
577 capela 952 if (i < 1)
578     free(pszHead);
579 capela 158
580 capela 952 for ( ; i < iSize; i++) {
581     ppSplit[i].key = NULL;
582     ppSplit[i].value = NULL;
583     }
584 capela 158
585 capela 952 return ppSplit;
586 capela 158 }
587    
588    
589     // Destroy a parameter list array.
590     void lscp_psplit_destroy ( lscp_param_t *ppSplit )
591     {
592 capela 952 if (ppSplit && ppSplit[0].key)
593     free(ppSplit[0].key);
594     if (ppSplit)
595     free(ppSplit);
596 capela 158 }
597    
598    
599     #ifdef LSCP_PSPLIT_COUNT
600    
601     // Compute a parameter list valid item count.
602     int lscp_psplit_count ( lscp_param_t *ppSplit )
603     {
604 capela 952 int i = 0;
605     while (ppSplit && ppSplit[i].key)
606     i++;
607     return i;
608 capela 158 }
609    
610     // Compute a parameter list size.
611     int lscp_psplit_size ( lscp_param_t *ppSplit )
612     {
613 capela 952 return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));
614 capela 158 }
615    
616     #endif // LSCP_PSPLIT_COUNT
617    
618    
619 capela 171 // Allocate a parameter list, optionally copying an existing one.
620     void lscp_plist_alloc (lscp_param_t **ppList)
621     {
622 capela 952 lscp_param_t *pParams;
623     int iSize, i;
624 capela 171
625 capela 952 if (ppList) {
626     iSize = LSCP_SPLIT_CHUNK1;
627     pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
628     if (pParams) {
629     for (i = 0 ; i < iSize; i++) {
630     pParams[i].key = NULL;
631     pParams[i].value = NULL;
632     }
633     }
634     *ppList = pParams;
635     }
636 capela 171 }
637    
638    
639     // Destroy a parameter list, including all it's contents.
640     void lscp_plist_free ( lscp_param_t **ppList )
641     {
642 capela 952 lscp_param_t *pParams;
643     int i;
644 capela 415
645 capela 952 if (ppList) {
646     if (*ppList) {
647     pParams = *ppList;
648     for (i = 0; pParams && pParams[i].key; i++) {
649     free(pParams[i].key);
650     free(pParams[i].value);
651     }
652     free(pParams);
653     }
654     *ppList = NULL;
655     }
656 capela 171 }
657    
658    
659     // Add an item to a parameter list, growing it as fit.
660     void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue )
661     {
662 capela 952 lscp_param_t *pParams;
663     lscp_param_t *pNewParams;
664     int iSize, iNewSize;
665     int i = 0;
666 capela 415
667 capela 952 if (ppList && *ppList) {
668     pParams = *ppList;
669     while (pParams[i].key) {
670     if (strcasecmp(pParams[i].key, pszKey) == 0) {
671     if (pParams[i].value)
672     free(pParams[i].value);
673     pParams[i].value = strdup(pszValue);
674     return;
675     }
676     i++;
677     }
678     iSize = LSCP_SPLIT_SIZE(i);
679     pParams[i].key = strdup(pszKey);
680     pParams[i].value = strdup(pszValue);
681     if (++i >= iSize) {
682     iNewSize = iSize + LSCP_SPLIT_CHUNK1;
683     pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t));
684     for (i = 0; i < iSize; i++) {
685     pNewParams[i].key = pParams[i].key;
686     pNewParams[i].value = pParams[i].value;
687     }
688     for ( ; i < iNewSize; i++) {
689     pNewParams[i].key = NULL;
690     pNewParams[i].value = NULL;
691     }
692     free(pParams);
693     *ppList = pNewParams;
694     }
695     }
696 capela 171 }
697    
698 capela 180 #ifdef LSCP_PLIST_COUNT
699 capela 171
700     // Compute a parameter list valid item count.
701     int lscp_plist_count ( lscp_param_t **ppList )
702     {
703 capela 952 lscp_param_t *pParams;
704     int i = 0;
705     if (ppList && *ppList) {
706     pParams = *ppList;
707     while (pParams[i].key)
708     i++;
709     }
710     return i;
711 capela 171 }
712    
713     // Compute the legal parameter list size.
714     int lscp_plist_size ( lscp_param_t **ppList )
715     {
716 capela 952 return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));
717 capela 171 }
718    
719 capela 180 #endif // LSCP_PLIST_COUNT
720 capela 171
721    
722 capela 948 // Split a string into an array of MIDI instrument triplets.
723     lscp_midi_instrument_t *lscp_midi_instruments_create ( const char *pszCsv )
724     {
725 capela 952 char *pchHead, *pch;
726     int iSize, i, j, k;
727     lscp_midi_instrument_t *pInstrs;
728     lscp_midi_instrument_t *pNewInstrs;
729    
730     // Get it clean first.
731     pchHead = lscp_ltrim((char *) pszCsv);
732     if (*pchHead == (char) 0)
733     return NULL;
734    
735     // Initial size is one chunk away.
736     iSize = LSCP_SPLIT_CHUNK1;
737     // Allocate and split...
738     pInstrs = (lscp_midi_instrument_t *) malloc(iSize * sizeof(lscp_midi_instrument_t));
739     if (pInstrs == NULL)
740     return NULL;
741    
742     // Go on for it...
743     i = 0;
744     k = 0;
745    
746     while ((pch = strpbrk(pchHead, "{,}")) != NULL) {
747     // Pre-advance to next item.
748     switch (*pch) {
749     case '{':
750     pchHead = pch + 1;
751     if (k == 0) {
752     pInstrs[i].bank_msb = atoi(pchHead);
753     k++;
754     }
755     break;
756     case ',':
757     pchHead = pch + 1;
758     if (k == 1) {
759     pInstrs[i].bank_lsb = atoi(pchHead);
760     k++;
761     }
762     else
763     if (k == 2) {
764     pInstrs[i].program = atoi(pchHead);
765     k++;
766     }
767     break;
768     case '}':
769     pchHead = pch + 1;
770     k = 0;
771     break;
772     }
773     // Do we need to grow?
774     if (k == 3 && ++i >= iSize) {
775     // Yes, but only grow in chunks.
776     iSize += LSCP_SPLIT_CHUNK1;
777     // Allocate and copy to new split array.
778     pNewInstrs = (lscp_midi_instrument_t *) malloc(iSize * sizeof(lscp_midi_instrument_t));
779     if (pNewInstrs) {
780     for (j = 0; j < i; j++) {
781     pNewInstrs[j].bank_msb = pInstrs[j].bank_msb;
782     pNewInstrs[j].bank_lsb = pInstrs[j].bank_lsb;
783     pNewInstrs[j].program = pInstrs[j].program;
784     }
785     free(pInstrs);
786     pInstrs = pNewInstrs;
787     }
788     }
789     }
790    
791     // Special terminate split array.
792     for ( ; i < iSize; i++) {
793     pInstrs[i].bank_msb = -1;
794     pInstrs[i].bank_lsb = -1;
795     pInstrs[i].program = -1;
796     }
797    
798     return pInstrs;
799 capela 948 }
800    
801     // Destroy a MIDI instrument triplet array.
802     void lscp_midi_instruments_destroy ( lscp_midi_instrument_t *pInstrs )
803     {
804 capela 952 if (pInstrs)
805     free(pInstrs);
806 capela 948 }
807    
808     #ifdef LSCP_MIDI_INSTRUMENTS_COUNT
809    
810     // Compute a MIDI instrument array item count.
811     int lscp_midi_instruments_count ( lscp_midi_instrument_t *pInstrs )
812     {
813 capela 952 int i = 0;
814     while (pInstrs && pInstrs[i].program >= 0)
815     i++;
816     return i;
817 capela 948 }
818    
819     // Compute a MIDI instrument array size.
820     int lscp_midi_instruments_size ( lscp_midi_instrument_t *pInstrs )
821     {
822 capela 952 return LSCP_SPLIT_SIZE(lscp_midi_instruments_count(pInstrs));
823 capela 948 }
824    
825     #endif // LSCP_MIDI_INSTRUMENTS_COUNT
826    
827    
828 capela 103 //-------------------------------------------------------------------------
829 capela 564 // Server info struct helper functions.
830    
831     void lscp_server_info_init ( lscp_server_info_t *pServerInfo )
832     {
833 capela 952 pServerInfo->description = NULL;
834     pServerInfo->version = NULL;
835 capela 564 }
836    
837     void lscp_server_info_free ( lscp_server_info_t *pServerInfo )
838     {
839 capela 952 if (pServerInfo->description)
840     free(pServerInfo->description);
841     if (pServerInfo->version)
842     free(pServerInfo->version);
843 capela 564 }
844    
845     void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )
846     {
847 capela 952 lscp_server_info_free(pServerInfo);
848     lscp_server_info_init(pServerInfo);
849 capela 564 }
850    
851    
852     //-------------------------------------------------------------------------
853 capela 103 // Engine info struct helper functions.
854    
855     void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
856     {
857 capela 952 pEngineInfo->description = NULL;
858     pEngineInfo->version = NULL;
859 capela 103 }
860    
861 capela 179 void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
862 capela 103 {
863 capela 952 if (pEngineInfo->description)
864     free(pEngineInfo->description);
865     if (pEngineInfo->version)
866     free(pEngineInfo->version);
867 capela 179 }
868 capela 103
869 capela 179 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
870     {
871 capela 952 lscp_engine_info_free(pEngineInfo);
872     lscp_engine_info_init(pEngineInfo);
873 capela 103 }
874    
875    
876     //-------------------------------------------------------------------------
877     // Channel info struct helper functions.
878    
879     void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
880     {
881 capela 952 pChannelInfo->engine_name = NULL;
882     pChannelInfo->audio_device = 0;
883     pChannelInfo->audio_channels = 0;
884     pChannelInfo->audio_routing = NULL;
885     pChannelInfo->instrument_file = NULL;
886     pChannelInfo->instrument_nr = 0;
887     pChannelInfo->instrument_name = NULL;
888     pChannelInfo->instrument_status = 0;
889     pChannelInfo->midi_device = 0;
890     pChannelInfo->midi_port = 0;
891     pChannelInfo->midi_channel = 0;
892     pChannelInfo->volume = 0.0;
893     pChannelInfo->mute = 0;
894     pChannelInfo->solo = 0;
895 capela 103 }
896    
897 capela 179 void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
898 capela 103 {
899 capela 952 if (pChannelInfo->engine_name)
900     free(pChannelInfo->engine_name);
901     if (pChannelInfo->audio_routing)
902     lscp_szsplit_destroy(pChannelInfo->audio_routing);
903     if (pChannelInfo->instrument_file)
904     free(pChannelInfo->instrument_file);
905     if (pChannelInfo->instrument_name)
906     free(pChannelInfo->instrument_name);
907 capela 179 }
908 capela 103
909 capela 179 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
910     {
911 capela 952 lscp_channel_info_free(pChannelInfo);
912     lscp_channel_info_init(pChannelInfo);
913 capela 103 }
914    
915    
916     //-------------------------------------------------------------------------
917     // Driver info struct functions.
918    
919     void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
920     {
921 capela 952 pDriverInfo->description = NULL;
922     pDriverInfo->version = NULL;
923     pDriverInfo->parameters = NULL;
924 capela 103 }
925    
926 capela 179 void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
927 capela 103 {
928 capela 952 if (pDriverInfo->description)
929     free(pDriverInfo->description);
930     if (pDriverInfo->version)
931     free(pDriverInfo->version);
932     lscp_szsplit_destroy(pDriverInfo->parameters);
933 capela 179 }
934 capela 103
935 capela 179 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
936     {
937 capela 952 lscp_driver_info_free(pDriverInfo);
938     lscp_driver_info_init(pDriverInfo);
939 capela 103 }
940    
941    
942 capela 163 //-------------------------------------------------------------------------
943 capela 171 // Device info struct functions.
944    
945     void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
946     {
947 capela 952 pDeviceInfo->driver = NULL;
948     lscp_plist_alloc(&(pDeviceInfo->params));
949 capela 171 }
950    
951 capela 179 void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
952 capela 171 {
953 capela 952 if (pDeviceInfo->driver)
954     free(pDeviceInfo->driver);
955     lscp_plist_free(&(pDeviceInfo->params));
956 capela 179 }
957 capela 171
958 capela 179 void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
959     {
960 capela 952 lscp_device_info_free(pDeviceInfo);
961     lscp_device_info_init(pDeviceInfo);
962 capela 171 }
963    
964    
965     //-------------------------------------------------------------------------
966     // Device channel/port info struct functions.
967    
968     void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
969     {
970 capela 952 pDevicePortInfo->name = NULL;
971     lscp_plist_alloc(&(pDevicePortInfo->params));
972 capela 171 }
973    
974 capela 179 void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
975 capela 171 {
976 capela 952 if (pDevicePortInfo->name)
977     free(pDevicePortInfo->name);
978     lscp_plist_free(&(pDevicePortInfo->params));
979 capela 179 }
980 capela 171
981 capela 179 void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
982     {
983 capela 952 lscp_device_port_info_free(pDevicePortInfo);
984     lscp_device_port_info_init(pDevicePortInfo);
985 capela 171 }
986    
987    
988     //-------------------------------------------------------------------------
989 capela 163 // Parameter struct helper functions.
990    
991     void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
992     {
993 capela 952 pParamInfo->type = LSCP_TYPE_NONE;
994     pParamInfo->description = NULL;
995     pParamInfo->mandatory = 0;
996     pParamInfo->fix = 0;
997     pParamInfo->multiplicity = 0;
998     pParamInfo->depends = NULL;
999     pParamInfo->defaultv = NULL;
1000     pParamInfo->range_min = NULL;
1001     pParamInfo->range_max = NULL;
1002     pParamInfo->possibilities = NULL;
1003 capela 163 }
1004    
1005 capela 179 void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
1006 capela 163 {
1007 capela 952 if (pParamInfo->description)
1008     free(pParamInfo->description);
1009     lscp_szsplit_destroy(pParamInfo->depends);
1010     if (pParamInfo->defaultv)
1011     free(pParamInfo->defaultv);
1012     if (pParamInfo->range_min)
1013     free(pParamInfo->range_min);
1014     if (pParamInfo->range_max)
1015     free(pParamInfo->range_max);
1016     lscp_szsplit_destroy(pParamInfo->possibilities);
1017 capela 179 }
1018    
1019     void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
1020     {
1021 capela 952 lscp_param_info_free(pParamInfo);
1022     lscp_param_info_init(pParamInfo);
1023 capela 163 }
1024    
1025    
1026     //-------------------------------------------------------------------------
1027 capela 171 // Concatenate a parameter list (key='value'...) into a string,
1028     // appending a crlf terminator.
1029 capela 163
1030     int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
1031     {
1032 capela 952 int cchBuffer, cchParam, i;
1033 capela 163
1034 capela 952 if (pszBuffer == NULL)
1035     return 0;
1036 capela 163
1037 capela 952 cchBuffer = strlen(pszBuffer);
1038     for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
1039     cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
1040     if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
1041     sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
1042     cchBuffer += cchParam;
1043     }
1044     }
1045    
1046     if (cchBuffer + 2 < cchMaxBuffer) {
1047     pszBuffer[cchBuffer++] = '\r';
1048     pszBuffer[cchBuffer++] = '\n';
1049     pszBuffer[cchBuffer ] = (char) 0;
1050     }
1051    
1052     return cchBuffer;
1053 capela 163 }
1054    
1055    
1056 capela 946 //-------------------------------------------------------------------------
1057     // MIDI instrument info struct helper functions.
1058    
1059     void lscp_midi_instrument_info_init ( lscp_midi_instrument_info_t *pInstrInfo )
1060     {
1061 capela 952 pInstrInfo->name = NULL;
1062     pInstrInfo->engine_name = NULL;
1063     pInstrInfo->instrument_file = NULL;
1064     pInstrInfo->instrument_nr = 0;
1065     pInstrInfo->instrument_name = NULL;
1066     pInstrInfo->load_mode = LSCP_LOAD_DEFAULT;
1067     pInstrInfo->volume = 0.0;
1068 capela 946 }
1069    
1070     void lscp_midi_instrument_info_free ( lscp_midi_instrument_info_t *pInstrInfo )
1071     {
1072 capela 952 if (pInstrInfo->name)
1073     free(pInstrInfo->name);
1074     if (pInstrInfo->engine_name)
1075     free(pInstrInfo->engine_name);
1076     if (pInstrInfo->instrument_file)
1077     free(pInstrInfo->instrument_file);
1078     if (pInstrInfo->instrument_name)
1079     free(pInstrInfo->instrument_name);
1080 capela 946 }
1081    
1082     void lscp_midi_instrument_info_reset ( lscp_midi_instrument_info_t *pInstrInfo )
1083     {
1084 capela 952 lscp_midi_instrument_info_free(pInstrInfo);
1085     lscp_midi_instrument_info_init(pInstrInfo);
1086 capela 946 }
1087    
1088    
1089 capela 103 // end of common.c

  ViewVC Help
Powered by ViewVC