/[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 564 by capela, Sun May 22 22:02:00 2005 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-2005, 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        // 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...  // Trimming left spaces...
220  char *lscp_ltrim ( char *psz )  char *lscp_ltrim ( char *psz )
# Line 77  char *lscp_unquote ( char **ppsz, int du Line 257  char *lscp_unquote ( char **ppsz, int du
257      return psz;      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.  // Custom tokenizer.
274  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 329  char **lscp_szsplit_create ( const char
329              --pch;              --pch;
330          *pch = (char) 0;          *pch = (char) 0;
331          // Make it official.          // Make it official.
332          ppszSplit[i++] = lscp_unquote(&pszHead, 0);          ppszSplit[i] = lscp_unquote(&pszHead, 0);
333          // Do we need to grow?          // Do we need to grow?
334          if (i >= iSize) {          if (++i >= iSize) {
335              // Yes, but only grow in chunks.              // Yes, but only grow in chunks.
336              iSize += LSCP_SPLIT_CHUNK1;              iSize += LSCP_SPLIT_CHUNK1;
337              // Allocate and copy to new split array.              // Allocate and copy to new split array.
# Line 193  int lscp_szsplit_size ( char **ppszSplit Line 385  int lscp_szsplit_size ( char **ppszSplit
385  #endif // LSCP_SZSPLIT_COUNT  #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    // Server info struct helper functions.
664    
665    void lscp_server_info_init ( lscp_server_info_t *pServerInfo )
666    {
667        pServerInfo->description = NULL;
668        pServerInfo->version     = NULL;
669    }
670    
671    void lscp_server_info_free ( lscp_server_info_t *pServerInfo )
672    {
673        if (pServerInfo->description)
674            free(pServerInfo->description);
675        if (pServerInfo->version)
676            free(pServerInfo->version);
677    }
678    
679    void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )
680    {
681        lscp_server_info_free(pServerInfo);
682        lscp_server_info_init(pServerInfo);
683    }
684    
685    
686  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
687  // Engine info struct helper functions.  // Engine info struct helper functions.
688    
# Line 202  void lscp_engine_info_init ( lscp_engine Line 692  void lscp_engine_info_init ( lscp_engine
692      pEngineInfo->version     = NULL;      pEngineInfo->version     = NULL;
693  }  }
694    
695  void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )  void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
696  {  {
697      if (pEngineInfo->description)      if (pEngineInfo->description)
698          free(pEngineInfo->description);          free(pEngineInfo->description);
699      if (pEngineInfo->version)      if (pEngineInfo->version)
700          free(pEngineInfo->version);          free(pEngineInfo->version);
701    }
702    
703    void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
704    {
705        lscp_engine_info_free(pEngineInfo);
706      lscp_engine_info_init(pEngineInfo);      lscp_engine_info_init(pEngineInfo);
707  }  }
708    
# Line 218  void lscp_engine_info_reset ( lscp_engin Line 712  void lscp_engine_info_reset ( lscp_engin
712    
713  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
714  {  {
715      pChannelInfo->engine_name     = NULL;      pChannelInfo->engine_name       = NULL;
716      pChannelInfo->audio_device    = 0;      pChannelInfo->audio_device      = 0;
717      pChannelInfo->audio_channels  = 0;      pChannelInfo->audio_channels    = 0;
718      pChannelInfo->audio_routing   = NULL;      pChannelInfo->audio_routing     = NULL;
719      pChannelInfo->instrument_file = NULL;      pChannelInfo->instrument_file   = NULL;
720      pChannelInfo->instrument_nr   = 0;      pChannelInfo->instrument_nr     = 0;
721      pChannelInfo->midi_device     = 0;      pChannelInfo->instrument_name   = NULL;
722      pChannelInfo->midi_port       = 0;      pChannelInfo->instrument_status = 0;
723      pChannelInfo->midi_channel    = 0;      pChannelInfo->midi_device       = 0;
724      pChannelInfo->volume          = 0.0;      pChannelInfo->midi_port         = 0;
725        pChannelInfo->midi_channel      = 0;
726        pChannelInfo->volume            = 0.0;
727  }  }
728    
729  void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
730  {  {
731      if (pChannelInfo->engine_name)      if (pChannelInfo->engine_name)
732          free(pChannelInfo->engine_name);          free(pChannelInfo->engine_name);
# Line 238  void lscp_channel_info_reset ( lscp_chan Line 734  void lscp_channel_info_reset ( lscp_chan
734          lscp_szsplit_destroy(pChannelInfo->audio_routing);          lscp_szsplit_destroy(pChannelInfo->audio_routing);
735      if (pChannelInfo->instrument_file)      if (pChannelInfo->instrument_file)
736          free(pChannelInfo->instrument_file);          free(pChannelInfo->instrument_file);
737        if (pChannelInfo->instrument_name)
738            free(pChannelInfo->instrument_name);
739    }
740    
741    void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
742    {
743        lscp_channel_info_free(pChannelInfo);
744      lscp_channel_info_init(pChannelInfo);      lscp_channel_info_init(pChannelInfo);
745  }  }
746    
# Line 253  void lscp_driver_info_init ( lscp_driver Line 755  void lscp_driver_info_init ( lscp_driver
755      pDriverInfo->parameters  = NULL;      pDriverInfo->parameters  = NULL;
756  }  }
757    
758  void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )  void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
759  {  {
760      if (pDriverInfo->description)      if (pDriverInfo->description)
761          free(pDriverInfo->description);          free(pDriverInfo->description);
762      if (pDriverInfo->version)      if (pDriverInfo->version)
763          free(pDriverInfo->version);          free(pDriverInfo->version);
764      lscp_szsplit_destroy(pDriverInfo->parameters);      lscp_szsplit_destroy(pDriverInfo->parameters);
765    }
766    
767    void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
768    {
769        lscp_driver_info_free(pDriverInfo);
770      lscp_driver_info_init(pDriverInfo);      lscp_driver_info_init(pDriverInfo);
771  }  }
772    
773    
774    //-------------------------------------------------------------------------
775    // Device info struct functions.
776    
777    void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
778    {
779        pDeviceInfo->driver = NULL;
780        lscp_plist_alloc(&(pDeviceInfo->params));
781    }
782    
783    void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
784    {
785        if (pDeviceInfo->driver)
786            free(pDeviceInfo->driver);
787        lscp_plist_free(&(pDeviceInfo->params));
788    }
789    
790    void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
791    {
792        lscp_device_info_free(pDeviceInfo);
793        lscp_device_info_init(pDeviceInfo);
794    }
795    
796    
797    //-------------------------------------------------------------------------
798    // Device channel/port info struct functions.
799    
800    void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
801    {
802        pDevicePortInfo->name = NULL;
803        lscp_plist_alloc(&(pDevicePortInfo->params));
804    }
805    
806    void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
807    {
808        if (pDevicePortInfo->name)
809            free(pDevicePortInfo->name);
810        lscp_plist_free(&(pDevicePortInfo->params));
811    }
812    
813    void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
814    {
815        lscp_device_port_info_free(pDevicePortInfo);
816        lscp_device_port_info_init(pDevicePortInfo);
817    }
818    
819    
820    //-------------------------------------------------------------------------
821    // Parameter struct helper functions.
822    
823    void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
824    {
825        pParamInfo->type          = LSCP_TYPE_NONE;
826        pParamInfo->description   = NULL;
827        pParamInfo->mandatory     = 0;
828        pParamInfo->fix           = 0;
829        pParamInfo->multiplicity  = 0;
830        pParamInfo->depends       = NULL;
831        pParamInfo->defaultv      = NULL;
832        pParamInfo->range_min     = NULL;
833        pParamInfo->range_max     = NULL;
834        pParamInfo->possibilities = NULL;
835    }
836    
837    void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
838    {
839        if (pParamInfo->description)
840            free(pParamInfo->description);
841        lscp_szsplit_destroy(pParamInfo->depends);
842        if (pParamInfo->defaultv)
843            free(pParamInfo->defaultv);
844        if (pParamInfo->range_min)
845            free(pParamInfo->range_min);
846        if (pParamInfo->range_max)
847            free(pParamInfo->range_max);
848        lscp_szsplit_destroy(pParamInfo->possibilities);
849    }
850    
851    void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
852    {
853        lscp_param_info_free(pParamInfo);
854        lscp_param_info_init(pParamInfo);
855    }
856    
857    
858    //-------------------------------------------------------------------------
859    // Concatenate a parameter list (key='value'...) into a string,
860    // appending a crlf terminator.
861    
862    int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
863    {
864        int cchBuffer, cchParam, i;
865    
866        if (pszBuffer == NULL)
867            return 0;
868    
869        cchBuffer = strlen(pszBuffer);
870        for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
871            cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
872            if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
873                sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
874                cchBuffer += cchParam;
875            }
876        }
877        
878        if (cchBuffer + 2 < cchMaxBuffer) {
879            pszBuffer[cchBuffer++] = '\r';
880            pszBuffer[cchBuffer++] = '\n';
881            pszBuffer[cchBuffer ]  = (char) 0;
882        }
883        
884        return cchBuffer;
885    }
886    
887    
888  // end of common.c  // end of common.c

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

  ViewVC Help
Powered by ViewVC