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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 625 - (show annotations) (download)
Thu Jun 9 15:55:49 2005 UTC (13 years ago) by capela
File MIME type: text/plain
File size: 25433 byte(s)
* Fixed an off-by-one timeout quirk, that has been a real
  showstopper on Mac OS X at least, which is incidental
  to qsampler's default timeout setting of 1000 msecs,
  giving up systematically on select() due to "Invalid
  argument" (EINVAL).

1 // common.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2005, rncbc aka Rui Nuno Capela. All rights reserved.
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
21 *****************************************************************************/
22
23 #include "common.h"
24
25 #include <ctype.h>
26
27
28 // Split chunk size magic:
29 // LSCP_SPLIT_CHUNK1 := 2 ^ LSCP_SPLIT_CHUNK2
30 #define LSCP_SPLIT_CHUNK1 4
31 #define LSCP_SPLIT_CHUNK2 2
32 // Chunk size legal calculator.
33 #define LSCP_SPLIT_SIZE(n) ((((n) >> LSCP_SPLIT_CHUNK2) + 1) << LSCP_SPLIT_CHUNK2)
34
35
36 //-------------------------------------------------------------------------
37 // Local client request executive.
38
39 // 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
53 // The common client receiver executive.
54 lscp_status_t lscp_client_recv ( lscp_client_t *pClient, char *pchBuffer, int *pcchBuffer, int iTimeout )
55 {
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
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 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
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 lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery )
111 {
112 int cchQuery;
113 char achResult[LSCP_BUFSIZ];
114 int cchResult;
115 const char *pszSeps = ":[]";
116 char *pszResult;
117 char *pszToken;
118 char *pch;
119 int iErrno;
120
121 lscp_status_t ret = LSCP_FAILED;
122
123 if (pClient == NULL)
124 return ret;
125
126 pszResult = NULL;
127 iErrno = -1;
128
129 // Check if command socket socket is still valid.
130 if (pClient->cmd.sock == INVALID_SOCKET) {
131 pszResult = "Connection closed or no longer valid";
132 lscp_client_set_result(pClient, pszResult, iErrno);
133 return ret;
134 }
135
136 // Check if last transaction has timed out, in which case
137 // we'll retry wait and flush for some pending garbage...
138 if (pClient->iTimeoutCount > 0) {
139 cchResult = sizeof(achResult);
140 ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);
141 if (ret == LSCP_OK) {
142 // We've got rid of timeout trouble (hopefully).
143 pClient->iTimeoutCount = 0;
144 } else {
145 // Things are worse than before. Fake a result message.
146 iErrno = (int) ret;
147 pszResult = "Failure during flush timeout operation";
148 lscp_client_set_result(pClient, pszResult, iErrno);
149 return ret;
150 }
151 }
152
153 // Send data, and then, wait for the result...
154 cchQuery = strlen(pszQuery);
155 if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {
156 lscp_socket_perror("lscp_client_call: send");
157 pszResult = "Failure during send operation";
158 lscp_client_set_result(pClient, pszResult, iErrno);
159 return ret;
160 }
161
162 // Wait for receive event...
163 cchResult = sizeof(achResult);
164 ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);
165
166 switch (ret) {
167
168 case LSCP_OK:
169 // Always force the result to be null terminated (and trim trailing CRLFs)!
170 while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))
171 cchResult--;
172 achResult[cchResult] = (char) 0;
173 // Check if the response it's an error or warning message.
174 if (strncasecmp(achResult, "WRN:", 4) == 0)
175 ret = LSCP_WARNING;
176 else if (strncasecmp(achResult, "ERR:", 4) == 0)
177 ret = LSCP_ERROR;
178 // So we got a result...
179 if (ret == LSCP_OK) {
180 // Reset errno in case of success.
181 iErrno = 0;
182 // Is it a special successful response?
183 if (strncasecmp(achResult, "OK[", 3) == 0) {
184 // Parse the OK message, get the return string under brackets...
185 pszToken = lscp_strtok(achResult, pszSeps, &(pch));
186 if (pszToken)
187 pszResult = lscp_strtok(NULL, pszSeps, &(pch));
188 }
189 else pszResult = achResult;
190 // The result string is now set to the command response, if any.
191 } else {
192 // Parse the error/warning message, skip first colon...
193 pszToken = lscp_strtok(achResult, pszSeps, &(pch));
194 if (pszToken) {
195 // Get the error number...
196 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
197 if (pszToken) {
198 iErrno = atoi(pszToken);
199 // And make the message text our final result.
200 pszResult = lscp_strtok(NULL, pszSeps, &(pch));
201 }
202 }
203 // The result string is set to the error/warning message text.
204 }
205 break;
206
207 case LSCP_TIMEOUT:
208 // We have trouble...
209 pClient->iTimeoutCount++;
210 // Fake a result message.
211 pszResult = "Timeout during receive operation";
212 iErrno = (int) ret;
213 break;
214
215 case LSCP_QUIT:
216 // Fake a result message.
217 pszResult = "Server terminated the connection";
218 iErrno = (int) ret;
219 break;
220
221 case LSCP_FAILED:
222 default:
223 // What's down?
224 pszResult = "Failure during receive operation";
225 break;
226 }
227
228 // Make the result official...
229 lscp_client_set_result(pClient, pszResult, iErrno);
230
231 return ret;
232 }
233
234
235 //-------------------------------------------------------------------------
236 // Other general utility functions.
237
238 // Trimming left spaces...
239 char *lscp_ltrim ( char *psz )
240 {
241 while (isspace(*psz))
242 psz++;
243 return psz;
244 }
245
246 // Unquote an in-split string.
247 char *lscp_unquote ( char **ppsz, int dup )
248 {
249 char chQuote;
250 char *psz = *ppsz;
251
252 while (isspace(*psz))
253 ++psz;
254 if (*psz == '\"' || *psz == '\'') {
255 chQuote = *psz++;
256 while (isspace(*psz))
257 ++psz;
258 if (dup)
259 psz = strdup(psz);
260 *ppsz = psz;
261 if (*ppsz) {
262 while (**ppsz && **ppsz != chQuote)
263 ++(*ppsz);
264 if (**ppsz) {
265 while (isspace(*(*ppsz - 1)) && *ppsz > psz)
266 --(*ppsz);
267 *(*ppsz)++ = (char) 0;
268 }
269 }
270 }
271 else if (dup) {
272 psz = strdup(psz);
273 *ppsz = psz;
274 }
275
276 return psz;
277 }
278
279 // Unquote and make a duplicate of an in-split string.
280 void lscp_unquote_dup ( char **ppszDst, char **ppszSrc )
281 {
282 // Free desteny string, if already there.
283 if (*ppszDst)
284 free(*ppszDst);
285 *ppszDst = NULL;
286 // Unquote and duplicate.
287 if (*ppszSrc)
288 *ppszDst = lscp_unquote(ppszSrc, 1);
289 }
290
291
292 // Custom tokenizer.
293 char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )
294 {
295 char *pszToken;
296
297 if (pchBuffer == NULL)
298 pchBuffer = *ppch;
299
300 pchBuffer += strspn(pchBuffer, pszSeps);
301 if (*pchBuffer == '\0')
302 return NULL;
303
304 pszToken = pchBuffer;
305 pchBuffer = strpbrk(pszToken, pszSeps);
306 if (pchBuffer == NULL) {
307 *ppch = strchr(pszToken, '\0');
308 } else {
309 *pchBuffer = '\0';
310 *ppch = pchBuffer + 1;
311 while (**ppch && strchr(pszSeps, **ppch))
312 (*ppch)++;
313 }
314
315 return pszToken;
316 }
317
318
319 // Split a comma separated string into a null terminated array of strings.
320 char **lscp_szsplit_create ( const char *pszCsv, const char *pszSeps )
321 {
322 char *pszHead, *pch;
323 int iSize, i, j, cchSeps;
324 char **ppszSplit, **ppszNewSplit;
325
326 // Initial size is one chunk away.
327 iSize = LSCP_SPLIT_CHUNK1;
328 // Allocate and split...
329 ppszSplit = (char **) malloc(iSize * sizeof(char *));
330 if (ppszSplit == NULL)
331 return NULL;
332
333 // Make a copy of the original string.
334 i = 0;
335 pszHead = (char *) pszCsv;
336 if ((ppszSplit[i++] = lscp_unquote(&pszHead, 1)) == NULL) {
337 free(ppszSplit);
338 return NULL;
339 }
340
341 // Go on for it...
342 cchSeps = strlen(pszSeps);
343 while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {
344 // Pre-advance to next item.
345 pszHead = pch + cchSeps;
346 // Trim and null terminate current item.
347 while (isspace(*(pch - 1)) && pch > ppszSplit[0])
348 --pch;
349 *pch = (char) 0;
350 // Make it official.
351 ppszSplit[i] = lscp_unquote(&pszHead, 0);
352 // Do we need to grow?
353 if (++i >= iSize) {
354 // Yes, but only grow in chunks.
355 iSize += LSCP_SPLIT_CHUNK1;
356 // Allocate and copy to new split array.
357 ppszNewSplit = (char **) malloc(iSize * sizeof(char *));
358 if (ppszNewSplit) {
359 for (j = 0; j < i; j++)
360 ppszNewSplit[j] = ppszSplit[j];
361 free(ppszSplit);
362 ppszSplit = ppszNewSplit;
363 }
364 }
365 }
366
367 // NULL terminate split array.
368 for ( ; i < iSize; i++)
369 ppszSplit[i] = NULL;
370
371 return ppszSplit;
372 }
373
374
375 // Free allocated memory of a legal null terminated array of strings.
376 void lscp_szsplit_destroy ( char **ppszSplit )
377 {
378 // Our split string is always the first item, if any.
379 if (ppszSplit && ppszSplit[0])
380 free(ppszSplit[0]);
381 // Now free the array itself.
382 if (ppszSplit)
383 free(ppszSplit);
384 }
385
386
387 #ifdef LSCP_SZSPLIT_COUNT
388
389 // Return the number of items of a null terminated array of strings.
390 int lscp_szsplit_count ( char **ppszSplit )
391 {
392 int i = 0;
393 while (ppszSplit && ppszSplit[i])
394 i++;
395 return i;
396 }
397
398 // Return the allocated number of items of a splitted string array.
399 int lscp_szsplit_size ( char **ppszSplit )
400 {
401 return LSCP_SPLIT_SIZE(lscp_szsplit_count(ppszSplit));
402 }
403
404 #endif // LSCP_SZSPLIT_COUNT
405
406
407 // Split a comma separated string into a -1 terminated array of positive integers.
408 int *lscp_isplit_create ( const char *pszCsv, const char *pszSeps )
409 {
410 char *pchHead, *pch;
411 int iSize, i, j, cchSeps;
412 int *piSplit, *piNewSplit;
413
414 // Get it clean first.
415 pchHead = lscp_ltrim((char *) pszCsv);
416 if (*pchHead == (char) 0)
417 return NULL;
418
419 // Initial size is one chunk away.
420 iSize = LSCP_SPLIT_CHUNK1;
421 // Allocate and split...
422 piSplit = (int *) malloc(iSize * sizeof(int));
423 if (piSplit == NULL)
424 return NULL;
425
426 // Make a copy of the original string.
427 i = 0;
428 if ((piSplit[i++] = atoi(pchHead)) < 0) {
429 free(piSplit);
430 return NULL;
431 }
432
433 // Go on for it...
434 cchSeps = strlen(pszSeps);
435 while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {
436 // Pre-advance to next item.
437 pchHead = pch + cchSeps;
438 // Make it official.
439 piSplit[i] = atoi(pchHead);
440 // Do we need to grow?
441 if (++i >= iSize) {
442 // Yes, but only grow in chunks.
443 iSize += LSCP_SPLIT_CHUNK1;
444 // Allocate and copy to new split array.
445 piNewSplit = (int *) malloc(iSize * sizeof(int));
446 if (piNewSplit) {
447 for (j = 0; j < i; j++)
448 piNewSplit[j] = piSplit[j];
449 free(piSplit);
450 piSplit = piNewSplit;
451 }
452 }
453 }
454
455 // NULL terminate split array.
456 for ( ; i < iSize; i++)
457 piSplit[i] = -1;
458
459 return piSplit;
460 }
461
462
463 // Destroy a integer splitted array.
464 void lscp_isplit_destroy ( int *piSplit )
465 {
466 if (piSplit)
467 free(piSplit);
468 }
469
470
471 #ifdef LSCP_ISPLIT_COUNT
472
473 // Compute a string list valid item count.
474 int lscp_isplit_count ( int *piSplit )
475 {
476 int i = 0;
477 while (piSplit && piSplit[i] >= 0)
478 i++;
479 return i;
480 }
481
482 // Compute a string list size.
483 int lscp_isplit_size ( int *piSplit )
484 {
485 return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
486 }
487
488 #endif // LSCP_ISPLIT_COUNT
489
490
491 // Split a string into a null terminated array of parameter items.
492 lscp_param_t *lscp_psplit_create ( const char *pszCsv, const char *pszSeps1, const char *pszSeps2 )
493 {
494 char *pszHead, *pch;
495 int iSize, i, j, cchSeps1, cchSeps2;
496 lscp_param_t *ppSplit, *ppNewSplit;
497
498 pszHead = strdup(pszCsv);
499 if (pszHead == NULL)
500 return NULL;
501
502 iSize = LSCP_SPLIT_CHUNK1;
503 ppSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
504 if (ppSplit == NULL) {
505 free(pszHead);
506 return NULL;
507 }
508
509 cchSeps1 = strlen(pszSeps1);
510 cchSeps2 = strlen(pszSeps2);
511
512 i = 0;
513 while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {
514 ppSplit[i].key = pszHead;
515 pszHead = pch + cchSeps1;
516 *pch = (char) 0;
517 ppSplit[i].value = lscp_unquote(&pszHead, 0);
518 if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {
519 pszHead = pch + cchSeps2;
520 *pch = (char) 0;
521 }
522 if (++i >= iSize) {
523 iSize += LSCP_SPLIT_CHUNK1;
524 ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
525 if (ppNewSplit) {
526 for (j = 0; j < i; j++) {
527 ppNewSplit[j].key = ppSplit[j].key;
528 ppNewSplit[j].value = ppSplit[j].value;
529 }
530 free(ppSplit);
531 ppSplit = ppNewSplit;
532 }
533 }
534 }
535
536 if (i < 1)
537 free(pszHead);
538
539 for ( ; i < iSize; i++) {
540 ppSplit[i].key = NULL;
541 ppSplit[i].value = NULL;
542 }
543
544 return ppSplit;
545 }
546
547
548 // Destroy a parameter list array.
549 void lscp_psplit_destroy ( lscp_param_t *ppSplit )
550 {
551 if (ppSplit && ppSplit[0].key)
552 free(ppSplit[0].key);
553 if (ppSplit)
554 free(ppSplit);
555 }
556
557
558 #ifdef LSCP_PSPLIT_COUNT
559
560 // Compute a parameter list valid item count.
561 int lscp_psplit_count ( lscp_param_t *ppSplit )
562 {
563 int i = 0;
564 while (ppSplit && ppSplit[i].key)
565 i++;
566 return i;
567 }
568
569 // Compute a parameter list size.
570 int lscp_psplit_size ( lscp_param_t *ppSplit )
571 {
572 return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));
573 }
574
575 #endif // LSCP_PSPLIT_COUNT
576
577
578 // Allocate a parameter list, optionally copying an existing one.
579 void lscp_plist_alloc (lscp_param_t **ppList)
580 {
581 lscp_param_t *pParams;
582 int iSize, i;
583
584 if (ppList) {
585 iSize = LSCP_SPLIT_CHUNK1;
586 pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
587 if (pParams) {
588 for (i = 0 ; i < iSize; i++) {
589 pParams[i].key = NULL;
590 pParams[i].value = NULL;
591 }
592 }
593 *ppList = pParams;
594 }
595 }
596
597
598 // Destroy a parameter list, including all it's contents.
599 void lscp_plist_free ( lscp_param_t **ppList )
600 {
601 lscp_param_t *pParams;
602 int i;
603
604 if (ppList) {
605 if (*ppList) {
606 pParams = *ppList;
607 for (i = 0; pParams && pParams[i].key; i++) {
608 free(pParams[i].key);
609 free(pParams[i].value);
610 }
611 free(pParams);
612 }
613 *ppList = NULL;
614 }
615 }
616
617
618 // Add an item to a parameter list, growing it as fit.
619 void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue )
620 {
621 lscp_param_t *pParams;
622 lscp_param_t *pNewParams;
623 int iSize, iNewSize;
624 int i = 0;
625
626 if (ppList && *ppList) {
627 pParams = *ppList;
628 while (pParams[i].key) {
629 if (strcasecmp(pParams[i].key, pszKey) == 0) {
630 if (pParams[i].value)
631 free(pParams[i].value);
632 pParams[i].value = strdup(pszValue);
633 return;
634 }
635 i++;
636 }
637 iSize = LSCP_SPLIT_SIZE(i);
638 pParams[i].key = strdup(pszKey);
639 pParams[i].value = strdup(pszValue);
640 if (++i >= iSize) {
641 iNewSize = iSize + LSCP_SPLIT_CHUNK1;
642 pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t));
643 for (i = 0; i < iSize; i++) {
644 pNewParams[i].key = pParams[i].key;
645 pNewParams[i].value = pParams[i].value;
646 }
647 for ( ; i < iNewSize; i++) {
648 pNewParams[i].key = NULL;
649 pNewParams[i].value = NULL;
650 }
651 free(pParams);
652 *ppList = pNewParams;
653 }
654 }
655 }
656
657 #ifdef LSCP_PLIST_COUNT
658
659 // Compute a parameter list valid item count.
660 int lscp_plist_count ( lscp_param_t **ppList )
661 {
662 lscp_param_t *pParams;
663 int i = 0;
664 if (ppList && *ppList) {
665 pParams = *ppList;
666 while (pParams[i].key)
667 i++;
668 }
669 return i;
670 }
671
672 // Compute the legal parameter list size.
673 int lscp_plist_size ( lscp_param_t **ppList )
674 {
675 return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));
676 }
677
678 #endif // LSCP_PLIST_COUNT
679
680
681 //-------------------------------------------------------------------------
682 // Server info struct helper functions.
683
684 void lscp_server_info_init ( lscp_server_info_t *pServerInfo )
685 {
686 pServerInfo->description = NULL;
687 pServerInfo->version = NULL;
688 }
689
690 void lscp_server_info_free ( lscp_server_info_t *pServerInfo )
691 {
692 if (pServerInfo->description)
693 free(pServerInfo->description);
694 if (pServerInfo->version)
695 free(pServerInfo->version);
696 }
697
698 void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )
699 {
700 lscp_server_info_free(pServerInfo);
701 lscp_server_info_init(pServerInfo);
702 }
703
704
705 //-------------------------------------------------------------------------
706 // Engine info struct helper functions.
707
708 void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
709 {
710 pEngineInfo->description = NULL;
711 pEngineInfo->version = NULL;
712 }
713
714 void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
715 {
716 if (pEngineInfo->description)
717 free(pEngineInfo->description);
718 if (pEngineInfo->version)
719 free(pEngineInfo->version);
720 }
721
722 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
723 {
724 lscp_engine_info_free(pEngineInfo);
725 lscp_engine_info_init(pEngineInfo);
726 }
727
728
729 //-------------------------------------------------------------------------
730 // Channel info struct helper functions.
731
732 void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
733 {
734 pChannelInfo->engine_name = NULL;
735 pChannelInfo->audio_device = 0;
736 pChannelInfo->audio_channels = 0;
737 pChannelInfo->audio_routing = NULL;
738 pChannelInfo->instrument_file = NULL;
739 pChannelInfo->instrument_nr = 0;
740 pChannelInfo->instrument_name = NULL;
741 pChannelInfo->instrument_status = 0;
742 pChannelInfo->midi_device = 0;
743 pChannelInfo->midi_port = 0;
744 pChannelInfo->midi_channel = 0;
745 pChannelInfo->volume = 0.0;
746 }
747
748 void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
749 {
750 if (pChannelInfo->engine_name)
751 free(pChannelInfo->engine_name);
752 if (pChannelInfo->audio_routing)
753 lscp_szsplit_destroy(pChannelInfo->audio_routing);
754 if (pChannelInfo->instrument_file)
755 free(pChannelInfo->instrument_file);
756 if (pChannelInfo->instrument_name)
757 free(pChannelInfo->instrument_name);
758 }
759
760 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
761 {
762 lscp_channel_info_free(pChannelInfo);
763 lscp_channel_info_init(pChannelInfo);
764 }
765
766
767 //-------------------------------------------------------------------------
768 // Driver info struct functions.
769
770 void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
771 {
772 pDriverInfo->description = NULL;
773 pDriverInfo->version = NULL;
774 pDriverInfo->parameters = NULL;
775 }
776
777 void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
778 {
779 if (pDriverInfo->description)
780 free(pDriverInfo->description);
781 if (pDriverInfo->version)
782 free(pDriverInfo->version);
783 lscp_szsplit_destroy(pDriverInfo->parameters);
784 }
785
786 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
787 {
788 lscp_driver_info_free(pDriverInfo);
789 lscp_driver_info_init(pDriverInfo);
790 }
791
792
793 //-------------------------------------------------------------------------
794 // Device info struct functions.
795
796 void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
797 {
798 pDeviceInfo->driver = NULL;
799 lscp_plist_alloc(&(pDeviceInfo->params));
800 }
801
802 void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
803 {
804 if (pDeviceInfo->driver)
805 free(pDeviceInfo->driver);
806 lscp_plist_free(&(pDeviceInfo->params));
807 }
808
809 void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
810 {
811 lscp_device_info_free(pDeviceInfo);
812 lscp_device_info_init(pDeviceInfo);
813 }
814
815
816 //-------------------------------------------------------------------------
817 // Device channel/port info struct functions.
818
819 void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
820 {
821 pDevicePortInfo->name = NULL;
822 lscp_plist_alloc(&(pDevicePortInfo->params));
823 }
824
825 void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
826 {
827 if (pDevicePortInfo->name)
828 free(pDevicePortInfo->name);
829 lscp_plist_free(&(pDevicePortInfo->params));
830 }
831
832 void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
833 {
834 lscp_device_port_info_free(pDevicePortInfo);
835 lscp_device_port_info_init(pDevicePortInfo);
836 }
837
838
839 //-------------------------------------------------------------------------
840 // Parameter struct helper functions.
841
842 void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
843 {
844 pParamInfo->type = LSCP_TYPE_NONE;
845 pParamInfo->description = NULL;
846 pParamInfo->mandatory = 0;
847 pParamInfo->fix = 0;
848 pParamInfo->multiplicity = 0;
849 pParamInfo->depends = NULL;
850 pParamInfo->defaultv = NULL;
851 pParamInfo->range_min = NULL;
852 pParamInfo->range_max = NULL;
853 pParamInfo->possibilities = NULL;
854 }
855
856 void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
857 {
858 if (pParamInfo->description)
859 free(pParamInfo->description);
860 lscp_szsplit_destroy(pParamInfo->depends);
861 if (pParamInfo->defaultv)
862 free(pParamInfo->defaultv);
863 if (pParamInfo->range_min)
864 free(pParamInfo->range_min);
865 if (pParamInfo->range_max)
866 free(pParamInfo->range_max);
867 lscp_szsplit_destroy(pParamInfo->possibilities);
868 }
869
870 void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
871 {
872 lscp_param_info_free(pParamInfo);
873 lscp_param_info_init(pParamInfo);
874 }
875
876
877 //-------------------------------------------------------------------------
878 // Concatenate a parameter list (key='value'...) into a string,
879 // appending a crlf terminator.
880
881 int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
882 {
883 int cchBuffer, cchParam, i;
884
885 if (pszBuffer == NULL)
886 return 0;
887
888 cchBuffer = strlen(pszBuffer);
889 for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
890 cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
891 if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
892 sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
893 cchBuffer += cchParam;
894 }
895 }
896
897 if (cchBuffer + 2 < cchMaxBuffer) {
898 pszBuffer[cchBuffer++] = '\r';
899 pszBuffer[cchBuffer++] = '\n';
900 pszBuffer[cchBuffer ] = (char) 0;
901 }
902
903 return cchBuffer;
904 }
905
906
907 // end of common.c

  ViewVC Help
Powered by ViewVC