/[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 132 by capela, Fri Jun 18 14:19:19 2004 UTC
# 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 193  int lscp_szsplit_size ( char **ppszSplit Line 339  int lscp_szsplit_size ( char **ppszSplit
339  #endif // LSCP_SZSPLIT_COUNT  #endif // LSCP_SZSPLIT_COUNT
340    
341    
342    // Split a comma separated string into a -1 terminated array of positive integers.
343    int *lscp_isplit_create ( const char *pszCsv, const char *pszSeps )
344    {
345        char *pchHead, *pch;
346        int iSize, i, j, cchSeps;
347        int *piSplit, *piNewSplit;
348    
349        // Initial size is one chunk away.
350        iSize = LSCP_SPLIT_CHUNK1;
351        // Allocate and split...
352        piSplit = (int *) malloc(iSize * sizeof(int));
353        if (piSplit == NULL)
354            return NULL;
355    
356        // Make a copy of the original string.
357        i = 0;
358        pchHead = (char *) pszCsv;
359        if ((piSplit[i++] = atoi(pchHead)) < 0) {
360            free(piSplit);
361            return NULL;
362        }
363    
364        // Go on for it...
365        cchSeps = strlen(pszSeps);
366        while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {
367            // Pre-advance to next item.
368            pchHead = pch + cchSeps;
369            // Make it official.
370            piSplit[i++] = atoi(pchHead);
371            // Do we need to grow?
372            if (i >= iSize) {
373                // Yes, but only grow in chunks.
374                iSize += LSCP_SPLIT_CHUNK1;
375                // Allocate and copy to new split array.
376                piNewSplit = (int *) malloc(iSize * sizeof(int));
377                if (piNewSplit) {
378                    for (j = 0; j < i; j++)
379                        piNewSplit[j] = piSplit[j];
380                    free(piSplit);
381                    piSplit = piNewSplit;
382                }
383            }
384        }
385    
386        // NULL terminate split array.
387        for ( ; i < iSize; i++)
388            piSplit[i] = -1;
389    
390        return piSplit;
391    }
392    
393    
394    // Destroy a integer splitted array.
395    void lscp_isplit_destroy ( int *piSplit )
396    {
397        if (piSplit)
398            free(piSplit);
399    }
400    
401    
402    #ifdef LSCP_ISPLIT_COUNT
403    
404    // Compute a string list valid item count.
405    int lscp_isplit_count ( int *piSplit )
406    {
407        int i = 0;
408        while (piSplit && piSplit[i] >= 0)
409            i++;
410        return i;
411    }
412    
413    // Compute a string list size.
414    int lscp_isplit_size ( int *piSplit )
415    {
416        return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
417    }
418    
419    #endif // LSCP_ISPLIT_COUNT
420    
421    
422  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
423  // Engine info struct helper functions.  // Engine info struct helper functions.
424    
# Line 218  void lscp_engine_info_reset ( lscp_engin Line 444  void lscp_engine_info_reset ( lscp_engin
444    
445  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
446  {  {
447      pChannelInfo->engine_name     = NULL;      pChannelInfo->engine_name       = NULL;
448      pChannelInfo->audio_device    = 0;      pChannelInfo->audio_device      = 0;
449      pChannelInfo->audio_channels  = 0;      pChannelInfo->audio_channels    = 0;
450      pChannelInfo->audio_routing   = NULL;      pChannelInfo->audio_routing     = NULL;
451      pChannelInfo->instrument_file = NULL;      pChannelInfo->instrument_file   = NULL;
452      pChannelInfo->instrument_nr   = 0;      pChannelInfo->instrument_nr     = 0;
453      pChannelInfo->midi_device     = 0;      pChannelInfo->instrument_status = 0;
454      pChannelInfo->midi_port       = 0;      pChannelInfo->midi_device       = 0;
455      pChannelInfo->midi_channel    = 0;      pChannelInfo->midi_port         = 0;
456      pChannelInfo->volume          = 0.0;      pChannelInfo->midi_channel      = 0;
457        pChannelInfo->volume            = 0.0;
458  }  }
459    
460  void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )

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

  ViewVC Help
Powered by ViewVC