*
*/
+#ifndef DOC_HIDDEN
#define _snd_config_iterator list_head
#include <stdarg.h>
snd_config_t *father;
};
-#define SYS_ASOUNDRC "/etc/asound.conf"
-#define USR_ASOUNDRC ".asoundrc"
-
struct filedesc {
char *name;
snd_input_t *in;
}
}
-snd_config_type_t snd_config_get_type(snd_config_t *config)
-{
- return config->type;
-}
-
-const char *snd_config_get_id(snd_config_t *config)
-{
- return config->id;
-}
-
static int _snd_config_make(snd_config_t **config, char *id,
snd_config_type_t type)
{
return 0;
}
-int snd_config_top(snd_config_t **config)
+void string_print(char *str, int id, snd_output_t *out)
{
- assert(config);
- return _snd_config_make(config, 0, SND_CONFIG_TYPE_COMPOUND);
+ unsigned char *p = str;
+ if (!id) {
+ switch (*p) {
+ case 0:
+ assert(0);
+ break;
+ case '0' ... '9':
+ case '-':
+ goto quoted;
+ }
+ }
+ if (!*p) {
+ snd_output_puts(out, "''");
+ return;
+ }
+ loop:
+ switch (*p) {
+ case 0:
+ goto nonquoted;
+ case 1 ... 31:
+ case 127 ... 255:
+ case ' ':
+ case '=':
+ case '.':
+ case '{':
+ case '}':
+ case ';':
+ case ',':
+ case '\'':
+ case '"':
+ goto quoted;
+ default:
+ p++;
+ goto loop;
+ }
+ nonquoted:
+ snd_output_puts(out, str);
+ return;
+ quoted:
+ snd_output_putc(out, '\'');
+ p = str;
+ while (*p) {
+ int c;
+ c = *p;
+ switch (c) {
+ case '\n':
+ snd_output_putc(out, '\\');
+ snd_output_putc(out, 'n');
+ break;
+ case '\t':
+ snd_output_putc(out, '\\');
+ snd_output_putc(out, 't');
+ break;
+ case '\v':
+ snd_output_putc(out, '\\');
+ snd_output_putc(out, 'v');
+ break;
+ case '\b':
+ snd_output_putc(out, '\\');
+ snd_output_putc(out, 'b');
+ break;
+ case '\r':
+ snd_output_putc(out, '\\');
+ snd_output_putc(out, 'r');
+ break;
+ case '\f':
+ snd_output_putc(out, '\\');
+ snd_output_putc(out, 'f');
+ break;
+ case '\'':
+ snd_output_putc(out, '\\');
+ snd_output_putc(out, c);
+ break;
+ case 32 ... '\'' - 1:
+ case '\'' + 1 ... 126:
+ snd_output_putc(out, c);
+ break;
+ default:
+ snd_output_printf(out, "\\%04o", c);
+ break;
+ }
+ p++;
+ }
+ snd_output_putc(out, '\'');
+}
+
+static int _snd_config_save_leaves(snd_config_t *config, snd_output_t *out, unsigned int level, unsigned int joins);
+
+static int _snd_config_save_leaf(snd_config_t *n, snd_output_t *out,
+ unsigned int level)
+{
+ int err;
+ unsigned int k;
+ switch (snd_enum_to_int(n->type)) {
+ case SND_CONFIG_TYPE_INTEGER:
+ snd_output_printf(out, "%ld", n->u.integer);
+ break;
+ case SND_CONFIG_TYPE_REAL:
+ snd_output_printf(out, "%16g", n->u.real);
+ break;
+ case SND_CONFIG_TYPE_STRING:
+ string_print(n->u.string, 0, out);
+ break;
+ case SND_CONFIG_TYPE_COMPOUND:
+ snd_output_putc(out, '{');
+ snd_output_putc(out, '\n');
+ err = _snd_config_save_leaves(n, out, level + 1, 0);
+ if (err < 0)
+ return err;
+ for (k = 0; k < level; ++k) {
+ snd_output_putc(out, '\t');
+ }
+ snd_output_putc(out, '}');
+ break;
+ }
+ return 0;
+}
+
+static void id_print(snd_config_t *n, snd_output_t *out, unsigned int joins)
+{
+ if (joins > 0) {
+ assert(n->father);
+ id_print(n->father, out, joins - 1);
+ snd_output_putc(out, '.');
+ }
+ string_print(n->id, 1, out);
}
+static int _snd_config_save_leaves(snd_config_t *config, snd_output_t *out, unsigned int level, unsigned int joins)
+{
+ unsigned int k;
+ int err;
+ snd_config_iterator_t i, next;
+ assert(config && out);
+ snd_config_for_each(i, next, config) {
+ snd_config_t *n = snd_config_iterator_entry(i);
+ if (n->type == SND_CONFIG_TYPE_COMPOUND &&
+ n->u.compound.join) {
+ err = _snd_config_save_leaves(n, out, level, joins + 1);
+ if (err < 0)
+ return err;
+ continue;
+ }
+ for (k = 0; k < level; ++k) {
+ snd_output_putc(out, '\t');
+ }
+ id_print(n, out, joins);
+ snd_output_putc(out, ' ');
+ snd_output_putc(out, '=');
+ snd_output_putc(out, ' ');
+ err = _snd_config_save_leaf(n, out, level);
+ if (err < 0)
+ return err;
+ snd_output_putc(out, ';');
+ snd_output_putc(out, '\n');
+ }
+ return 0;
+}
+#endif
+
+
+/**
+ * \brief Return type of a config node
+ * \param config Config node handle
+ * \return node type
+ */
+snd_config_type_t snd_config_get_type(snd_config_t *config)
+{
+ return config->type;
+}
+
+/**
+ * \brief Return id of a config node
+ * \param config Config node handle
+ * \return node id
+ */
+const char *snd_config_get_id(snd_config_t *config)
+{
+ return config->id;
+}
+
+/**
+ * \brief Build a top level config node
+ * \param configp Returned config node handle pointer
+ * \return 0 on success otherwise a negative error code
+ */
+int snd_config_top(snd_config_t **configp)
+{
+ assert(configp);
+ return _snd_config_make(configp, 0, SND_CONFIG_TYPE_COMPOUND);
+}
+
+/**
+ * \brief Load a config tree
+ * \param config Config top node handle
+ * \param in Input handle
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_load(snd_config_t *config, snd_input_t *in)
{
int err;
return err;
}
+/**
+ * \brief Add a leaf to a config compound node
+ * \param father Config compound node handle
+ * \param leaf Leaf config node handle
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_add(snd_config_t *father, snd_config_t *leaf)
{
snd_config_iterator_t i, next;
return 0;
}
+/**
+ * \brief Remove a leaf config node (freeing all the related resources)
+ * \param config Config node handle
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_delete(snd_config_t *config)
{
assert(config);
return 0;
}
+/**
+ * \brief Build a config node
+ * \param configp Returned config node handle pointer
+ * \param id Node id
+ * \param type Node type
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_make(snd_config_t **config, const char *id,
snd_config_type_t type)
{
return _snd_config_make(config, id1, type);
}
+/**
+ * \brief Build an integer config node
+ * \param configp Returned config node handle pointer
+ * \param id Node id
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_make_integer(snd_config_t **config, const char *id)
{
return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER);
}
+/**
+ * \brief Build a real config node
+ * \param configp Returned config node handle pointer
+ * \param id Node id
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_make_real(snd_config_t **config, const char *id)
{
return snd_config_make(config, id, SND_CONFIG_TYPE_REAL);
}
+/**
+ * \brief Build a string config node
+ * \param configp Returned config node handle pointer
+ * \param id Node id
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_make_string(snd_config_t **config, const char *id)
{
return snd_config_make(config, id, SND_CONFIG_TYPE_STRING);
}
+/**
+ * \brief Build an empty compound config node
+ * \param configp Returned config node handle pointer
+ * \param id Node id
+ * \param join Join flag (checked in snd_config_save to change look)
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_make_compound(snd_config_t **config, const char *id,
int join)
{
return 0;
}
+/**
+ * \brief Change the value of an integer config node
+ * \param config Config node handle
+ * \param value Value
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_set_integer(snd_config_t *config, long value)
{
assert(config);
return 0;
}
+/**
+ * \brief Change the value of a real config node
+ * \param config Config node handle
+ * \param value Value
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_set_real(snd_config_t *config, double value)
{
assert(config);
return 0;
}
+/**
+ * \brief Change the value of a string config node
+ * \param config Config node handle
+ * \param value Value
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_set_string(snd_config_t *config, const char *value)
{
assert(config);
return 0;
}
+/**
+ * \brief Get the value of an integer config node
+ * \param config Config node handle
+ * \param ptr Returned value pointer
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_get_integer(snd_config_t *config, long *ptr)
{
assert(config && ptr);
return 0;
}
+/**
+ * \brief Get the value of a real config node
+ * \param config Config node handle
+ * \param ptr Returned value pointer
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_get_real(snd_config_t *config, double *ptr)
{
assert(config && ptr);
return 0;
}
+/**
+ * \brief Get the value of a string config node
+ * \param config Config node handle
+ * \param ptr Returned value pointer
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_get_string(snd_config_t *config, const char **ptr)
{
assert(config && ptr);
return 0;
}
-void string_print(char *str, int id, snd_output_t *out)
-{
- unsigned char *p = str;
- if (!id) {
- switch (*p) {
- case 0:
- assert(0);
- break;
- case '0' ... '9':
- case '-':
- goto quoted;
- }
- }
- if (!*p) {
- snd_output_puts(out, "''");
- return;
- }
- loop:
- switch (*p) {
- case 0:
- goto nonquoted;
- case 1 ... 31:
- case 127 ... 255:
- case ' ':
- case '=':
- case '.':
- case '{':
- case '}':
- case ';':
- case ',':
- case '\'':
- case '"':
- goto quoted;
- default:
- p++;
- goto loop;
- }
- nonquoted:
- snd_output_puts(out, str);
- return;
- quoted:
- snd_output_putc(out, '\'');
- p = str;
- while (*p) {
- int c;
- c = *p;
- switch (c) {
- case '\n':
- snd_output_putc(out, '\\');
- snd_output_putc(out, 'n');
- break;
- case '\t':
- snd_output_putc(out, '\\');
- snd_output_putc(out, 't');
- break;
- case '\v':
- snd_output_putc(out, '\\');
- snd_output_putc(out, 'v');
- break;
- case '\b':
- snd_output_putc(out, '\\');
- snd_output_putc(out, 'b');
- break;
- case '\r':
- snd_output_putc(out, '\\');
- snd_output_putc(out, 'r');
- break;
- case '\f':
- snd_output_putc(out, '\\');
- snd_output_putc(out, 'f');
- break;
- case '\'':
- snd_output_putc(out, '\\');
- snd_output_putc(out, c);
- break;
- case 32 ... '\'' - 1:
- case '\'' + 1 ... 126:
- snd_output_putc(out, c);
- break;
- default:
- snd_output_printf(out, "\\%04o", c);
- break;
- }
- p++;
- }
- snd_output_putc(out, '\'');
-}
-
-static int _snd_config_save_leaves(snd_config_t *config, snd_output_t *out, unsigned int level, unsigned int joins);
-
-static int _snd_config_save_leaf(snd_config_t *n, snd_output_t *out,
- unsigned int level)
-{
- int err;
- unsigned int k;
- switch (snd_enum_to_int(n->type)) {
- case SND_CONFIG_TYPE_INTEGER:
- snd_output_printf(out, "%ld", n->u.integer);
- break;
- case SND_CONFIG_TYPE_REAL:
- snd_output_printf(out, "%16g", n->u.real);
- break;
- case SND_CONFIG_TYPE_STRING:
- string_print(n->u.string, 0, out);
- break;
- case SND_CONFIG_TYPE_COMPOUND:
- snd_output_putc(out, '{');
- snd_output_putc(out, '\n');
- err = _snd_config_save_leaves(n, out, level + 1, 0);
- if (err < 0)
- return err;
- for (k = 0; k < level; ++k) {
- snd_output_putc(out, '\t');
- }
- snd_output_putc(out, '}');
- break;
- }
- return 0;
-}
-
-static void id_print(snd_config_t *n, snd_output_t *out, unsigned int joins)
-{
- if (joins > 0) {
- assert(n->father);
- id_print(n->father, out, joins - 1);
- snd_output_putc(out, '.');
- }
- string_print(n->id, 1, out);
-}
-
-static int _snd_config_save_leaves(snd_config_t *config, snd_output_t *out, unsigned int level, unsigned int joins)
-{
- unsigned int k;
- int err;
- snd_config_iterator_t i, next;
- assert(config && out);
- snd_config_for_each(i, next, config) {
- snd_config_t *n = snd_config_iterator_entry(i);
- if (n->type == SND_CONFIG_TYPE_COMPOUND &&
- n->u.compound.join) {
- err = _snd_config_save_leaves(n, out, level, joins + 1);
- if (err < 0)
- return err;
- continue;
- }
- for (k = 0; k < level; ++k) {
- snd_output_putc(out, '\t');
- }
- id_print(n, out, joins);
- snd_output_putc(out, ' ');
- snd_output_putc(out, '=');
- snd_output_putc(out, ' ');
- err = _snd_config_save_leaf(n, out, level);
- if (err < 0)
- return err;
- snd_output_putc(out, ';');
- snd_output_putc(out, '\n');
- }
- return 0;
-}
-
+/**
+ * \brief Dump a config tree contents
+ * \param config Config node handle
+ * \param out Output handle
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_save(snd_config_t *config, snd_output_t *out)
{
assert(config && out);
return _snd_config_save_leaves(config, out, 0, 0);
}
+/**
+ * \brief Search a node inside a config tree
+ * \param config Config node handle
+ * \param key Dot separated search key
+ * \param result Pointer to found node
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_search(snd_config_t *config, const char *key, snd_config_t **result)
{
assert(config && key && result);
}
}
+/**
+ * \brief Search a node inside a config tree
+ * \param config Config node handle
+ * \param result Pointer to found node
+ * \param ... one or more concatenated dot separated search key
+ * \return 0 on success otherwise a negative error code
+ */
int snd_config_searchv(snd_config_t *config,
snd_config_t **result, ...)
{
return 0;
}
+/**
+ * \brief Search a node inside a config tree using alias
+ * \param config Config node handle
+ * \param base Key base
+ * \param key Key suffix
+ * \param result Pointer to found node
+ * \return 0 on success otherwise a negative error code
+ *
+ * If base.key is found and it's a string the value found is recursively
+ * tried instead of suffix.
+ */
int snd_config_search_alias(snd_config_t *config,
const char *base, const char *key,
snd_config_t **result)
return 0;
}
-snd_config_t *snd_config = 0;
-static dev_t sys_asoundrc_device;
-static ino_t sys_asoundrc_inode;
-static time_t sys_asoundrc_mtime;
-static dev_t usr_asoundrc_device;
-static ino_t usr_asoundrc_inode;
-static time_t usr_asoundrc_mtime;
-
+/** File used for system wide ALSA configuration */
+#define SYS_ASOUNDRC "/etc/asound.conf"
+/** File resident in home directory used for user specific ALSA configuration */
+#define USR_ASOUNDRC ".asoundrc"
+
+/** Config top node */
+snd_config_t *snd_config = NULL;
+
+/**
+ * \brief Update #snd_config rereading if needed #SYS_ASOUNDRC and #USR_ASOUNDRC
+ * \return 0 if no action is needed, 1 if tree has been rebuilt otherwise a negative error code
+ *
+ * Warning: If config tree is reread all the string pointer and config
+ * node handle previously obtained from this tree become invalid
+ */
int snd_config_update()
{
+ static dev_t sys_asoundrc_device;
+ static ino_t sys_asoundrc_inode;
+ static time_t sys_asoundrc_mtime;
+ static dev_t usr_asoundrc_device;
+ static ino_t usr_asoundrc_inode;
+ static time_t usr_asoundrc_mtime;
int err;
char *usr_asoundrc = NULL;
char *home = getenv("HOME");
usr_asoundrc_inode = usr_st.st_ino;
usr_asoundrc_mtime = usr_st.st_mtime;
}
- return 0;
+ return 1;
}
+/**
+ * \brief Return an iterator pointing to first leaf of a compound config node
+ * \param node Config node handle
+ * \return iterator value for first leaf
+ */
snd_config_iterator_t snd_config_iterator_first(snd_config_t *node)
{
assert(node->type == SND_CONFIG_TYPE_COMPOUND);
return node->u.compound.fields.next;
}
+/**
+ * \brief Return an iterator pointing to next leaf
+ * \param iterator Config node iterator
+ * \return iterator value for next leaf
+ */
snd_config_iterator_t snd_config_iterator_next(snd_config_iterator_t iterator)
{
return iterator->next;
}
+/**
+ * \brief Return an iterator pointing past the last leaf of a compound config node
+ * \param node Config node handle
+ * \return iterator value for end
+ */
snd_config_iterator_t snd_config_iterator_end(snd_config_t *node)
{
assert(node->type == SND_CONFIG_TYPE_COMPOUND);
return &node->u.compound.fields;
}
+/**
+ * \brief Return the node handle pointed by iterator
+ * \param iterator Config node iterator
+ * \return config node handle
+ */
snd_config_t *snd_config_iterator_entry(snd_config_iterator_t iterator)
{
return list_entry(iterator, snd_config_t, list);
+/**
+ * \file input.c
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \date 2000
+ *
+ * Generic stdio-like input interface
+ */
/*
* Input object
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
*
*/
+#ifndef DOC_HIDDEN
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
snd_input_ops_t *ops;
void *private_data;
};
+#endif
+/**
+ * \brief close input handle
+ * \param input Input handle
+ * \return zero on success otherwise a negative error code
+ */
int snd_input_close(snd_input_t *input)
{
int err = input->ops->close(input);
return err;
}
+/**
+ * \brief fscanf(3) like on an input handle
+ * \param input Input handle
+ * \param format fscanf format
+ * \param ... other fscanf arguments
+ * \return number of input itmes assigned or a negative error code
+ */
int snd_input_scanf(snd_input_t *input, const char *format, ...)
{
int result;
return result;
}
+/**
+ * \brief fgets(3) like on an input handle
+ * \param input Input handle
+ * \param str Destination buffer pointer
+ * \param size Buffer size
+ * \return Pointer to buffer or NULL on error
+ */
char *snd_input_gets(snd_input_t *input, char *str, size_t size)
{
return input->ops->gets(input, str, size);
}
+/**
+ * \brief fgetc(3) like on an input handle
+ * \param input Input handle
+ * \return character read or EOF on end of file or error
+ */
int snd_input_getc(snd_input_t *input)
{
return input->ops->getch(input);
}
+/**
+ * \brief ungetc(3) like on an input handle
+ * \param input Input handle
+ * \param c Char to push back
+ * \return character pushed back or EOF on error
+ */
int snd_input_ungetc(snd_input_t *input, int c)
{
return input->ops->ungetch(input, c);
}
+#ifndef DOC_HIDDEN
typedef struct _snd_input_stdio {
int close;
FILE *fp;
} snd_input_stdio_t;
-int snd_input_stdio_close(snd_input_t *input ATTRIBUTE_UNUSED)
+static int snd_input_stdio_close(snd_input_t *input ATTRIBUTE_UNUSED)
{
snd_input_stdio_t *stdio = input->private_data;
if (close)
return 0;
}
-int snd_input_stdio_scanf(snd_input_t *input, const char *format, va_list args)
+static int snd_input_stdio_scanf(snd_input_t *input, const char *format, va_list args)
{
snd_input_stdio_t *stdio = input->private_data;
extern int vfscanf(FILE *fp, const char *format, va_list args);
return vfscanf(stdio->fp, format, args);
}
-char *snd_input_stdio_gets(snd_input_t *input, char *str, size_t size)
+static char *snd_input_stdio_gets(snd_input_t *input, char *str, size_t size)
{
snd_input_stdio_t *stdio = input->private_data;
return fgets(str, size, stdio->fp);
}
-int snd_input_stdio_getc(snd_input_t *input)
+static int snd_input_stdio_getc(snd_input_t *input)
{
snd_input_stdio_t *stdio = input->private_data;
return getc(stdio->fp);
}
-int snd_input_stdio_ungetc(snd_input_t *input, int c)
+static int snd_input_stdio_ungetc(snd_input_t *input, int c)
{
snd_input_stdio_t *stdio = input->private_data;
return ungetc(c, stdio->fp);
}
-snd_input_ops_t snd_input_stdio_ops = {
+static snd_input_ops_t snd_input_stdio_ops = {
close: snd_input_stdio_close,
scanf: snd_input_stdio_scanf,
gets: snd_input_stdio_gets,
getch: snd_input_stdio_getc,
ungetch: snd_input_stdio_ungetc,
};
+#endif
+/**
+ * \brief Create a new input using an existing stdio FILE pointer
+ * \param inputp Pointer to returned input handle
+ * \param fp FILE pointer
+ * \param close Close flag (1 if FILE is fclose'd when input handle is closed)
+ * \return 0 on success otherwise a negative error code
+ */
int snd_input_stdio_attach(snd_input_t **inputp, FILE *fp, int close)
{
snd_input_t *input;
return 0;
}
+/**
+ * \brief Open a new input from a file
+ * \param inputp Pointer to returned input handle
+ * \param file File name
+ * \return 0 on success otherwise a negative error code
+ */
int snd_input_stdio_open(snd_input_t **inputp, const char *file)
{
int err;
return err;
}
+#ifndef DOC_HIDDEN
+
typedef struct _snd_input_buffer {
unsigned char *buf;
unsigned char *ptr;
size_t size;
} snd_input_buffer_t;
-int snd_input_buffer_close(snd_input_t *input)
+static int snd_input_buffer_close(snd_input_t *input)
{
snd_input_buffer_t *buffer = input->private_data;
free(buffer->buf);
return 0;
}
-int snd_input_buffer_scanf(snd_input_t *input, const char *format, va_list args)
+static int snd_input_buffer_scanf(snd_input_t *input, const char *format, va_list args)
{
snd_input_buffer_t *buffer = input->private_data;
extern int vsscanf(const char *buf, const char *format, va_list args);
return vsscanf(buffer->ptr, format, args);
}
-char *snd_input_buffer_gets(snd_input_t *input, char *str, size_t size)
+static char *snd_input_buffer_gets(snd_input_t *input, char *str, size_t size)
{
snd_input_buffer_t *buffer = input->private_data;
size_t bsize = buffer->size;
return str;
}
-int snd_input_buffer_getc(snd_input_t *input)
+static int snd_input_buffer_getc(snd_input_t *input)
{
snd_input_buffer_t *buffer = input->private_data;
if (buffer->size == 0)
return *buffer->ptr++;
}
-int snd_input_buffer_ungetc(snd_input_t *input, int c)
+static int snd_input_buffer_ungetc(snd_input_t *input, int c)
{
snd_input_buffer_t *buffer = input->private_data;
if (buffer->ptr == buffer->buf)
return c;
}
-snd_input_ops_t snd_input_buffer_ops = {
+static snd_input_ops_t snd_input_buffer_ops = {
close: snd_input_buffer_close,
scanf: snd_input_buffer_scanf,
gets: snd_input_buffer_gets,
getch: snd_input_buffer_getc,
ungetch: snd_input_buffer_ungetc,
};
+#endif
+/**
+ * \brief Open a new input from a memory buffer
+ * \param inputp Pointer to returned input handle
+ * \param buf Buffer pointer
+ * \param size Buffer size
+ * \return 0 on success otherwise a negative error code
+ */
int snd_input_buffer_open(snd_input_t **inputp, const char *buf, int size)
{
snd_input_t *input;
+/**
+ * \file output.c
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \date 2000
+ *
+ * Generic stdio-like output interface
+ */
/*
* Output object
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
*
*/
+#ifndef DOC_HIDDEN
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
snd_output_ops_t *ops;
void *private_data;
};
+#endif
+/**
+ * \brief close output handle
+ * \param output Output handle
+ * \return zero on success otherwise a negative error code
+ */
int snd_output_close(snd_output_t *output)
{
int err = output->ops->close(output);
return err;
}
+/**
+ * \brief fprintf(3) like on an output handle
+ * \param output Output handle
+ * \param format fprintf format
+ * \param ... other fprintf arguments
+ * \return number of characters written or a negative error code
+ */
int snd_output_printf(snd_output_t *output, const char *format, ...)
{
int result;
return result;
}
+/**
+ * \brief fputs(3) like on an output handle
+ * \param output Output handle
+ * \param str Buffer pointer
+ * \return 0 on success otherwise a negative error code
+ */
int snd_output_puts(snd_output_t *output, const char *str)
{
return output->ops->puts(output, str);
}
+/**
+ * \brief fputs(3) like on an output handle
+ * \param output Output handle
+ * \param str Source buffer pointer
+ * \return 0 on success otherwise a negative error code
+ */
int snd_output_putc(snd_output_t *output, int c)
{
return output->ops->putch(output, c);
}
+/**
+ * \brief fflush(3) like on an output handle
+ * \param output Output handle
+ * \return 0 on success otherwise a negative error code
+ */
int snd_output_flush(snd_output_t *output)
{
return output->ops->flush(output);
}
+#ifndef DOC_HIDDEN
typedef struct _snd_output_stdio {
int close;
FILE *fp;
} snd_output_stdio_t;
-int snd_output_stdio_close(snd_output_t *output ATTRIBUTE_UNUSED)
+static int snd_output_stdio_close(snd_output_t *output ATTRIBUTE_UNUSED)
{
snd_output_stdio_t *stdio = output->private_data;
if (close)
return 0;
}
-int snd_output_stdio_printf(snd_output_t *output, const char *format, va_list args)
+static int snd_output_stdio_printf(snd_output_t *output, const char *format, va_list args)
{
snd_output_stdio_t *stdio = output->private_data;
return vfprintf(stdio->fp, format, args);
}
-int snd_output_stdio_puts(snd_output_t *output, const char *str)
+static int snd_output_stdio_puts(snd_output_t *output, const char *str)
{
snd_output_stdio_t *stdio = output->private_data;
return fputs(str, stdio->fp);
}
-int snd_output_stdio_putc(snd_output_t *output, int c)
+static int snd_output_stdio_putc(snd_output_t *output, int c)
{
snd_output_stdio_t *stdio = output->private_data;
return putc(c, stdio->fp);
}
-int snd_output_stdio_flush(snd_output_t *output)
+static int snd_output_stdio_flush(snd_output_t *output)
{
snd_output_stdio_t *stdio = output->private_data;
return fflush(stdio->fp);
}
-snd_output_ops_t snd_output_stdio_ops = {
+static snd_output_ops_t snd_output_stdio_ops = {
close: snd_output_stdio_close,
printf: snd_output_stdio_printf,
puts: snd_output_stdio_puts,
flush: snd_output_stdio_flush,
};
+#endif
+
+/**
+ * \brief Create a new output using an existing stdio FILE pointer
+ * \param outputp Pointer to returned output handle
+ * \param fp FILE pointer
+ * \param close Close flag (1 if FILE is fclose'd when output handle is closed)
+ * \return 0 on success otherwise a negative error code
+ */
int snd_output_stdio_attach(snd_output_t **outputp, FILE *fp, int close)
{
snd_output_t *output;
return err;
}
+#ifndef DOC_HIDDEN
+
typedef struct _snd_output_buffer {
unsigned char *buf;
size_t alloc;
size_t size;
} snd_output_buffer_t;
-int snd_output_buffer_close(snd_output_t *output ATTRIBUTE_UNUSED)
+static int snd_output_buffer_close(snd_output_t *output ATTRIBUTE_UNUSED)
{
snd_output_buffer_t *buffer = output->private_data;
free(buffer->buf);
return 0;
}
-int snd_output_buffer_need(snd_output_t *output, size_t size)
+static int snd_output_buffer_need(snd_output_t *output, size_t size)
{
snd_output_buffer_t *buffer = output->private_data;
size_t free = buffer->alloc - buffer->size;
return buffer->alloc - buffer->size;
}
-int snd_output_buffer_printf(snd_output_t *output, const char *format, va_list args)
+static int snd_output_buffer_printf(snd_output_t *output, const char *format, va_list args)
{
snd_output_buffer_t *buffer = output->private_data;
size_t size = 256;
return result;
}
-int snd_output_buffer_puts(snd_output_t *output, const char *str)
+static int snd_output_buffer_puts(snd_output_t *output, const char *str)
{
snd_output_buffer_t *buffer = output->private_data;
size_t size = strlen(str);
return size;
}
-int snd_output_buffer_putc(snd_output_t *output, int c)
+static int snd_output_buffer_putc(snd_output_t *output, int c)
{
snd_output_buffer_t *buffer = output->private_data;
int err;
return 0;
}
-int snd_output_buffer_flush(snd_output_t *output ATTRIBUTE_UNUSED)
+static int snd_output_buffer_flush(snd_output_t *output ATTRIBUTE_UNUSED)
{
snd_output_buffer_t *buffer = output->private_data;
buffer->size = 0;
return 0;
}
-size_t snd_output_buffer_string(snd_output_t *output, char **buf)
-{
- snd_output_buffer_t *buffer = output->private_data;
- *buf = buffer->buf;
- return buffer->size;
-}
-
-snd_output_ops_t snd_output_buffer_ops = {
+static snd_output_ops_t snd_output_buffer_ops = {
close: snd_output_buffer_close,
printf: snd_output_buffer_printf,
puts: snd_output_buffer_puts,
putch: snd_output_buffer_putc,
flush: snd_output_buffer_flush,
};
+#endif
+/**
+ * \brief Return buffer info for a #SND_OUTPUT_TYPE_BUFFER output handle
+ * \param output Output handle
+ * \param buf Pointer to returned buffer
+ * \return size of data in buffer
+ */
+size_t snd_output_buffer_string(snd_output_t *output, char **buf)
+{
+ snd_output_buffer_t *buffer = output->private_data;
+ *buf = buffer->buf;
+ return buffer->size;
+}
+
+/**
+ * \brief Open a new output to an auto extended memory buffer
+ * \param outputp Pointer to returned output handle
+ * \return 0 on success otherwise a negative error code
+ */
int snd_output_buffer_open(snd_output_t **outputp)
{
snd_output_t *output;