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

Legend:
Removed from v.187  
changed lines
  Added in v.977

  ViewVC Help
Powered by ViewVC