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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 948 - (hide annotations) (download)
Tue Nov 28 15:31:20 2006 UTC (17 years, 4 months ago) by capela
File MIME type: text/plain
File size: 31618 byte(s)
* Fixed some compilation warnings due to suspicious type
  casting and unsused header macros.

* Changed deprecated copyright attribute to license
  and added ldconfig to post-(un)install steps
  to liblscp.spec (RPM).

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

  ViewVC Help
Powered by ViewVC