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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 975 - (hide annotations) (download)
Sun Dec 17 00:59:40 2006 UTC (17 years, 4 months ago) by capela
File MIME type: text/plain
File size: 27480 byte(s)
* MIDI instrument mapping, second round, according to
  LSCP 1.2 draft document as of December 15, 2006.

* New client interface functions:
     lscp_set_channel_midi_map();
     lscp_add_midi_instrument_map();
     lscp_remove_midi_instrument_map();
     lscp_get_midi_instrument_maps();
     lscp_list_midi_instrument_maps();
     lscp_get_midi_instrument_map_name();
     lscp_set_midi_instrument_map_name();

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

  ViewVC Help
Powered by ViewVC