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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 965 - (show annotations) (download)
Mon Dec 4 23:56:27 2006 UTC (13 years ago) by capela
File MIME type: text/plain
File size: 27490 byte(s)
Going up into 0.4.2 release really fast.

1 // common.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2006, 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].bank_msb = atoi(pchHead);
758 k++;
759 }
760 break;
761 case ',':
762 pchHead = pch + 1;
763 if (k == 1) {
764 pInstrs[i].bank_lsb = atoi(pchHead);
765 k++;
766 }
767 else
768 if (k == 2) {
769 pInstrs[i].program = 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].bank_msb = pInstrs[j].bank_msb;
787 pNewInstrs[j].bank_lsb = pInstrs[j].bank_lsb;
788 pNewInstrs[j].program = pInstrs[j].program;
789 }
790 free(pInstrs);
791 pInstrs = pNewInstrs;
792 }
793 }
794 }
795
796 // Special terminate split array.
797 for ( ; i < iSize; i++) {
798 pInstrs[i].bank_msb = -1;
799 pInstrs[i].bank_lsb = -1;
800 pInstrs[i].program = -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 }
841
842 void lscp_server_info_free ( lscp_server_info_t *pServerInfo )
843 {
844 if (pServerInfo->description)
845 free(pServerInfo->description);
846 if (pServerInfo->version)
847 free(pServerInfo->version);
848 }
849
850 void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )
851 {
852 lscp_server_info_free(pServerInfo);
853 lscp_server_info_init(pServerInfo);
854 }
855
856
857 //-------------------------------------------------------------------------
858 // Engine info struct helper functions.
859
860 void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
861 {
862 pEngineInfo->description = NULL;
863 pEngineInfo->version = NULL;
864 }
865
866 void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
867 {
868 if (pEngineInfo->description)
869 free(pEngineInfo->description);
870 if (pEngineInfo->version)
871 free(pEngineInfo->version);
872 }
873
874 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
875 {
876 lscp_engine_info_free(pEngineInfo);
877 lscp_engine_info_init(pEngineInfo);
878 }
879
880
881 //-------------------------------------------------------------------------
882 // Channel info struct helper functions.
883
884 void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
885 {
886 pChannelInfo->engine_name = NULL;
887 pChannelInfo->audio_device = 0;
888 pChannelInfo->audio_channels = 0;
889 pChannelInfo->audio_routing = NULL;
890 pChannelInfo->instrument_file = NULL;
891 pChannelInfo->instrument_nr = 0;
892 pChannelInfo->instrument_name = NULL;
893 pChannelInfo->instrument_status = 0;
894 pChannelInfo->midi_device = 0;
895 pChannelInfo->midi_port = 0;
896 pChannelInfo->midi_channel = 0;
897 pChannelInfo->volume = 0.0;
898 pChannelInfo->mute = 0;
899 pChannelInfo->solo = 0;
900 }
901
902 void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
903 {
904 if (pChannelInfo->engine_name)
905 free(pChannelInfo->engine_name);
906 if (pChannelInfo->audio_routing)
907 lscp_szsplit_destroy(pChannelInfo->audio_routing);
908 if (pChannelInfo->instrument_file)
909 free(pChannelInfo->instrument_file);
910 if (pChannelInfo->instrument_name)
911 free(pChannelInfo->instrument_name);
912 }
913
914 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
915 {
916 lscp_channel_info_free(pChannelInfo);
917 lscp_channel_info_init(pChannelInfo);
918 }
919
920
921 //-------------------------------------------------------------------------
922 // Driver info struct functions.
923
924 void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
925 {
926 pDriverInfo->description = NULL;
927 pDriverInfo->version = NULL;
928 pDriverInfo->parameters = NULL;
929 }
930
931 void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
932 {
933 if (pDriverInfo->description)
934 free(pDriverInfo->description);
935 if (pDriverInfo->version)
936 free(pDriverInfo->version);
937 lscp_szsplit_destroy(pDriverInfo->parameters);
938 }
939
940 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
941 {
942 lscp_driver_info_free(pDriverInfo);
943 lscp_driver_info_init(pDriverInfo);
944 }
945
946
947 //-------------------------------------------------------------------------
948 // Device info struct functions.
949
950 void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
951 {
952 pDeviceInfo->driver = NULL;
953 lscp_plist_alloc(&(pDeviceInfo->params));
954 }
955
956 void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
957 {
958 if (pDeviceInfo->driver)
959 free(pDeviceInfo->driver);
960 lscp_plist_free(&(pDeviceInfo->params));
961 }
962
963 void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
964 {
965 lscp_device_info_free(pDeviceInfo);
966 lscp_device_info_init(pDeviceInfo);
967 }
968
969
970 //-------------------------------------------------------------------------
971 // Device channel/port info struct functions.
972
973 void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
974 {
975 pDevicePortInfo->name = NULL;
976 lscp_plist_alloc(&(pDevicePortInfo->params));
977 }
978
979 void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
980 {
981 if (pDevicePortInfo->name)
982 free(pDevicePortInfo->name);
983 lscp_plist_free(&(pDevicePortInfo->params));
984 }
985
986 void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
987 {
988 lscp_device_port_info_free(pDevicePortInfo);
989 lscp_device_port_info_init(pDevicePortInfo);
990 }
991
992
993 //-------------------------------------------------------------------------
994 // Parameter struct helper functions.
995
996 void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
997 {
998 pParamInfo->type = LSCP_TYPE_NONE;
999 pParamInfo->description = NULL;
1000 pParamInfo->mandatory = 0;
1001 pParamInfo->fix = 0;
1002 pParamInfo->multiplicity = 0;
1003 pParamInfo->depends = NULL;
1004 pParamInfo->defaultv = NULL;
1005 pParamInfo->range_min = NULL;
1006 pParamInfo->range_max = NULL;
1007 pParamInfo->possibilities = NULL;
1008 }
1009
1010 void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
1011 {
1012 if (pParamInfo->description)
1013 free(pParamInfo->description);
1014 lscp_szsplit_destroy(pParamInfo->depends);
1015 if (pParamInfo->defaultv)
1016 free(pParamInfo->defaultv);
1017 if (pParamInfo->range_min)
1018 free(pParamInfo->range_min);
1019 if (pParamInfo->range_max)
1020 free(pParamInfo->range_max);
1021 lscp_szsplit_destroy(pParamInfo->possibilities);
1022 }
1023
1024 void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
1025 {
1026 lscp_param_info_free(pParamInfo);
1027 lscp_param_info_init(pParamInfo);
1028 }
1029
1030
1031 //-------------------------------------------------------------------------
1032 // Concatenate a parameter list (key='value'...) into a string,
1033 // appending a crlf terminator.
1034
1035 int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
1036 {
1037 int cchBuffer, cchParam, i;
1038
1039 if (pszBuffer == NULL)
1040 return 0;
1041
1042 cchBuffer = strlen(pszBuffer);
1043 for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
1044 cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
1045 if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
1046 sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
1047 cchBuffer += cchParam;
1048 }
1049 }
1050
1051 if (cchBuffer + 2 < cchMaxBuffer) {
1052 pszBuffer[cchBuffer++] = '\r';
1053 pszBuffer[cchBuffer++] = '\n';
1054 pszBuffer[cchBuffer ] = (char) 0;
1055 }
1056
1057 return cchBuffer;
1058 }
1059
1060
1061 //-------------------------------------------------------------------------
1062 // MIDI instrument info struct helper functions.
1063
1064 void lscp_midi_instrument_info_init ( lscp_midi_instrument_info_t *pInstrInfo )
1065 {
1066 pInstrInfo->name = NULL;
1067 pInstrInfo->engine_name = NULL;
1068 pInstrInfo->instrument_file = NULL;
1069 pInstrInfo->instrument_nr = 0;
1070 pInstrInfo->instrument_name = NULL;
1071 pInstrInfo->load_mode = LSCP_LOAD_DEFAULT;
1072 pInstrInfo->volume = 0.0;
1073 }
1074
1075 void lscp_midi_instrument_info_free ( lscp_midi_instrument_info_t *pInstrInfo )
1076 {
1077 if (pInstrInfo->name)
1078 free(pInstrInfo->name);
1079 if (pInstrInfo->engine_name)
1080 free(pInstrInfo->engine_name);
1081 if (pInstrInfo->instrument_file)
1082 free(pInstrInfo->instrument_file);
1083 if (pInstrInfo->instrument_name)
1084 free(pInstrInfo->instrument_name);
1085 }
1086
1087 void lscp_midi_instrument_info_reset ( lscp_midi_instrument_info_t *pInstrInfo )
1088 {
1089 lscp_midi_instrument_info_free(pInstrInfo);
1090 lscp_midi_instrument_info_init(pInstrInfo);
1091 }
1092
1093
1094 // end of common.c

  ViewVC Help
Powered by ViewVC