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

Legend:
Removed from v.951  
changed lines
  Added in v.952

  ViewVC Help
Powered by ViewVC