--- liblscp/trunk/src/common.c 2004/06/30 15:16:03 163 +++ liblscp/trunk/src/common.c 2004/07/07 23:41:07 187 @@ -223,6 +223,18 @@ return psz; } +// Unquote and make a duplicate of an in-split string. +void lscp_unquote_dup ( char **ppszDst, char **ppszSrc ) +{ + // Free desteny string, if already there. + if (*ppszDst) + free(*ppszDst); + *ppszDst = NULL; + // Unquote and duplicate. + if (*ppszSrc) + *ppszDst = lscp_unquote(ppszSrc, 1); +} + // Custom tokenizer. char *lscp_strtok ( char *pchBuffer, const char *pszSeps, char **ppch ) @@ -346,6 +358,11 @@ int iSize, i, j, cchSeps; int *piSplit, *piNewSplit; + // Get it clean first. + pchHead = lscp_ltrim((char *) pszCsv); + if (*pchHead == (char) 0) + return NULL; + // Initial size is one chunk away. iSize = LSCP_SPLIT_CHUNK1; // Allocate and split... @@ -355,7 +372,6 @@ // Make a copy of the original string. i = 0; - pchHead = (char *) pszCsv; if ((piSplit[i++] = atoi(pchHead)) < 0) { free(piSplit); return NULL; @@ -506,6 +522,109 @@ #endif // LSCP_PSPLIT_COUNT +// Allocate a parameter list, optionally copying an existing one. +void lscp_plist_alloc (lscp_param_t **ppList) +{ + lscp_param_t *pParams; + int iSize, i; + + if (ppList) { + iSize = LSCP_SPLIT_CHUNK1; + pParams = (lscp_param_t *) malloc(iSize * sizeof(lscp_param_t)); + if (pParams) { + for (i = 0 ; i < iSize; i++) { + pParams[i].key = NULL; + pParams[i].value = NULL; + } + } + *ppList = pParams; + } +} + + +// Destroy a parameter list, including all it's contents. +void lscp_plist_free ( lscp_param_t **ppList ) +{ + lscp_param_t *pParams; + int i; + + if (ppList) { + if (*ppList) { + pParams = *ppList; + for (i = 0; pParams && pParams[i].key; i++) { + free(pParams[i].key); + free(pParams[i].value); + } + free(pParams); + } + *ppList = NULL; + } +} + + +// Add an item to a parameter list, growing it as fit. +void lscp_plist_append ( lscp_param_t **ppList, const char *pszKey, const char *pszValue ) +{ + lscp_param_t *pParams; + lscp_param_t *pNewParams; + int iSize, iNewSize; + int i = 0; + + if (ppList && *ppList) { + pParams = *ppList; + while (pParams[i].key) { + if (strcasecmp(pParams[i].key, pszKey) == 0) { + if (pParams[i].value) + free(pParams[i].value); + pParams[i].value = strdup(pszValue); + return; + } + i++; + } + iSize = LSCP_SPLIT_SIZE(i); + pParams[i].key = strdup(pszKey); + pParams[i].value = strdup(pszValue); + if (++i >= iSize) { + iNewSize = iSize + LSCP_SPLIT_CHUNK1; + pNewParams = (lscp_param_t *) malloc(iNewSize * sizeof(lscp_param_t)); + for (i = 0; i < iSize; i++) { + pParams[i].key = pParams[i].key; + pParams[i].value = pParams[i].value; + } + for ( ; i < iNewSize; i++) { + pNewParams[i].key = NULL; + pNewParams[i].value = NULL; + } + free(pParams); + *ppList = pNewParams; + } + } +} + +#ifdef LSCP_PLIST_COUNT + +// Compute a parameter list valid item count. +int lscp_plist_count ( lscp_param_t **ppList ) +{ + lscp_param_t *pParams; + int i = 0; + if (ppList && *ppList) { + pParams = *ppList; + while (pParams[i].key) + i++; + } + return i; +} + +// Compute the legal parameter list size. +int lscp_plist_size ( lscp_param_t **ppList ) +{ + return LSCP_SPLIT_SIZE(lscp_plist_count(ppList)); +} + +#endif // LSCP_PLIST_COUNT + + //------------------------------------------------------------------------- // Engine info struct helper functions. @@ -515,13 +634,17 @@ pEngineInfo->version = NULL; } -void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo ) +void lscp_engine_info_free ( lscp_engine_info_t *pEngineInfo ) { if (pEngineInfo->description) free(pEngineInfo->description); if (pEngineInfo->version) free(pEngineInfo->version); +} +void lscp_engine_info_reset ( lscp_engine_info_t *pEngineInfo ) +{ + lscp_engine_info_free(pEngineInfo); lscp_engine_info_init(pEngineInfo); } @@ -544,7 +667,7 @@ pChannelInfo->volume = 0.0; } -void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo ) +void lscp_channel_info_free ( lscp_channel_info_t *pChannelInfo ) { if (pChannelInfo->engine_name) free(pChannelInfo->engine_name); @@ -552,7 +675,11 @@ lscp_szsplit_destroy(pChannelInfo->audio_routing); if (pChannelInfo->instrument_file) free(pChannelInfo->instrument_file); +} +void lscp_channel_info_reset ( lscp_channel_info_t *pChannelInfo ) +{ + lscp_channel_info_free(pChannelInfo); lscp_channel_info_init(pChannelInfo); } @@ -567,19 +694,69 @@ pDriverInfo->parameters = NULL; } -void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo ) +void lscp_driver_info_free ( lscp_driver_info_t *pDriverInfo ) { if (pDriverInfo->description) free(pDriverInfo->description); if (pDriverInfo->version) free(pDriverInfo->version); lscp_szsplit_destroy(pDriverInfo->parameters); +} +void lscp_driver_info_reset ( lscp_driver_info_t *pDriverInfo ) +{ + lscp_driver_info_free(pDriverInfo); lscp_driver_info_init(pDriverInfo); } //------------------------------------------------------------------------- +// Device info struct functions. + +void lscp_device_info_init ( lscp_device_info_t *pDeviceInfo ) +{ + pDeviceInfo->driver = NULL; + lscp_plist_alloc(&(pDeviceInfo->params)); +} + +void lscp_device_info_free ( lscp_device_info_t *pDeviceInfo ) +{ + if (pDeviceInfo->driver) + free(pDeviceInfo->driver); + lscp_plist_free(&(pDeviceInfo->params)); +} + +void lscp_device_info_reset ( lscp_device_info_t *pDeviceInfo ) +{ + lscp_device_info_free(pDeviceInfo); + lscp_device_info_init(pDeviceInfo); +} + + +//------------------------------------------------------------------------- +// Device channel/port info struct functions. + +void lscp_device_port_info_init ( lscp_device_port_info_t *pDevicePortInfo ) +{ + pDevicePortInfo->name = NULL; + lscp_plist_alloc(&(pDevicePortInfo->params)); +} + +void lscp_device_port_info_free ( lscp_device_port_info_t *pDevicePortInfo ) +{ + if (pDevicePortInfo->name) + free(pDevicePortInfo->name); + lscp_plist_free(&(pDevicePortInfo->params)); +} + +void lscp_device_port_info_reset ( lscp_device_port_info_t *pDevicePortInfo ) +{ + lscp_device_port_info_free(pDevicePortInfo); + lscp_device_port_info_init(pDevicePortInfo); +} + + +//------------------------------------------------------------------------- // Parameter struct helper functions. void lscp_param_info_init ( lscp_param_info_t *pParamInfo ) @@ -596,7 +773,7 @@ pParamInfo->possibilities = NULL; } -void lscp_param_info_reset ( lscp_param_info_t *pParamInfo ) +void lscp_param_info_free ( lscp_param_info_t *pParamInfo ) { if (pParamInfo->description) free(pParamInfo->description); @@ -608,29 +785,40 @@ if (pParamInfo->range_max) free(pParamInfo->range_max); lscp_szsplit_destroy(pParamInfo->possibilities); - +} + +void lscp_param_info_reset ( lscp_param_info_t *pParamInfo ) +{ + lscp_param_info_free(pParamInfo); lscp_param_info_init(pParamInfo); } //------------------------------------------------------------------------- -// Concatenate a parameter list (key='value'...) into a string. +// Concatenate a parameter list (key='value'...) into a string, +// appending a crlf terminator. int lscp_param_concat ( char *pszBuffer, int cchMaxBuffer, lscp_param_t *pParams ) { int cchBuffer, cchParam, i; - if (pszBuffer == NULL || pParams == NULL) + if (pszBuffer == NULL) return 0; cchBuffer = strlen(pszBuffer); - for (i = 0; pParams[i].key && pParams[i].value; i++) { + for (i = 0; pParams && pParams[i].key && pParams[i].value; i++) { cchParam = strlen(pParams[i].key) + strlen(pParams[i].value) + 4; - if (cchBuffer + cchParam < cchMaxBuffer) { + if (cchBuffer + cchParam + 2 < cchMaxBuffer) { sprintf(pszBuffer + cchBuffer, " %s='%s'", pParams[i].key, pParams[i].value); cchBuffer += cchParam; } } + + if (cchBuffer + 2 < cchMaxBuffer) { + pszBuffer[cchBuffer++] = '\r'; + pszBuffer[cchBuffer++] = '\n'; + } + return cchBuffer; }