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

Legend:
Removed from v.189  
changed lines
  Added in v.3665

  ViewVC Help
Powered by ViewVC