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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1020 - (show annotations) (download)
Thu Jan 11 15:25:04 2007 UTC (15 years, 5 months ago) by capela
File MIME type: text/plain
File size: 28240 byte(s)
* Audio routing representation changed to integer array.

1 // common.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2007, 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 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
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, int iResult )
111 {
112 int cchQuery;
113 char achBuffer[LSCP_BUFSIZ];
114 int cchBuffer;
115 const char *pszSeps = ":[]";
116 char *pszBuffer;
117 char *pszToken;
118 char *pch;
119 int iErrno;
120 char *pszResult;
121 int cchResult;
122
123 lscp_status_t ret = LSCP_FAILED;
124
125 if (pClient == NULL)
126 return ret;
127
128 iErrno = -1;
129 cchResult = 0;
130 pszResult = NULL;
131 pszBuffer = NULL;
132
133 // Check if command socket socket is still valid.
134 if (pClient->cmd.sock == INVALID_SOCKET) {
135 pszResult = "Connection closed or no longer valid";
136 lscp_client_set_result(pClient, pszResult, iErrno);
137 return ret;
138 }
139
140 // Check if last transaction has timed out, in which case
141 // we'll retry wait and flush for some pending garbage...
142 if (pClient->iTimeoutCount > 0) {
143 // We'll hope to get rid of timeout trouble...
144 pClient->iTimeoutCount = 0;
145 cchBuffer = sizeof(achBuffer);
146 ret = lscp_client_recv(pClient, achBuffer, &cchBuffer, pClient->iTimeout);
147 if (ret != LSCP_OK) {
148 // Things seems to be unresolved. Fake a result message.
149 iErrno = (int) ret;
150 pszResult = "Failure during flush timeout operation";
151 lscp_client_set_result(pClient, pszResult, iErrno);
152 return ret;
153 }
154 }
155
156 // Send data, and then, wait for the result...
157 cchQuery = strlen(pszQuery);
158 if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {
159 lscp_socket_perror("lscp_client_call: send");
160 pszResult = "Failure during send operation";
161 lscp_client_set_result(pClient, pszResult, iErrno);
162 return ret;
163 }
164
165 // Keep receiving while result is not the expected one:
166 // single-line result (iResult = 0) : one single CRLF ends the receipt;
167 // multi-line result (iResult > 0) : one "." followed by a last CRLF;
168
169 while (pszResult == NULL) {
170
171 // Wait for receive event...
172 cchBuffer = sizeof(achBuffer) - 1;
173 ret = lscp_client_recv(pClient, achBuffer, &cchBuffer, pClient->iTimeout);
174
175 switch (ret) {
176
177 case LSCP_OK:
178 // Always force the result to be null terminated.
179 achBuffer[cchBuffer] = (char) 0;
180 // Check if the response it's an error or warning message.
181 if (strncasecmp(achBuffer, "WRN:", 4) == 0)
182 ret = LSCP_WARNING;
183 else if (strncasecmp(achBuffer, "ERR:", 4) == 0)
184 ret = LSCP_ERROR;
185 // So we got a result...
186 if (ret == LSCP_OK) {
187 // Reset errno in case of success.
188 iErrno = 0;
189 // Is it a special successful response?
190 if (iResult < 1 && strncasecmp(achBuffer, "OK[", 3) == 0) {
191 // Parse the OK message, get the return string under brackets...
192 pszToken = lscp_strtok(achBuffer, pszSeps, &(pch));
193 if (pszToken)
194 pszResult = lscp_strtok(NULL, pszSeps, &(pch));
195 } else {
196 // It can be specially long response...
197 cchResult += sizeof(achBuffer);
198 pszResult = malloc(cchResult + 1);
199 pszResult[0] = (char) 0;
200 if (pszBuffer) {
201 strcat(pszResult, pszBuffer);
202 free(pszBuffer);
203 }
204 strcat(pszResult, achBuffer);
205 pszBuffer = pszResult;
206 pszResult = NULL;
207 // Check for correct end-of-transmission...
208 // Depending whether its single or multi-line we'll
209 // flag end-of-transmission...
210 cchBuffer = strlen(pszBuffer);
211 if (cchBuffer >= 2
212 && pszBuffer[cchBuffer - 1] == '\n'
213 && pszBuffer[cchBuffer - 2] == '\r'
214 && (iResult < 1 || (cchBuffer >= 3
215 && pszBuffer[cchBuffer - 3] == '.'))) {
216 // Get rid of the trailling dot and CRLF anyway...
217 while (cchBuffer > 0 && (
218 pszBuffer[cchBuffer - 1] == '\r' ||
219 pszBuffer[cchBuffer - 1] == '\n' ||
220 pszBuffer[cchBuffer - 1] == '.'))
221 cchBuffer--;
222 pszBuffer[cchBuffer] = (char) 0;
223 pszResult = pszBuffer;
224 }
225 }
226 // The result string is now set to the command response, if any.
227 } else {
228 // 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 // 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 iErrno = atoi(pszToken) + 100;
240 // 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 }
279
280
281 //-------------------------------------------------------------------------
282 // Other general utility functions.
283
284 // Trimming left spaces...
285 char *lscp_ltrim ( char *psz )
286 {
287 while (isspace(*psz))
288 psz++;
289 return psz;
290 }
291
292 // Unquote an in-split string.
293 char *lscp_unquote ( char **ppsz, int dup )
294 {
295 char chQuote;
296 char *psz = *ppsz;
297
298 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
322 return psz;
323 }
324
325 // Unquote and make a duplicate of an in-split string.
326 void lscp_unquote_dup ( char **ppszDst, char **ppszSrc )
327 {
328 // 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 }
336
337
338 // Custom tokenizer.
339 char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )
340 {
341 char *pszToken;
342
343 if (pchBuffer == NULL)
344 pchBuffer = *ppch;
345
346 pchBuffer += strspn(pchBuffer, pszSeps);
347 if (*pchBuffer == '\0')
348 return NULL;
349
350 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
361 return pszToken;
362 }
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 char *pszHead, *pch;
369 int iSize, i, j, cchSeps;
370 char **ppszSplit, **ppszNewSplit;
371
372 // 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
379 // 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
387 // 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
413 // NULL terminate split array.
414 for ( ; i < iSize; i++)
415 ppszSplit[i] = NULL;
416
417 return ppszSplit;
418 }
419
420
421 // Free allocated memory of a legal null terminated array of strings.
422 void lscp_szsplit_destroy ( char **ppszSplit )
423 {
424 // 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 }
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 int i = 0;
439 while (ppszSplit && ppszSplit[i])
440 i++;
441 return i;
442 }
443
444 // Return the allocated number of items of a splitted string array.
445 int lscp_szsplit_size ( char **ppszSplit )
446 {
447 return LSCP_SPLIT_SIZE(lscp_szsplit_count(ppszSplit));
448 }
449
450 #endif // LSCP_SZSPLIT_COUNT
451
452
453 // 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 char *pchHead, *pch;
457 int iSize, i, j, cchSeps;
458 int *piSplit, *piNewSplit;
459
460 // Get it clean first.
461 pchHead = lscp_ltrim((char *) pszCsv);
462 if (*pchHead == (char) 0)
463 return NULL;
464
465 // 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
472 // 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
479 // 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
501 // NULL terminate split array.
502 for ( ; i < iSize; i++)
503 piSplit[i] = -1;
504
505 return piSplit;
506 }
507
508
509 // Destroy a integer splitted array.
510 void lscp_isplit_destroy ( int *piSplit )
511 {
512 if (piSplit)
513 free(piSplit);
514 }
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 int i = 0;
523 while (piSplit && piSplit[i] >= 0)
524 i++;
525 return i;
526 }
527
528 // Compute a string list size.
529 int lscp_isplit_size ( int *piSplit )
530 {
531 return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
532 }
533
534 #endif // LSCP_ISPLIT_COUNT
535
536
537 // 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 char *pszHead, *pch;
541 int iSize, i, j, cchSeps1, cchSeps2;
542 lscp_param_t *ppSplit, *ppNewSplit;
543
544 pszHead = strdup(pszCsv);
545 if (pszHead == NULL)
546 return NULL;
547
548 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
555 cchSeps1 = strlen(pszSeps1);
556 cchSeps2 = strlen(pszSeps2);
557
558 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
582 if (i < 1)
583 free(pszHead);
584
585 for ( ; i < iSize; i++) {
586 ppSplit[i].key = NULL;
587 ppSplit[i].value = NULL;
588 }
589
590 return ppSplit;
591 }
592
593
594 // Destroy a parameter list array.
595 void lscp_psplit_destroy ( lscp_param_t *ppSplit )
596 {
597 if (ppSplit && ppSplit[0].key)
598 free(ppSplit[0].key);
599 if (ppSplit)
600 free(ppSplit);
601 }
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 int i = 0;
610 while (ppSplit && ppSplit[i].key)
611 i++;
612 return i;
613 }
614
615 // Compute a parameter list size.
616 int lscp_psplit_size ( lscp_param_t *ppSplit )
617 {
618 return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));
619 }
620
621 #endif // LSCP_PSPLIT_COUNT
622
623
624 // Allocate a parameter list, optionally copying an existing one.
625 void lscp_plist_alloc (lscp_param_t **ppList)
626 {
627 lscp_param_t *pParams;
628 int iSize, i;
629
630 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 }
642
643
644 // Destroy a parameter list, including all it's contents.
645 void lscp_plist_free ( lscp_param_t **ppList )
646 {
647 lscp_param_t *pParams;
648 int i;
649
650 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 }
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 lscp_param_t *pParams;
668 lscp_param_t *pNewParams;
669 int iSize, iNewSize;
670 int i = 0;
671
672 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 }
702
703 #ifdef LSCP_PLIST_COUNT
704
705 // Compute a parameter list valid item count.
706 int lscp_plist_count ( lscp_param_t **ppList )
707 {
708 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 }
717
718 // Compute the legal parameter list size.
719 int lscp_plist_size ( lscp_param_t **ppList )
720 {
721 return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));
722 }
723
724 #endif // LSCP_PLIST_COUNT
725
726
727 // Split a string into an array of MIDI instrument triplets.
728 lscp_midi_instrument_t *lscp_midi_instruments_create ( const char *pszCsv )
729 {
730 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 pInstrs[i].map = atoi(pchHead);
758 k++;
759 }
760 break;
761 case ',':
762 pchHead = pch + 1;
763 if (k == 1) {
764 pInstrs[i].bank = atoi(pchHead);
765 k++;
766 }
767 else
768 if (k == 2) {
769 pInstrs[i].prog = atoi(pchHead);
770 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 pNewInstrs[j].map = pInstrs[j].map;
787 pNewInstrs[j].bank = pInstrs[j].bank;
788 pNewInstrs[j].prog = pInstrs[j].prog;
789 }
790 free(pInstrs);
791 pInstrs = pNewInstrs;
792 }
793 }
794 }
795
796 // Special terminate split array.
797 for ( ; i < iSize; i++) {
798 pInstrs[i].map = -1;
799 pInstrs[i].bank = -1;
800 pInstrs[i].prog = -1;
801 }
802
803 return pInstrs;
804 }
805
806 // Destroy a MIDI instrument triplet array.
807 void lscp_midi_instruments_destroy ( lscp_midi_instrument_t *pInstrs )
808 {
809 if (pInstrs)
810 free(pInstrs);
811 }
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 int i = 0;
819 while (pInstrs && pInstrs[i].program >= 0)
820 i++;
821 return i;
822 }
823
824 // Compute a MIDI instrument array size.
825 int lscp_midi_instruments_size ( lscp_midi_instrument_t *pInstrs )
826 {
827 return LSCP_SPLIT_SIZE(lscp_midi_instruments_count(pInstrs));
828 }
829
830 #endif // LSCP_MIDI_INSTRUMENTS_COUNT
831
832
833 //-------------------------------------------------------------------------
834 // Server info struct helper functions.
835
836 void lscp_server_info_init ( lscp_server_info_t *pServerInfo )
837 {
838 pServerInfo->description = NULL;
839 pServerInfo->version = NULL;
840 pServerInfo->protocol_version = NULL;
841 }
842
843 void lscp_server_info_free ( lscp_server_info_t *pServerInfo )
844 {
845 if (pServerInfo->description)
846 free(pServerInfo->description);
847 if (pServerInfo->version)
848 free(pServerInfo->version);
849 if (pServerInfo->protocol_version)
850 free(pServerInfo->protocol_version);
851 }
852
853 void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )
854 {
855 lscp_server_info_free(pServerInfo);
856 lscp_server_info_init(pServerInfo);
857 }
858
859
860 //-------------------------------------------------------------------------
861 // Engine info struct helper functions.
862
863 void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
864 {
865 pEngineInfo->description = NULL;
866 pEngineInfo->version = NULL;
867 }
868
869 void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
870 {
871 if (pEngineInfo->description)
872 free(pEngineInfo->description);
873 if (pEngineInfo->version)
874 free(pEngineInfo->version);
875 }
876
877 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
878 {
879 lscp_engine_info_free(pEngineInfo);
880 lscp_engine_info_init(pEngineInfo);
881 }
882
883
884 //-------------------------------------------------------------------------
885 // Channel info struct helper functions.
886
887 void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
888 {
889 pChannelInfo->engine_name = NULL;
890 pChannelInfo->audio_device = 0;
891 pChannelInfo->audio_channels = 0;
892 pChannelInfo->audio_routing = NULL;
893 pChannelInfo->instrument_file = NULL;
894 pChannelInfo->instrument_nr = 0;
895 pChannelInfo->instrument_name = NULL;
896 pChannelInfo->instrument_status = 0;
897 pChannelInfo->midi_device = 0;
898 pChannelInfo->midi_port = 0;
899 pChannelInfo->midi_channel = 0;
900 pChannelInfo->midi_map = 0;
901 pChannelInfo->volume = 0.0;
902 pChannelInfo->mute = 0;
903 pChannelInfo->solo = 0;
904 }
905
906 void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
907 {
908 if (pChannelInfo->engine_name)
909 free(pChannelInfo->engine_name);
910 if (pChannelInfo->audio_routing)
911 lscp_isplit_destroy(pChannelInfo->audio_routing);
912 if (pChannelInfo->instrument_file)
913 free(pChannelInfo->instrument_file);
914 if (pChannelInfo->instrument_name)
915 free(pChannelInfo->instrument_name);
916 }
917
918 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
919 {
920 lscp_channel_info_free(pChannelInfo);
921 lscp_channel_info_init(pChannelInfo);
922 }
923
924
925 //-------------------------------------------------------------------------
926 // Driver info struct functions.
927
928 void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
929 {
930 pDriverInfo->description = NULL;
931 pDriverInfo->version = NULL;
932 pDriverInfo->parameters = NULL;
933 }
934
935 void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
936 {
937 if (pDriverInfo->description)
938 free(pDriverInfo->description);
939 if (pDriverInfo->version)
940 free(pDriverInfo->version);
941 lscp_szsplit_destroy(pDriverInfo->parameters);
942 }
943
944 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
945 {
946 lscp_driver_info_free(pDriverInfo);
947 lscp_driver_info_init(pDriverInfo);
948 }
949
950
951 //-------------------------------------------------------------------------
952 // Device info struct functions.
953
954 void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
955 {
956 pDeviceInfo->driver = NULL;
957 lscp_plist_alloc(&(pDeviceInfo->params));
958 }
959
960 void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
961 {
962 if (pDeviceInfo->driver)
963 free(pDeviceInfo->driver);
964 lscp_plist_free(&(pDeviceInfo->params));
965 }
966
967 void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
968 {
969 lscp_device_info_free(pDeviceInfo);
970 lscp_device_info_init(pDeviceInfo);
971 }
972
973
974 //-------------------------------------------------------------------------
975 // Device channel/port info struct functions.
976
977 void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
978 {
979 pDevicePortInfo->name = NULL;
980 lscp_plist_alloc(&(pDevicePortInfo->params));
981 }
982
983 void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
984 {
985 if (pDevicePortInfo->name)
986 free(pDevicePortInfo->name);
987 lscp_plist_free(&(pDevicePortInfo->params));
988 }
989
990 void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
991 {
992 lscp_device_port_info_free(pDevicePortInfo);
993 lscp_device_port_info_init(pDevicePortInfo);
994 }
995
996
997 //-------------------------------------------------------------------------
998 // Parameter struct helper functions.
999
1000 void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
1001 {
1002 pParamInfo->type = LSCP_TYPE_NONE;
1003 pParamInfo->description = NULL;
1004 pParamInfo->mandatory = 0;
1005 pParamInfo->fix = 0;
1006 pParamInfo->multiplicity = 0;
1007 pParamInfo->depends = NULL;
1008 pParamInfo->defaultv = NULL;
1009 pParamInfo->range_min = NULL;
1010 pParamInfo->range_max = NULL;
1011 pParamInfo->possibilities = NULL;
1012 }
1013
1014 void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
1015 {
1016 if (pParamInfo->description)
1017 free(pParamInfo->description);
1018 lscp_szsplit_destroy(pParamInfo->depends);
1019 if (pParamInfo->defaultv)
1020 free(pParamInfo->defaultv);
1021 if (pParamInfo->range_min)
1022 free(pParamInfo->range_min);
1023 if (pParamInfo->range_max)
1024 free(pParamInfo->range_max);
1025 lscp_szsplit_destroy(pParamInfo->possibilities);
1026 }
1027
1028 void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
1029 {
1030 lscp_param_info_free(pParamInfo);
1031 lscp_param_info_init(pParamInfo);
1032 }
1033
1034
1035 //-------------------------------------------------------------------------
1036 // Concatenate a parameter list (key='value'...) into a string,
1037 // appending a crlf terminator.
1038
1039 int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
1040 {
1041 int cchBuffer, cchParam, i;
1042
1043 if (pszBuffer == NULL)
1044 return 0;
1045
1046 cchBuffer = strlen(pszBuffer);
1047 for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
1048 cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
1049 if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
1050 sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
1051 cchBuffer += cchParam;
1052 }
1053 }
1054
1055 if (cchBuffer + 2 < cchMaxBuffer) {
1056 pszBuffer[cchBuffer++] = '\r';
1057 pszBuffer[cchBuffer++] = '\n';
1058 pszBuffer[cchBuffer ] = (char) 0;
1059 }
1060
1061 return cchBuffer;
1062 }
1063
1064
1065 //-------------------------------------------------------------------------
1066 // Effect struct helper functions.
1067
1068 void lscp_fxsend_info_init ( lscp_fxsend_info_t *pFxSendInfo )
1069 {
1070 pFxSendInfo->name = NULL;
1071 pFxSendInfo->midi_controller = 0;
1072 pFxSendInfo->audio_routing = NULL;
1073 }
1074
1075 void lscp_fxsend_info_free ( lscp_fxsend_info_t *pFxSendInfo )
1076 {
1077 if (pFxSendInfo->name)
1078 free(pFxSendInfo->name);
1079 if (pFxSendInfo->audio_routing)
1080 lscp_isplit_destroy(pFxSendInfo->audio_routing);
1081 }
1082
1083 void lscp_fxsend_info_reset (lscp_fxsend_info_t *pFxSendInfo )
1084 {
1085 lscp_fxsend_info_free(pFxSendInfo);
1086 lscp_fxsend_info_init(pFxSendInfo);
1087 }
1088
1089
1090 //-------------------------------------------------------------------------
1091 // MIDI instrument info struct helper functions.
1092
1093 void lscp_midi_instrument_info_init ( lscp_midi_instrument_info_t *pInstrInfo )
1094 {
1095 pInstrInfo->name = NULL;
1096 pInstrInfo->engine_name = NULL;
1097 pInstrInfo->instrument_file = NULL;
1098 pInstrInfo->instrument_nr = 0;
1099 pInstrInfo->instrument_name = NULL;
1100 pInstrInfo->load_mode = LSCP_LOAD_DEFAULT;
1101 pInstrInfo->volume = 0.0;
1102 }
1103
1104 void lscp_midi_instrument_info_free ( lscp_midi_instrument_info_t *pInstrInfo )
1105 {
1106 if (pInstrInfo->name)
1107 free(pInstrInfo->name);
1108 if (pInstrInfo->engine_name)
1109 free(pInstrInfo->engine_name);
1110 if (pInstrInfo->instrument_file)
1111 free(pInstrInfo->instrument_file);
1112 if (pInstrInfo->instrument_name)
1113 free(pInstrInfo->instrument_name);
1114 }
1115
1116 void lscp_midi_instrument_info_reset ( lscp_midi_instrument_info_t *pInstrInfo )
1117 {
1118 lscp_midi_instrument_info_free(pInstrInfo);
1119 lscp_midi_instrument_info_init(pInstrInfo);
1120 }
1121
1122
1123 // end of common.c

  ViewVC Help
Powered by ViewVC