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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 180 - (hide 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 capela 144 // common.c
2 capela 103 //
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 capela 158 // Split chunk size magic:
29     // LSCP_SPLIT_CHUNK1 := 2 ^ LSCP_SPLIT_CHUNK2
30 capela 103 #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 capela 132 // Local client request executive.
38 capela 103
39 capela 132 // 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 capela 103 // 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 capela 180 // 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 capela 103
238 capela 180
239 capela 103 // 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 capela 125 // 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 capela 158 // 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 capela 163 ppSplit[i].value = lscp_unquote(&pszHead, 0);
461 capela 158 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 capela 163 ppNewSplit[j].key = ppSplit[j].key;
471     ppNewSplit[j].value = ppSplit[j].value;
472 capela 158 }
473     free(ppSplit);
474     ppSplit = ppNewSplit;
475     }
476     }
477     }
478    
479     if (i < 1)
480     free(pszHead);
481    
482     for ( ; i < iSize; i++) {
483 capela 163 ppSplit[i].key = NULL;
484     ppSplit[i].value = NULL;
485 capela 158 }
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 capela 171 // 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 capela 180 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 capela 171 i++;
579 capela 180 }
580 capela 171 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 capela 180 #ifdef LSCP_PLIST_COUNT
601 capela 171
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 capela 180 #endif // LSCP_PLIST_COUNT
622 capela 171
623    
624 capela 103 //-------------------------------------------------------------------------
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 capela 179 void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
634 capela 103 {
635     if (pEngineInfo->description)
636     free(pEngineInfo->description);
637     if (pEngineInfo->version)
638     free(pEngineInfo->version);
639 capela 179 }
640 capela 103
641 capela 179 void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
642     {
643     lscp_engine_info_free(pEngineInfo);
644 capela 103 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 capela 132 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 capela 103 }
665    
666 capela 179 void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
667 capela 103 {
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 capela 179 }
675 capela 103
676 capela 179 void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
677     {
678     lscp_channel_info_free(pChannelInfo);
679 capela 103 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 capela 179 void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
694 capela 103 {
695     if (pDriverInfo->description)
696     free(pDriverInfo->description);
697     if (pDriverInfo->version)
698     free(pDriverInfo->version);
699     lscp_szsplit_destroy(pDriverInfo->parameters);
700 capela 179 }
701 capela 103
702 capela 179 void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
703     {
704     lscp_driver_info_free(pDriverInfo);
705 capela 103 lscp_driver_info_init(pDriverInfo);
706     }
707    
708    
709 capela 163 //-------------------------------------------------------------------------
710 capela 171 // 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 capela 179 void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
719 capela 171 {
720     if (pDeviceInfo->driver)
721     free(pDeviceInfo->driver);
722     lscp_plist_free(&(pDeviceInfo->params));
723 capela 179 }
724 capela 171
725 capela 179 void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
726     {
727     lscp_device_info_free(pDeviceInfo);
728 capela 171 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 capela 179 void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
742 capela 171 {
743     if (pDevicePortInfo->name)
744     free(pDevicePortInfo->name);
745     lscp_plist_free(&(pDevicePortInfo->params));
746 capela 179 }
747 capela 171
748 capela 179 void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
749     {
750     lscp_device_port_info_free(pDevicePortInfo);
751 capela 171 lscp_device_port_info_init(pDevicePortInfo);
752     }
753    
754    
755     //-------------------------------------------------------------------------
756 capela 163 // 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 capela 179 void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
773 capela 163 {
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 capela 179 }
785    
786     void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
787     {
788     lscp_param_info_free(pParamInfo);
789 capela 163 lscp_param_info_init(pParamInfo);
790     }
791    
792    
793     //-------------------------------------------------------------------------
794 capela 171 // Concatenate a parameter list (key='value'...) into a string,
795     // appending a crlf terminator.
796 capela 163
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 capela 171 if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
808 capela 163 sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
809     cchBuffer += cchParam;
810     }
811     }
812 capela 171
813     if (cchBuffer + 2 < cchMaxBuffer) {
814     pszBuffer[cchBuffer++] = '\r';
815     pszBuffer[cchBuffer++] = '\n';
816     }
817    
818 capela 163 return cchBuffer;
819     }
820    
821    
822 capela 103 // end of common.c

  ViewVC Help
Powered by ViewVC