aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2011-04-20 08:44:10 +0200
committerTakashi Iwai <tiwai@suse.de>2011-04-20 09:49:01 +0200
commit1146d04435f87b6f7befdb76f74f8bc20b2acf2b (patch)
treeafa69a3f7528130befea3cdd722b72b711fabb1f
parent6db98efdfd0ff0fa5f75c210510ddc62f2323c86 (diff)
downloadsalsa-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.ac13
-rw-r--r--src/output.h86
-rw-r--r--src/output_abi.c110
-rw-r--r--src/recipe.h.in3
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 */