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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 103 by capela, Fri Jun 4 14:32:51 2004 UTC revision 869 by capela, Thu Jun 1 08:32:16 2006 UTC
# Line 1  Line 1 
1  // client.c  // common.c
2  //  //
3  /****************************************************************************  /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API     liblscp - LinuxSampler Control Protocol API
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2006, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This library is free software; you can redistribute it and/or     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public     modify it under the terms of the GNU Lesser General Public
# Line 25  Line 25 
25  #include <ctype.h>  #include <ctype.h>
26    
27    
28  // Chunk size magic:  // Split chunk size magic:
29  // LSCP_SPLIT_CHUNK1 = 2 ^ LSCP_SPLIT_CHUNK2  // LSCP_SPLIT_CHUNK1 := 2 ^ LSCP_SPLIT_CHUNK2
30  #define LSCP_SPLIT_CHUNK1   4  #define LSCP_SPLIT_CHUNK1   4
31  #define LSCP_SPLIT_CHUNK2   2  #define LSCP_SPLIT_CHUNK2   2
32  // Chunk size legal calculator.  // Chunk size legal calculator.
# Line 34  Line 34 
34    
35    
36  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
37  // General utility functions.  // 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            // Check if last transaction has timed out, in which case
137            // we'll retry wait and flush for some pending garbage...
138            if (pClient->iTimeoutCount > 0) {
139                    cchResult = sizeof(achResult);
140                    ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);
141                    if (ret == LSCP_OK) {
142                            // We've got rid of timeout trouble (hopefully).
143                            pClient->iTimeoutCount = 0;
144                    } else {
145                            // Things are worse than before. Fake a result message.
146                            iErrno = (int) ret;
147                            pszResult = "Failure during flush timeout operation";
148                            lscp_client_set_result(pClient, pszResult, iErrno);
149                            return ret;
150                    }
151            }
152    
153        // Send data, and then, wait for the result...
154        cchQuery = strlen(pszQuery);
155        if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {
156            lscp_socket_perror("lscp_client_call: send");
157            pszResult = "Failure during send operation";
158            lscp_client_set_result(pClient, pszResult, iErrno);
159            return ret;
160        }
161    
162        // Wait for receive event...
163        cchResult = sizeof(achResult);
164        ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);
165    
166        switch (ret) {
167    
168          case LSCP_OK:
169            // Always force the result to be null terminated (and trim trailing CRLFs)!
170            while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))
171                cchResult--;
172            achResult[cchResult] = (char) 0;
173            // Check if the response it's an error or warning message.
174            if (strncasecmp(achResult, "WRN:", 4) == 0)
175                ret = LSCP_WARNING;
176            else if (strncasecmp(achResult, "ERR:", 4) == 0)
177                ret = LSCP_ERROR;
178            // So we got a result...
179            if (ret == LSCP_OK) {
180                // Reset errno in case of success.
181                iErrno = 0;
182                // Is it a special successful response?
183                if (strncasecmp(achResult, "OK[", 3) == 0) {
184                    // Parse the OK message, get the return string under brackets...
185                    pszToken = lscp_strtok(achResult, pszSeps, &(pch));
186                    if (pszToken)
187                        pszResult = lscp_strtok(NULL, pszSeps, &(pch));
188                }
189                else pszResult = achResult;
190                // The result string is now set to the command response, if any.
191            } else {
192                // Parse the error/warning message, skip first colon...
193                pszToken = lscp_strtok(achResult, pszSeps, &(pch));
194                if (pszToken) {
195                    // Get the error number...
196                    pszToken = lscp_strtok(NULL, pszSeps, &(pch));
197                    if (pszToken) {
198                        iErrno = atoi(pszToken);
199                        // And make the message text our final result.
200                        pszResult = lscp_strtok(NULL, pszSeps, &(pch));
201                    }
202                }
203                // The result string is set to the error/warning message text.
204            }
205            break;
206    
207          case LSCP_TIMEOUT:
208                    // We have trouble...
209                    pClient->iTimeoutCount++;
210            // Fake a result message.
211            pszResult = "Timeout during receive operation";
212            iErrno = (int) ret;
213            break;
214    
215          case LSCP_QUIT:
216            // Fake a result message.
217            pszResult = "Server terminated the connection";
218            iErrno = (int) ret;
219            break;
220    
221          case LSCP_FAILED:
222          default:
223            // What's down?
224            pszResult = "Failure during receive operation";
225            break;
226        }
227    
228        // Make the result official...
229        lscp_client_set_result(pClient, pszResult, iErrno);
230    
231        return ret;
232    }
233    
234    
235    //-------------------------------------------------------------------------
236    // Other general utility functions.
237    
238  // Trimming left spaces...  // Trimming left spaces...
239  char *lscp_ltrim ( char *psz )  char *lscp_ltrim ( char *psz )
# Line 77  char *lscp_unquote ( char **ppsz, int du Line 276  char *lscp_unquote ( char **ppsz, int du
276      return psz;      return psz;
277  }  }
278    
279    // Unquote and make a duplicate of an in-split string.
280    void lscp_unquote_dup ( char **ppszDst, char **ppszSrc )
281    {
282         // Free desteny string, if already there.
283         if (*ppszDst)
284             free(*ppszDst);
285         *ppszDst = NULL;
286         // Unquote and duplicate.
287         if (*ppszSrc)
288             *ppszDst = lscp_unquote(ppszSrc, 1);
289    }
290    
291    
292  // Custom tokenizer.  // Custom tokenizer.
293  char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )  char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )
# Line 137  char **lscp_szsplit_create ( const char Line 348  char **lscp_szsplit_create ( const char
348              --pch;              --pch;
349          *pch = (char) 0;          *pch = (char) 0;
350          // Make it official.          // Make it official.
351          ppszSplit[i++] = lscp_unquote(&pszHead, 0);          ppszSplit[i] = lscp_unquote(&pszHead, 0);
352          // Do we need to grow?          // Do we need to grow?
353          if (i >= iSize) {          if (++i >= iSize) {
354              // Yes, but only grow in chunks.              // Yes, but only grow in chunks.
355              iSize += LSCP_SPLIT_CHUNK1;              iSize += LSCP_SPLIT_CHUNK1;
356              // Allocate and copy to new split array.              // Allocate and copy to new split array.
# Line 193  int lscp_szsplit_size ( char **ppszSplit Line 404  int lscp_szsplit_size ( char **ppszSplit
404  #endif // LSCP_SZSPLIT_COUNT  #endif // LSCP_SZSPLIT_COUNT
405    
406    
407    // Split a comma separated string into a -1 terminated array of positive integers.
408    int *lscp_isplit_create ( const char *pszCsv, const char *pszSeps )
409    {
410        char *pchHead, *pch;
411        int iSize, i, j, cchSeps;
412        int *piSplit, *piNewSplit;
413    
414        // Get it clean first.
415        pchHead = lscp_ltrim((char *) pszCsv);
416        if (*pchHead == (char) 0)
417            return NULL;
418    
419        // Initial size is one chunk away.
420        iSize = LSCP_SPLIT_CHUNK1;
421        // Allocate and split...
422        piSplit = (int *) malloc(iSize * sizeof(int));
423        if (piSplit == NULL)
424            return NULL;
425    
426        // Make a copy of the original string.
427        i = 0;
428        if ((piSplit[i++] = atoi(pchHead)) < 0) {
429            free(piSplit);
430            return NULL;
431        }
432    
433        // Go on for it...
434        cchSeps = strlen(pszSeps);
435        while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {
436            // Pre-advance to next item.
437            pchHead = pch + cchSeps;
438            // Make it official.
439            piSplit[i] = atoi(pchHead);
440            // Do we need to grow?
441            if (++i >= iSize) {
442                // Yes, but only grow in chunks.
443                iSize += LSCP_SPLIT_CHUNK1;
444                // Allocate and copy to new split array.
445                piNewSplit = (int *) malloc(iSize * sizeof(int));
446                if (piNewSplit) {
447                    for (j = 0; j < i; j++)
448                        piNewSplit[j] = piSplit[j];
449                    free(piSplit);
450                    piSplit = piNewSplit;
451                }
452            }
453        }
454    
455        // NULL terminate split array.
456        for ( ; i < iSize; i++)
457            piSplit[i] = -1;
458    
459        return piSplit;
460    }
461    
462    
463    // Destroy a integer splitted array.
464    void lscp_isplit_destroy ( int *piSplit )
465    {
466        if (piSplit)
467            free(piSplit);
468    }
469    
470    
471    #ifdef LSCP_ISPLIT_COUNT
472    
473    // Compute a string list valid item count.
474    int lscp_isplit_count ( int *piSplit )
475    {
476        int i = 0;
477        while (piSplit && piSplit[i] >= 0)
478            i++;
479        return i;
480    }
481    
482    // Compute a string list size.
483    int lscp_isplit_size ( int *piSplit )
484    {
485        return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
486    }
487    
488    #endif // LSCP_ISPLIT_COUNT
489    
490    
491    // Split a string into a null terminated array of parameter items.
492    lscp_param_t *lscp_psplit_create ( const char *pszCsv, const char *pszSeps1, const char *pszSeps2 )
493    {
494        char *pszHead, *pch;
495        int iSize, i, j, cchSeps1, cchSeps2;
496        lscp_param_t *ppSplit, *ppNewSplit;
497    
498        pszHead = strdup(pszCsv);
499        if (pszHead == NULL)
500            return NULL;
501    
502        iSize = LSCP_SPLIT_CHUNK1;
503        ppSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
504        if (ppSplit == NULL) {
505            free(pszHead);
506            return NULL;
507        }
508    
509        cchSeps1 = strlen(pszSeps1);
510        cchSeps2 = strlen(pszSeps2);
511    
512        i = 0;
513        while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {
514            ppSplit[i].key = pszHead;
515            pszHead = pch + cchSeps1;
516            *pch = (char) 0;
517            ppSplit[i].value = lscp_unquote(&pszHead, 0);
518            if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {
519                pszHead = pch + cchSeps2;
520                *pch = (char) 0;
521            }
522            if (++i >= iSize) {
523                iSize += LSCP_SPLIT_CHUNK1;
524                ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
525                if (ppNewSplit) {
526                    for (j = 0; j < i; j++) {
527                        ppNewSplit[j].key   = ppSplit[j].key;
528                        ppNewSplit[j].value = ppSplit[j].value;
529                    }
530                    free(ppSplit);
531                    ppSplit = ppNewSplit;
532                }
533            }
534        }
535    
536        if (i < 1)
537            free(pszHead);
538    
539        for ( ; i < iSize; i++) {
540            ppSplit[i].key   = NULL;
541            ppSplit[i].value = NULL;
542        }
543    
544        return ppSplit;
545    }
546    
547    
548    // Destroy a parameter list array.
549    void lscp_psplit_destroy ( lscp_param_t *ppSplit )
550    {
551        if (ppSplit && ppSplit[0].key)
552            free(ppSplit[0].key);
553        if (ppSplit)
554            free(ppSplit);
555    }
556    
557    
558    #ifdef LSCP_PSPLIT_COUNT
559    
560    // Compute a parameter list valid item count.
561    int lscp_psplit_count ( lscp_param_t *ppSplit )
562    {
563        int i = 0;
564        while (ppSplit && ppSplit[i].key)
565            i++;
566        return i;
567    }
568    
569    // Compute a parameter list size.
570    int lscp_psplit_size ( lscp_param_t *ppSplit )
571    {
572        return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));
573    }
574    
575    #endif // LSCP_PSPLIT_COUNT
576    
577    
578    // Allocate a parameter list, optionally copying an existing one.
579    void lscp_plist_alloc (lscp_param_t **ppList)
580    {
581        lscp_param_t *pParams;
582        int iSize, i;
583    
584        if (ppList) {
585            iSize = LSCP_SPLIT_CHUNK1;
586            pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
587            if (pParams) {
588                for (i = 0 ; i < iSize; i++) {
589                    pParams[i].key   = NULL;
590                    pParams[i].value = NULL;
591                }
592            }
593            *ppList = pParams;
594        }
595    }
596    
597    
598    // Destroy a parameter list, including all it's contents.
599    void lscp_plist_free ( lscp_param_t **ppList )
600    {
601        lscp_param_t *pParams;
602        int i;
603    
604        if (ppList) {
605            if (*ppList) {
606                pParams = *ppList;
607                for (i = 0; pParams && pParams[i].key; i++) {
608                    free(pParams[i].key);
609                    free(pParams[i].value);
610                }
611                free(pParams);
612            }
613            *ppList = NULL;
614        }
615    }
616    
617    
618    // Add an item to a parameter list, growing it as fit.
619    void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue )
620    {
621        lscp_param_t *pParams;
622        lscp_param_t *pNewParams;
623        int iSize, iNewSize;
624        int i = 0;
625    
626        if (ppList && *ppList) {
627            pParams = *ppList;
628            while (pParams[i].key) {
629                if (strcasecmp(pParams[i].key, pszKey) == 0) {
630                    if (pParams[i].value)
631                        free(pParams[i].value);
632                    pParams[i].value = strdup(pszValue);
633                    return;
634                }
635                i++;
636            }
637            iSize = LSCP_SPLIT_SIZE(i);
638            pParams[i].key   = strdup(pszKey);
639            pParams[i].value = strdup(pszValue);
640            if (++i >= iSize) {
641                iNewSize   = iSize + LSCP_SPLIT_CHUNK1;
642                pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t));
643                for (i = 0; i < iSize; i++) {
644                    pNewParams[i].key   = pParams[i].key;
645                    pNewParams[i].value = pParams[i].value;
646                }
647                for ( ; i < iNewSize; i++) {
648                    pNewParams[i].key   = NULL;
649                    pNewParams[i].value = NULL;
650                }
651                free(pParams);
652                *ppList = pNewParams;
653            }
654        }
655    }
656    
657    #ifdef LSCP_PLIST_COUNT
658    
659    // Compute a parameter list valid item count.
660    int lscp_plist_count ( lscp_param_t **ppList )
661    {
662        lscp_param_t *pParams;
663        int i = 0;
664        if (ppList && *ppList) {
665            pParams = *ppList;
666            while (pParams[i].key)
667                i++;
668        }
669        return i;
670    }
671    
672    // Compute the legal parameter list size.
673    int lscp_plist_size ( lscp_param_t **ppList )
674    {
675        return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));
676    }
677    
678    #endif // LSCP_PLIST_COUNT
679    
680    
681    //-------------------------------------------------------------------------
682    // Server info struct helper functions.
683    
684    void lscp_server_info_init ( lscp_server_info_t *pServerInfo )
685    {
686        pServerInfo->description = NULL;
687        pServerInfo->version     = NULL;
688    }
689    
690    void lscp_server_info_free ( lscp_server_info_t *pServerInfo )
691    {
692        if (pServerInfo->description)
693            free(pServerInfo->description);
694        if (pServerInfo->version)
695            free(pServerInfo->version);
696    }
697    
698    void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )
699    {
700        lscp_server_info_free(pServerInfo);
701        lscp_server_info_init(pServerInfo);
702    }
703    
704    
705  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
706  // Engine info struct helper functions.  // Engine info struct helper functions.
707    
# Line 202  void lscp_engine_info_init ( lscp_engine Line 711  void lscp_engine_info_init ( lscp_engine
711      pEngineInfo->version     = NULL;      pEngineInfo->version     = NULL;
712  }  }
713    
714  void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )  void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
715  {  {
716      if (pEngineInfo->description)      if (pEngineInfo->description)
717          free(pEngineInfo->description);          free(pEngineInfo->description);
718      if (pEngineInfo->version)      if (pEngineInfo->version)
719          free(pEngineInfo->version);          free(pEngineInfo->version);
720    }
721    
722    void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
723    {
724        lscp_engine_info_free(pEngineInfo);
725      lscp_engine_info_init(pEngineInfo);      lscp_engine_info_init(pEngineInfo);
726  }  }
727    
# Line 218  void lscp_engine_info_reset ( lscp_engin Line 731  void lscp_engine_info_reset ( lscp_engin
731    
732  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
733  {  {
734      pChannelInfo->engine_name     = NULL;      pChannelInfo->engine_name       = NULL;
735      pChannelInfo->audio_device    = 0;      pChannelInfo->audio_device      = 0;
736      pChannelInfo->audio_channels  = 0;      pChannelInfo->audio_channels    = 0;
737      pChannelInfo->audio_routing   = NULL;      pChannelInfo->audio_routing     = NULL;
738      pChannelInfo->instrument_file = NULL;      pChannelInfo->instrument_file   = NULL;
739      pChannelInfo->instrument_nr   = 0;      pChannelInfo->instrument_nr     = 0;
740      pChannelInfo->midi_device     = 0;      pChannelInfo->instrument_name   = NULL;
741      pChannelInfo->midi_port       = 0;      pChannelInfo->instrument_status = 0;
742      pChannelInfo->midi_channel    = 0;      pChannelInfo->midi_device       = 0;
743      pChannelInfo->volume          = 0.0;      pChannelInfo->midi_port         = 0;
744        pChannelInfo->midi_channel      = 0;
745        pChannelInfo->volume            = 0.0;
746        pChannelInfo->mute              = 0;
747        pChannelInfo->solo              = 0;
748  }  }
749    
750  void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
751  {  {
752      if (pChannelInfo->engine_name)      if (pChannelInfo->engine_name)
753          free(pChannelInfo->engine_name);          free(pChannelInfo->engine_name);
# Line 238  void lscp_channel_info_reset ( lscp_chan Line 755  void lscp_channel_info_reset ( lscp_chan
755          lscp_szsplit_destroy(pChannelInfo->audio_routing);          lscp_szsplit_destroy(pChannelInfo->audio_routing);
756      if (pChannelInfo->instrument_file)      if (pChannelInfo->instrument_file)
757          free(pChannelInfo->instrument_file);          free(pChannelInfo->instrument_file);
758        if (pChannelInfo->instrument_name)
759            free(pChannelInfo->instrument_name);
760    }
761    
762    void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
763    {
764        lscp_channel_info_free(pChannelInfo);
765      lscp_channel_info_init(pChannelInfo);      lscp_channel_info_init(pChannelInfo);
766  }  }
767    
# Line 253  void lscp_driver_info_init ( lscp_driver Line 776  void lscp_driver_info_init ( lscp_driver
776      pDriverInfo->parameters  = NULL;      pDriverInfo->parameters  = NULL;
777  }  }
778    
779  void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )  void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
780  {  {
781      if (pDriverInfo->description)      if (pDriverInfo->description)
782          free(pDriverInfo->description);          free(pDriverInfo->description);
783      if (pDriverInfo->version)      if (pDriverInfo->version)
784          free(pDriverInfo->version);          free(pDriverInfo->version);
785      lscp_szsplit_destroy(pDriverInfo->parameters);      lscp_szsplit_destroy(pDriverInfo->parameters);
786    }
787    
788    void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
789    {
790        lscp_driver_info_free(pDriverInfo);
791      lscp_driver_info_init(pDriverInfo);      lscp_driver_info_init(pDriverInfo);
792  }  }
793    
794    
795    //-------------------------------------------------------------------------
796    // Device info struct functions.
797    
798    void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
799    {
800        pDeviceInfo->driver = NULL;
801        lscp_plist_alloc(&(pDeviceInfo->params));
802    }
803    
804    void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
805    {
806        if (pDeviceInfo->driver)
807            free(pDeviceInfo->driver);
808        lscp_plist_free(&(pDeviceInfo->params));
809    }
810    
811    void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
812    {
813        lscp_device_info_free(pDeviceInfo);
814        lscp_device_info_init(pDeviceInfo);
815    }
816    
817    
818    //-------------------------------------------------------------------------
819    // Device channel/port info struct functions.
820    
821    void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
822    {
823        pDevicePortInfo->name = NULL;
824        lscp_plist_alloc(&(pDevicePortInfo->params));
825    }
826    
827    void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
828    {
829        if (pDevicePortInfo->name)
830            free(pDevicePortInfo->name);
831        lscp_plist_free(&(pDevicePortInfo->params));
832    }
833    
834    void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
835    {
836        lscp_device_port_info_free(pDevicePortInfo);
837        lscp_device_port_info_init(pDevicePortInfo);
838    }
839    
840    
841    //-------------------------------------------------------------------------
842    // Parameter struct helper functions.
843    
844    void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
845    {
846        pParamInfo->type          = LSCP_TYPE_NONE;
847        pParamInfo->description   = NULL;
848        pParamInfo->mandatory     = 0;
849        pParamInfo->fix           = 0;
850        pParamInfo->multiplicity  = 0;
851        pParamInfo->depends       = NULL;
852        pParamInfo->defaultv      = NULL;
853        pParamInfo->range_min     = NULL;
854        pParamInfo->range_max     = NULL;
855        pParamInfo->possibilities = NULL;
856    }
857    
858    void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
859    {
860        if (pParamInfo->description)
861            free(pParamInfo->description);
862        lscp_szsplit_destroy(pParamInfo->depends);
863        if (pParamInfo->defaultv)
864            free(pParamInfo->defaultv);
865        if (pParamInfo->range_min)
866            free(pParamInfo->range_min);
867        if (pParamInfo->range_max)
868            free(pParamInfo->range_max);
869        lscp_szsplit_destroy(pParamInfo->possibilities);
870    }
871    
872    void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
873    {
874        lscp_param_info_free(pParamInfo);
875        lscp_param_info_init(pParamInfo);
876    }
877    
878    
879    //-------------------------------------------------------------------------
880    // Concatenate a parameter list (key='value'...) into a string,
881    // appending a crlf terminator.
882    
883    int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
884    {
885        int cchBuffer, cchParam, i;
886    
887        if (pszBuffer == NULL)
888            return 0;
889    
890        cchBuffer = strlen(pszBuffer);
891        for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
892            cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
893            if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
894                sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
895                cchBuffer += cchParam;
896            }
897        }
898        
899        if (cchBuffer + 2 < cchMaxBuffer) {
900            pszBuffer[cchBuffer++] = '\r';
901            pszBuffer[cchBuffer++] = '\n';
902            pszBuffer[cchBuffer ]  = (char) 0;
903        }
904        
905        return cchBuffer;
906    }
907    
908    
909  // end of common.c  // end of common.c

Legend:
Removed from v.103  
changed lines
  Added in v.869

  ViewVC Help
Powered by ViewVC