/[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 946 by capela, Mon Nov 27 18:33:02 2006 UTC revision 3664 by schoenebeck, Sun Dec 22 12:53:26 2019 UTC
# Line 2  Line 2 
2  //  //
3  /****************************************************************************  /****************************************************************************
4     liblscp - LinuxSampler Control Protocol API     liblscp - LinuxSampler Control Protocol API
5     Copyright (C) 2004-2006, rncbc aka Rui Nuno Capela. All rights reserved.     Copyright (C) 2004-2007, 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 23  Line 23 
23  #include "common.h"  #include "common.h"
24    
25  #include <ctype.h>  #include <ctype.h>
26    #include <sys/time.h>
27    #include <sys/errno.h>
28    
29    
30  // Split chunk size magic:  // Split chunk size magic:
# Line 39  Line 41 
41  // Result buffer internal settler.  // Result buffer internal settler.
42  void lscp_client_set_result ( lscp_client_t *pClient, char *pszResult, int iErrno )  void lscp_client_set_result ( lscp_client_t *pClient, char *pszResult, int iErrno )
43  {  {
44      if (pClient->pszResult)          if (pClient->pszResult)
45          free(pClient->pszResult);                  free(pClient->pszResult);
46      pClient->pszResult = NULL;          pClient->pszResult = NULL;
47    
48      pClient->iErrno = iErrno;          pClient->iErrno = iErrno;
49    
50      if (pszResult)          if (pszResult)
51          pClient->pszResult = strdup(lscp_ltrim(pszResult));                  pClient->pszResult = strdup(lscp_ltrim(pszResult));
52  }  }
53    
54    
55  // The common client receiver executive.  // The common client receiver executive.
56  lscp_status_t lscp_client_recv ( lscp_client_t *pClient, char *pchBuffer, int *pcchBuffer, int iTimeout )  lscp_status_t lscp_client_recv ( lscp_client_t *pClient, char *pchBuffer, int *pcchBuffer, int iTimeout )
57  {  {
58      fd_set fds;                         // File descriptor list for select().          fd_set fds;         // File descriptor list for select().
59      int    fd, fdmax;                   // Maximum file descriptor number.          int    fd, fdmax;   // Maximum file descriptor number.
60      struct timeval tv;                  // For specifying a timeout value.          struct timeval tv;  // For specifying a timeout value.
61      int    iSelect;                     // Holds select return status.          int    iSelect;     // Holds select return status.
62    
63      lscp_status_t ret = LSCP_FAILED;          lscp_status_t ret = LSCP_FAILED;
64    
65      if (pClient == NULL)          if (pClient == NULL)
66          return ret;                  return ret;
67    
68      // Prepare for waiting on select...          // Prepare for waiting on select...
69      fd = (int) pClient->cmd.sock;          fd = (int) pClient->cmd.sock;
70      FD_ZERO(&fds);          FD_ZERO(&fds);
71      FD_SET((unsigned int) fd, &fds);          FD_SET((unsigned int) fd, &fds);
72      fdmax = fd;          fdmax = fd;
73    
74      // Use the timeout select feature...          // Use the timeout select feature...
75      if (iTimeout < 1)          if (iTimeout < 1)
76          iTimeout = pClient->iTimeout;                  iTimeout = pClient->iTimeout;
77      if (iTimeout >= 1000) {          if (iTimeout >= 1000) {
78          tv.tv_sec = iTimeout / 1000;                  tv.tv_sec = iTimeout / 1000;
79          iTimeout -= tv.tv_sec * 1000;                  iTimeout -= tv.tv_sec * 1000;
80      }          }
81      else tv.tv_sec = 0;          else tv.tv_sec = 0;
82      tv.tv_usec = iTimeout * 1000;          tv.tv_usec = iTimeout * 1000;
83    
84      // Wait for event...          // Wait for event...
85      iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);          iSelect = select(fdmax + 1, &fds, NULL, NULL, &tv);
86      if (iSelect > 0 && FD_ISSET(fd, &fds)) {          if (iSelect > 0 && FD_ISSET(fd, &fds)) {
87          // May recv now...                  // May recv now...
88          *pcchBuffer = recv(pClient->cmd.sock, pchBuffer, *pcchBuffer, 0);                  *pcchBuffer = recv(pClient->cmd.sock, pchBuffer, *pcchBuffer, 0);
89          if (*pcchBuffer > 0)                  if (*pcchBuffer > 0)
90              ret = LSCP_OK;                          ret = LSCP_OK;
91          else if (*pcchBuffer < 0)                  else if (*pcchBuffer < 0)
92              lscp_socket_perror("lscp_client_recv: recv");                          lscp_socket_perror("lscp_client_recv: recv");
93          else if (*pcchBuffer == 0) {                  else if (*pcchBuffer == 0) {
94              // Damn, server probably disconnected,                          // Damn, server probably disconnected,
95              // we better free everything down here.                          // we better free everything down here.
96              lscp_socket_agent_free(&(pClient->evt));                          lscp_socket_agent_free(&(pClient->evt));
97              lscp_socket_agent_free(&(pClient->cmd));                          lscp_socket_agent_free(&(pClient->cmd));
98              // Fake a result message.                          // Fake a result message.
99              ret = LSCP_QUIT;                          ret = LSCP_QUIT;
100          }                  }
101      }   // Check if select has timed out.          }   // Check if select has timed out.
102      else if (iSelect == 0)          else if (iSelect == 0)
103          ret = LSCP_TIMEOUT;                  ret = LSCP_TIMEOUT;
104      else          else
105          lscp_socket_perror("lscp_client_recv: select");                  lscp_socket_perror("lscp_client_recv: select");
106    
107      return ret;          return ret;
108  }  }
109    
110    
111  // The main client requester call executive.  // The main client requester call executive.
112  lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery )  lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery, int iResult )
113  {  {
114      int    cchQuery;          int    cchQuery;
115      char   achResult[LSCP_BUFSIZ];          char   achBuffer[LSCP_BUFSIZ];
116      int    cchResult;          int    cchBuffer;
117      const  char *pszSeps = ":[]";          const  char *pszSeps = ":[]";
118      char  *pszResult;          char  *pszBuffer;
119      char  *pszToken;          char  *pszToken;
120      char  *pch;          char  *pch;
121      int    iErrno;          int    iErrno;
122            char  *pszResult;
123      lscp_status_t ret = LSCP_FAILED;          int    cchResult;
124            ssize_t sz;
125      if (pClient == NULL)          
126          return ret;          lscp_status_t ret = LSCP_FAILED;
127            
128      pszResult = NULL;          if (pClient == NULL)
129      iErrno = -1;                  return ret;
130            
131      // Check if command socket socket is still valid.          iErrno = -1;
132      if (pClient->cmd.sock == INVALID_SOCKET) {          cchResult = 0;
133          pszResult = "Connection closed or no longer valid";          pszResult = NULL;
134          lscp_client_set_result(pClient, pszResult, iErrno);          pszBuffer = NULL;
135          return ret;  
136      }          // Check if command socket socket is still valid.
137            if (pClient->cmd.sock == INVALID_SOCKET) {
138                    pszResult = "Connection closed or no longer valid";
139                    lscp_client_set_result(pClient, pszResult, iErrno);
140                    return ret;
141            }
142    
143          // Check if last transaction has timed out, in which case          // Check if last transaction has timed out, in which case
144          // we'll retry wait and flush for some pending garbage...          // we'll retry wait and flush for some pending garbage...
145          if (pClient->iTimeoutCount > 0) {          if (pClient->iTimeoutCount > 0) {
146                  cchResult = sizeof(achResult);                  // We'll hope to get rid of timeout trouble...
147                  ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);                  pClient->iTimeoutCount = 0;
148                  if (ret == LSCP_OK) {                  cchBuffer = sizeof(achBuffer);
149                          // We've got rid of timeout trouble (hopefully).                  ret = lscp_client_recv(pClient, achBuffer, &cchBuffer, pClient->iTimeout);
150                          pClient->iTimeoutCount = 0;                  if (ret != LSCP_OK) {
151                  } else {                          // Things seems to be unresolved. Fake a result message.
                         // Things are worse than before. Fake a result message.  
152                          iErrno = (int) ret;                          iErrno = (int) ret;
153                          pszResult = "Failure during flush timeout operation";                          pszResult = "Failure during flush timeout operation";
154                          lscp_client_set_result(pClient, pszResult, iErrno);                          lscp_client_set_result(pClient, pszResult, iErrno);
# Line 150  lscp_status_t lscp_client_call ( lscp_cl Line 156  lscp_status_t lscp_client_call ( lscp_cl
156                  }                  }
157          }          }
158    
159      // Send data, and then, wait for the result...          // Send data, and then, wait for the result...
160      cchQuery = strlen(pszQuery);          cchQuery = strlen(pszQuery);
161      if (send(pClient->cmd.sock, pszQuery, cchQuery, 0) < cchQuery) {          sz = send(pClient->cmd.sock, pszQuery, cchQuery, 0);
162          lscp_socket_perror("lscp_client_call: send");          if (sz < cchQuery) {
163          pszResult = "Failure during send operation";                  lscp_socket_perror("lscp_client_call: send");
164          lscp_client_set_result(pClient, pszResult, iErrno);                  pszResult = "Failure during send operation";
165          return ret;                  if (sz < 0)
166      }                          iErrno = -errno;
167                    lscp_client_set_result(pClient, pszResult, iErrno);
168      // Wait for receive event...                  return ret;
169      cchResult = sizeof(achResult);          }
170      ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);  
171            // Keep receiving while result is not the expected one:
172      switch (ret) {          // single-line result (iResult = 0) : one single CRLF ends the receipt;
173            // multi-line result  (iResult > 0) : one "." followed by a last CRLF;
174        case LSCP_OK:  
175          // Always force the result to be null terminated (and trim trailing CRLFs)!          while (pszResult == NULL) {
176          while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))  
177              cchResult--;                  // Wait for receive event...
178          achResult[cchResult] = (char) 0;                  cchBuffer = sizeof(achBuffer) - 1;
179          // Check if the response it's an error or warning message.                  ret = lscp_client_recv(pClient, achBuffer, &cchBuffer, pClient->iTimeout);
180          if (strncasecmp(achResult, "WRN:", 4) == 0)  
181              ret = LSCP_WARNING;                  switch (ret) {
182          else if (strncasecmp(achResult, "ERR:", 4) == 0)  
183              ret = LSCP_ERROR;                  case LSCP_OK:
184          // So we got a result...                          // Always force the result to be null terminated.
185          if (ret == LSCP_OK) {                          achBuffer[cchBuffer] = (char) 0;
186              // Reset errno in case of success.                          // Check if the response it's an error or warning message.
187              iErrno = 0;                          if (strncasecmp(achBuffer, "WRN:", 4) == 0)
188              // Is it a special successful response?                                  ret = LSCP_WARNING;
189              if (strncasecmp(achResult, "OK[", 3) == 0) {                          else if (strncasecmp(achBuffer, "ERR:", 4) == 0)
190                  // Parse the OK message, get the return string under brackets...                                  ret = LSCP_ERROR;
191                  pszToken = lscp_strtok(achResult, pszSeps, &(pch));                          // So we got a result...
192                  if (pszToken)                          if (ret == LSCP_OK) {
193                      pszResult = lscp_strtok(NULL, pszSeps, &(pch));                                  // Reset errno in case of success.
194              }                                  iErrno = 0;
195              else pszResult = achResult;                                  // Is it a special successful response?
196              // The result string is now set to the command response, if any.                                  if (iResult < 1 && strncasecmp(achBuffer, "OK[", 3) == 0) {
197          } else {                                          // Parse the OK message, get the return string under brackets...
198              // Parse the error/warning message, skip first colon...                                          pszToken = lscp_strtok(achBuffer, pszSeps, &(pch));
199              pszToken = lscp_strtok(achResult, pszSeps, &(pch));                                          if (pszToken)
200              if (pszToken) {                                                  pszResult = lscp_strtok(NULL, pszSeps, &(pch));
201                  // Get the error number...                                  } else {
202                  pszToken = lscp_strtok(NULL, pszSeps, &(pch));                                          // It can be specially long response...
203                  if (pszToken) {                                          cchResult += sizeof(achBuffer);
204                      iErrno = atoi(pszToken);                                          pszResult  = malloc(cchResult + 1);
205                      // And make the message text our final result.                                          pszResult[0] = (char) 0;
206                      pszResult = lscp_strtok(NULL, pszSeps, &(pch));                                          if (pszBuffer) {
207                  }                                                  strcat(pszResult, pszBuffer);
208              }                                                  free(pszBuffer);
209              // The result string is set to the error/warning message text.                                          }
210          }                                          strcat(pszResult, achBuffer);
211          break;                                          pszBuffer = pszResult;
212                                            pszResult = NULL;
213        case LSCP_TIMEOUT:                                          // Check for correct end-of-transmission...
214                  // We have trouble...                                          // Depending whether its single or multi-line we'll
215                  pClient->iTimeoutCount++;                                          // flag end-of-transmission...
216          // Fake a result message.                                          cchBuffer = strlen(pszBuffer);
217          pszResult = "Timeout during receive operation";                                          if (cchBuffer >= 2
218          iErrno = (int) ret;                                                  && pszBuffer[cchBuffer - 1] == '\n'
219          break;                                                  && pszBuffer[cchBuffer - 2] == '\r'
220                                                    && (iResult < 1 || (cchBuffer >= 3
221        case LSCP_QUIT:                                                                  && pszBuffer[cchBuffer - 3] == '.'))) {
222          // Fake a result message.                                                  // Get rid of the trailling dot and CRLF anyway...
223          pszResult = "Server terminated the connection";                                                  while (cchBuffer > 0 && (
224          iErrno = (int) ret;                                                          pszBuffer[cchBuffer - 1] == '\r' ||
225          break;                                                          pszBuffer[cchBuffer - 1] == '\n' ||
226                                                            pszBuffer[cchBuffer - 1] == '.'))
227        case LSCP_FAILED:                                                          cchBuffer--;
228        default:                                                  pszBuffer[cchBuffer] = (char) 0;
229          // What's down?                                                  pszResult = pszBuffer;
230          pszResult = "Failure during receive operation";                                          }
231          break;                                  }
232      }                                  // The result string is now set to the command response, if any.
233                            } else {
234                                    // Get rid of the CRLF anyway...
235                                    while (cchBuffer > 0 && (
236                                            achBuffer[cchBuffer - 1] == '\r' ||
237                                            achBuffer[cchBuffer - 1] == '\n'))
238                                            achBuffer[--cchBuffer] = (char) 0;
239                                    // Parse the error/warning message, skip first colon...
240                                    pszToken = lscp_strtok(achBuffer, pszSeps, &(pch));
241                                    if (pszToken) {
242                                            // Get the error number...
243                                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
244                                            if (pszToken) {
245                                                    iErrno = atoi(pszToken) + 100;
246                                                    // And make the message text our final result.
247                                                    pszResult = lscp_strtok(NULL, pszSeps, &(pch));
248                                            }
249                                    }
250                                    // The result string is set to the error/warning message text.
251                            }
252                            break;
253    
254                    case LSCP_TIMEOUT:
255                            // We have trouble...
256                            pClient->iTimeoutCount++;
257                            // Fake a result message.
258                            pszResult = "Timeout during receive operation";
259                            iErrno = (int) ret;
260                            break;
261    
262                    case LSCP_QUIT:
263                            // Fake a result message.
264                            pszResult = "Server terminated the connection";
265                            iErrno = (int) ret;
266                            break;
267    
268                    case LSCP_FAILED:
269                    default:
270                            // What's down?
271                            pszResult = "Failure during receive operation";
272                            break;
273                    }
274            }
275    
276            // Make the result official...
277            lscp_client_set_result(pClient, pszResult, iErrno);
278    
279      // Make the result official...          // Free long-buffer, if any...
280      lscp_client_set_result(pClient, pszResult, iErrno);          if (pszBuffer)
281                    free(pszBuffer);
282    
283      return ret;          return ret;
284  }  }
285    
286    
# Line 238  lscp_status_t lscp_client_call ( lscp_cl Line 290  lscp_status_t lscp_client_call ( lscp_cl
290  // Trimming left spaces...  // Trimming left spaces...
291  char *lscp_ltrim ( char *psz )  char *lscp_ltrim ( char *psz )
292  {  {
293      while (isspace(*psz))          while (isspace(*psz))
294          psz++;                  psz++;
295      return psz;          return psz;
296  }  }
297    
298  // Unquote an in-split string.  // Unquote an in-split string.
299  char *lscp_unquote ( char **ppsz, int dup )  char *lscp_unquote ( char **ppsz, int dup )
300  {  {
301      char  chQuote;          char  chQuote;
302      char *psz = *ppsz;          char *psz = *ppsz;
303    
304      while (isspace(*psz))          while (isspace(*psz))
305          ++psz;                  ++psz;
306      if (*psz == '\"' || *psz == '\'') {          if (*psz == '\"' || *psz == '\'') {
307          chQuote = *psz++;                  chQuote = *psz++;
308          while (isspace(*psz))                  while (isspace(*psz))
309              ++psz;                          ++psz;
310          if (dup)                  if (dup)
311              psz = strdup(psz);                          psz = strdup(psz);
312          *ppsz = psz;                  *ppsz = psz;
313          if (*ppsz) {                  if (*ppsz) {
314              while (**ppsz && **ppsz != chQuote)                          while (**ppsz && **ppsz != chQuote)
315                  ++(*ppsz);                                  ++(*ppsz);
316              if (**ppsz) {                          if (**ppsz) {
317                  while (isspace(*(*ppsz - 1)) && *ppsz > psz)                                  while (isspace(*(*ppsz - 1)) && *ppsz > psz)
318                      --(*ppsz);                                          --(*ppsz);
319                  *(*ppsz)++ = (char) 0;                                  *(*ppsz)++ = (char) 0;
320              }                          }
321          }                  }
322      }          }
323      else if (dup) {          else if (dup) {
324          psz = strdup(psz);                  psz = strdup(psz);
325          *ppsz = psz;                  *ppsz = psz;
326      }          }
327    
328      return psz;          return psz;
329  }  }
330    
331  // Unquote and make a duplicate of an in-split string.  // Unquote and make a duplicate of an in-split string.
332  void lscp_unquote_dup ( char **ppszDst, char **ppszSrc )  void lscp_unquote_dup ( char **ppszDst, char **ppszSrc )
333  {  {
334       // Free desteny string, if already there.          // Free desteny string, if already there.
335       if (*ppszDst)          if (*ppszDst)
336           free(*ppszDst);                  free(*ppszDst);
337       *ppszDst = NULL;          *ppszDst = NULL;
338       // Unquote and duplicate.          // Unquote and duplicate.
339       if (*ppszSrc)          if (*ppszSrc)
340           *ppszDst = lscp_unquote(ppszSrc, 1);                  *ppszDst = lscp_unquote(ppszSrc, 1);
341  }  }
342    
343    
344  // Custom tokenizer.  // Custom tokenizer.
345  char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )  char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch )
346  {  {
347      char *pszToken;          char *pszToken;
348    
349      if (pchBuffer == NULL)          if (pchBuffer == NULL)
350          pchBuffer = *ppch;                  pchBuffer = *ppch;
351    
352      pchBuffer += strspn(pchBuffer, pszSeps);          pchBuffer += strspn(pchBuffer, pszSeps);
353      if (*pchBuffer == '\0')          if (*pchBuffer == '\0')
354          return NULL;                  return NULL;
355    
356      pszToken  = pchBuffer;          pszToken  = pchBuffer;
357      pchBuffer = strpbrk(pszToken, pszSeps);          pchBuffer = strpbrk(pszToken, pszSeps);
358      if (pchBuffer == NULL) {          if (pchBuffer == NULL) {
359          *ppch = strchr(pszToken, '\0');                  *ppch = strchr(pszToken, '\0');
360      } else {          } else {
361          *pchBuffer = '\0';                  *pchBuffer = '\0';
362          *ppch = pchBuffer + 1;                  *ppch = pchBuffer + 1;
363          while (**ppch && strchr(pszSeps, **ppch))                  while (**ppch && strchr(pszSeps, **ppch))
364              (*ppch)++;                          (*ppch)++;
365      }          }
366    
367      return pszToken;          return pszToken;
368  }  }
369    
370    
371  // Split a comma separated string into a null terminated array of strings.  // Split a comma separated string into a null terminated array of strings.
372  char **lscp_szsplit_create ( const char *pszCsv, const char *pszSeps )  char **lscp_szsplit_create ( const char *pszCsv, const char *pszSeps )
373  {  {
374      char *pszHead, *pch;          char *pszHead, *pch;
375      int iSize, i, j, cchSeps;          int iSize, i, j, cchSeps;
376      char **ppszSplit, **ppszNewSplit;          char **ppszSplit, **ppszNewSplit;
377    
378      // Initial size is one chunk away.          // Initial size is one chunk away.
379      iSize = LSCP_SPLIT_CHUNK1;          iSize = LSCP_SPLIT_CHUNK1;
380      // Allocate and split...          // Allocate and split...
381      ppszSplit = (char **) malloc(iSize * sizeof(char *));          ppszSplit = (char **) malloc(iSize * sizeof(char *));
382      if (ppszSplit == NULL)          if (ppszSplit == NULL)
383          return NULL;                  return NULL;
384    
385      // Make a copy of the original string.          // Make a copy of the original string.
386      i = 0;          i = 0;
387      pszHead = (char *) pszCsv;          pszHead = (char *) pszCsv;
388      if ((ppszSplit[i++] = lscp_unquote(&pszHead, 1)) == NULL) {          if ((ppszSplit[i++] = lscp_unquote(&pszHead, 1)) == NULL) {
389          free(ppszSplit);                  free(ppszSplit);
390          return NULL;                  return NULL;
391      }          }
   
     // Go on for it...  
     cchSeps = strlen(pszSeps);  
     while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {  
         // Pre-advance to next item.  
         pszHead = pch + cchSeps;  
         // Trim and null terminate current item.  
         while (isspace(*(pch - 1)) && pch > ppszSplit[0])  
             --pch;  
         *pch = (char) 0;  
         // Make it official.  
         ppszSplit[i] = lscp_unquote(&pszHead, 0);  
         // Do we need to grow?  
         if (++i >= iSize) {  
             // Yes, but only grow in chunks.  
             iSize += LSCP_SPLIT_CHUNK1;  
             // Allocate and copy to new split array.  
             ppszNewSplit = (char **) malloc(iSize * sizeof(char *));  
             if (ppszNewSplit) {  
                 for (j = 0; j < i; j++)  
                     ppszNewSplit[j] = ppszSplit[j];  
                 free(ppszSplit);  
                 ppszSplit = ppszNewSplit;  
             }  
         }  
     }  
   
     // NULL terminate split array.  
     for ( ; i < iSize; i++)  
         ppszSplit[i] = NULL;  
392    
393      return ppszSplit;          // Go on for it...
394            cchSeps = strlen(pszSeps);
395            while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {
396                    // Pre-advance to next item.
397                    pszHead = pch + cchSeps;
398                    // Trim and null terminate current item.
399                    while (isspace(*(pch - 1)) && pch > ppszSplit[0])
400                            --pch;
401                    *pch = (char) 0;
402                    // Make it official.
403                    ppszSplit[i] = lscp_unquote(&pszHead, 0);
404                    // Do we need to grow?
405                    if (++i >= iSize) {
406                            // Yes, but only grow in chunks.
407                            iSize += LSCP_SPLIT_CHUNK1;
408                            // Allocate and copy to new split array.
409                            ppszNewSplit = (char **) malloc(iSize * sizeof(char *));
410                            if (ppszNewSplit) {
411                                    for (j = 0; j < i; j++)
412                                            ppszNewSplit[j] = ppszSplit[j];
413                                    free(ppszSplit);
414                                    ppszSplit = ppszNewSplit;
415                            }
416                    }
417            }
418    
419            // NULL terminate split array.
420            for ( ; i < iSize; i++)
421                    ppszSplit[i] = NULL;
422    
423            return ppszSplit;
424  }  }
425    
426    
427  // Free allocated memory of a legal null terminated array of strings.  // Free allocated memory of a legal null terminated array of strings.
428  void lscp_szsplit_destroy ( char **ppszSplit )  void lscp_szsplit_destroy ( char **ppszSplit )
429  {  {
430      // Our split string is always the first item, if any.          // Our split string is always the first item, if any.
431      if (ppszSplit && ppszSplit[0])          if (ppszSplit && ppszSplit[0])
432          free(ppszSplit[0]);                  free(ppszSplit[0]);
433      // Now free the array itself.          // Now free the array itself.
434      if (ppszSplit)          if (ppszSplit)
435          free(ppszSplit);                  free(ppszSplit);
436  }  }
437    
438    
# Line 389  void lscp_szsplit_destroy ( char **ppszS Line 441  void lscp_szsplit_destroy ( char **ppszS
441  // Return the number of items of a null terminated array of strings.  // Return the number of items of a null terminated array of strings.
442  int lscp_szsplit_count ( char **ppszSplit )  int lscp_szsplit_count ( char **ppszSplit )
443  {  {
444      int i = 0;          int i = 0;
445      while (ppszSplit && ppszSplit[i])          while (ppszSplit && ppszSplit[i])
446          i++;                  i++;
447      return i;          return i;
448  }  }
449    
450  // Return the allocated number of items of a splitted string array.  // Return the allocated number of items of a splitted string array.
451  int lscp_szsplit_size ( char **ppszSplit )  int lscp_szsplit_size ( char **ppszSplit )
452  {  {
453      return LSCP_SPLIT_SIZE(lscp_szsplit_count(ppszSplit));          return LSCP_SPLIT_SIZE(lscp_szsplit_count(ppszSplit));
454  }  }
455    
456  #endif // LSCP_SZSPLIT_COUNT  #endif // LSCP_SZSPLIT_COUNT
# Line 407  int lscp_szsplit_size ( char **ppszSplit Line 459  int lscp_szsplit_size ( char **ppszSplit
459  // Split a comma separated string into a -1 terminated array of positive integers.  // Split a comma separated string into a -1 terminated array of positive integers.
460  int *lscp_isplit_create ( const char *pszCsv, const char *pszSeps )  int *lscp_isplit_create ( const char *pszCsv, const char *pszSeps )
461  {  {
462      char *pchHead, *pch;          char *pchHead, *pch;
463      int iSize, i, j, cchSeps;          int iSize, i, j, cchSeps;
464      int *piSplit, *piNewSplit;          int *piSplit, *piNewSplit;
465    
466      // Get it clean first.          // Get it clean first.
467      pchHead = lscp_ltrim((char *) pszCsv);          pchHead = lscp_ltrim((char *) pszCsv);
468      if (*pchHead == (char) 0)          if (*pchHead == (char) 0)
469          return NULL;                  return NULL;
470    
471      // Initial size is one chunk away.          // Initial size is one chunk away.
472      iSize = LSCP_SPLIT_CHUNK1;          iSize = LSCP_SPLIT_CHUNK1;
473      // Allocate and split...          // Allocate and split...
474      piSplit = (int *) malloc(iSize * sizeof(int));          piSplit = (int *) malloc(iSize * sizeof(int));
475      if (piSplit == NULL)          if (piSplit == NULL)
476          return NULL;                  return NULL;
477    
478      // Make a copy of the original string.          // Make a copy of the original string.
479      i = 0;          i = 0;
480      if ((piSplit[i++] = atoi(pchHead)) < 0) {          if ((piSplit[i++] = atoi(pchHead)) < 0) {
481          free(piSplit);                  free(piSplit);
482          return NULL;                  return NULL;
483      }          }
484    
485      // Go on for it...          // Go on for it...
486      cchSeps = strlen(pszSeps);          cchSeps = strlen(pszSeps);
487      while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {          while ((pch = strpbrk(pchHead, pszSeps)) != NULL) {
488          // Pre-advance to next item.                  // Pre-advance to next item.
489          pchHead = pch + cchSeps;                  pchHead = pch + cchSeps;
490          // Make it official.                  // Make it official.
491          piSplit[i] = atoi(pchHead);                  piSplit[i] = atoi(pchHead);
492          // Do we need to grow?                  // Do we need to grow?
493          if (++i >= iSize) {                  if (++i >= iSize) {
494              // Yes, but only grow in chunks.                          // Yes, but only grow in chunks.
495              iSize += LSCP_SPLIT_CHUNK1;                          iSize += LSCP_SPLIT_CHUNK1;
496              // Allocate and copy to new split array.                          // Allocate and copy to new split array.
497              piNewSplit = (int *) malloc(iSize * sizeof(int));                          piNewSplit = (int *) malloc(iSize * sizeof(int));
498              if (piNewSplit) {                          if (piNewSplit) {
499                  for (j = 0; j < i; j++)                                  for (j = 0; j < i; j++)
500                      piNewSplit[j] = piSplit[j];                                          piNewSplit[j] = piSplit[j];
501                  free(piSplit);                                  free(piSplit);
502                  piSplit = piNewSplit;                                  piSplit = piNewSplit;
503              }                          }
504          }                  }
505      }          }
506    
507      // NULL terminate split array.          // NULL terminate split array.
508      for ( ; i < iSize; i++)          for ( ; i < iSize; i++)
509          piSplit[i] = -1;                  piSplit[i] = -1;
510    
511      return piSplit;          return piSplit;
512  }  }
513    
514    
515  // Destroy a integer splitted array.  // Destroy a integer splitted array.
516  void lscp_isplit_destroy ( int *piSplit )  void lscp_isplit_destroy ( int *piSplit )
517  {  {
518      if (piSplit)          if (piSplit)
519          free(piSplit);                  free(piSplit);
520  }  }
521    
522    
# Line 473  void lscp_isplit_destroy ( int *piSplit Line 525  void lscp_isplit_destroy ( int *piSplit
525  // Compute a string list valid item count.  // Compute a string list valid item count.
526  int lscp_isplit_count ( int *piSplit )  int lscp_isplit_count ( int *piSplit )
527  {  {
528      int i = 0;          int i = 0;
529      while (piSplit && piSplit[i] >= 0)          while (piSplit && piSplit[i] >= 0)
530          i++;                  i++;
531      return i;          return i;
532  }  }
533    
534  // Compute a string list size.  // Compute a string list size.
535  int lscp_isplit_size ( int *piSplit )  int lscp_isplit_size ( int *piSplit )
536  {  {
537      return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));          return LSCP_SPLIT_SIZE(lscp_isplit_count(piSplit));
538  }  }
539    
540  #endif // LSCP_ISPLIT_COUNT  #endif // LSCP_ISPLIT_COUNT
# Line 491  int lscp_isplit_size ( int *piSplit ) Line 543  int lscp_isplit_size ( int *piSplit )
543  // Split a string into a null terminated array of parameter items.  // Split a string into a null terminated array of parameter items.
544  lscp_param_t *lscp_psplit_create ( const char *pszCsv, const char *pszSeps1, const char *pszSeps2 )  lscp_param_t *lscp_psplit_create ( const char *pszCsv, const char *pszSeps1, const char *pszSeps2 )
545  {  {
546      char *pszHead, *pch;          char *pszHead, *pch;
547      int iSize, i, j, cchSeps1, cchSeps2;          int iSize, i, j, cchSeps1, cchSeps2;
548      lscp_param_t *ppSplit, *ppNewSplit;          lscp_param_t *ppSplit, *ppNewSplit;
549    
550      pszHead = strdup(pszCsv);          pszHead = strdup(pszCsv);
551      if (pszHead == NULL)          if (pszHead == NULL)
552          return NULL;                  return NULL;
553    
554      iSize = LSCP_SPLIT_CHUNK1;          iSize = LSCP_SPLIT_CHUNK1;
555      ppSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));          ppSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
556      if (ppSplit == NULL) {          if (ppSplit == NULL) {
557          free(pszHead);                  free(pszHead);
558          return NULL;                  return NULL;
559      }          }
   
     cchSeps1 = strlen(pszSeps1);  
     cchSeps2 = strlen(pszSeps2);  
   
     i = 0;  
     while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {  
         ppSplit[i].key = pszHead;  
         pszHead = pch + cchSeps1;  
         *pch = (char) 0;  
         ppSplit[i].value = lscp_unquote(&pszHead, 0);  
         if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {  
             pszHead = pch + cchSeps2;  
             *pch = (char) 0;  
         }  
         if (++i >= iSize) {  
             iSize += LSCP_SPLIT_CHUNK1;  
             ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));  
             if (ppNewSplit) {  
                 for (j = 0; j < i; j++) {  
                     ppNewSplit[j].key   = ppSplit[j].key;  
                     ppNewSplit[j].value = ppSplit[j].value;  
                 }  
                 free(ppSplit);  
                 ppSplit = ppNewSplit;  
             }  
         }  
     }  
   
     if (i < 1)  
         free(pszHead);  
   
     for ( ; i < iSize; i++) {  
         ppSplit[i].key   = NULL;  
         ppSplit[i].value = NULL;  
     }  
560    
561      return ppSplit;          cchSeps1 = strlen(pszSeps1);
562            cchSeps2 = strlen(pszSeps2);
563    
564            i = 0;
565            while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {
566                    ppSplit[i].key = pszHead;
567                    pszHead = pch + cchSeps1;
568                    *pch = (char) 0;
569                    ppSplit[i].value = lscp_unquote(&pszHead, 0);
570                    if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {
571                            pszHead = pch + cchSeps2;
572                            *pch = (char) 0;
573                    }
574                    if (++i >= iSize) {
575                            iSize += LSCP_SPLIT_CHUNK1;
576                            ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
577                            if (ppNewSplit) {
578                                    for (j = 0; j < i; j++) {
579                                            ppNewSplit[j].key   = ppSplit[j].key;
580                                            ppNewSplit[j].value = ppSplit[j].value;
581                                    }
582                                    free(ppSplit);
583                                    ppSplit = ppNewSplit;
584                            }
585                    }
586            }
587    
588            if (i < 1)
589                    free(pszHead);
590    
591            for ( ; i < iSize; i++) {
592                    ppSplit[i].key   = NULL;
593                    ppSplit[i].value = NULL;
594            }
595    
596            return ppSplit;
597  }  }
598    
599    
600  // Destroy a parameter list array.  // Destroy a parameter list array.
601  void lscp_psplit_destroy ( lscp_param_t *ppSplit )  void lscp_psplit_destroy ( lscp_param_t *ppSplit )
602  {  {
603      if (ppSplit && ppSplit[0].key)          if (ppSplit && ppSplit[0].key)
604          free(ppSplit[0].key);                  free(ppSplit[0].key);
605      if (ppSplit)          if (ppSplit)
606          free(ppSplit);                  free(ppSplit);
607  }  }
608    
609    
# Line 560  void lscp_psplit_destroy ( lscp_param_t Line 612  void lscp_psplit_destroy ( lscp_param_t
612  // Compute a parameter list valid item count.  // Compute a parameter list valid item count.
613  int lscp_psplit_count ( lscp_param_t *ppSplit )  int lscp_psplit_count ( lscp_param_t *ppSplit )
614  {  {
615      int i = 0;          int i = 0;
616      while (ppSplit && ppSplit[i].key)          while (ppSplit && ppSplit[i].key)
617          i++;                  i++;
618      return i;          return i;
619  }  }
620    
621  // Compute a parameter list size.  // Compute a parameter list size.
622  int lscp_psplit_size ( lscp_param_t *ppSplit )  int lscp_psplit_size ( lscp_param_t *ppSplit )
623  {  {
624      return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));          return LSCP_SPLIT_SIZE(lscp_psplit_count(ppSplit));
625  }  }
626    
627  #endif // LSCP_PSPLIT_COUNT  #endif // LSCP_PSPLIT_COUNT
# Line 578  int lscp_psplit_size ( lscp_param_t *ppS Line 630  int lscp_psplit_size ( lscp_param_t *ppS
630  // Allocate a parameter list, optionally copying an existing one.  // Allocate a parameter list, optionally copying an existing one.
631  void lscp_plist_alloc (lscp_param_t **ppList)  void lscp_plist_alloc (lscp_param_t **ppList)
632  {  {
633      lscp_param_t *pParams;          lscp_param_t *pParams;
634      int iSize, i;          int iSize, i;
635    
636      if (ppList) {          if (ppList) {
637          iSize = LSCP_SPLIT_CHUNK1;                  iSize = LSCP_SPLIT_CHUNK1;
638          pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));                  pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
639          if (pParams) {                  if (pParams) {
640              for (i = 0 ; i < iSize; i++) {                          for (i = 0 ; i < iSize; i++) {
641                  pParams[i].key   = NULL;                                  pParams[i].key   = NULL;
642                  pParams[i].value = NULL;                                  pParams[i].value = NULL;
643              }                          }
644          }                  }
645          *ppList = pParams;                  *ppList = pParams;
646      }          }
647  }  }
648    
649    
650  // Destroy a parameter list, including all it's contents.  // Destroy a parameter list, including all it's contents.
651  void lscp_plist_free ( lscp_param_t **ppList )  void lscp_plist_free ( lscp_param_t **ppList )
652  {  {
653      lscp_param_t *pParams;          lscp_param_t *pParams;
654      int i;          int i;
655    
656      if (ppList) {          if (ppList) {
657          if (*ppList) {                  if (*ppList) {
658              pParams = *ppList;                          pParams = *ppList;
659              for (i = 0; pParams && pParams[i].key; i++) {                          for (i = 0; pParams && pParams[i].key; i++) {
660                  free(pParams[i].key);                                  free(pParams[i].key);
661                  free(pParams[i].value);                                  free(pParams[i].value);
662              }                          }
663              free(pParams);                          free(pParams);
664          }                  }
665          *ppList = NULL;                  *ppList = NULL;
666      }          }
667  }  }
668    
669    
670  // Add an item to a parameter list, growing it as fit.  // Add an item to a parameter list, growing it as fit.
671  void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue )  void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue )
672  {  {
673      lscp_param_t *pParams;          lscp_param_t *pParams;
674      lscp_param_t *pNewParams;          lscp_param_t *pNewParams;
675      int iSize, iNewSize;          int iSize, iNewSize;
676      int i = 0;          int i = 0;
677    
678      if (ppList && *ppList) {          if (ppList && *ppList) {
679          pParams = *ppList;                  pParams = *ppList;
680          while (pParams[i].key) {                  while (pParams[i].key) {
681              if (strcasecmp(pParams[i].key, pszKey) == 0) {                          if (strcasecmp(pParams[i].key, pszKey) == 0) {
682                  if (pParams[i].value)                                  if (pParams[i].value)
683                      free(pParams[i].value);                                          free(pParams[i].value);
684                  pParams[i].value = strdup(pszValue);                                  pParams[i].value = strdup(pszValue);
685                  return;                                  return;
686              }                          }
687              i++;                          i++;
688          }                  }
689          iSize = LSCP_SPLIT_SIZE(i);                  iSize = LSCP_SPLIT_SIZE(i);
690          pParams[i].key   = strdup(pszKey);                  pParams[i].key   = strdup(pszKey);
691          pParams[i].value = strdup(pszValue);                  pParams[i].value = strdup(pszValue);
692          if (++i >= iSize) {                  if (++i >= iSize) {
693              iNewSize   = iSize + LSCP_SPLIT_CHUNK1;                          iNewSize   = iSize + LSCP_SPLIT_CHUNK1;
694              pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t));                          pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t));
695              for (i = 0; i < iSize; i++) {                          for (i = 0; i < iSize; i++) {
696                  pNewParams[i].key   = pParams[i].key;                                  pNewParams[i].key   = pParams[i].key;
697                  pNewParams[i].value = pParams[i].value;                                  pNewParams[i].value = pParams[i].value;
698              }                          }
699              for ( ; i < iNewSize; i++) {                          for ( ; i < iNewSize; i++) {
700                  pNewParams[i].key   = NULL;                                  pNewParams[i].key   = NULL;
701                  pNewParams[i].value = NULL;                                  pNewParams[i].value = NULL;
702              }                          }
703              free(pParams);                          free(pParams);
704              *ppList = pNewParams;                          *ppList = pNewParams;
705          }                  }
706      }          }
707  }  }
708    
709  #ifdef LSCP_PLIST_COUNT  #ifdef LSCP_PLIST_COUNT
# Line 659  void lscp_plist_append ( lscp_param_t ** Line 711  void lscp_plist_append ( lscp_param_t **
711  // Compute a parameter list valid item count.  // Compute a parameter list valid item count.
712  int lscp_plist_count ( lscp_param_t **ppList )  int lscp_plist_count ( lscp_param_t **ppList )
713  {  {
714      lscp_param_t *pParams;          lscp_param_t *pParams;
715      int i = 0;          int i = 0;
716      if (ppList && *ppList) {          if (ppList && *ppList) {
717          pParams = *ppList;                  pParams = *ppList;
718          while (pParams[i].key)                  while (pParams[i].key)
719              i++;                          i++;
720      }          }
721      return i;          return i;
722  }  }
723    
724  // Compute the legal parameter list size.  // Compute the legal parameter list size.
725  int lscp_plist_size ( lscp_param_t **ppList )  int lscp_plist_size ( lscp_param_t **ppList )
726  {  {
727      return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));          return LSCP_SPLIT_SIZE(lscp_plist_count(ppList));
728  }  }
729    
730  #endif // LSCP_PLIST_COUNT  #endif // LSCP_PLIST_COUNT
731    
732    
733    // Split a string into an array of MIDI instrument triplets.
734    lscp_midi_instrument_t *lscp_midi_instruments_create ( const char *pszCsv )
735    {
736            char *pchHead, *pch;
737            int iSize, i, j, k;
738            lscp_midi_instrument_t *pInstrs;
739            lscp_midi_instrument_t *pNewInstrs;
740            
741            // Get it clean first.
742            pchHead = lscp_ltrim((char *) pszCsv);
743            if (*pchHead == (char) 0)
744                    return NULL;
745            
746            // Initial size is one chunk away.
747            iSize = LSCP_SPLIT_CHUNK1;
748            // Allocate and split...
749            pInstrs = (lscp_midi_instrument_t *) malloc(iSize * sizeof(lscp_midi_instrument_t));
750            if (pInstrs == NULL)
751                    return NULL;
752            
753            // Go on for it...
754            i = 0;
755            k = 0;
756            
757            while ((pch = strpbrk(pchHead, "{,}")) != NULL) {
758                    // Pre-advance to next item.
759                    switch (*pch) {
760                    case '{':
761                            pchHead = pch + 1;
762                            if (k == 0) {
763                                    pInstrs[i].map = atoi(pchHead);
764                                    k++;
765                            }
766                            break;
767                    case ',':
768                            pchHead = pch + 1;
769                            if (k == 1) {
770                                    pInstrs[i].bank = atoi(pchHead);
771                                    k++;
772                            }
773                            else
774                            if (k == 2) {
775                                    pInstrs[i].prog = atoi(pchHead);
776                                    k++;
777                            }
778                            break;
779                    case '}':
780                            pchHead = pch + 1;
781                            k = 0;
782                            break;
783                    }
784                    // Do we need to grow?
785                    if (k == 3 && ++i >= iSize) {
786                            // Yes, but only grow in chunks.
787                            iSize += LSCP_SPLIT_CHUNK1;
788                            // Allocate and copy to new split array.
789                            pNewInstrs = (lscp_midi_instrument_t *) malloc(iSize * sizeof(lscp_midi_instrument_t));
790                            if (pNewInstrs) {
791                                    for (j = 0; j < i; j++) {
792                                            pNewInstrs[j].map  = pInstrs[j].map;
793                                            pNewInstrs[j].bank = pInstrs[j].bank;
794                                            pNewInstrs[j].prog = pInstrs[j].prog;
795                                    }
796                                    free(pInstrs);
797                                    pInstrs = pNewInstrs;
798                            }
799                    }
800            }
801            
802            // Special terminate split array.
803            for ( ; i < iSize; i++) {
804                    pInstrs[i].map  = -1;
805                    pInstrs[i].bank = -1;
806                    pInstrs[i].prog = -1;
807            }
808            
809            return pInstrs;
810    }
811    
812    // Destroy a MIDI instrument triplet array.
813    void lscp_midi_instruments_destroy ( lscp_midi_instrument_t *pInstrs )
814    {
815            if (pInstrs)
816                    free(pInstrs);
817    }
818    
819    #ifdef LSCP_MIDI_INSTRUMENTS_COUNT
820    
821    // Compute a MIDI instrument array item count.
822    int lscp_midi_instruments_count ( lscp_midi_instrument_t *pInstrs )
823    {
824            int i = 0;
825            while (pInstrs && pInstrs[i].program >= 0)
826                    i++;
827            return i;
828    }
829    
830    // Compute a MIDI instrument array size.
831    int lscp_midi_instruments_size ( lscp_midi_instrument_t *pInstrs )
832    {
833            return LSCP_SPLIT_SIZE(lscp_midi_instruments_count(pInstrs));
834    }
835    
836    #endif // LSCP_MIDI_INSTRUMENTS_COUNT
837    
838    
839  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
840  // Server info struct helper functions.  // Server info struct helper functions.
841    
842  void lscp_server_info_init ( lscp_server_info_t *pServerInfo )  void lscp_server_info_init ( lscp_server_info_t *pServerInfo )
843  {  {
844      pServerInfo->description = NULL;          pServerInfo->description      = NULL;
845      pServerInfo->version     = NULL;          pServerInfo->version          = NULL;
846            pServerInfo->protocol_version = NULL;
847  }  }
848    
849  void lscp_server_info_free ( lscp_server_info_t *pServerInfo )  void lscp_server_info_free ( lscp_server_info_t *pServerInfo )
850  {  {
851      if (pServerInfo->description)          if (pServerInfo->description)
852          free(pServerInfo->description);                  free(pServerInfo->description);
853      if (pServerInfo->version)          if (pServerInfo->version)
854          free(pServerInfo->version);                  free(pServerInfo->version);
855            if (pServerInfo->protocol_version)
856                    free(pServerInfo->protocol_version);
857  }  }
858    
859  void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )  void lscp_server_info_reset ( lscp_server_info_t *pServerInfo )
860  {  {
861      lscp_server_info_free(pServerInfo);          lscp_server_info_free(pServerInfo);
862      lscp_server_info_init(pServerInfo);          lscp_server_info_init(pServerInfo);
863  }  }
864    
865    
# Line 707  void lscp_server_info_reset ( lscp_serve Line 868  void lscp_server_info_reset ( lscp_serve
868    
869  void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )  void lscp_engine_info_init ( lscp_engine_info_t *pEngineInfo )
870  {  {
871      pEngineInfo->description = NULL;          pEngineInfo->description = NULL;
872      pEngineInfo->version     = NULL;          pEngineInfo->version     = NULL;
873  }  }
874    
875  void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )  void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo )
876  {  {
877      if (pEngineInfo->description)          if (pEngineInfo->description)
878          free(pEngineInfo->description);                  free(pEngineInfo->description);
879      if (pEngineInfo->version)          if (pEngineInfo->version)
880          free(pEngineInfo->version);                  free(pEngineInfo->version);
881  }  }
882    
883  void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )  void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo )
884  {  {
885      lscp_engine_info_free(pEngineInfo);          lscp_engine_info_free(pEngineInfo);
886      lscp_engine_info_init(pEngineInfo);          lscp_engine_info_init(pEngineInfo);
887  }  }
888    
889    
# Line 731  void lscp_engine_info_reset ( lscp_engin Line 892  void lscp_engine_info_reset ( lscp_engin
892    
893  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_init ( lscp_channel_info_t *pChannelInfo )
894  {  {
895      pChannelInfo->engine_name       = NULL;          pChannelInfo->engine_name       = NULL;
896      pChannelInfo->audio_device      = 0;          pChannelInfo->audio_device      = 0;
897      pChannelInfo->audio_channels    = 0;          pChannelInfo->audio_channels    = 0;
898      pChannelInfo->audio_routing     = NULL;          pChannelInfo->audio_routing     = NULL;
899      pChannelInfo->instrument_file   = NULL;          pChannelInfo->instrument_file   = NULL;
900      pChannelInfo->instrument_nr     = 0;          pChannelInfo->instrument_nr     = 0;
901      pChannelInfo->instrument_name   = NULL;          pChannelInfo->instrument_name   = NULL;
902      pChannelInfo->instrument_status = 0;          pChannelInfo->instrument_status = 0;
903      pChannelInfo->midi_device       = 0;          pChannelInfo->midi_device       = 0;
904      pChannelInfo->midi_port         = 0;          pChannelInfo->midi_port         = 0;
905      pChannelInfo->midi_channel      = 0;          pChannelInfo->midi_channel      = 0;
906      pChannelInfo->volume            = 0.0;          pChannelInfo->midi_map          = 0;
907      pChannelInfo->mute              = 0;          pChannelInfo->volume            = 0.0;
908      pChannelInfo->solo              = 0;          pChannelInfo->mute              = 0;
909            pChannelInfo->solo              = 0;
910  }  }
911    
912  void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo )
913  {  {
914      if (pChannelInfo->engine_name)          if (pChannelInfo->engine_name)
915          free(pChannelInfo->engine_name);                  free(pChannelInfo->engine_name);
916      if (pChannelInfo->audio_routing)          if (pChannelInfo->audio_routing)
917          lscp_szsplit_destroy(pChannelInfo->audio_routing);                  lscp_isplit_destroy(pChannelInfo->audio_routing);
918      if (pChannelInfo->instrument_file)          if (pChannelInfo->instrument_file)
919          free(pChannelInfo->instrument_file);                  free(pChannelInfo->instrument_file);
920      if (pChannelInfo->instrument_name)          if (pChannelInfo->instrument_name)
921          free(pChannelInfo->instrument_name);                  free(pChannelInfo->instrument_name);
922  }  }
923    
924  void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )  void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo )
925  {  {
926      lscp_channel_info_free(pChannelInfo);          lscp_channel_info_free(pChannelInfo);
927      lscp_channel_info_init(pChannelInfo);          lscp_channel_info_init(pChannelInfo);
928  }  }
929    
930    
# Line 771  void lscp_channel_info_reset ( lscp_chan Line 933  void lscp_channel_info_reset ( lscp_chan
933    
934  void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )  void lscp_driver_info_init ( lscp_driver_info_t *pDriverInfo )
935  {  {
936      pDriverInfo->description = NULL;          pDriverInfo->description = NULL;
937      pDriverInfo->version     = NULL;          pDriverInfo->version     = NULL;
938      pDriverInfo->parameters  = NULL;          pDriverInfo->parameters  = NULL;
939  }  }
940    
941  void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )  void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo )
942  {  {
943      if (pDriverInfo->description)          if (pDriverInfo->description)
944          free(pDriverInfo->description);                  free(pDriverInfo->description);
945      if (pDriverInfo->version)          if (pDriverInfo->version)
946          free(pDriverInfo->version);                  free(pDriverInfo->version);
947      lscp_szsplit_destroy(pDriverInfo->parameters);          lscp_szsplit_destroy(pDriverInfo->parameters);
948  }  }
949    
950  void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )  void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo )
951  {  {
952      lscp_driver_info_free(pDriverInfo);          lscp_driver_info_free(pDriverInfo);
953      lscp_driver_info_init(pDriverInfo);          lscp_driver_info_init(pDriverInfo);
954  }  }
955    
956    
# Line 797  void lscp_driver_info_reset ( lscp_drive Line 959  void lscp_driver_info_reset ( lscp_drive
959    
960  void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )  void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo )
961  {  {
962      pDeviceInfo->driver = NULL;          pDeviceInfo->driver = NULL;
963      lscp_plist_alloc(&(pDeviceInfo->params));          lscp_plist_alloc(&(pDeviceInfo->params));
964  }  }
965    
966  void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )  void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo )
967  {  {
968      if (pDeviceInfo->driver)          if (pDeviceInfo->driver)
969          free(pDeviceInfo->driver);                  free(pDeviceInfo->driver);
970      lscp_plist_free(&(pDeviceInfo->params));          lscp_plist_free(&(pDeviceInfo->params));
971  }  }
972    
973  void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )  void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo )
974  {  {
975      lscp_device_info_free(pDeviceInfo);          lscp_device_info_free(pDeviceInfo);
976      lscp_device_info_init(pDeviceInfo);          lscp_device_info_init(pDeviceInfo);
977  }  }
978    
979    
# Line 820  void lscp_device_info_reset ( lscp_devic Line 982  void lscp_device_info_reset ( lscp_devic
982    
983  void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )  void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo )
984  {  {
985      pDevicePortInfo->name = NULL;          pDevicePortInfo->name = NULL;
986      lscp_plist_alloc(&(pDevicePortInfo->params));          lscp_plist_alloc(&(pDevicePortInfo->params));
987  }  }
988    
989  void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )  void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo )
990  {  {
991      if (pDevicePortInfo->name)          if (pDevicePortInfo->name)
992          free(pDevicePortInfo->name);                  free(pDevicePortInfo->name);
993      lscp_plist_free(&(pDevicePortInfo->params));          lscp_plist_free(&(pDevicePortInfo->params));
994  }  }
995    
996  void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )  void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo )
997  {  {
998      lscp_device_port_info_free(pDevicePortInfo);          lscp_device_port_info_free(pDevicePortInfo);
999      lscp_device_port_info_init(pDevicePortInfo);          lscp_device_port_info_init(pDevicePortInfo);
1000  }  }
1001    
1002    
# Line 843  void lscp_device_port_info_reset ( lscp_ Line 1005  void lscp_device_port_info_reset ( lscp_
1005    
1006  void lscp_param_info_init ( lscp_param_info_t *pParamInfo )  void lscp_param_info_init ( lscp_param_info_t *pParamInfo )
1007  {  {
1008      pParamInfo->type          = LSCP_TYPE_NONE;          pParamInfo->type          = LSCP_TYPE_NONE;
1009      pParamInfo->description   = NULL;          pParamInfo->description   = NULL;
1010      pParamInfo->mandatory     = 0;          pParamInfo->mandatory     = 0;
1011      pParamInfo->fix           = 0;          pParamInfo->fix           = 0;
1012      pParamInfo->multiplicity  = 0;          pParamInfo->multiplicity  = 0;
1013      pParamInfo->depends       = NULL;          pParamInfo->depends       = NULL;
1014      pParamInfo->defaultv      = NULL;          pParamInfo->defaultv      = NULL;
1015      pParamInfo->range_min     = NULL;          pParamInfo->range_min     = NULL;
1016      pParamInfo->range_max     = NULL;          pParamInfo->range_max     = NULL;
1017      pParamInfo->possibilities = NULL;          pParamInfo->possibilities = NULL;
1018  }  }
1019    
1020  void lscp_param_info_free ( lscp_param_info_t *pParamInfo )  void lscp_param_info_free ( lscp_param_info_t *pParamInfo )
1021  {  {
1022      if (pParamInfo->description)          if (pParamInfo->description)
1023          free(pParamInfo->description);                  free(pParamInfo->description);
1024      lscp_szsplit_destroy(pParamInfo->depends);          lscp_szsplit_destroy(pParamInfo->depends);
1025      if (pParamInfo->defaultv)          if (pParamInfo->defaultv)
1026          free(pParamInfo->defaultv);                  free(pParamInfo->defaultv);
1027      if (pParamInfo->range_min)          if (pParamInfo->range_min)
1028          free(pParamInfo->range_min);                  free(pParamInfo->range_min);
1029      if (pParamInfo->range_max)          if (pParamInfo->range_max)
1030          free(pParamInfo->range_max);                  free(pParamInfo->range_max);
1031      lscp_szsplit_destroy(pParamInfo->possibilities);          lscp_szsplit_destroy(pParamInfo->possibilities);
1032  }  }
1033    
1034  void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )  void lscp_param_info_reset ( lscp_param_info_t *pParamInfo )
1035  {  {
1036      lscp_param_info_free(pParamInfo);          lscp_param_info_free(pParamInfo);
1037      lscp_param_info_init(pParamInfo);          lscp_param_info_init(pParamInfo);
1038  }  }
1039    
1040    
# Line 882  void lscp_param_info_reset ( lscp_param_ Line 1044  void lscp_param_info_reset ( lscp_param_
1044    
1045  int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )  int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams )
1046  {  {
1047      int cchBuffer, cchParam, i;          int cchBuffer, cchParam, i;
1048    
1049            if (pszBuffer == NULL)
1050                    return 0;
1051    
1052            cchBuffer = strlen(pszBuffer);
1053            for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
1054                    cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
1055                    if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
1056                            sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
1057                            cchBuffer += cchParam;
1058                    }
1059            }
1060            
1061            if (cchBuffer + 2 < cchMaxBuffer) {
1062                    pszBuffer[cchBuffer++] = '\r';
1063                    pszBuffer[cchBuffer++] = '\n';
1064                    pszBuffer[cchBuffer ]  = (char) 0;
1065            }
1066            
1067            return cchBuffer;
1068    }
1069    
     if (pszBuffer == NULL)  
         return 0;  
1070    
1071      cchBuffer = strlen(pszBuffer);  //-------------------------------------------------------------------------
1072      for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {  // Effect struct helper functions.
1073          cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;  
1074          if (cchBuffer + cchParam + 2 < cchMaxBuffer) {  void lscp_fxsend_info_init ( lscp_fxsend_info_t *pFxSendInfo )
1075              sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);  {
1076              cchBuffer += cchParam;          pFxSendInfo->name            = NULL;
1077          }          pFxSendInfo->midi_controller = 0;
1078      }          pFxSendInfo->audio_routing   = NULL;
1079                pFxSendInfo->level           = 0.0f;
1080      if (cchBuffer + 2 < cchMaxBuffer) {  }
1081          pszBuffer[cchBuffer++] = '\r';  
1082          pszBuffer[cchBuffer++] = '\n';  void lscp_fxsend_info_free ( lscp_fxsend_info_t *pFxSendInfo )
1083          pszBuffer[cchBuffer ]  = (char) 0;  {
1084      }          if (pFxSendInfo->name)
1085                        free(pFxSendInfo->name);
1086      return cchBuffer;          if (pFxSendInfo->audio_routing)
1087                    lscp_isplit_destroy(pFxSendInfo->audio_routing);
1088    }
1089    
1090    void lscp_fxsend_info_reset (lscp_fxsend_info_t *pFxSendInfo )
1091    {
1092            lscp_fxsend_info_free(pFxSendInfo);
1093            lscp_fxsend_info_init(pFxSendInfo);
1094  }  }
1095    
1096    
# Line 911  int lscp_param_concat ( char *pszBuffer, Line 1099  int lscp_param_concat ( char *pszBuffer,
1099    
1100  void lscp_midi_instrument_info_init ( lscp_midi_instrument_info_t *pInstrInfo )  void lscp_midi_instrument_info_init ( lscp_midi_instrument_info_t *pInstrInfo )
1101  {  {
1102      pInstrInfo->name              = NULL;          pInstrInfo->name              = NULL;
1103      pInstrInfo->engine_name       = NULL;          pInstrInfo->engine_name       = NULL;
1104      pInstrInfo->instrument_file   = NULL;          pInstrInfo->instrument_file   = NULL;
1105      pInstrInfo->instrument_nr     = 0;          pInstrInfo->instrument_nr     = 0;
1106      pInstrInfo->instrument_name   = NULL;          pInstrInfo->instrument_name   = NULL;
1107      pInstrInfo->load_mode         = LSCP_LOAD_DEFAULT;          pInstrInfo->load_mode         = LSCP_LOAD_DEFAULT;
1108      pInstrInfo->volume            = 0.0;          pInstrInfo->volume            = 0.0;
1109  }  }
1110    
1111  void lscp_midi_instrument_info_free ( lscp_midi_instrument_info_t *pInstrInfo )  void lscp_midi_instrument_info_free ( lscp_midi_instrument_info_t *pInstrInfo )
1112  {  {
1113      if (pInstrInfo->name)          if (pInstrInfo->name)
1114          free(pInstrInfo->name);                  free(pInstrInfo->name);
1115      if (pInstrInfo->engine_name)          if (pInstrInfo->engine_name)
1116          free(pInstrInfo->engine_name);                  free(pInstrInfo->engine_name);
1117      if (pInstrInfo->instrument_file)          if (pInstrInfo->instrument_file)
1118          free(pInstrInfo->instrument_file);                  free(pInstrInfo->instrument_file);
1119      if (pInstrInfo->instrument_name)          if (pInstrInfo->instrument_name)
1120          free(pInstrInfo->instrument_name);                  free(pInstrInfo->instrument_name);
1121  }  }
1122    
1123  void lscp_midi_instrument_info_reset ( lscp_midi_instrument_info_t *pInstrInfo )  void lscp_midi_instrument_info_reset ( lscp_midi_instrument_info_t *pInstrInfo )
1124  {  {
1125      lscp_midi_instrument_info_free(pInstrInfo);          lscp_midi_instrument_info_free(pInstrInfo);
1126      lscp_midi_instrument_info_init(pInstrInfo);          lscp_midi_instrument_info_init(pInstrInfo);
1127  }  }
1128    
1129    

Legend:
Removed from v.946  
changed lines
  Added in v.3664

  ViewVC Help
Powered by ViewVC