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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3663 - (show annotations) (download)
Sun Dec 22 12:41:28 2019 UTC (16 months, 2 weeks ago) by schoenebeck
File MIME type: text/plain
File size: 28300 byte(s)
- Fixed compile errors on macOS.

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

  ViewVC Help
Powered by ViewVC