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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC