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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 180 - (show annotations) (download)
Tue Jul 6 20:20:51 2004 UTC (19 years, 8 months ago) by capela
File MIME type: text/plain
File size: 23434 byte(s)
Prepared for 0.2.0 release.

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 // Initial size is one chunk away.
362 iSize = LSCP_SPLIT_CHUNK1;
363 // Allocate and split...
364 piSplit = (int *) malloc(iSize * sizeof(int));
365 if (piSplit == NULL)
366 return NULL;
367
368 // Make a copy of the original string.
369 i = 0;
370 pchHead = (char *) pszCsv;
371 if ((piSplit[i++] = atoi(pchHead)) < 0) {
372 free(piSplit);
373 return NULL;
374 }
375
376 // Go on for it...
377 cchSeps = strlen(pszSeps);
378 while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {
379 // Pre-advance to next item.
380 pchHead = pch + cchSeps;
381 // Make it official.
382 piSplit[i++] = atoi(pchHead);
383 // Do we need to grow?
384 if (i >= iSize) {
385 // Yes, but only grow in chunks.
386 iSize += LSCP_SPLIT_CHUNK1;
387 // Allocate and copy to new split array.
388 piNewSplit = (int *) malloc(iSize * sizeof(int));
389 if (piNewSplit) {
390 for (j = 0; j < i; j++)
391 piNewSplit[j] = piSplit[j];
392 free(piSplit);
393 piSplit = piNewSplit;
394 }
395 }
396 }
397
398 // NULL terminate split array.
399 for ( ; i < iSize; i++)
400 piSplit[i] = -1;
401
402 return piSplit;
403 }
404
405
406 // Destroy a integer splitted array.
407 void lscp_isplit_destroy ( int *piSplit )
408 {
409 if (piSplit)
410 free(piSplit);
411 }
412
413
414 #ifdef LSCP_ISPLIT_COUNT
415
416 // Compute a string list valid item count.
417 int lscp_isplit_count ( int *piSplit )
418 {
419 int i = 0;
420 while (piSplit && piSplit[i] >= 0)
421 i++;
422 return i;
423 }
424
425 // Compute a string list size.
426 int lscp_isplit_size ( int *piSplit )
427 {
428 return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
429 }
430
431 #endif // LSCP_ISPLIT_COUNT
432
433
434 // Split a string into a null terminated array of parameter items.
435 lscp_param_t *lscp_psplit_create ( const char *pszCsv, const char *pszSeps1, const char *pszSeps2 )
436 {
437 char *pszHead, *pch;
438 int iSize, i, j, cchSeps1, cchSeps2;
439 lscp_param_t *ppSplit, *ppNewSplit;
440
441 pszHead = strdup(pszCsv);
442 if (pszHead == NULL)
443 return NULL;
444
445 iSize = LSCP_SPLIT_CHUNK1;
446 ppSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
447 if (ppSplit == NULL) {
448 free(pszHead);
449 return NULL;
450 }
451
452 cchSeps1 = strlen(pszSeps1);
453 cchSeps2 = strlen(pszSeps2);
454
455 i = 0;
456 while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {
457 ppSplit[i].key = pszHead;
458 pszHead = pch + cchSeps1;
459 *pch = (char) 0;
460 ppSplit[i].value = lscp_unquote(&pszHead, 0);
461 if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {
462 pszHead = pch + cchSeps2;
463 *pch = (char) 0;
464 }
465 if (++i >= iSize) {
466 iSize += LSCP_SPLIT_CHUNK1;
467 ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
468 if (ppNewSplit) {
469 for (j = 0; j < i; j++) {
470 ppNewSplit[j].key = ppSplit[j].key;
471 ppNewSplit[j].value = ppSplit[j].value;
472 }
473 free(ppSplit);
474 ppSplit = ppNewSplit;
475 }
476 }
477 }
478
479 if (i < 1)
480 free(pszHead);
481
482 for ( ; i < iSize; i++) {
483 ppSplit[i].key = NULL;
484 ppSplit[i].value = NULL;
485 }
486
487 return ppSplit;
488 }
489
490
491 // Destroy a parameter list array.
492 void lscp_psplit_destroy ( lscp_param_t *ppSplit )
493 {
494 if (ppSplit && ppSplit[0].key)
495 free(ppSplit[0].key);
496 if (ppSplit)
497 free(ppSplit);
498 }
499
500
501 #ifdef LSCP_PSPLIT_COUNT
502
503 // Compute a parameter list valid item count.
504 int lscp_psplit_count ( lscp_param_t *ppSplit )
505 {
506 int i = 0;
507 while (ppSplit && ppSplit[i].key)
508 i++;
509 return i;
510 }
511
512 // Compute a parameter list size.
513 int lscp_psplit_size ( lscp_param_t *ppSplit )
514 {
515 return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));
516 }
517
518 #endif // LSCP_PSPLIT_COUNT
519
520
521 // Allocate a parameter list, optionally copying an existing one.
522 void lscp_plist_alloc (lscp_param_t **ppList)
523 {
524 lscp_param_t *pParams;
525 int iSize, i;
526
527 if (ppList) {
528 iSize = LSCP_SPLIT_CHUNK1;
529 pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
530 if (pParams) {
531 for (i = 0 ; i < iSize; i++) {
532 pParams[i].key = NULL;
533 pParams[i].value = NULL;
534 }
535 }
536 *ppList = pParams;
537 }
538 }
539
540
541 // Destroy a parameter list, including all it's contents.
542 void lscp_plist_free ( lscp_param_t **ppList )
543 {
544 lscp_param_t *pParams;
545 int i;
546
547 if (ppList) {
548 if (*ppList) {
549 pParams = *ppList;
550 for (i = 0; pParams && pParams[i].key; i++) {
551 free(pParams[i].key);
552 free(pParams[i].value);
553 }
554 free(pParams);
555 }
556 *ppList = NULL;
557 }
558 }
559
560
561 // Add an item to a parameter list, growing it as fit.
562 void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue )
563 {
564 lscp_param_t *pParams;
565 lscp_param_t *pNewParams;
566 int iSize, iNewSize;
567 int i = 0;
568
569 if (ppList && *ppList) {
570 pParams = *ppList;
571 while (pParams[i].key) {
572 if (strcasecmp(pParams[i].key, pszKey) == 0) {
573 if (pParams[i].value)
574 free(pParams[i].value);
575 pParams[i].value = strdup(pszValue);
576 return;
577 }
578 i++;
579 }
580 iSize = LSCP_SPLIT_SIZE(i);
581 pParams[i].key = strdup(pszKey);
582 pParams[i].value = strdup(pszValue);
583 if (++i >= iSize) {
584 iNewSize = iSize + LSCP_SPLIT_CHUNK1;
585 pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t));
586 for (i = 0; i < iSize; i++) {
587 pParams[i].key = pParams[i].key;
588 pParams[i].value = pParams[i].value;
589 }
590 for ( ; i < iNewSize; i++) {
591 pNewParams[i].key = NULL;
592 pNewParams[i].value = NULL;
593 }
594 free(pParams);
595 *ppList = pNewParams;
596 }
597 }
598 }
599
600 #ifdef LSCP_PLIST_COUNT
601
602 // Compute a parameter list valid item count.
603 int lscp_plist_count ( lscp_param_t **ppList )
604 {
605 lscp_param_t *pParams;
606 int i = 0;
607 if (ppList && *ppList) {
608 pParams = *ppList;
609 while (pParams[i].key)
610 i++;
611 }
612 return i;
613 }
614
615 // Compute the legal parameter list size.
616 int lscp_plist_size ( lscp_param_t **ppList )
617 {
618 return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));
619 }
620
621 #endif // LSCP_PLIST_COUNT
622
623
624 //-------------------------------------------------------------------------
625 // Engine info struct helper functions.
626
627 void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
628 {
629 pEngineInfo->description = NULL;
630 pEngineInfo->version = NULL;
631 }
632
633 void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
634 {
635 if (pEngineInfo->description)
636 free(pEngineInfo->description);
637 if (pEngineInfo->version)
638 free(pEngineInfo->version);
639 }
640
641 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
642 {
643 lscp_engine_info_free(pEngineInfo);
644 lscp_engine_info_init(pEngineInfo);
645 }
646
647
648 //-------------------------------------------------------------------------
649 // Channel info struct helper functions.
650
651 void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
652 {
653 pChannelInfo->engine_name = NULL;
654 pChannelInfo->audio_device = 0;
655 pChannelInfo->audio_channels = 0;
656 pChannelInfo->audio_routing = NULL;
657 pChannelInfo->instrument_file = NULL;
658 pChannelInfo->instrument_nr = 0;
659 pChannelInfo->instrument_status = 0;
660 pChannelInfo->midi_device = 0;
661 pChannelInfo->midi_port = 0;
662 pChannelInfo->midi_channel = 0;
663 pChannelInfo->volume = 0.0;
664 }
665
666 void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
667 {
668 if (pChannelInfo->engine_name)
669 free(pChannelInfo->engine_name);
670 if (pChannelInfo->audio_routing)
671 lscp_szsplit_destroy(pChannelInfo->audio_routing);
672 if (pChannelInfo->instrument_file)
673 free(pChannelInfo->instrument_file);
674 }
675
676 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
677 {
678 lscp_channel_info_free(pChannelInfo);
679 lscp_channel_info_init(pChannelInfo);
680 }
681
682
683 //-------------------------------------------------------------------------
684 // Driver info struct functions.
685
686 void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
687 {
688 pDriverInfo->description = NULL;
689 pDriverInfo->version = NULL;
690 pDriverInfo->parameters = NULL;
691 }
692
693 void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
694 {
695 if (pDriverInfo->description)
696 free(pDriverInfo->description);
697 if (pDriverInfo->version)
698 free(pDriverInfo->version);
699 lscp_szsplit_destroy(pDriverInfo->parameters);
700 }
701
702 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
703 {
704 lscp_driver_info_free(pDriverInfo);
705 lscp_driver_info_init(pDriverInfo);
706 }
707
708
709 //-------------------------------------------------------------------------
710 // Device info struct functions.
711
712 void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
713 {
714 pDeviceInfo->driver = NULL;
715 lscp_plist_alloc(&(pDeviceInfo->params));
716 }
717
718 void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
719 {
720 if (pDeviceInfo->driver)
721 free(pDeviceInfo->driver);
722 lscp_plist_free(&(pDeviceInfo->params));
723 }
724
725 void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
726 {
727 lscp_device_info_free(pDeviceInfo);
728 lscp_device_info_init(pDeviceInfo);
729 }
730
731
732 //-------------------------------------------------------------------------
733 // Device channel/port info struct functions.
734
735 void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
736 {
737 pDevicePortInfo->name = NULL;
738 lscp_plist_alloc(&(pDevicePortInfo->params));
739 }
740
741 void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
742 {
743 if (pDevicePortInfo->name)
744 free(pDevicePortInfo->name);
745 lscp_plist_free(&(pDevicePortInfo->params));
746 }
747
748 void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
749 {
750 lscp_device_port_info_free(pDevicePortInfo);
751 lscp_device_port_info_init(pDevicePortInfo);
752 }
753
754
755 //-------------------------------------------------------------------------
756 // Parameter struct helper functions.
757
758 void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
759 {
760 pParamInfo->type = LSCP_TYPE_NONE;
761 pParamInfo->description = NULL;
762 pParamInfo->mandatory = 0;
763 pParamInfo->fix = 0;
764 pParamInfo->multiplicity = 0;
765 pParamInfo->depends = NULL;
766 pParamInfo->defaultv = NULL;
767 pParamInfo->range_min = NULL;
768 pParamInfo->range_max = NULL;
769 pParamInfo->possibilities = NULL;
770 }
771
772 void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
773 {
774 if (pParamInfo->description)
775 free(pParamInfo->description);
776 lscp_szsplit_destroy(pParamInfo->depends);
777 if (pParamInfo->defaultv)
778 free(pParamInfo->defaultv);
779 if (pParamInfo->range_min)
780 free(pParamInfo->range_min);
781 if (pParamInfo->range_max)
782 free(pParamInfo->range_max);
783 lscp_szsplit_destroy(pParamInfo->possibilities);
784 }
785
786 void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
787 {
788 lscp_param_info_free(pParamInfo);
789 lscp_param_info_init(pParamInfo);
790 }
791
792
793 //-------------------------------------------------------------------------
794 // Concatenate a parameter list (key='value'...) into a string,
795 // appending a crlf terminator.
796
797 int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
798 {
799 int cchBuffer, cchParam, i;
800
801 if (pszBuffer == NULL || pParams == NULL)
802 return 0;
803
804 cchBuffer = strlen(pszBuffer);
805 for (i = 0; pParams[i].key && pParams[i].value; i++) {
806 cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
807 if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
808 sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
809 cchBuffer += cchParam;
810 }
811 }
812
813 if (cchBuffer + 2 < cchMaxBuffer) {
814 pszBuffer[cchBuffer++] = '\r';
815 pszBuffer[cchBuffer++] = '\n';
816 }
817
818 return cchBuffer;
819 }
820
821
822 // end of common.c

  ViewVC Help
Powered by ViewVC