/[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 125 by capela, Mon Jun 14 21:04:04 2004 UTC revision 179 by capela, Tue Jul 6 16:24:41 2004 UTC
# Line 1  Line 1 
1  // client.c  // common.c
2  //  //
3  /****************************************************************************  /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API     liblscp - LinuxSampler Control Protocol API
# 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    // The main client requester call executive.
53    lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery )
54    {
55        fd_set fds;                         // File descriptor list for select().
56        int    fd, fdmax;                   // Maximum file descriptor number.
57        struct timeval tv;                  // For specifying a timeout value.
58        int    iSelect;                     // Holds select return status.
59        int    iTimeout;
60        int    cchQuery;
61        char   achResult[LSCP_BUFSIZ];
62        int    cchResult;
63        const  char *pszSeps = ":[]";
64        char  *pszResult;
65        char  *pszToken;
66        char  *pch;
67        int    iErrno;
68    
69        lscp_status_t ret = LSCP_FAILED;
70    
71        if (pClient == NULL)
72            return ret;
73    
74        pszResult = NULL;
75        iErrno = -1;
76    
77        // Check if command socket socket is still valid.
78        if (pClient->cmd.sock == INVALID_SOCKET) {
79            pszResult = "Connection closed or no longer valid";
80            lscp_client_set_result(pClient, pszResult, iErrno);
81            return ret;
82        }
83    
84        // Send data, and then, wait for the result...
85        cchQuery = strlen(pszQuery);
86        if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {
87            lscp_socket_perror("_lscp_client_call: send");
88            pszResult = "Failure during send operation";
89            lscp_client_set_result(pClient, pszResult, iErrno);
90            return ret;
91        }
92    
93        // Prepare for waiting on select...
94        fd = (int) pClient->cmd.sock;
95        FD_ZERO(&fds);
96        FD_SET((unsigned int) fd, &fds);
97        fdmax = fd;
98    
99        // Use the timeout select feature...
100        iTimeout = pClient->iTimeout;
101        if (iTimeout > 1000) {
102            tv.tv_sec = iTimeout / 1000;
103            iTimeout -= tv.tv_sec * 1000;
104        }
105        else tv.tv_sec = 0;
106        tv.tv_usec = iTimeout * 1000;
107    
108        // Wait for event...
109        iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);
110        if (iSelect > 0 && FD_ISSET(fd, &fds)) {
111            // May recv now...
112            cchResult = recv(pClient->cmd.sock, achResult, sizeof(achResult), 0);
113            if (cchResult > 0) {
114                // Assume early success.
115                ret = LSCP_OK;
116                // Always force the result to be null terminated (and trim trailing CRLFs)!
117                while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))
118                    cchResult--;
119                achResult[cchResult] = (char) 0;
120                // Check if the response it's an error or warning message.
121                if (strncasecmp(achResult, "WRN:", 4) == 0)
122                    ret = LSCP_WARNING;
123                else if (strncasecmp(achResult, "ERR:", 4) == 0)
124                    ret = LSCP_ERROR;
125                // So we got a result...
126                if (ret == LSCP_OK) {
127                    // Reset errno in case of success.
128                    iErrno = 0;
129                    // Is it a special successful response?
130                    if (strncasecmp(achResult, "OK[", 3) == 0) {
131                        // Parse the OK message, get the return string under brackets...
132                        pszToken = lscp_strtok(achResult, pszSeps, &(pch));
133                        if (pszToken)
134                            pszResult = lscp_strtok(NULL, pszSeps, &(pch));
135                    }
136                    else pszResult = achResult;
137                    // The result string is now set to the command response, if any.
138                } else {
139                    // Parse the error/warning message, skip first colon...
140                    pszToken = lscp_strtok(achResult, pszSeps, &(pch));
141                    if (pszToken) {
142                        // Get the error number...
143                        pszToken = lscp_strtok(NULL, pszSeps, &(pch));
144                        if (pszToken) {
145                            iErrno = atoi(pszToken);
146                            // And make the message text our final result.
147                            pszResult = lscp_strtok(NULL, pszSeps, &(pch));
148                        }
149                    }
150                    // The result string is set to the error/warning message text.
151                }
152            }
153            else if (cchResult == 0) {
154                // Damn, server disconnected, we better free everything down here.
155                lscp_socket_agent_free(&(pClient->evt));
156                lscp_socket_agent_free(&(pClient->cmd));
157                // Fake a result message.
158                ret = LSCP_QUIT;
159                pszResult = "Server terminated the connection";
160                iErrno = (int) ret;
161            } else {
162                // What's down?
163                lscp_socket_perror("_lscp_client_call: recv");
164                pszResult = "Failure during receive operation";
165            }
166        }   // Check if select has timed out.
167        else if (iSelect == 0) {
168            // Fake a result message.
169            ret = LSCP_TIMEOUT;
170            pszResult = "Timeout during receive operation";
171            iErrno = (int) ret;
172       }
173        else lscp_socket_perror("_lscp_client_call: select");
174    
175        // Make the result official...
176        lscp_client_set_result(pClient, pszResult, iErrno);
177    
178        return ret;
179    }
180    
181    
182    //-------------------------------------------------------------------------
183    // Other general utility functions.
184    
185  // Trimming left spaces...  // Trimming left spaces...
186  char *lscp_ltrim ( char *psz )  char *lscp_ltrim ( char *psz )
# Line 273  int lscp_isplit_size ( int *piSplit ) Line 419  int lscp_isplit_size ( int *piSplit )
419  #endif // LSCP_ISPLIT_COUNT  #endif // LSCP_ISPLIT_COUNT
420    
421    
422    // Split a string into a null terminated array of parameter items.
423    lscp_param_t *lscp_psplit_create ( const char *pszCsv, const char *pszSeps1, const char *pszSeps2 )
424    {
425        char *pszHead, *pch;
426        int iSize, i, j, cchSeps1, cchSeps2;
427        lscp_param_t *ppSplit, *ppNewSplit;
428    
429        pszHead = strdup(pszCsv);
430        if (pszHead == NULL)
431            return NULL;
432    
433        iSize = LSCP_SPLIT_CHUNK1;
434        ppSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
435        if (ppSplit == NULL) {
436            free(pszHead);
437            return NULL;
438        }
439    
440        cchSeps1 = strlen(pszSeps1);
441        cchSeps2 = strlen(pszSeps2);
442    
443        i = 0;
444        while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {
445            ppSplit[i].key = pszHead;
446            pszHead = pch + cchSeps1;
447            *pch = (char) 0;
448            ppSplit[i].value = lscp_unquote(&pszHead, 0);
449            if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {
450                pszHead = pch + cchSeps2;
451                *pch = (char) 0;
452            }
453            if (++i >= iSize) {
454                iSize += LSCP_SPLIT_CHUNK1;
455                ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
456                if (ppNewSplit) {
457                    for (j = 0; j < i; j++) {
458                        ppNewSplit[j].key   = ppSplit[j].key;
459                        ppNewSplit[j].value = ppSplit[j].value;
460                    }
461                    free(ppSplit);
462                    ppSplit = ppNewSplit;
463                }
464            }
465        }
466    
467        if (i < 1)
468            free(pszHead);
469    
470        for ( ; i < iSize; i++) {
471            ppSplit[i].key   = NULL;
472            ppSplit[i].value = NULL;
473        }
474    
475        return ppSplit;
476    }
477    
478    
479    // Destroy a parameter list array.
480    void lscp_psplit_destroy ( lscp_param_t *ppSplit )
481    {
482        if (ppSplit && ppSplit[0].key)
483            free(ppSplit[0].key);
484        if (ppSplit)
485            free(ppSplit);
486    }
487    
488    
489    #ifdef LSCP_PSPLIT_COUNT
490    
491    // Compute a parameter list valid item count.
492    int lscp_psplit_count ( lscp_param_t *ppSplit )
493    {
494        int i = 0;
495        while (ppSplit && ppSplit[i].key)
496            i++;
497        return i;
498    }
499    
500    // Compute a parameter list size.
501    int lscp_psplit_size ( lscp_param_t *ppSplit )
502    {
503        return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));
504    }
505    
506    #endif // LSCP_PSPLIT_COUNT
507    
508    
509    // Allocate a parameter list, optionally copying an existing one.
510    void lscp_plist_alloc (lscp_param_t **ppList)
511    {
512        lscp_param_t *pParams;
513        int iSize, i;
514    
515        if (ppList) {
516            iSize = LSCP_SPLIT_CHUNK1;
517            pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
518            if (pParams) {
519                for (i = 0 ; i < iSize; i++) {
520                    pParams[i].key   = NULL;
521                    pParams[i].value = NULL;
522                }
523            }
524            *ppList = pParams;
525        }
526    }
527    
528    
529    // Destroy a parameter list, including all it's contents.
530    void lscp_plist_free ( lscp_param_t **ppList )
531    {
532        lscp_param_t *pParams;
533        int i;
534        
535        if (ppList) {
536            if (*ppList) {
537                pParams = *ppList;
538                for (i = 0; pParams && pParams[i].key; i++) {
539                    free(pParams[i].key);
540                    free(pParams[i].value);
541                }
542                free(pParams);
543            }
544            *ppList = NULL;
545        }
546    }
547    
548    
549    // Add an item to a parameter list, growing it as fit.
550    void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue )
551    {
552        lscp_param_t *pParams;
553        lscp_param_t *pNewParams;
554        int iSize, iNewSize;
555        int i = 0;
556        
557        if (ppList && *ppList) {
558            pParams = *ppList;
559            while (pParams[i].key)
560                i++;
561            iSize = LSCP_SPLIT_SIZE(i);
562            pParams[i].key   = strdup(pszKey);
563            pParams[i].value = strdup(pszValue);
564            if (++i >= iSize) {
565                iNewSize   = iSize + LSCP_SPLIT_CHUNK1;
566                pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t));
567                for (i = 0; i < iSize; i++) {
568                    pParams[i].key   = pParams[i].key;
569                    pParams[i].value = pParams[i].value;
570                }
571                for ( ; i < iNewSize; i++) {
572                    pNewParams[i].key   = NULL;
573                    pNewParams[i].value = NULL;
574                }
575                free(pParams);
576                *ppList = pNewParams;
577            }
578        }
579    }
580    
581    
582    // Compute a parameter list valid item count.
583    int lscp_plist_count ( lscp_param_t **ppList )
584    {
585        lscp_param_t *pParams;
586        int i = 0;
587        if (ppList && *ppList) {
588            pParams = *ppList;
589            while (pParams[i].key)
590                i++;
591        }
592        return i;
593    }
594    
595    
596    // Compute the legal parameter list size.
597    int lscp_plist_size ( lscp_param_t **ppList )
598    {
599        return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));
600    }
601    
602    
603    
604  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
605  // Engine info struct helper functions.  // Engine info struct helper functions.
606    
# Line 282  void lscp_engine_info_init ( lscp_engine Line 610  void lscp_engine_info_init ( lscp_engine
610      pEngineInfo->version     = NULL;      pEngineInfo->version     = NULL;
611  }  }
612    
613  void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )  void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
614  {  {
615      if (pEngineInfo->description)      if (pEngineInfo->description)
616          free(pEngineInfo->description);          free(pEngineInfo->description);
617      if (pEngineInfo->version)      if (pEngineInfo->version)
618          free(pEngineInfo->version);          free(pEngineInfo->version);
619    }
620    
621    void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
622    {
623        lscp_engine_info_free(pEngineInfo);
624      lscp_engine_info_init(pEngineInfo);      lscp_engine_info_init(pEngineInfo);
625  }  }
626    
# Line 298  void lscp_engine_info_reset ( lscp_engin Line 630  void lscp_engine_info_reset ( lscp_engin
630    
631  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
632  {  {
633      pChannelInfo->engine_name     = NULL;      pChannelInfo->engine_name       = NULL;
634      pChannelInfo->audio_device    = 0;      pChannelInfo->audio_device      = 0;
635      pChannelInfo->audio_channels  = 0;      pChannelInfo->audio_channels    = 0;
636      pChannelInfo->audio_routing   = NULL;      pChannelInfo->audio_routing     = NULL;
637      pChannelInfo->instrument_file = NULL;      pChannelInfo->instrument_file   = NULL;
638      pChannelInfo->instrument_nr   = 0;      pChannelInfo->instrument_nr     = 0;
639      pChannelInfo->midi_device     = 0;      pChannelInfo->instrument_status = 0;
640      pChannelInfo->midi_port       = 0;      pChannelInfo->midi_device       = 0;
641      pChannelInfo->midi_channel    = 0;      pChannelInfo->midi_port         = 0;
642      pChannelInfo->volume          = 0.0;      pChannelInfo->midi_channel      = 0;
643        pChannelInfo->volume            = 0.0;
644  }  }
645    
646  void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
647  {  {
648      if (pChannelInfo->engine_name)      if (pChannelInfo->engine_name)
649          free(pChannelInfo->engine_name);          free(pChannelInfo->engine_name);
# Line 318  void lscp_channel_info_reset ( lscp_chan Line 651  void lscp_channel_info_reset ( lscp_chan
651          lscp_szsplit_destroy(pChannelInfo->audio_routing);          lscp_szsplit_destroy(pChannelInfo->audio_routing);
652      if (pChannelInfo->instrument_file)      if (pChannelInfo->instrument_file)
653          free(pChannelInfo->instrument_file);          free(pChannelInfo->instrument_file);
654    }
655    
656    void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
657    {
658        lscp_channel_info_free(pChannelInfo);
659      lscp_channel_info_init(pChannelInfo);      lscp_channel_info_init(pChannelInfo);
660  }  }
661    
# Line 333  void lscp_driver_info_init ( lscp_driver Line 670  void lscp_driver_info_init ( lscp_driver
670      pDriverInfo->parameters  = NULL;      pDriverInfo->parameters  = NULL;
671  }  }
672    
673  void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )  void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
674  {  {
675      if (pDriverInfo->description)      if (pDriverInfo->description)
676          free(pDriverInfo->description);          free(pDriverInfo->description);
677      if (pDriverInfo->version)      if (pDriverInfo->version)
678          free(pDriverInfo->version);          free(pDriverInfo->version);
679      lscp_szsplit_destroy(pDriverInfo->parameters);      lscp_szsplit_destroy(pDriverInfo->parameters);
680    }
681    
682    void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
683    {
684        lscp_driver_info_free(pDriverInfo);
685      lscp_driver_info_init(pDriverInfo);      lscp_driver_info_init(pDriverInfo);
686  }  }
687    
688    
689    //-------------------------------------------------------------------------
690    // Device info struct functions.
691    
692    void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
693    {
694        pDeviceInfo->driver = NULL;
695        lscp_plist_alloc(&(pDeviceInfo->params));
696    }
697    
698    void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
699    {
700        if (pDeviceInfo->driver)
701            free(pDeviceInfo->driver);
702        lscp_plist_free(&(pDeviceInfo->params));
703    }
704    
705    void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
706    {
707        lscp_device_info_free(pDeviceInfo);
708        lscp_device_info_init(pDeviceInfo);
709    }
710    
711    
712    //-------------------------------------------------------------------------
713    // Device channel/port info struct functions.
714    
715    void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
716    {
717        pDevicePortInfo->name = NULL;
718        lscp_plist_alloc(&(pDevicePortInfo->params));
719    }
720    
721    void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
722    {
723        if (pDevicePortInfo->name)
724            free(pDevicePortInfo->name);
725        lscp_plist_free(&(pDevicePortInfo->params));
726    }
727    
728    void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
729    {
730        lscp_device_port_info_free(pDevicePortInfo);
731        lscp_device_port_info_init(pDevicePortInfo);
732    }
733    
734    
735    //-------------------------------------------------------------------------
736    // Parameter struct helper functions.
737    
738    void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
739    {
740        pParamInfo->type          = LSCP_TYPE_NONE;
741        pParamInfo->description   = NULL;
742        pParamInfo->mandatory     = 0;
743        pParamInfo->fix           = 0;
744        pParamInfo->multiplicity  = 0;
745        pParamInfo->depends       = NULL;
746        pParamInfo->defaultv      = NULL;
747        pParamInfo->range_min     = NULL;
748        pParamInfo->range_max     = NULL;
749        pParamInfo->possibilities = NULL;
750    }
751    
752    void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
753    {
754        if (pParamInfo->description)
755            free(pParamInfo->description);
756        lscp_szsplit_destroy(pParamInfo->depends);
757        if (pParamInfo->defaultv)
758            free(pParamInfo->defaultv);
759        if (pParamInfo->range_min)
760            free(pParamInfo->range_min);
761        if (pParamInfo->range_max)
762            free(pParamInfo->range_max);
763        lscp_szsplit_destroy(pParamInfo->possibilities);
764    }
765    
766    void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
767    {
768        lscp_param_info_free(pParamInfo);
769        lscp_param_info_init(pParamInfo);
770    }
771    
772    
773    //-------------------------------------------------------------------------
774    // Concatenate a parameter list (key='value'...) into a string,
775    // appending a crlf terminator.
776    
777    int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
778    {
779        int cchBuffer, cchParam, i;
780    
781        if (pszBuffer == NULL || pParams == NULL)
782            return 0;
783    
784        cchBuffer = strlen(pszBuffer);
785        for (i = 0; pParams[i].key && pParams[i].value; i++) {
786            cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
787            if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
788                sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
789                cchBuffer += cchParam;
790            }
791        }
792        
793        if (cchBuffer + 2 < cchMaxBuffer) {
794            pszBuffer[cchBuffer++] = '\r';
795            pszBuffer[cchBuffer++] = '\n';
796        }
797        
798        return cchBuffer;
799    }
800    
801    
802  // end of common.c  // end of common.c

Legend:
Removed from v.125  
changed lines
  Added in v.179

  ViewVC Help
Powered by ViewVC