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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 158 - (hide annotations) (download)
Tue Jun 29 16:39:11 2004 UTC (19 years, 9 months ago) by capela
File MIME type: text/plain
File size: 16847 byte(s)
Initial split parameter array code.

1 capela 144 // common.c
2 capela 103 //
3     /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API
5     Copyright (C) 2004, rncbc aka Rui Nuno Capela. All rights reserved.
6    
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Lesser General Public
9     License as published by the Free Software Foundation; either
10     version 2.1 of the License, or (at your option) any later version.
11    
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15     Lesser General Public License for more details.
16    
17     You should have received a copy of the GNU Lesser General Public
18     License along with this library; if not, write to the Free Software
19     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20    
21     *****************************************************************************/
22    
23     #include "common.h"
24    
25     #include <ctype.h>
26    
27    
28 capela 158 // Split chunk size magic:
29     // LSCP_SPLIT_CHUNK1 := 2 ^ LSCP_SPLIT_CHUNK2
30 capela 103 #define LSCP_SPLIT_CHUNK1 4
31     #define LSCP_SPLIT_CHUNK2 2
32     // Chunk size legal calculator.
33     #define LSCP_SPLIT_SIZE(n) ((((n) >> LSCP_SPLIT_CHUNK2) + 1) << LSCP_SPLIT_CHUNK2)
34    
35    
36     //-------------------------------------------------------------------------
37 capela 132 // Local client request executive.
38 capela 103
39 capela 132 // Result buffer internal settler.
40     void lscp_client_set_result ( lscp_client_t *pClient, char *pszResult, int iErrno )
41     {
42     if (pClient->pszResult)
43     free(pClient->pszResult);
44     pClient->pszResult = NULL;
45    
46     pClient->iErrno = iErrno;
47    
48     if (pszResult)
49     pClient->pszResult = strdup(lscp_ltrim(pszResult));
50     }
51    
52     // The main client requester call executive.
53     lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery )
54     {
55     fd_set fds; // File descriptor list for select().
56     int fd, fdmax; // Maximum file descriptor number.
57     struct timeval tv; // For specifying a timeout value.
58     int iSelect; // Holds select return status.
59     int iTimeout;
60     int cchQuery;
61     char achResult[LSCP_BUFSIZ];
62     int cchResult;
63     const char *pszSeps = ":[]";
64     char *pszResult;
65     char *pszToken;
66     char *pch;
67     int iErrno;
68    
69     lscp_status_t ret = LSCP_FAILED;
70    
71     if (pClient == NULL)
72     return ret;
73    
74     pszResult = NULL;
75     iErrno = -1;
76    
77     // Check if command socket socket is still valid.
78     if (pClient->cmd.sock == INVALID_SOCKET) {
79     pszResult = "Connection closed or no longer valid";
80     lscp_client_set_result(pClient, pszResult, iErrno);
81     return ret;
82     }
83    
84     // Send data, and then, wait for the result...
85     cchQuery = strlen(pszQuery);
86     if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {
87     lscp_socket_perror("_lscp_client_call: send");
88     pszResult = "Failure during send operation";
89     lscp_client_set_result(pClient, pszResult, iErrno);
90     return ret;
91     }
92    
93     // Prepare for waiting on select...
94     fd = (int) pClient->cmd.sock;
95     FD_ZERO(&fds);
96     FD_SET((unsigned int) fd, &fds);
97     fdmax = fd;
98    
99     // Use the timeout select feature...
100     iTimeout = pClient->iTimeout;
101     if (iTimeout > 1000) {
102     tv.tv_sec = iTimeout / 1000;
103     iTimeout -= tv.tv_sec * 1000;
104     }
105     else tv.tv_sec = 0;
106     tv.tv_usec = iTimeout * 1000;
107    
108     // Wait for event...
109     iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);
110     if (iSelect > 0 && FD_ISSET(fd, &fds)) {
111     // May recv now...
112     cchResult = recv(pClient->cmd.sock, achResult, sizeof(achResult), 0);
113     if (cchResult > 0) {
114     // Assume early success.
115     ret = LSCP_OK;
116     // Always force the result to be null terminated (and trim trailing CRLFs)!
117     while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))
118     cchResult--;
119     achResult[cchResult] = (char) 0;
120     // Check if the response it's an error or warning message.
121     if (strncasecmp(achResult, "WRN:", 4) == 0)
122     ret = LSCP_WARNING;
123     else if (strncasecmp(achResult, "ERR:", 4) == 0)
124     ret = LSCP_ERROR;
125     // So we got a result...
126     if (ret == LSCP_OK) {
127     // Reset errno in case of success.
128     iErrno = 0;
129     // Is it a special successful response?
130     if (strncasecmp(achResult, "OK[", 3) == 0) {
131     // Parse the OK message, get the return string under brackets...
132     pszToken = lscp_strtok(achResult, pszSeps, &(pch));
133     if (pszToken)
134     pszResult = lscp_strtok(NULL, pszSeps, &(pch));
135     }
136     else pszResult = achResult;
137     // The result string is now set to the command response, if any.
138     } else {
139     // Parse the error/warning message, skip first colon...
140     pszToken = lscp_strtok(achResult, pszSeps, &(pch));
141     if (pszToken) {
142     // Get the error number...
143     pszToken = lscp_strtok(NULL, pszSeps, &(pch));
144     if (pszToken) {
145     iErrno = atoi(pszToken);
146     // And make the message text our final result.
147     pszResult = lscp_strtok(NULL, pszSeps, &(pch));
148     }
149     }
150     // The result string is set to the error/warning message text.
151     }
152     }
153     else if (cchResult == 0) {
154     // Damn, server disconnected, we better free everything down here.
155     lscp_socket_agent_free(&(pClient->evt));
156     lscp_socket_agent_free(&(pClient->cmd));
157     // Fake a result message.
158     ret = LSCP_QUIT;
159     pszResult = "Server terminated the connection";
160     iErrno = (int) ret;
161     } else {
162     // What's down?
163     lscp_socket_perror("_lscp_client_call: recv");
164     pszResult = "Failure during receive operation";
165     }
166     } // Check if select has timed out.
167     else if (iSelect == 0) {
168     // Fake a result message.
169     ret = LSCP_TIMEOUT;
170     pszResult = "Timeout during receive operation";
171     iErrno = (int) ret;
172     }
173     else lscp_socket_perror("_lscp_client_call: select");
174    
175     // Make the result official...
176     lscp_client_set_result(pClient, pszResult, iErrno);
177    
178     return ret;
179     }
180    
181    
182     //-------------------------------------------------------------------------
183     // Other general utility functions.
184    
185 capela 103 // Trimming left spaces...
186     char *lscp_ltrim ( char *psz )
187     {
188     while (isspace(*psz))
189     psz++;
190     return psz;
191     }
192    
193     // Unquote an in-split string.
194     char *lscp_unquote ( char **ppsz, int dup )
195     {
196     char chQuote;
197     char *psz = *ppsz;
198    
199     while (isspace(*psz))
200     ++psz;
201     if (*psz == '\"' || *psz == '\'') {
202     chQuote = *psz++;
203     while (isspace(*psz))
204     ++psz;
205     if (dup)
206     psz = strdup(psz);
207     *ppsz = psz;
208     if (*ppsz) {
209     while (**ppsz && **ppsz != chQuote)
210     ++(*ppsz);
211     if (**ppsz) {
212     while (isspace(*(*ppsz - 1)) && *ppsz > psz)
213     --(*ppsz);
214     *(*ppsz)++ = (char) 0;
215     }
216     }
217     }
218     else if (dup) {
219     psz = strdup(psz);
220     *ppsz = psz;
221     }
222    
223     return psz;
224     }
225    
226    
227     // Custom tokenizer.
228     char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )
229     {
230     char *pszToken;
231    
232     if (pchBuffer == NULL)
233     pchBuffer = *ppch;
234    
235     pchBuffer += strspn(pchBuffer, pszSeps);
236     if (*pchBuffer == '\0')
237     return NULL;
238    
239     pszToken = pchBuffer;
240     pchBuffer = strpbrk(pszToken, pszSeps);
241     if (pchBuffer == NULL) {
242     *ppch = strchr(pszToken, '\0');
243     } else {
244     *pchBuffer = '\0';
245     *ppch = pchBuffer + 1;
246     while (**ppch && strchr(pszSeps, **ppch))
247     (*ppch)++;
248     }
249    
250     return pszToken;
251     }
252    
253    
254     // Split a comma separated string into a null terminated array of strings.
255     char **lscp_szsplit_create ( const char *pszCsv, const char *pszSeps )
256     {
257     char *pszHead, *pch;
258     int iSize, i, j, cchSeps;
259     char **ppszSplit, **ppszNewSplit;
260    
261     // Initial size is one chunk away.
262     iSize = LSCP_SPLIT_CHUNK1;
263     // Allocate and split...
264     ppszSplit = (char **) malloc(iSize * sizeof(char *));
265     if (ppszSplit == NULL)
266     return NULL;
267    
268     // Make a copy of the original string.
269     i = 0;
270     pszHead = (char *) pszCsv;
271     if ((ppszSplit[i++] = lscp_unquote(&pszHead, 1)) == NULL) {
272     free(ppszSplit);
273     return NULL;
274     }
275    
276     // Go on for it...
277     cchSeps = strlen(pszSeps);
278     while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {
279     // Pre-advance to next item.
280     pszHead = pch + cchSeps;
281     // Trim and null terminate current item.
282     while (isspace(*(pch - 1)) && pch > ppszSplit[0])
283     --pch;
284     *pch = (char) 0;
285     // Make it official.
286     ppszSplit[i++] = lscp_unquote(&pszHead, 0);
287     // Do we need to grow?
288     if (i >= iSize) {
289     // Yes, but only grow in chunks.
290     iSize += LSCP_SPLIT_CHUNK1;
291     // Allocate and copy to new split array.
292     ppszNewSplit = (char **) malloc(iSize * sizeof(char *));
293     if (ppszNewSplit) {
294     for (j = 0; j < i; j++)
295     ppszNewSplit[j] = ppszSplit[j];
296     free(ppszSplit);
297     ppszSplit = ppszNewSplit;
298     }
299     }
300     }
301    
302     // NULL terminate split array.
303     for ( ; i < iSize; i++)
304     ppszSplit[i] = NULL;
305    
306     return ppszSplit;
307     }
308    
309    
310     // Free allocated memory of a legal null terminated array of strings.
311     void lscp_szsplit_destroy ( char **ppszSplit )
312     {
313     // Our split string is always the first item, if any.
314     if (ppszSplit && ppszSplit[0])
315     free(ppszSplit[0]);
316     // Now free the array itself.
317     if (ppszSplit)
318     free(ppszSplit);
319     }
320    
321    
322     #ifdef LSCP_SZSPLIT_COUNT
323    
324     // Return the number of items of a null terminated array of strings.
325     int lscp_szsplit_count ( char **ppszSplit )
326     {
327     int i = 0;
328     while (ppszSplit && ppszSplit[i])
329     i++;
330     return i;
331     }
332    
333     // Return the allocated number of items of a splitted string array.
334     int lscp_szsplit_size ( char **ppszSplit )
335     {
336     return LSCP_SPLIT_SIZE(lscp_szsplit_count(ppszSplit));
337     }
338    
339     #endif // LSCP_SZSPLIT_COUNT
340    
341    
342 capela 125 // 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 capela 158 // 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.psz = 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.psz = ppSplit[j].value.psz;
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.psz = 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 capela 103 //-------------------------------------------------------------------------
510     // Engine info struct helper functions.
511    
512     void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
513     {
514     pEngineInfo->description = NULL;
515     pEngineInfo->version = NULL;
516     }
517    
518     void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
519     {
520     if (pEngineInfo->description)
521     free(pEngineInfo->description);
522     if (pEngineInfo->version)
523     free(pEngineInfo->version);
524    
525     lscp_engine_info_init(pEngineInfo);
526     }
527    
528    
529     //-------------------------------------------------------------------------
530     // Channel info struct helper functions.
531    
532     void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
533     {
534 capela 132 pChannelInfo->engine_name = NULL;
535     pChannelInfo->audio_device = 0;
536     pChannelInfo->audio_channels = 0;
537     pChannelInfo->audio_routing = NULL;
538     pChannelInfo->instrument_file = NULL;
539     pChannelInfo->instrument_nr = 0;
540     pChannelInfo->instrument_status = 0;
541     pChannelInfo->midi_device = 0;
542     pChannelInfo->midi_port = 0;
543     pChannelInfo->midi_channel = 0;
544     pChannelInfo->volume = 0.0;
545 capela 103 }
546    
547     void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
548     {
549     if (pChannelInfo->engine_name)
550     free(pChannelInfo->engine_name);
551     if (pChannelInfo->audio_routing)
552     lscp_szsplit_destroy(pChannelInfo->audio_routing);
553     if (pChannelInfo->instrument_file)
554     free(pChannelInfo->instrument_file);
555    
556     lscp_channel_info_init(pChannelInfo);
557     }
558    
559    
560     //-------------------------------------------------------------------------
561     // Driver info struct functions.
562    
563     void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
564     {
565     pDriverInfo->description = NULL;
566     pDriverInfo->version = NULL;
567     pDriverInfo->parameters = NULL;
568     }
569    
570     void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
571     {
572     if (pDriverInfo->description)
573     free(pDriverInfo->description);
574     if (pDriverInfo->version)
575     free(pDriverInfo->version);
576     lscp_szsplit_destroy(pDriverInfo->parameters);
577    
578     lscp_driver_info_init(pDriverInfo);
579     }
580    
581    
582     // end of common.c

  ViewVC Help
Powered by ViewVC