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.
lscp_client_set_result(lscp_client_t * pClient,char * pszResult,int iErrno)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.
lscp_client_recv(lscp_client_t * pClient,char * pchBuffer,int * pcchBuffer,int iTimeout)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.
lscp_client_call(lscp_client_t * pClient,const char * pszQuery,int iResult)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...
lscp_ltrim(char * psz)295 char *lscp_ltrim ( char *psz )
296 {
297 	while (isspace(*psz))
298 		psz++;
299 	return psz;
300 }
301 
302 // Unquote an in-split string.
lscp_unquote(char ** ppsz,int dup)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.
lscp_unquote_dup(char ** ppszDst,char ** ppszSrc)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.
lscp_strtok(char * pchBuffer,const char * pszSeps,char ** ppch)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.
lscp_szsplit_create(const char * pszCsv,const char * pszSeps)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.
lscp_szsplit_destroy(char ** ppszSplit)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.
lscp_szsplit_count(char ** ppszSplit)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.
lscp_szsplit_size(char ** ppszSplit)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.
lscp_isplit_create(const char * pszCsv,const char * pszSeps)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.
lscp_isplit_destroy(int * piSplit)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.
lscp_isplit_count(int * piSplit)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.
lscp_isplit_size(int * piSplit)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.
lscp_psplit_create(const char * pszCsv,const char * pszSeps1,const char * pszSeps2)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.
lscp_psplit_destroy(lscp_param_t * ppSplit)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.
lscp_psplit_count(lscp_param_t * ppSplit)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.
lscp_psplit_size(lscp_param_t * ppSplit)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.
lscp_plist_alloc(lscp_param_t ** ppList)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.
lscp_plist_free(lscp_param_t ** ppList)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.
lscp_plist_append(lscp_param_t ** ppList,const char * pszKey,const char * pszValue)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.
lscp_plist_count(lscp_param_t ** ppList)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.
lscp_plist_size(lscp_param_t ** ppList)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.
lscp_midi_instruments_create(const char * pszCsv)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.
lscp_midi_instruments_destroy(lscp_midi_instrument_t * pInstrs)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.
lscp_midi_instruments_count(lscp_midi_instrument_t * pInstrs)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.
lscp_midi_instruments_size(lscp_midi_instrument_t * pInstrs)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 
lscp_server_info_init(lscp_server_info_t * pServerInfo)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 
lscp_server_info_free(lscp_server_info_t * pServerInfo)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 
lscp_server_info_reset(lscp_server_info_t * pServerInfo)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 
lscp_engine_info_init(lscp_engine_info_t * pEngineInfo)873 void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
874 {
875 	pEngineInfo->description = NULL;
876 	pEngineInfo->version     = NULL;
877 }
878 
lscp_engine_info_free(lscp_engine_info_t * pEngineInfo)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 
lscp_engine_info_reset(lscp_engine_info_t * pEngineInfo)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 
lscp_channel_info_init(lscp_channel_info_t * pChannelInfo)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 
lscp_channel_info_free(lscp_channel_info_t * pChannelInfo)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 
lscp_channel_info_reset(lscp_channel_info_t * pChannelInfo)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 
lscp_driver_info_init(lscp_driver_info_t * pDriverInfo)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 
lscp_driver_info_free(lscp_driver_info_t * pDriverInfo)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 
lscp_driver_info_reset(lscp_driver_info_t * pDriverInfo)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 
lscp_device_info_init(lscp_device_info_t * pDeviceInfo)964 void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
965 {
966 	pDeviceInfo->driver = NULL;
967 	lscp_plist_alloc(&(pDeviceInfo->params));
968 }
969 
lscp_device_info_free(lscp_device_info_t * pDeviceInfo)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 
lscp_device_info_reset(lscp_device_info_t * pDeviceInfo)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 
lscp_device_port_info_init(lscp_device_port_info_t * pDevicePortInfo)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 
lscp_device_port_info_free(lscp_device_port_info_t * pDevicePortInfo)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 
lscp_device_port_info_reset(lscp_device_port_info_t * pDevicePortInfo)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 
lscp_param_info_init(lscp_param_info_t * pParamInfo)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 
lscp_param_info_free(lscp_param_info_t * pParamInfo)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 
lscp_param_info_reset(lscp_param_info_t * pParamInfo)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 
lscp_param_concat(char * pszBuffer,int cchMaxBuffer,lscp_param_t * pParams)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 
lscp_fxsend_info_init(lscp_fxsend_info_t * pFxSendInfo)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 
lscp_fxsend_info_free(lscp_fxsend_info_t * pFxSendInfo)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 
lscp_fxsend_info_reset(lscp_fxsend_info_t * pFxSendInfo)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 
lscp_midi_instrument_info_init(lscp_midi_instrument_info_t * pInstrInfo)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 
lscp_midi_instrument_info_free(lscp_midi_instrument_info_t * pInstrInfo)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 
lscp_midi_instrument_info_reset(lscp_midi_instrument_info_t * pInstrInfo)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
1135