/[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 869 by capela, Thu Jun 1 08:32:16 2006 UTC revision 952 by capela, Tue Nov 28 22:46:32 2006 UTC
# 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;          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 )  lscp_status_t lscp_client_call ( lscp_client_t *pClient, const char *pszQuery, int iResult )
111  {  {
112      int    cchQuery;          int    cchQuery;
113      char   achResult[LSCP_BUFSIZ];          char   achBuffer[LSCP_BUFSIZ];
114      int    cchResult;          int    cchBuffer;
115      const  char *pszSeps = ":[]";          const  char *pszSeps = ":[]";
116      char  *pszResult;          char  *pszBuffer;
117      char  *pszToken;          char  *pszToken;
118      char  *pch;          char  *pch;
119      int    iErrno;          int    iErrno;
120            char  *pszResult;
121      lscp_status_t ret = LSCP_FAILED;          int    cchResult;
122            
123      if (pClient == NULL)          lscp_status_t ret = LSCP_FAILED;
124          return ret;          
125            if (pClient == NULL)
126      pszResult = NULL;                  return ret;
127      iErrno = -1;          
128            iErrno = -1;
129      // Check if command socket socket is still valid.          cchResult = 0;
130      if (pClient->cmd.sock == INVALID_SOCKET) {          pszResult = NULL;
131          pszResult = "Connection closed or no longer valid";          pszBuffer = NULL;
132          lscp_client_set_result(pClient, pszResult, iErrno);  
133          return ret;          // Check if command socket socket is still valid.
134      }          if (pClient->cmd.sock == INVALID_SOCKET) {
135                    pszResult = "Connection closed or no longer valid";
136                    lscp_client_set_result(pClient, pszResult, iErrno);
137                    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                  cchResult = sizeof(achResult);                  // We'll hope to get rid of timeout trouble...
144                  ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);                  pClient->iTimeoutCount = 0;
145                  if (ret == LSCP_OK) {                  cchBuffer = sizeof(achBuffer);
146                          // We've got rid of timeout trouble (hopefully).                  ret = lscp_client_recv(pClient, achBuffer, &cchBuffer, pClient->iTimeout);
147                          pClient->iTimeoutCount = 0;                  if (ret != LSCP_OK) {
148                  } else {                          // Things seems to be unresolved. Fake a result message.
                         // Things are worse than before. 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);
# Line 150  lscp_status_t lscp_client_call ( lscp_cl Line 153  lscp_status_t lscp_client_call ( lscp_cl
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      // Wait for receive event...          // Keep receiving while result is not the expected one:
166      cchResult = sizeof(achResult);          // single-line result (iResult = 0) : one single CRLF ends the receipt;
167      ret = lscp_client_recv(pClient, achResult, &cchResult, pClient->iTimeout);          // multi-line result  (iResult > 0) : one "." followed by a last CRLF;
168    
169      switch (ret) {          while (pszResult == NULL) {
170    
171        case LSCP_OK:                  // Wait for receive event...
172          // Always force the result to be null terminated (and trim trailing CRLFs)!                  cchBuffer = sizeof(achBuffer) - 1;
173          while (cchResult > 0 && (achResult[cchResult - 1] == '\n' || achResult[cchResult- 1] == '\r'))                  ret = lscp_client_recv(pClient, achBuffer, &cchBuffer, pClient->iTimeout);
174              cchResult--;  
175          achResult[cchResult] = (char) 0;                  switch (ret) {
176          // Check if the response it's an error or warning message.  
177          if (strncasecmp(achResult, "WRN:", 4) == 0)                  case LSCP_OK:
178              ret = LSCP_WARNING;                          // Always force the result to be null terminated.
179          else if (strncasecmp(achResult, "ERR:", 4) == 0)                          achBuffer[cchBuffer] = (char) 0;
180              ret = LSCP_ERROR;                          // Check if the response it's an error or warning message.
181          // So we got a result...                          if (strncasecmp(achBuffer, "WRN:", 4) == 0)
182          if (ret == LSCP_OK) {                                  ret = LSCP_WARNING;
183              // Reset errno in case of success.                          else if (strncasecmp(achBuffer, "ERR:", 4) == 0)
184              iErrno = 0;                                  ret = LSCP_ERROR;
185              // Is it a special successful response?                          // So we got a result...
186              if (strncasecmp(achResult, "OK[", 3) == 0) {                          if (ret == LSCP_OK) {
187                  // Parse the OK message, get the return string under brackets...                                  // Reset errno in case of success.
188                  pszToken = lscp_strtok(achResult, pszSeps, &(pch));                                  iErrno = 0;
189                  if (pszToken)                                  // Is it a special successful response?
190                      pszResult = lscp_strtok(NULL, pszSeps, &(pch));                                  if (iResult < 1 && strncasecmp(achBuffer, "OK[", 3) == 0) {
191              }                                          // Parse the OK message, get the return string under brackets...
192              else pszResult = achResult;                                          pszToken = lscp_strtok(achBuffer, pszSeps, &(pch));
193              // The result string is now set to the command response, if any.                                          if (pszToken)
194          } else {                                                  pszResult = lscp_strtok(NULL, pszSeps, &(pch));
195              // Parse the error/warning message, skip first colon...                                  } else {
196              pszToken = lscp_strtok(achResult, pszSeps, &(pch));                                          // It can be specially long response...
197              if (pszToken) {                                          cchResult += sizeof(achBuffer);
198                  // Get the error number...                                          pszResult  = malloc(cchResult + 1);
199                  pszToken = lscp_strtok(NULL, pszSeps, &(pch));                                          pszResult[0] = (char) 0;
200                  if (pszToken) {                                          if (pszBuffer) {
201                      iErrno = atoi(pszToken);                                                  strcat(pszResult, pszBuffer);
202                      // And make the message text our final result.                                                  free(pszBuffer);
203                      pszResult = lscp_strtok(NULL, pszSeps, &(pch));                                          }
204                  }                                          strcat(pszResult, achBuffer);
205              }                                          pszBuffer = pszResult;
206              // The result string is set to the error/warning message text.                                          pszResult = NULL;
207          }                                          // Check for correct end-of-transmission...
208          break;                                          // Depending whether its single or multi-line we'll
209                                            // flag end-of-transmission...
210        case LSCP_TIMEOUT:                                          cchBuffer = strlen(pszBuffer);
211                  // We have trouble...                                          if (cchBuffer >= 2
212                  pClient->iTimeoutCount++;                                                  && pszBuffer[cchBuffer - 1] == '\n'
213          // Fake a result message.                                                  && pszBuffer[cchBuffer - 2] == '\r'
214          pszResult = "Timeout during receive operation";                                                  && (iResult < 1 || (cchBuffer >= 3
215          iErrno = (int) ret;                                                                  && pszBuffer[cchBuffer - 3] == '.'))) {
216          break;                                                  // Get rid of the trailing dot and CRLF anyway...
217                                                    while (cchBuffer > 0 && (
218        case LSCP_QUIT:                                                          pszBuffer[cchBuffer - 1] == '\r' ||
219          // Fake a result message.                                                          pszBuffer[cchBuffer - 1] == '\n' ||
220          pszResult = "Server terminated the connection";                                                          pszBuffer[cchBuffer - 1] == '.'))
221          iErrno = (int) ret;                                                          cchBuffer--;
222          break;                                                  pszBuffer[cchBuffer] = (char) 0;
223                                                    pszResult = pszBuffer;
224        case LSCP_FAILED:                                          }
225        default:                                  }
226          // What's down?                                  // The result string is now set to the command response, if any.
227          pszResult = "Failure during receive operation";                          } else {
228          break;                                  // Parse the error/warning message, skip first colon...
229      }                                  pszToken = lscp_strtok(achBuffer, pszSeps, &(pch));
230                                    if (pszToken) {
231                                            // Get the error number...
232                                            pszToken = lscp_strtok(NULL, pszSeps, &(pch));
233                                            if (pszToken) {
234                                                    iErrno = atoi(pszToken);
235                                                    // And make the message text our final result.
236                                                    pszResult = lscp_strtok(NULL, pszSeps, &(pch));
237                                            }
238                                    }
239                                    // The result string is set to the error/warning message text.
240                            }
241                            break;
242    
243                    case LSCP_TIMEOUT:
244                            // We have trouble...
245                            pClient->iTimeoutCount++;
246                            // Fake a result message.
247                            pszResult = "Timeout during receive operation";
248                            iErrno = (int) ret;
249                            break;
250    
251                    case LSCP_QUIT:
252                            // Fake a result message.
253                            pszResult = "Server terminated the connection";
254                            iErrno = (int) ret;
255                            break;
256    
257                    case LSCP_FAILED:
258                    default:
259                            // What's down?
260                            pszResult = "Failure during receive operation";
261                            break;
262                    }
263            }
264    
265            // Make the result official...
266            lscp_client_set_result(pClient, pszResult, iErrno);
267    
268      // Make the result official...          // Free long-buffer, if any...
269      lscp_client_set_result(pClient, pszResult, iErrno);          if (pszBuffer)
270                    free(pszBuffer);
271    
272      return ret;          return ret;
273  }  }
274    
275    
# Line 238  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      }          }
   
     // Go on for it...  
     cchSeps = strlen(pszSeps);  
     while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {  
         // Pre-advance to next item.  
         pszHead = pch + cchSeps;  
         // Trim and null terminate current item.  
         while (isspace(*(pch - 1)) && pch > ppszSplit[0])  
             --pch;  
         *pch = (char) 0;  
         // Make it official.  
         ppszSplit[i] = lscp_unquote(&pszHead, 0);  
         // Do we need to grow?  
         if (++i >= iSize) {  
             // Yes, but only grow in chunks.  
             iSize += LSCP_SPLIT_CHUNK1;  
             // Allocate and copy to new split array.  
             ppszNewSplit = (char **) malloc(iSize * sizeof(char *));  
             if (ppszNewSplit) {  
                 for (j = 0; j < i; j++)  
                     ppszNewSplit[j] = ppszSplit[j];  
                 free(ppszSplit);  
                 ppszSplit = ppszNewSplit;  
             }  
         }  
     }  
   
     // NULL terminate split array.  
     for ( ; i < iSize; i++)  
         ppszSplit[i] = NULL;  
381    
382      return ppszSplit;          // Go on for it...
383            cchSeps = strlen(pszSeps);
384            while ((pch = strpbrk(pszHead, pszSeps)) != NULL) {
385                    // Pre-advance to next item.
386                    pszHead = pch + cchSeps;
387                    // Trim and null terminate current item.
388                    while (isspace(*(pch - 1)) && pch > ppszSplit[0])
389                            --pch;
390                    *pch = (char) 0;
391                    // Make it official.
392                    ppszSplit[i] = lscp_unquote(&pszHead, 0);
393                    // Do we need to grow?
394                    if (++i >= iSize) {
395                            // Yes, but only grow in chunks.
396                            iSize += LSCP_SPLIT_CHUNK1;
397                            // Allocate and copy to new split array.
398                            ppszNewSplit = (char **) malloc(iSize * sizeof(char *));
399                            if (ppszNewSplit) {
400                                    for (j = 0; j < i; j++)
401                                            ppszNewSplit[j] = ppszSplit[j];
402                                    free(ppszSplit);
403                                    ppszSplit = ppszNewSplit;
404                            }
405                    }
406            }
407    
408            // NULL terminate split array.
409            for ( ; i < iSize; i++)
410                    ppszSplit[i] = NULL;
411    
412            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 389  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 407  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 473  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 491  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      }          }
   
     cchSeps1 = strlen(pszSeps1);  
     cchSeps2 = strlen(pszSeps2);  
   
     i = 0;  
     while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {  
         ppSplit[i].key = pszHead;  
         pszHead = pch + cchSeps1;  
         *pch = (char) 0;  
         ppSplit[i].value = lscp_unquote(&pszHead, 0);  
         if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {  
             pszHead = pch + cchSeps2;  
             *pch = (char) 0;  
         }  
         if (++i >= iSize) {  
             iSize += LSCP_SPLIT_CHUNK1;  
             ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));  
             if (ppNewSplit) {  
                 for (j = 0; j < i; j++) {  
                     ppNewSplit[j].key   = ppSplit[j].key;  
                     ppNewSplit[j].value = ppSplit[j].value;  
                 }  
                 free(ppSplit);  
                 ppSplit = ppNewSplit;  
             }  
         }  
     }  
   
     if (i < 1)  
         free(pszHead);  
   
     for ( ; i < iSize; i++) {  
         ppSplit[i].key   = NULL;  
         ppSplit[i].value = NULL;  
     }  
