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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 564 - (show annotations) (download)
Sun May 22 22:02:00 2005 UTC (18 years, 11 months ago) by capela
File MIME type: text/plain
File size: 24776 byte(s)
* Added support for the newest LSCP command: GET SERVER INFO.

1 // common.c
2 //
3 /****************************************************************************
4 liblscp - LinuxSampler Control Protocol API
5 Copyright (C) 2004-2005, 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 Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 )
111 {
112 int cchQuery;
113 char achResult[LSCP_BUFSIZ];
114 int cchResult;
115 const char *pszSeps = ":[]";
116 char *pszResult;
117 char *pszToken;
118 char *pch;
119 int iErrno;
120
121 lscp_status_t ret = LSCP_FAILED;
122
123 if (pClient == NULL)
124 return ret;
125
126 pszResult = NULL;
127 iErrno = -1;
128
129 // Check if command socket socket is still valid.
130 if (pClient->cmd.sock == INVALID_SOCKET) {
131 pszResult = "Connection closed or no longer valid";
132 lscp_client_set_result(pClient, pszResult, iErrno);
133 return ret;
134 }
135
136 // Send data, and then, wait for the result...
137 cchQuery = strlen(pszQuery);
138 if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {
139 lscp_socket_perror("lscp_client_call: send");
140 pszResult = "Failure during send operation";
141 lscp_client_set_result(pClient, pszResult, iErrno);
142 return ret;
143 }
144
145 // Wait for receive event...
146 cchResult = sizeof(achResult);
147 ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);
148
149 switch (ret) {
150
151 case LSCP_OK:
152 // Always force the result to be null terminated (and trim trailing CRLFs)!
153 while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))
154 cchResult--;
155 achResult[cchResult] = (char) 0;
156 // Check if the response it's an error or warning message.
157 if (strncasecmp(achResult, "WRN:", 4) == 0)
158 ret = LSCP_WARNING;
159 else if (strncasecmp(achResult, "ERR:", 4) == 0)
160 ret = LSCP_ERROR;
161 // So we got a result...
162 if (ret == LSCP_OK) {
163 // Reset errno in case of success.
164 iErrno = 0;
165 // Is it a special successful response?
166 if (strncasecmp(achResult, "OK[", 3) == 0) {
167 // Parse the OK message, get the return string under brackets...
168 pszToken = lscp_strtok(achResult, pszSeps, &(pch));
169 if (pszToken)
170 pszResult = lscp_strtok(NULL, pszSeps, &(pch));
171 }
172 else pszResult = achResult;
173 // The result string is now set to the command response, if any.
174 } else {
175 // Parse the error/warning message, skip first colon...
176 pszToken = lscp_strtok(achResult, pszSeps, &(pch));
177 if (pszToken) {
178 // Get the error number...
179 pszToken = lscp_strtok(NULL, pszSeps, &(pch));
180 if (pszToken) {
181 iErrno = atoi(pszToken);
182 // And make the message text our final result.
183 pszResult = lscp_strtok(NULL, pszSeps, &(pch));
184 }
185 }
186 // The result string is set to the error/warning message text.
187 }
188 break;
189
190 case LSCP_TIMEOUT:
191 // Fake a result message.
192 pszResult = "Timeout during receive operation";
193 iErrno = (int) ret;
194 break;
195
196 case LSCP_QUIT:
197 // Fake a result message.
198 pszResult = "Server terminated the connection";
199 iErrno = (int) ret;
200 break;
201
202 case LSCP_FAILED:
203 default:
204 // What's down?
205 pszResult = "Failure during receive operation";
206 break;
207 }
208
209 // Make the result official...
210 lscp_client_set_result(pClient, pszResult, iErrno);
211
212 return ret;
213 }
214
215
216 //-------------------------------------------------------------------------
217 // Other general utility functions.
218
219 // Trimming left spaces...
220 char *lscp_ltrim ( char *psz )
221 {
222 while (isspace(*psz))
223 psz++;
224 return psz;
225 }
226
227 // Unquote an in-split string.
228 char *lscp_unquote ( char **ppsz, int dup )
229 {
230 char chQuote;
231 char *psz = *ppsz;
232
233 while (isspace(*psz))
234 ++psz;
235 if (*psz == '\"' || *psz == '\'') {
236 chQuote = *psz++;
237 while (isspace(*psz))
238 ++psz;
239 if (dup)
240 psz = strdup(psz);
241 *ppsz = psz;
242 if (*ppsz) {
243 while (**ppsz && **ppsz != chQuote)
244 ++(*ppsz);
245 if (**ppsz) {
246 while (isspace(*(*ppsz - 1)) && *ppsz > psz)
247 --(*ppsz);
248 *(*ppsz)++ = (char) 0;
249 }
250 }
251 }
252 else if (dup) {
253 psz = strdup(psz);
254 *ppsz = psz;
255 }
256
257 return psz;
258 }
259
260 // Unquote and make a duplicate of an in-split string.
261 void lscp_unquote_dup ( char **ppszDst, char **ppszSrc )
262 {
263 // Free desteny string, if already there.
264 if (*ppszDst)
265 free(*ppszDst);
266 *ppszDst = NULL;
267 // Unquote and duplicate.
268 if (*ppszSrc)
269 *ppszDst = lscp_unquote(ppszSrc, 1);
270 }
271
272
273 // Custom tokenizer.
274 char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )
275 {
276 char *pszToken;
277
278 if (pchBuffer == NULL)
279 pchBuffer = *ppch;
280
281 pchBuffer += strspn(pchBuffer, pszSeps);
282 if (*pchBuffer == '\0')
283 return NULL;
284
285 pszToken = pchBuffer;
286 pchBuffer = strpbrk(pszToken, pszSeps);
287 if (pchBuffer == NULL) {
288 *ppch = strchr(pszToken, '\0');
289 } else {
290 *pchBuffer = '\0';
291 *ppch = pchBuffer + 1;
292 while (**ppch && strchr(pszSeps, **ppch))
293 (*ppch)++;
294 }
295
296 return pszToken;
297 }
298
299
300 // Split a comma separated string into a null terminated array of strings.
301 char **lscp_szsplit_create ( const char *pszCsv, const char *pszSeps )
302 {
303 char *pszHead, *pch;
304 int iSize, i, j, cchSeps;
305 char **ppszSplit, **ppszNewSplit;
306
307 // Initial size is one chunk away.
308 iSize = LSCP_SPLIT_CHUNK1;
309 // Allocate and split...
310 ppszSplit = (char **) malloc(iSize * sizeof(char *));
311 if (ppszSplit == NULL)
312 return NULL;
313
314 // Make a copy of the original string.
315 i = 0;
316 pszHead = (char *) pszCsv;
317 if ((ppszSplit[i++] = lscp_unquote(&pszHead, 1)) == NULL) {
318 free(ppszSplit);
319 return NULL;
320 }
321
322 // Go on for it...
323 cchSeps = strlen(pszSeps);
324 while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {
325 // Pre-advance to next item.
326 pszHead = pch + cchSeps;
327 // Trim and null terminate current item.
328 while (isspace(*(pch - 1)) && pch > ppszSplit[0])
329 --pch;
330 *pch = (char) 0;
331 // Make it official.
332 ppszSplit[i] = lscp_unquote(&pszHead, 0);
333 // Do we need to grow?
334 if (++i >= iSize) {
335 // Yes, but only grow in chunks.
336 iSize += LSCP_SPLIT_CHUNK1;
337 // Allocate and copy to new split array.
338 ppszNewSplit = (char **) malloc(iSize * sizeof(char *));
339 if (ppszNewSplit) {
340 for (j = 0; j < i; j++)
341 ppszNewSplit[j] = ppszSplit[j];
342 free(ppszSplit);
343 ppszSplit = ppszNewSplit;
344 }
345 }
346 }
347
348 // NULL terminate split array.
349 for ( ; i < iSize; i++)
350 ppszSplit[i] = NULL;
351
352 return ppszSplit;
353 }
354
355
356 // Free allocated memory of a legal null terminated array of strings.
357 void lscp_szsplit_destroy ( char **ppszSplit )
358 {
359 // Our split string is always the first item, if any.
360 if (ppszSplit && ppszSplit[0])
361 free(ppszSplit[0]);
362 // Now free the array itself.
363 if (ppszSplit)
364 free(ppszSplit);
365 }
366
367
368 #ifdef LSCP_SZSPLIT_COUNT
369
370 // Return the number of items of a null terminated array of strings.
371 int lscp_szsplit_count ( char **ppszSplit )
372 {
373 int i = 0;
374 while (ppszSplit && ppszSplit[i])
375 i++;
376 return i;
377 }
378
379 // Return the allocated number of items of a splitted string array.
380 int lscp_szsplit_size ( char **ppszSplit )
381 {
382 return LSCP_SPLIT_SIZE(lscp_szsplit_count(ppszSplit));
383 }
384
385 #endif // LSCP_SZSPLIT_COUNT
386
387
388 // Split a comma separated string into a -1 terminated array of positive integers.
389 int *lscp_isplit_create ( const char *pszCsv, const char *pszSeps )
390 {
391 char *pchHead, *pch;
392 int iSize, i, j, cchSeps;
393 int *piSplit, *piNewSplit;
394
395 // Get it clean first.
396 pchHead = lscp_ltrim((char *) pszCsv);
397 if (*pchHead == (char) 0)
398 return NULL;
399
400 // Initial size is one chunk away.
401 iSize = LSCP_SPLIT_CHUNK1;
402 // Allocate and split...
403 piSplit = (int *) malloc(iSize * sizeof(int));
404 if (piSplit == NULL)
405 return NULL;
406
407 // Make a copy of the original string.
408 i = 0;
409 if ((piSplit[i++] = atoi(pchHead)) < 0) {
410 free(piSplit);
411 return NULL;
412 }
413
414 // Go on for it...
415 cchSeps = strlen(pszSeps);
416 while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {
417 // Pre-advance to next item.
418 pchHead = pch + cchSeps;
419 // Make it official.
420 piSplit[i] = atoi(pchHead);
421 // Do we need to grow?
422 if (++i >= iSize) {
423 // Yes, but only grow in chunks.
424 iSize += LSCP_SPLIT_CHUNK1;
425 // Allocate and copy to new split array.
426 piNewSplit = (int *) malloc(iSize * sizeof(int));
427 if (piNewSplit) {
428 for (j = 0; j < i; j++)
429 piNewSplit[j] = piSplit[j];
430 free(piSplit);
431 piSplit = piNewSplit;
432 }
433 }
434 }
435
436 // NULL terminate split array.
437 for ( ; i < iSize; i++)
438 piSplit[i] = -1;
439
440 return piSplit;
441 }
442
443
444 // Destroy a integer splitted array.
445 void lscp_isplit_destroy ( int *piSplit )
446 {
447 if (piSplit)
448 free(piSplit);
449 }
450
451
452 #ifdef LSCP_ISPLIT_COUNT
453
454 // Compute a string list valid item count.
455 int lscp_isplit_count ( int *piSplit )
456 {
457 int i = 0;
458 while (piSplit && piSplit[i] >= 0)
459 i++;
460 return i;
461 }
462
463 // Compute a string list size.
464 int lscp_isplit_size ( int *piSplit )
465 {
466 return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
467 }
468
469 #endif // LSCP_ISPLIT_COUNT
470
471
472 // Split a string into a null terminated array of parameter items.
473 lscp_param_t *lscp_psplit_create ( const char *pszCsv, const char *pszSeps1, const char *pszSeps2 )
474 {
475 char *pszHead, *pch;
476 int iSize, i, j, cchSeps1, cchSeps2;
477 lscp_param_t *ppSplit, *ppNewSplit;
478
479 pszHead = strdup(pszCsv);
480 if (pszHead == NULL)
481 return NULL;
482
483 iSize = LSCP_SPLIT_CHUNK1;
484 ppSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
485 if (ppSplit == NULL) {
486 free(pszHead);
487 return NULL;
488 }
489
490 cchSeps1 = strlen(pszSeps1);
491 cchSeps2 = strlen(pszSeps2);
492
493 i = 0;
494 while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {
495 ppSplit[i].key = pszHead;
496 pszHead = pch + cchSeps1;
497 *pch = (char) 0;
498 ppSplit[i].value = lscp_unquote(&pszHead, 0);
499 if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {
500 pszHead = pch + cchSeps2;
501 *pch = (char) 0;
502 }
503 if (++i >= iSize) {
504 iSize += LSCP_SPLIT_CHUNK1;
505 ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
506 if (ppNewSplit) {
507 for (j = 0; j < i; j++) {
508 ppNewSplit[j].key = ppSplit[j].key;
509 ppNewSplit[j].value = ppSplit[j].value;
510 }
511 free(ppSplit);
512 ppSplit = ppNewSplit;
513 }
514 }
515 }
516
517 if (i < 1)
518 free(pszHead);
519
520 for ( ; i < iSize; i++) {
521 ppSplit[i].key = NULL;
522 ppSplit[i].value = NULL;
523 }
524
525 return ppSplit;
526 }
527
528
529 // Destroy a parameter list array.
530 void lscp_psplit_destroy ( lscp_param_t *ppSplit )
531 {
532 if (ppSplit && ppSplit[0].key)
533 free(ppSplit[0].key);
534 if (ppSplit)
535 free(ppSplit);
536 }
537
538
539 #ifdef LSCP_PSPLIT_COUNT
540
541 // Compute a parameter list valid item count.
542 int lscp_psplit_count ( lscp_param_t *ppSplit )
543 {
544 int i = 0;
545 while (ppSplit && ppSplit[i].key)
546 i++;
547 return i;
548 }
549
550 // Compute a parameter list size.
551 int lscp_psplit_size ( lscp_param_t *ppSplit )
552 {
553 return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));
554 }
555
556 #endif // LSCP_PSPLIT_COUNT
557
558
559 // Allocate a parameter list, optionally copying an existing one.
560 void lscp_plist_alloc (lscp_param_t **ppList)
561 {
562 lscp_param_t *pParams;
563 int iSize, i;
564
565 if (ppList) {
566 iSize = LSCP_SPLIT_CHUNK1;
567 pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
568 if (pParams) {
569 for (i = 0 ; i < iSize; i++) {
570 pParams[i].key = NULL;
571 pParams[i].value = NULL;
572 }
573 }
574 *ppList = pParams;
575 }
576 }
577
578
579 // Destroy a parameter list, including all it's contents.
580 void lscp_plist_free ( lscp_param_t **ppList )
581 {
582 lscp_param_t *pParams;
583 int i;
584
585 if (ppList) {
586 if (*ppList) {
587 pParams = *ppList;
588 for (i = 0; pParams && pParams[i].key; i++) {
589 free(pParams[i].key);
590 free(pParams[i].value);
591 }
592 free(pParams);
593 }
594 *ppList = NULL;
595 }
596 }
597
598
599 // Add an item to a parameter list, growing it as fit.
600 void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue )
601 {
602 lscp_param_t *pParams;
603 lscp_param_t *pNewParams;
604 int iSize, iNewSize;
605 int i = 0;
606
607 if (ppList && *ppList) {
608 pParams = *ppList;
609 while (pParams[i].key) {
610 if (strcasecmp(pParams[i].key, pszKey) == 0) {
611 if (pParams[i].value)
612 free(pParams[i].value);
613 pParams[i].value = strdup(pszValue);
614 return;
615 }
616 i++;
617 }
618 iSize = LSCP_SPLIT_SIZE(i);
619 pParams[i].key = strdup(pszKey);
620 pParams[i].value = strdup(pszValue);
621 if (++i >= iSize) {
622 iNewSize = iSize + LSCP_SPLIT_CHUNK1;
623 pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t));
624 for (i = 0; i < iSize; i++) {
625 pNewParams[i].key = pParams[i].key;
626 pNewParams[i].value = pParams[i].value;
627 }
628 for ( ; i < iNewSize; i++) {
629 pNewParams[i].key = NULL;
630 pNewParams[i].value = NULL;
631 }
632 free(pParams);
633 *ppList = pNewParams;
634 }
635 }
636 }
637
638 #ifdef LSCP_PLIST_COUNT
639
640 // Compute a parameter list valid item count.
641 int lscp_plist_count ( lscp_param_t **ppList )
642 {
643 lscp_param_t *pParams;
644 int i = 0;
645 if (ppList && *ppList) {
646 pParams = *ppList;
647 while (pParams[i].key)
648 i++;
649 }
650 return i;
651 }
652
653 // Compute the legal parameter list size.
654 int lscp_plist_size ( lscp_param_t **ppList )
655 {
656 return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));
657 }
658
659 #endif // LSCP_PLIST_COUNT
660
661
662 //-------------------------------------------------------------------------
663 // Server info struct helper functions.
664
665 void lscp_server_info_init ( lscp_server_info_t *pServerInfo )
666 {
667 pServerInfo->description = NULL;
668 pServerInfo->version = NULL;
669 }
670
671 void lscp_server_info_free ( lscp_server_info_t *pServerInfo )
672 {
673 if (pServerInfo->description)
674 free(pServerInfo->description);
675 if (pServerInfo->version)
676 free(pServerInfo->version);
677 }
678
679 void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )
680 {
681 lscp_server_info_free(pServerInfo);
682 lscp_server_info_init(pServerInfo);
683 }
684
685
686 //-------------------------------------------------------------------------
687 // Engine info struct helper functions.
688
689 void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
690 {
691 pEngineInfo->description = NULL;
692 pEngineInfo->version = NULL;
693 }
694
695 void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
696 {
697 if (pEngineInfo->description)
698 free(pEngineInfo->description);
699 if (pEngineInfo->version)
700 free(pEngineInfo->version);
701 }
702
703 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
704 {
705 lscp_engine_info_free(pEngineInfo);
706 lscp_engine_info_init(pEngineInfo);
707 }
708
709
710 //-------------------------------------------------------------------------
711 // Channel info struct helper functions.
712
713 void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
714 {
715 pChannelInfo->engine_name = NULL;
716 pChannelInfo->audio_device = 0;
717 pChannelInfo->audio_channels = 0;
718 pChannelInfo->audio_routing = NULL;
719 pChannelInfo->instrument_file = NULL;
720 pChannelInfo->instrument_nr = 0;
721 pChannelInfo->instrument_name = NULL;
722 pChannelInfo->instrument_status = 0;
723 pChannelInfo->midi_device = 0;
724 pChannelInfo->midi_port = 0;
725 pChannelInfo->midi_channel = 0;
726 pChannelInfo->volume = 0.0;
727 }
728
729 void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
730 {
731 if (pChannelInfo->engine_name)
732 free(pChannelInfo->engine_name);
733 if (pChannelInfo->audio_routing)
734 lscp_szsplit_destroy(pChannelInfo->audio_routing);
735 if (pChannelInfo->instrument_file)
736 free(pChannelInfo->instrument_file);
737 if (pChannelInfo->instrument_name)
738 free(pChannelInfo->instrument_name);
739 }
740
741 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
742 {
743 lscp_channel_info_free(pChannelInfo);
744 lscp_channel_info_init(pChannelInfo);
745 }
746
747
748 //-------------------------------------------------------------------------
749 // Driver info struct functions.
750
751 void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
752 {
753 pDriverInfo->description = NULL;
754 pDriverInfo->version = NULL;
755 pDriverInfo->parameters = NULL;
756 }
757
758 void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
759 {
760 if (pDriverInfo->description)
761 free(pDriverInfo->description);
762 if (pDriverInfo->version)
763 free(pDriverInfo->version);
764 lscp_szsplit_destroy(pDriverInfo->parameters);
765 }
766
767 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
768 {
769 lscp_driver_info_free(pDriverInfo);
770 lscp_driver_info_init(pDriverInfo);
771 }
772
773
774 //-------------------------------------------------------------------------
775 // Device info struct functions.
776
777 void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
778 {
779 pDeviceInfo->driver = NULL;
780 lscp_plist_alloc(&(pDeviceInfo->params));
781 }
782
783 void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
784 {
785 if (pDeviceInfo->driver)
786 free(pDeviceInfo->driver);
787 lscp_plist_free(&(pDeviceInfo->params));
788 }
789
790 void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
791 {
792 lscp_device_info_free(pDeviceInfo);
793 lscp_device_info_init(pDeviceInfo);
794 }
795
796
797 //-------------------------------------------------------------------------
798 // Device channel/port info struct functions.
799
800 void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
801 {
802 pDevicePortInfo->name = NULL;
803 lscp_plist_alloc(&(pDevicePortInfo->params));
804 }
805
806 void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
807 {
808 if (pDevicePortInfo->name)
809 free(pDevicePortInfo->name);
810 lscp_plist_free(&(pDevicePortInfo->params));
811 }
812
813 void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
814 {
815 lscp_device_port_info_free(pDevicePortInfo);
816 lscp_device_port_info_init(pDevicePortInfo);
817 }
818
819
820 //-------------------------------------------------------------------------
821 // Parameter struct helper functions.
822
823 void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
824 {
825 pParamInfo->type = LSCP_TYPE_NONE;
826 pParamInfo->description = NULL;
827 pParamInfo->mandatory = 0;
828 pParamInfo->fix = 0;
829 pParamInfo->multiplicity = 0;
830 pParamInfo->depends = NULL;
831 pParamInfo->defaultv = NULL;
832 pParamInfo->range_min = NULL;
833 pParamInfo->range_max = NULL;
834 pParamInfo->possibilities = NULL;
835 }
836
837 void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
838 {
839 if (pParamInfo->description)
840 free(pParamInfo->description);
841 lscp_szsplit_destroy(pParamInfo->depends);
842 if (pParamInfo->defaultv)
843 free(pParamInfo->defaultv);
844 if (pParamInfo->range_min)
845 free(pParamInfo->range_min);
846 if (pParamInfo->range_max)
847 free(pParamInfo->range_max);
848 lscp_szsplit_destroy(pParamInfo->possibilities);
849 }
850
851 void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
852 {
853 lscp_param_info_free(pParamInfo);
854 lscp_param_info_init(pParamInfo);
855 }
856
857
858 //-------------------------------------------------------------------------
859 // Concatenate a parameter list (key='value'...) into a string,
860 // appending a crlf terminator.
861
862 int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
863 {
864 int cchBuffer, cchParam, i;
865
866 if (pszBuffer == NULL)
867 return 0;
868
869 cchBuffer = strlen(pszBuffer);
870 for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
871 cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
872 if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
873 sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
874 cchBuffer += cchParam;
875 }
876 }
877
878 if (cchBuffer + 2 < cchMaxBuffer) {
879 pszBuffer[cchBuffer++] = '\r';
880 pszBuffer[cchBuffer++] = '\n';
881 pszBuffer[cchBuffer ] = (char) 0;
882 }
883
884 return cchBuffer;
885 }
886
887
888 // end of common.c

  ViewVC Help
Powered by ViewVC