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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 419 - (show annotations) (download)
Wed Mar 2 16:25:27 2005 UTC (19 years, 1 month ago) by capela
File MIME type: text/plain
File size: 24159 byte(s)
Mini bitsy regression.

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 // Engine info struct helper functions.
664
665 void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
666 {
667 pEngineInfo->description = NULL;
668 pEngineInfo->version = NULL;
669 }
670
671 void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
672 {
673 if (pEngineInfo->description)
674 free(pEngineInfo->description);
675 if (pEngineInfo->version)
676 free(pEngineInfo->version);
677 }
678
679 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
680 {
681 lscp_engine_info_free(pEngineInfo);
682 lscp_engine_info_init(pEngineInfo);
683 }
684
685
686 //-------------------------------------------------------------------------
687 // Channel info struct helper functions.
688
689 void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
690 {
691 pChannelInfo->engine_name = NULL;
692 pChannelInfo->audio_device = 0;
693 pChannelInfo->audio_channels = 0;
694 pChannelInfo->audio_routing = NULL;
695 pChannelInfo->instrument_file = NULL;
696 pChannelInfo->instrument_nr = 0;
697 pChannelInfo->instrument_name = NULL;
698 pChannelInfo->instrument_status = 0;
699 pChannelInfo->midi_device = 0;
700 pChannelInfo->midi_port = 0;
701 pChannelInfo->midi_channel = 0;
702 pChannelInfo->volume = 0.0;
703 }
704
705 void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
706 {
707 if (pChannelInfo->engine_name)
708 free(pChannelInfo->engine_name);
709 if (pChannelInfo->audio_routing)
710 lscp_szsplit_destroy(pChannelInfo->audio_routing);
711 if (pChannelInfo->instrument_file)
712 free(pChannelInfo->instrument_file);
713 if (pChannelInfo->instrument_name)
714 free(pChannelInfo->instrument_name);
715 }
716
717 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
718 {
719 lscp_channel_info_free(pChannelInfo);
720 lscp_channel_info_init(pChannelInfo);
721 }
722
723
724 //-------------------------------------------------------------------------
725 // Driver info struct functions.
726
727 void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
728 {
729 pDriverInfo->description = NULL;
730 pDriverInfo->version = NULL;
731 pDriverInfo->parameters = NULL;
732 }
733
734 void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
735 {
736 if (pDriverInfo->description)
737 free(pDriverInfo->description);
738 if (pDriverInfo->version)
739 free(pDriverInfo->version);
740 lscp_szsplit_destroy(pDriverInfo->parameters);
741 }
742
743 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
744 {
745 lscp_driver_info_free(pDriverInfo);
746 lscp_driver_info_init(pDriverInfo);
747 }
748
749
750 //-------------------------------------------------------------------------
751 // Device info struct functions.
752
753 void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
754 {
755 pDeviceInfo->driver = NULL;
756 lscp_plist_alloc(&(pDeviceInfo->params));
757 }
758
759 void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
760 {
761 if (pDeviceInfo->driver)
762 free(pDeviceInfo->driver);
763 lscp_plist_free(&(pDeviceInfo->params));
764 }
765
766 void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
767 {
768 lscp_device_info_free(pDeviceInfo);
769 lscp_device_info_init(pDeviceInfo);
770 }
771
772
773 //-------------------------------------------------------------------------
774 // Device channel/port info struct functions.
775
776 void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
777 {
778 pDevicePortInfo->name = NULL;
779 lscp_plist_alloc(&(pDevicePortInfo->params));
780 }
781
782 void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
783 {
784 if (pDevicePortInfo->name)
785 free(pDevicePortInfo->name);
786 lscp_plist_free(&(pDevicePortInfo->params));
787 }
788
789 void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
790 {
791 lscp_device_port_info_free(pDevicePortInfo);
792 lscp_device_port_info_init(pDevicePortInfo);
793 }
794
795
796 //-------------------------------------------------------------------------
797 // Parameter struct helper functions.
798
799 void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
800 {
801 pParamInfo->type = LSCP_TYPE_NONE;
802 pParamInfo->description = NULL;
803 pParamInfo->mandatory = 0;
804 pParamInfo->fix = 0;
805 pParamInfo->multiplicity = 0;
806 pParamInfo->depends = NULL;
807 pParamInfo->defaultv = NULL;
808 pParamInfo->range_min = NULL;
809 pParamInfo->range_max = NULL;
810 pParamInfo->possibilities = NULL;
811 }
812
813 void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
814 {
815 if (pParamInfo->description)
816 free(pParamInfo->description);
817 lscp_szsplit_destroy(pParamInfo->depends);
818 if (pParamInfo->defaultv)
819 free(pParamInfo->defaultv);
820 if (pParamInfo->range_min)
821 free(pParamInfo->range_min);
822 if (pParamInfo->range_max)
823 free(pParamInfo->range_max);
824 lscp_szsplit_destroy(pParamInfo->possibilities);
825 }
826
827 void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
828 {
829 lscp_param_info_free(pParamInfo);
830 lscp_param_info_init(pParamInfo);
831 }
832
833
834 //-------------------------------------------------------------------------
835 // Concatenate a parameter list (key='value'...) into a string,
836 // appending a crlf terminator.
837
838 int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
839 {
840 int cchBuffer, cchParam, i;
841
842 if (pszBuffer == NULL)
843 return 0;
844
845 cchBuffer = strlen(pszBuffer);
846 for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
847 cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
848 if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
849 sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
850 cchBuffer += cchParam;
851 }
852 }
853
854 if (cchBuffer + 2 < cchMaxBuffer) {
855 pszBuffer[cchBuffer++] = '\r';
856 pszBuffer[cchBuffer++] = '\n';
857 pszBuffer[cchBuffer ] = (char) 0;
858 }
859
860 return cchBuffer;
861 }
862
863
864 // end of common.c

  ViewVC Help
Powered by ViewVC