549    
550      return ppSplit;          cchSeps1 = strlen(pszSeps1);
551            cchSeps2 = strlen(pszSeps2);
552    
553            i = 0;
554            while ((pch = strpbrk(pszHead, pszSeps1)) != NULL) {
555                    ppSplit[i].key = pszHead;
556                    pszHead = pch + cchSeps1;
557                    *pch = (char) 0;
558                    ppSplit[i].value = lscp_unquote(&pszHead, 0);
559                    if ((pch = strpbrk(pszHead, pszSeps2)) != NULL) {
560                            pszHead = pch + cchSeps2;
561                            *pch = (char) 0;
562                    }
563                    if (++i >= iSize) {
564                            iSize += LSCP_SPLIT_CHUNK1;
565                            ppNewSplit = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t));
566                            if (ppNewSplit) {
567                                    for (j = 0; j < i; j++) {
568                                            ppNewSplit[j].key   = ppSplit[j].key;
569                                            ppNewSplit[j].value = ppSplit[j].value;
570                                    }
571                                    free(ppSplit);
572                                    ppSplit = ppNewSplit;
573                            }
574                    }
575            }
576    
577            if (i < 1)
578                    free(pszHead);
579    
580            for ( ; i < iSize; i++) {
581                    ppSplit[i].key   = NULL;
582                    ppSplit[i].value = NULL;
583            }
584    
585            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 560  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 578  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 659  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
720    
721    
722    // Split a string into an array of MIDI instrument triplets.
723    lscp_midi_instrument_t *lscp_midi_instruments_create ( const char *pszCsv )
724    {
725            char *pchHead, *pch;
726            int iSize, i, j, k;
727            lscp_midi_instrument_t *pInstrs;
728            lscp_midi_instrument_t *pNewInstrs;
729            
730            // Get it clean first.
731            pchHead = lscp_ltrim((char *) pszCsv);
732            if (*pchHead == (char) 0)
733                    return NULL;
734            
735            // Initial size is one chunk away.
736            iSize = LSCP_SPLIT_CHUNK1;
737            // Allocate and split...
738            pInstrs = (lscp_midi_instrument_t *) malloc(iSize * sizeof(lscp_midi_instrument_t));
739            if (pInstrs == NULL)
740                    return NULL;
741            
742            // Go on for it...
743            i = 0;
744            k = 0;
745            
746            while ((pch = strpbrk(pchHead, "{,}")) != NULL) {
747                    // Pre-advance to next item.
748                    switch (*pch) {
749                    case '{':
750                            pchHead = pch + 1;
751                            if (k == 0) {
752                                    pInstrs[i].bank_msb = atoi(pchHead);
753                                    k++;
754                            }
755                            break;
756                    case ',':
757                            pchHead = pch + 1;
758                            if (k == 1) {
759                                    pInstrs[i].bank_lsb = atoi(pchHead);
760                                    k++;
761                            }
762                            else
763                            if (k == 2) {
764                                    pInstrs[i].program = atoi(pchHead);
765                                    k++;
766                            }
767                            break;
768                    case '}':
769                            pchHead = pch + 1;
770                            k = 0;
771                            break;
772                    }
773                    // Do we need to grow?
774                    if (k == 3 && ++i >= iSize) {
775                            // Yes, but only grow in chunks.
776                            iSize += LSCP_SPLIT_CHUNK1;
777                            // Allocate and copy to new split array.
778                            pNewInstrs = (lscp_midi_instrument_t *) malloc(iSize * sizeof(lscp_midi_instrument_t));
779                            if (pNewInstrs) {
780                                    for (j = 0; j < i; j++) {
781                                            pNewInstrs[j].bank_msb = pInstrs[j].bank_msb;
782                                            pNewInstrs[j].bank_lsb = pInstrs[j].bank_lsb;
783                                            pNewInstrs[j].program  = pInstrs[j].program;
784                                    }
785                                    free(pInstrs);
786                                    pInstrs = pNewInstrs;
787                            }
788                    }
789            }
790            
791            // Special terminate split array.
792            for ( ; i < iSize; i++) {
793                    pInstrs[i].bank_msb = -1;
794                    pInstrs[i].bank_lsb = -1;
795                    pInstrs[i].program  = -1;
796            }
797            
798            return pInstrs;
799    }
800    
801    // Destroy a MIDI instrument triplet array.
802    void lscp_midi_instruments_destroy ( lscp_midi_instrument_t *pInstrs )
803    {
804            if (pInstrs)
805                    free(pInstrs);
806    }
807    
808    #ifdef LSCP_MIDI_INSTRUMENTS_COUNT
809    
810    // Compute a MIDI instrument array item count.
811    int lscp_midi_instruments_count ( lscp_midi_instrument_t *pInstrs )
812    {
813            int i = 0;
814            while (pInstrs && pInstrs[i].program >= 0)
815                    i++;
816            return i;
817    }
818    
819    // Compute a MIDI instrument array size.
820    int lscp_midi_instruments_size ( lscp_midi_instrument_t *pInstrs )
821    {
822            return LSCP_SPLIT_SIZE(lscp_midi_instruments_count(pInstrs));
823    }
824    
825    #endif // LSCP_MIDI_INSTRUMENTS_COUNT
826    
827    
828  //-------------------------------------------------------------------------  //-------------------------------------------------------------------------
829  // Server info struct helper functions.  // Server info struct helper functions.
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 707  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 731  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 771  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 797  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 820  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 843  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 882  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)
1035                    return 0;
1036    
1037            cchBuffer = strlen(pszBuffer);
1038            for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {
1039                    cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;
1040                    if (cchBuffer + cchParam + 2 < cchMaxBuffer) {
1041                            sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);
1042                            cchBuffer += cchParam;
1043                    }
1044            }
1045            
1046            if (cchBuffer + 2 < cchMaxBuffer) {
1047                    pszBuffer[cchBuffer++] = '\r';
1048                    pszBuffer[cchBuffer++] = '\n';
1049                    pszBuffer[cchBuffer ]  = (char) 0;
1050            }
1051            
1052            return cchBuffer;
1053    }
1054    
     if (pszBuffer == NULL)  
         return 0;  
