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

Legend:
Removed from v.749  
changed lines
  Added in v.3663

  ViewVC Help
Powered by ViewVC