diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-04-20 08:44:10 +0200 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-04-20 09:49:01 +0200 |
commit | 1146d04435f87b6f7befdb76f74f8bc20b2acf2b (patch) | |
tree | afa69a3f7528130befea3cdd722b72b711fabb1f | |
parent | 6db98efdfd0ff0fa5f75c210510ddc62f2323c86 (diff) | |
download | salsa-lib-1146d04435f87b6f7befdb76f74f8bc20b2acf2b.tar.gz |
Add string-buffer output via snd_output_*()
With the configure option, the strings can be output to a buffer.
Otherwise, ignores with dummy funtions.
-rw-r--r-- | configure.ac | 13 | ||||
-rw-r--r-- | src/output.h | 86 | ||||
-rw-r--r-- | src/output_abi.c | 110 | ||||
-rw-r--r-- | src/recipe.h.in | 3 |
4 files changed, 185 insertions, 27 deletions
diff --git a/configure.ac b/configure.ac index d600332..8b9290d 100644 --- a/configure.ac +++ b/configure.ac @@ -153,6 +153,18 @@ else fi AC_SUBST(SALSA_MARK_DEPRECATED) +AC_ARG_ENABLE(output-buffer, + AS_HELP_STRING([--enable-output-buffer], + [support the string output via snd_output_*() functions]), + output_buffer="$enableval", output_buffer="no") + +if test "$output_buffer" = "yes"; then + SALSA_SUPPORT_OUTPUT_BUFFER=1 +else + SALSA_SUPPORT_OUTPUT_BUFFER=0 +fi +AC_SUBST(SALSA_SUPPORT_OUTPUT_BUFFER) + AC_ARG_ENABLE(libasound, AS_HELP_STRING([--disable-delight-valgrind], [do not initialize unnecessary fields for ioctls]), @@ -196,3 +208,4 @@ echo " - TLV (dB) support: $tlv" echo " - Async handler support: $async" echo " - Make ABI-compatible libasound.so: $libasound" echo " - Mark deprecated attribute: $markdeprecated" +echo " - Support string-output via snd_output: $output_buffer" diff --git a/src/output.h b/src/output.h index a2d3186..c68037e 100644 --- a/src/output.h +++ b/src/output.h @@ -24,14 +24,38 @@ #include <stdio.h> #include <errno.h> - -typedef FILE snd_output_t; +#include <stdarg.h> typedef enum _snd_output_type { SND_OUTPUT_STDIO, - /* SND_OUTPUT_BUFFER */ + SND_OUTPUT_BUFFER } snd_output_type_t; + +#if SALSA_SUPPORT_OUTPUT_BUFFER + +typedef struct snd_output snd_output_t; + +extern int snd_output_stdio_open(snd_output_t **outputp, const char *file, const char *mode); +extern int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int _close); +extern int snd_output_close(snd_output_t *out); +extern int snd_output_printf(snd_output_t *out, const char *fmt, ...); +extern int snd_output_puts(snd_output_t *out, const char *str); +extern int snd_output_putc(snd_output_t *out, int c); +extern int snd_output_flush(snd_output_t *out); +extern int snd_output_buffer_open(snd_output_t **outputp); +extern size_t snd_output_buffer_string(snd_output_t *output, char **buf); + +#else /* SALSA_SUPPORT_OUTPUT_BUFFER */ + +/* + * Simplified version; don't support the string output + */ + +typedef FILE snd_output_t; + +#define _SALSA_BUF_OUT (snd_output_t *)-1 + __SALSA_EXPORT_FUNC int snd_output_stdio_open(snd_output_t **outputp, const char *file, const char *mode) { @@ -47,22 +71,66 @@ int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int _close) return 0; } -#define snd_output_close(out) fclose(out) -#define snd_output_printf fprintf -#define snd_output_puts(out, str) fputs(str, out) -#define snd_output_putc(out, c) putc(c, out) -#define snd_output_flush(out) fflush(out) +__SALSA_EXPORT_FUNC +int snd_output_close(snd_output_t *out) +{ + if (out != _SALSA_BUF_OUT && out != stdout && out != stderr) + return fclose(out); + return 0; +} + +__SALSA_EXPORT_FUNC +int snd_output_printf(snd_output_t *out, const char *fmt, ...) +{ + va_list ap; + int ret; + if (out == _SALSA_BUF_OUT) + return 0; + va_start(ap, fmt); + ret = vfprintf(out, fmt, ap); + va_end(ap); + return ret; +} + +__SALSA_EXPORT_FUNC +int snd_output_puts(snd_output_t *out, const char *str) +{ + if (out != _SALSA_BUF_OUT) + return fputs(str, out); + return 0; +} + +__SALSA_EXPORT_FUNC +int snd_output_putc(snd_output_t *out, int c) +{ + if (out != _SALSA_BUF_OUT) + return putc(c, out); + return 0; +} + +__SALSA_EXPORT_FUNC +int snd_output_flush(snd_output_t *out) +{ + if (out != _SALSA_BUF_OUT) + return fflush(out); + return 0; +} __SALSA_EXPORT_FUNC __SALSA_NOT_IMPLEMENTED int snd_output_buffer_open(snd_output_t **outputp) { - return -ENXIO; + *outputp = _SALSA_BUF_OUT; + return 0; } __SALSA_EXPORT_FUNC __SALSA_NOT_IMPLEMENTED size_t snd_output_buffer_string(snd_output_t *output, char **buf) { + static char tmp[1]; + *buf = tmp; return 0; } +#endif /* SALSA_SUPPORT_OUTPUT_BUFFER */ + #endif /* __ALSA_OUTPUT_H */ diff --git a/src/output_abi.c b/src/output_abi.c index bb689af..f5fc58c 100644 --- a/src/output_abi.c +++ b/src/output_abi.c @@ -4,31 +4,68 @@ #include <stdio.h> #include <errno.h> #include <stdarg.h> +#include <string.h> +#include <stdlib.h> #include <unistd.h> -typedef FILE snd_output_t; +#include "recipe.h" +#include "global.h" +#undef __SALSA_EXPORT_FUNC +#define __SALSA_EXPORT_FUNC +#include "output.h" -typedef enum _snd_output_type { - SND_OUTPUT_STDIO, - /* SND_OUTPUT_BUFFER */ -} snd_output_type_t; +#if SALSA_SUPPORT_OUTPUT_BUFFER + +#define CHUNK 4000 + +struct snd_output { + int mode; + void *ptr; + int len; + int size; +}; + +int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int _close) +{ + snd_output_t *out; + out = malloc(sizeof(*out)); + if (!out) + return -ENOMEM; + out->mode = SND_OUTPUT_STDIO; + out->ptr = fp; + out->len = _close; + *outputp = out; + return 0; +} int snd_output_stdio_open(snd_output_t **outputp, const char *file, const char *mode) { - if ((*outputp = fopen(file, mode)) == NULL) + FILE *fp = fopen(file, mode); + if (!fp) return -errno; - return 0; + return snd_output_stdio_attach(outputp, fp, 1); } -int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int _close) +int snd_output_close(snd_output_t *out) { - *outputp = fp; + if (out->mode == SND_OUTPUT_STDIO) { + if (out->len) + return fclose(out->ptr); + } else + free(out->ptr); + free(out); return 0; } -int snd_output_close(snd_output_t *out) +static int resize(snd_output_t *out, int new) { - return fclose(out); + int size = out->len + new + CHUNK; + void *buf = realloc(out->ptr, size); + if (!buf) + return -ENOMEM; + out->ptr = buf; + out->size = size; + return 0; } int snd_output_printf(snd_output_t *out, const char *fmt, ...) @@ -36,32 +73,69 @@ int snd_output_printf(snd_output_t *out, const char *fmt, ...) va_list ap; int ret; va_start(ap, fmt); - ret = vfprintf(out, fmt, ap); + if (out->mode == SND_OUTPUT_STDIO) + ret = vfprintf(out->ptr, fmt, ap); + else { + ret = vsnprintf(out->ptr + out->len, out->size - out->len, + fmt, ap); + if (ret >= out->size - out->len) { + if (resize(out, ret) < 0) + return -ENOMEM; + ret = vsnprintf(out->ptr + out->len, + out->size - out->len, + fmt, ap); + } + } va_end(ap); return ret; } int snd_output_puts(snd_output_t *out, const char *str) { - return fputs(str, out); + if (out->mode == SND_OUTPUT_STDIO) + return fputs(str, out->ptr); + else { + int len = strlen(str); + if (out->size - out->len <= len && resize(out, len) < 0) + return -ENOMEM; + strcpy(out->ptr + len, str); + return len; + } } int snd_output_putc(snd_output_t *out, int c) { - return putc(c, out); + if (out->mode == SND_OUTPUT_STDIO) + return putc(c, out->ptr); + if (out->len + 1 >= out->size && resize(out, 1) < 0) + return -ENOMEM; + ((char *)out->ptr)[out->len++] = c; + return 0; } int snd_output_flush(snd_output_t *out) { - return fflush(out); + if (out->mode == SND_OUTPUT_STDIO) + return fflush(out->ptr); + else + out->len = 0; + return 0; } int snd_output_buffer_open(snd_output_t **outputp) { - return -ENXIO; + snd_output_t *out = calloc(1, sizeof(*out)); + if (!out) + return -ENOMEM; + out->mode = SND_OUTPUT_BUFFER; + *outputp = out; + return resize(out, 0); } -size_t snd_output_buffer_string(snd_output_t *output, char **buf) +size_t snd_output_buffer_string(snd_output_t *out, char **buf) { - return 0; + *buf = out->ptr; + return out->len; } + +#endif /* !SALSA_SIMPLE_OUTPUT */ diff --git a/src/recipe.h.in b/src/recipe.h.in index 5b0bb2b..24ef2e2 100644 --- a/src/recipe.h.in +++ b/src/recipe.h.in @@ -13,6 +13,9 @@ /* Enable deprecated attribute for non-working functions */ #define SALSA_MARK_DEPRECATED @SALSA_MARK_DEPRECATED@ +/* Don't support string output via snd_output_*() */ +#define SALSA_SIMPLE_OUTPUT @SALSA_SIMPLE_OUTPUT@ + #define SALSA_DEVPATH "@DEVPATH@" #endif /* __ALSA_RECIPE_H */ |