1055    
1056      cchBuffer = strlen(pszBuffer);  //-------------------------------------------------------------------------
1057      for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) {  // MIDI instrument info struct helper functions.
1058          cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4;  
1059          if (cchBuffer + cchParam + 2 < cchMaxBuffer) {  void lscp_midi_instrument_info_init ( lscp_midi_instrument_info_t *pInstrInfo )
1060              sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value);  {
1061              cchBuffer += cchParam;          pInstrInfo->name              = NULL;
1062          }          pInstrInfo->engine_name       = NULL;
1063      }          pInstrInfo->instrument_file   = NULL;
1064                pInstrInfo->instrument_nr     = 0;
1065      if (cchBuffer + 2 < cchMaxBuffer) {          pInstrInfo->instrument_name   = NULL;
1066          pszBuffer[cchBuffer++] = '\r';          pInstrInfo->load_mode         = LSCP_LOAD_DEFAULT;
1067          pszBuffer[cchBuffer++] = '\n';          pInstrInfo->volume            = 0.0;
1068          pszBuffer[cchBuffer ]  = (char) 0;  }
1069      }  
1070        void lscp_midi_instrument_info_free ( lscp_midi_instrument_info_t *pInstrInfo )
1071      return cchBuffer;  {
1072            if (pInstrInfo->name)
1073                    free(pInstrInfo->name);
1074            if (pInstrInfo->engine_name)
1075                    free(pInstrInfo->engine_name);
1076            if (pInstrInfo->instrument_file)
1077                    free(pInstrInfo->instrument_file);
1078            if (pInstrInfo->instrument_name)
1079                    free(pInstrInfo->instrument_name);
1080    }
1081    
1082    void lscp_midi_instrument_info_reset ( lscp_midi_instrument_info_t *pInstrInfo )
1083    {
1084            lscp_midi_instrument_info_free(pInstrInfo);
1085            lscp_midi_instrument_info_init(pInstrInfo);
1086  }  }
1087    
1088    

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

  ViewVC Help
Powered by ViewVC