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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 189 - (show annotations) (download)
Thu Jul 8 16:31:47 2004 UTC (19 years, 8 months ago) by capela
File MIME type: text/plain
File size: 23564 byte(s)
- fixes underway; example_client/server are better crash test dummies now.

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

  ViewVC Help
Powered by ViewVC