diff options
author | Lennart Poettering <lennart@poettering.net> | 2006-06-19 21:53:48 +0000 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2006-06-19 21:53:48 +0000 |
commit | f44ba092651aa75055e109e04b4164ea92ae7fdc (patch) | |
tree | 5dfe076191b32946e78edf64d584d0a65f320013 /src/polypcore | |
parent | dd21f11deda64e65a6f75817496534c2c9dda1a8 (diff) |
big s/polyp/pulse/g
git-svn-id: file:///home/lennart/svn/public/pulseaudio/trunk@1033 fefdeb5f-60dc-0310-8127-8f9354f1896f
Diffstat (limited to 'src/polypcore')
145 files changed, 0 insertions, 27456 deletions
diff --git a/src/polypcore/Makefile b/src/polypcore/Makefile deleted file mode 120000 index cd2a5c9a..00000000 --- a/src/polypcore/Makefile +++ /dev/null @@ -1 +0,0 @@ -../polyp/Makefile
\ No newline at end of file diff --git a/src/polypcore/authkey-prop.c b/src/polypcore/authkey-prop.c deleted file mode 100644 index 6172d432..00000000 --- a/src/polypcore/authkey-prop.c +++ /dev/null @@ -1,89 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <assert.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/props.h> -#include <polypcore/log.h> - -#include "authkey-prop.h" - -struct authkey_data { - int ref; - size_t length; -}; - -int pa_authkey_prop_get(pa_core *c, const char *name, void *data, size_t len) { - struct authkey_data *a; - assert(c && name && data && len > 0); - - if (!(a = pa_property_get(c, name))) - return -1; - - assert(a->length == len); - memcpy(data, a+1, len); - return 0; -} - -int pa_authkey_prop_put(pa_core *c, const char *name, const void *data, size_t len) { - struct authkey_data *a; - assert(c && name); - - if (pa_property_get(c, name)) - return -1; - - a = pa_xmalloc(sizeof(struct authkey_data) + len); - a->ref = 1; - a->length = len; - memcpy(a+1, data, len); - - pa_property_set(c, name, a); - - return 0; -} - -void pa_authkey_prop_ref(pa_core *c, const char *name) { - struct authkey_data *a; - assert(c && name); - - a = pa_property_get(c, name); - assert(a && a->ref >= 1); - - a->ref++; -} - -void pa_authkey_prop_unref(pa_core *c, const char *name) { - struct authkey_data *a; - assert(c && name); - - a = pa_property_get(c, name); - assert(a && a->ref >= 1); - - if (!(--a->ref)) { - pa_property_remove(c, name); - pa_xfree(a); - } -} - - diff --git a/src/polypcore/authkey-prop.h b/src/polypcore/authkey-prop.h deleted file mode 100644 index 63fde5d8..00000000 --- a/src/polypcore/authkey-prop.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef fooauthkeyprophfoo -#define fooauthkeyprophfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> - -/* The authkey-prop uses a central property to store a previously - * loaded cookie in memory. Useful for sharing the same cookie between - * several modules. */ - -/* Return the data of the specified authorization key property. Doesn't alter the refernce count of the key */ -int pa_authkey_prop_get(pa_core *c, const char *name, void *data, size_t len); - -/* Store data in the specified authorization key property. The initial reference count is set to 1 */ -int pa_authkey_prop_put(pa_core *c, const char *name, const void *data, size_t len); - -/* Increase the reference count of the specified authorization key */ -void pa_authkey_prop_ref(pa_core *c, const char *name); - -/* Decrease the reference count of the specified authorization key */ -void pa_authkey_prop_unref(pa_core *c, const char *name); - -#endif diff --git a/src/polypcore/authkey.c b/src/polypcore/authkey.c deleted file mode 100644 index 54f4dd86..00000000 --- a/src/polypcore/authkey.c +++ /dev/null @@ -1,209 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <unistd.h> -#include <fcntl.h> -#include <string.h> -#include <errno.h> -#include <stdio.h> -#include <inttypes.h> -#include <stdlib.h> -#include <time.h> -#include <limits.h> -#include <sys/stat.h> - -#include <polyp/util.h> -#include <polypcore/core-error.h> -#include <polypcore/core-util.h> -#include <polypcore/log.h> -#include <polypcore/random.h> - -#include "authkey.h" - -/* Generate a new authorization key, store it in file fd and return it in *data */ -static int generate(int fd, void *ret_data, size_t length) { - ssize_t r; - assert(fd >= 0 && ret_data && length); - - pa_random(ret_data, length); - - lseek(fd, 0, SEEK_SET); - ftruncate(fd, 0); - - if ((r = pa_loop_write(fd, ret_data, length)) < 0 || (size_t) r != length) { - pa_log(__FILE__": failed to write cookie file: %s", pa_cstrerror(errno)); - return -1; - } - - return 0; -} - -#ifndef O_BINARY -#define O_BINARY 0 -#endif - -/* Load an euthorization cookie from file fn and store it in data. If - * the cookie file doesn't exist, create it */ -static int load(const char *fn, void *data, size_t length) { - int fd = -1; - int writable = 1; - int unlock = 0, ret = -1; - ssize_t r; - assert(fn && data && length); - - if ((fd = open(fn, O_RDWR|O_CREAT|O_BINARY, S_IRUSR|S_IWUSR)) < 0) { - if (errno != EACCES || (fd = open(fn, O_RDONLY|O_BINARY)) < 0) { - pa_log(__FILE__": failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); - goto finish; - } else - writable = 0; - } - - unlock = pa_lock_fd(fd, 1) >= 0; - - if ((r = pa_loop_read(fd, data, length)) < 0) { - pa_log(__FILE__": failed to read cookie file '%s': %s", fn, pa_cstrerror(errno)); - goto finish; - } - - if ((size_t) r != length) { - pa_log_debug(__FILE__": got %d bytes from cookie file '%s', expected %d", (int)r, fn, (int)length); - - if (!writable) { - pa_log(__FILE__": unable to write cookie to read only file"); - goto finish; - } - - if (generate(fd, data, length) < 0) - goto finish; - } - - ret = 0; - -finish: - - if (fd >= 0) { - - if (unlock) - pa_lock_fd(fd, 0); - - close(fd); - } - - return ret; -} - -/* Load a cookie from a cookie file. If the file doesn't exist, create it. */ -int pa_authkey_load(const char *path, void *data, size_t length) { - int ret; - - assert(path && data && length); - - ret = load(path, data, length); - - if (ret < 0) - pa_log(__FILE__": Failed to load authorization key '%s': %s", path, - (ret == -1) ? pa_cstrerror(errno) : "file corrupt"); - - return ret; -} - -/* If the specified file path starts with / return it, otherwise - * return path prepended with home directory */ -static const char *normalize_path(const char *fn, char *s, size_t l) { - assert(fn && s && l > 0); - -#ifndef OS_IS_WIN32 - if (fn[0] != '/') { -#else - if (strlen(fn) < 3 || !isalpha(fn[0]) || fn[1] != ':' || fn[2] != '\\') { -#endif - char homedir[PATH_MAX]; - if (!pa_get_home_dir(homedir, sizeof(homedir))) - return NULL; - -#ifndef OS_IS_WIN32 - snprintf(s, l, "%s/%s", homedir, fn); -#else - snprintf(s, l, "%s\\%s", homedir, fn); -#endif - return s; - } - - return fn; -} - -/* Load a cookie from a file in the home directory. If the specified - * path starts with /, use it as absolute path instead. */ -int pa_authkey_load_auto(const char *fn, void *data, size_t length) { - char path[PATH_MAX]; - const char *p; - assert(fn && data && length); - - if (!(p = normalize_path(fn, path, sizeof(path)))) - return -2; - - return pa_authkey_load(p, data, length); -} - -/* Store the specified cookie in the speicified cookie file */ -int pa_authkey_save(const char *fn, const void *data, size_t length) { - int fd = -1; - int unlock = 0, ret = -1; - ssize_t r; - char path[PATH_MAX]; - const char *p; - assert(fn && data && length); - - if (!(p = normalize_path(fn, path, sizeof(path)))) - return -2; - - if ((fd = open(p, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR)) < 0) { - pa_log(__FILE__": failed to open cookie file '%s': %s", fn, pa_cstrerror(errno)); - goto finish; - } - - unlock = pa_lock_fd(fd, 1) >= 0; - - if ((r = pa_loop_write(fd, data, length)) < 0 || (size_t) r != length) { - pa_log(__FILE__": failed to read cookie file '%s': %s", fn, pa_cstrerror(errno)); - goto finish; - } - - ret = 0; - -finish: - - if (fd >= 0) { - - if (unlock) - pa_lock_fd(fd, 0); - - close(fd); - } - - return ret; -} diff --git a/src/polypcore/authkey.h b/src/polypcore/authkey.h deleted file mode 100644 index 81b1a578..00000000 --- a/src/polypcore/authkey.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef fooauthkeyhfoo -#define fooauthkeyhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <sys/types.h> - -int pa_authkey_load(const char *path, void *data, size_t len); -int pa_authkey_load_auto(const char *fn, void *data, size_t length); - -int pa_authkey_save(const char *path, const void *data, size_t length); - -#endif diff --git a/src/polypcore/autoload.c b/src/polypcore/autoload.c deleted file mode 100644 index 386de219..00000000 --- a/src/polypcore/autoload.c +++ /dev/null @@ -1,182 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/module.h> -#include <polypcore/memchunk.h> -#include <polypcore/sound-file.h> -#include <polypcore/log.h> -#include <polypcore/core-scache.h> -#include <polypcore/core-subscribe.h> - -#include "autoload.h" - -static void entry_free(pa_autoload_entry *e) { - assert(e); - pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_REMOVE, PA_INVALID_INDEX); - pa_xfree(e->name); - pa_xfree(e->module); - pa_xfree(e->argument); - pa_xfree(e); -} - -static void entry_remove_and_free(pa_autoload_entry *e) { - assert(e && e->core); - - pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL); - pa_hashmap_remove(e->core->autoload_hashmap, e->name); - entry_free(e); -} - -static pa_autoload_entry* entry_new(pa_core *c, const char *name) { - pa_autoload_entry *e = NULL; - assert(c && name); - - if (c->autoload_hashmap && (e = pa_hashmap_get(c->autoload_hashmap, name))) - return NULL; - - e = pa_xmalloc(sizeof(pa_autoload_entry)); - e->core = c; - e->name = pa_xstrdup(name); - e->module = e->argument = NULL; - e->in_action = 0; - - if (!c->autoload_hashmap) - c->autoload_hashmap = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - assert(c->autoload_hashmap); - - pa_hashmap_put(c->autoload_hashmap, e->name, e); - - if (!c->autoload_idxset) - c->autoload_idxset = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - pa_idxset_put(c->autoload_idxset, e, &e->index); - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_NEW, e->index); - - return e; -} - -int pa_autoload_add(pa_core *c, const char*name, pa_namereg_type_t type, const char*module, const char *argument, uint32_t *idx) { - pa_autoload_entry *e = NULL; - assert(c && name && module && (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE)); - - if (!(e = entry_new(c, name))) - return -1; - - e->module = pa_xstrdup(module); - e->argument = pa_xstrdup(argument); - e->type = type; - - if (idx) - *idx = e->index; - - return 0; -} - -int pa_autoload_remove_by_name(pa_core *c, const char*name, pa_namereg_type_t type) { - pa_autoload_entry *e; - assert(c && name && type); - - if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type) - return -1; - - entry_remove_and_free(e); - return 0; -} - -int pa_autoload_remove_by_index(pa_core *c, uint32_t idx) { - pa_autoload_entry *e; - assert(c && idx != PA_IDXSET_INVALID); - - if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, idx))) - return -1; - - entry_remove_and_free(e); - return 0; -} - -void pa_autoload_request(pa_core *c, const char *name, pa_namereg_type_t type) { - pa_autoload_entry *e; - pa_module *m; - assert(c && name); - - if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || (e->type != type)) - return; - - if (e->in_action) - return; - - e->in_action = 1; - - if (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE) { - if ((m = pa_module_load(c, e->module, e->argument))) - m->auto_unload = 1; - } - - e->in_action = 0; -} - -static void free_func(void *p, PA_GCC_UNUSED void *userdata) { - pa_autoload_entry *e = p; - pa_idxset_remove_by_data(e->core->autoload_idxset, e, NULL); - entry_free(e); -} - -void pa_autoload_free(pa_core *c) { - if (c->autoload_hashmap) { - pa_hashmap_free(c->autoload_hashmap, free_func, NULL); - c->autoload_hashmap = NULL; - } - - if (c->autoload_idxset) { - pa_idxset_free(c->autoload_idxset, NULL, NULL); - c->autoload_idxset = NULL; - } -} - -const pa_autoload_entry* pa_autoload_get_by_name(pa_core *c, const char*name, pa_namereg_type_t type) { - pa_autoload_entry *e; - assert(c && name); - - if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || e->type != type) - return NULL; - - return e; -} - -const pa_autoload_entry* pa_autoload_get_by_index(pa_core *c, uint32_t idx) { - pa_autoload_entry *e; - assert(c && idx != PA_IDXSET_INVALID); - - if (!c->autoload_idxset || !(e = pa_idxset_get_by_index(c->autoload_idxset, idx))) - return NULL; - - return e; -} diff --git a/src/polypcore/autoload.h b/src/polypcore/autoload.h deleted file mode 100644 index a8931fc7..00000000 --- a/src/polypcore/autoload.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef fooautoloadhfoo -#define fooautoloadhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/namereg.h> - -/* Using the autoloading facility, modules by be loaded on-demand and - * synchronously. The user may register a "ghost sink" or "ghost - * source". Whenever this sink/source is requested but not available a - * specified module is loaded. */ - -/* An autoload entry, or "ghost" sink/source */ -typedef struct pa_autoload_entry { - pa_core *core; - uint32_t index; - char *name; - pa_namereg_type_t type; /* Type of the autoload entry */ - int in_action; /* Currently loaded */ - char *module, *argument; -} pa_autoload_entry; - -/* Add a new autoload entry of the given time, with the speicified - * sink/source name, module name and argument. Return the entry's - * index in *index */ -int pa_autoload_add(pa_core *c, const char*name, pa_namereg_type_t type, const char*module, const char *argument, uint32_t *idx); - -/* Free all autoload entries */ -void pa_autoload_free(pa_core *c); -int pa_autoload_remove_by_name(pa_core *c, const char*name, pa_namereg_type_t type); -int pa_autoload_remove_by_index(pa_core *c, uint32_t idx); - -/* Request an autoload entry by its name, effectively causing a module to be loaded */ -void pa_autoload_request(pa_core *c, const char *name, pa_namereg_type_t type); - -const pa_autoload_entry* pa_autoload_get_by_name(pa_core *c, const char*name, pa_namereg_type_t type); -const pa_autoload_entry* pa_autoload_get_by_index(pa_core *c, uint32_t idx); - -#endif diff --git a/src/polypcore/cli-command.c b/src/polypcore/cli-command.c deleted file mode 100644 index e25e464c..00000000 --- a/src/polypcore/cli-command.c +++ /dev/null @@ -1,947 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <stdlib.h> -#include <errno.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/module.h> -#include <polypcore/sink.h> -#include <polypcore/source.h> -#include <polypcore/client.h> -#include <polypcore/sink-input.h> -#include <polypcore/source-output.h> -#include <polypcore/tokenizer.h> -#include <polypcore/strbuf.h> -#include <polypcore/namereg.h> -#include <polypcore/cli-text.h> -#include <polypcore/core-scache.h> -#include <polypcore/sample-util.h> -#include <polypcore/sound-file.h> -#include <polypcore/play-memchunk.h> -#include <polypcore/autoload.h> -#include <polypcore/sound-file-stream.h> -#include <polypcore/props.h> -#include <polypcore/core-util.h> -#include <polypcore/core-error.h> - -#include "cli-command.h" - -struct command { - const char *name; - int (*proc) (pa_core *c, pa_tokenizer*t, pa_strbuf *buf, int *fail); - const char *help; - unsigned args; -}; - -#define INCLUDE_META ".include" -#define FAIL_META ".fail" -#define NOFAIL_META ".nofail" - -/* Prototypes for all available commands */ -static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_autoload_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_autoload_add(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_autoload_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); -static int pa_cli_command_list_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail); - - -/* A method table for all available commands */ - -static const struct command commands[] = { - { "exit", pa_cli_command_exit, "Terminate the daemon", 1 }, - { "help", pa_cli_command_help, "Show this help", 1 }, - { "list-modules", pa_cli_command_modules, "List loaded modules", 1 }, - { "list-sinks", pa_cli_command_sinks, "List loaded sinks", 1 }, - { "list-sources", pa_cli_command_sources, "List loaded sources", 1 }, - { "list-clients", pa_cli_command_clients, "List loaded clients", 1 }, - { "list-sink-inputs", pa_cli_command_sink_inputs, "List sink inputs", 1 }, - { "list-source-outputs", pa_cli_command_source_outputs, "List source outputs", 1 }, - { "stat", pa_cli_command_stat, "Show memory block statistics", 1 }, - { "info", pa_cli_command_info, "Show comprehensive status", 1 }, - { "ls", pa_cli_command_info, NULL, 1 }, - { "list", pa_cli_command_info, NULL, 1 }, - { "load-module", pa_cli_command_load, "Load a module (args: name, arguments)", 3}, - { "unload-module", pa_cli_command_unload, "Unload a module (args: index)", 2}, - { "set-sink-volume", pa_cli_command_sink_volume, "Set the volume of a sink (args: index|name, volume)", 3}, - { "set-sink-input-volume", pa_cli_command_sink_input_volume, "Set the volume of a sink input (args: index|name, volume)", 3}, - { "set-source-volume", pa_cli_command_source_volume, "Set the volume of a source (args: index|name, volume)", 3}, - { "set-sink-mute", pa_cli_command_sink_mute, "Set the mute switch of a sink (args: index|name, mute)", 3}, - { "set-source-mute", pa_cli_command_source_mute, "Set the mute switch of a source (args: index|name, mute)", 3}, - { "set-default-sink", pa_cli_command_sink_default, "Set the default sink (args: index|name)", 2}, - { "set-default-source", pa_cli_command_source_default, "Set the default source (args: index|name)", 2}, - { "kill-client", pa_cli_command_kill_client, "Kill a client (args: index)", 2}, - { "kill-sink-input", pa_cli_command_kill_sink_input, "Kill a sink input (args: index)", 2}, - { "kill-source-output", pa_cli_command_kill_source_output, "Kill a source output (args: index)", 2}, - { "list-samples", pa_cli_command_scache_list, "List all entries in the sample cache", 1}, - { "play-sample", pa_cli_command_scache_play, "Play a sample from the sample cache (args: name, sink|index)", 3}, - { "remove-sample", pa_cli_command_scache_remove, "Remove a sample from the sample cache (args: name)", 2}, - { "load-sample", pa_cli_command_scache_load, "Load a sound file into the sample cache (args: name, filename)", 3}, - { "load-sample-lazy", pa_cli_command_scache_load, "Lazily load a sound file into the sample cache (args: name, filename)", 3}, - { "load-sample-dir-lazy", pa_cli_command_scache_load_dir, "Lazily load all files in a directory into the sample cache (args: pathname)", 2}, - { "play-file", pa_cli_command_play_file, "Play a sound file (args: filename, sink|index)", 3}, - { "list-autoload", pa_cli_command_autoload_list, "List autoload entries", 1}, - { "add-autoload-sink", pa_cli_command_autoload_add, "Add autoload entry for a sink (args: sink, module name, arguments)", 4}, - { "add-autoload-source", pa_cli_command_autoload_add, "Add autoload entry for a source (args: source, module name, arguments)", 4}, - { "remove-autoload-sink", pa_cli_command_autoload_remove, "Remove autoload entry for a sink (args: name)", 2}, - { "remove-autoload-source", pa_cli_command_autoload_remove, "Remove autoload entry for a source (args: name)", 2}, - { "dump", pa_cli_command_dump, "Dump daemon configuration", 1}, - { "list-props", pa_cli_command_list_props, NULL, 1}, - { NULL, NULL, NULL, 0 } -}; - -static const char whitespace[] = " \t\n\r"; -static const char linebreak[] = "\n\r"; - -static uint32_t parse_index(const char *n) { - uint32_t idx; - - if (pa_atou(n, &idx) < 0) - return (uint32_t) PA_IDXSET_INVALID; - - return idx; -} - -static int pa_cli_command_exit(pa_core *c, pa_tokenizer *t, PA_GCC_UNUSED pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - assert(c && c->mainloop && t); - c->mainloop->quit(c->mainloop, 0); - return 0; -} - -static int pa_cli_command_help(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const struct command*command; - assert(c && t && buf); - - pa_strbuf_puts(buf, "Available commands:\n"); - - for (command = commands; command->name; command++) - if (command->help) - pa_strbuf_printf(buf, " %-25s %s\n", command->name, command->help); - return 0; -} - -static int pa_cli_command_modules(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char *s; - assert(c && t); - s = pa_module_list_to_string(c); - assert(s); - pa_strbuf_puts(buf, s); - pa_xfree(s); - return 0; -} - -static int pa_cli_command_clients(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char *s; - assert(c && t); - s = pa_client_list_to_string(c); - assert(s); - pa_strbuf_puts(buf, s); - pa_xfree(s); - return 0; -} - -static int pa_cli_command_sinks(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char *s; - assert(c && t); - s = pa_sink_list_to_string(c); - assert(s); - pa_strbuf_puts(buf, s); - pa_xfree(s); - return 0; -} - -static int pa_cli_command_sources(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char *s; - assert(c && t); - s = pa_source_list_to_string(c); - assert(s); - pa_strbuf_puts(buf, s); - pa_xfree(s); - return 0; -} - -static int pa_cli_command_sink_inputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char *s; - assert(c && t); - s = pa_sink_input_list_to_string(c); - assert(s); - pa_strbuf_puts(buf, s); - pa_xfree(s); - return 0; -} - -static int pa_cli_command_source_outputs(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char *s; - assert(c && t); - s = pa_source_output_list_to_string(c); - assert(s); - pa_strbuf_puts(buf, s); - pa_xfree(s); - return 0; -} - -static int pa_cli_command_stat(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char s[256]; - assert(c && t); - - pa_bytes_snprint(s, sizeof(s), c->memblock_stat->total_size); - pa_strbuf_printf(buf, "Memory blocks currently allocated: %u, size: %s.\n", - c->memblock_stat->total, - s); - - pa_bytes_snprint(s, sizeof(s), c->memblock_stat->allocated_size); - pa_strbuf_printf(buf, "Memory blocks allocated during the whole lifetime: %u, size: %s.\n", - c->memblock_stat->allocated, - s); - - pa_bytes_snprint(s, sizeof(s), pa_scache_total_size(c)); - pa_strbuf_printf(buf, "Total sample cache size: %s.\n", s); - - pa_sample_spec_snprint(s, sizeof(s), &c->default_sample_spec); - pa_strbuf_printf(buf, "Default sample spec: %s\n", s); - - pa_strbuf_printf(buf, "Default sink name: %s\n" - "Default source name: %s\n", - pa_namereg_get_default_sink_name(c), - pa_namereg_get_default_source_name(c)); - - return 0; -} - -static int pa_cli_command_info(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - assert(c && t); - pa_cli_command_stat(c, t, buf, fail); - pa_cli_command_modules(c, t, buf, fail); - pa_cli_command_sinks(c, t, buf, fail); - pa_cli_command_sources(c, t, buf, fail); - pa_cli_command_clients(c, t, buf, fail); - pa_cli_command_sink_inputs(c, t, buf, fail); - pa_cli_command_source_outputs(c, t, buf, fail); - pa_cli_command_scache_list(c, t, buf, fail); - pa_cli_command_autoload_list(c, t, buf, fail); - return 0; -} - -static int pa_cli_command_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - pa_module *m; - const char *name; - assert(c && t); - - if (!(name = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify the module name and optionally arguments.\n"); - return -1; - } - - if (!(m = pa_module_load(c, name, pa_tokenizer_get(t, 2)))) { - pa_strbuf_puts(buf, "Module load failed.\n"); - return -1; - } - - return 0; -} - -static int pa_cli_command_unload(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - pa_module *m; - uint32_t idx; - const char *i; - char *e; - assert(c && t); - - if (!(i = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify the module index.\n"); - return -1; - } - - idx = (uint32_t) strtoul(i, &e, 10); - if (*e || !(m = pa_idxset_get_by_index(c->modules, idx))) { - pa_strbuf_puts(buf, "Invalid module index.\n"); - return -1; - } - - pa_module_unload_request(m); - return 0; -} - -static int pa_cli_command_sink_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n, *v; - pa_sink *sink; - uint32_t volume; - pa_cvolume cvolume; - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); - return -1; - } - - if (!(v = pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x100 is normal volume)\n"); - return -1; - } - - if (pa_atou(v, &volume) < 0) { - pa_strbuf_puts(buf, "Failed to parse volume.\n"); - return -1; - } - - if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK, 1))) { - pa_strbuf_puts(buf, "No sink found by this name or index.\n"); - return -1; - } - - pa_cvolume_set(&cvolume, sink->sample_spec.channels, volume); - pa_sink_set_volume(sink, PA_MIXER_HARDWARE, &cvolume); - return 0; -} - -static int pa_cli_command_sink_input_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n, *v; - pa_sink_input *si; - pa_volume_t volume; - pa_cvolume cvolume; - uint32_t idx; - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n"); - return -1; - } - - if ((idx = parse_index(n)) == PA_IDXSET_INVALID) { - pa_strbuf_puts(buf, "Failed to parse index.\n"); - return -1; - } - - if (!(v = pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x100 is normal volume)\n"); - return -1; - } - - if (pa_atou(v, &volume) < 0) { - pa_strbuf_puts(buf, "Failed to parse volume.\n"); - return -1; - } - - if (!(si = pa_idxset_get_by_index(c->sink_inputs, (uint32_t) idx))) { - pa_strbuf_puts(buf, "No sink input found with this index.\n"); - return -1; - } - - pa_cvolume_set(&cvolume, si->sample_spec.channels, volume); - pa_sink_input_set_volume(si, &cvolume); - return 0; -} - -static int pa_cli_command_source_volume(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n, *v; - pa_source *source; - uint32_t volume; - pa_cvolume cvolume; - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n"); - return -1; - } - - if (!(v = pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "You need to specify a volume >= 0. (0 is muted, 0x100 is normal volume)\n"); - return -1; - } - - if (pa_atou(v, &volume) < 0) { - pa_strbuf_puts(buf, "Failed to parse volume.\n"); - return -1; - } - - if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE, 1))) { - pa_strbuf_puts(buf, "No source found by this name or index.\n"); - return -1; - } - - pa_cvolume_set(&cvolume, source->sample_spec.channels, volume); - pa_source_set_volume(source, PA_MIXER_HARDWARE, &cvolume); - return 0; -} - -static int pa_cli_command_sink_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n, *m; - pa_sink *sink; - int mute; - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); - return -1; - } - - if (!(m = pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n"); - return -1; - } - - if (pa_atoi(m, &mute) < 0) { - pa_strbuf_puts(buf, "Failed to parse mute switch.\n"); - return -1; - } - - if (!(sink = pa_namereg_get(c, n, PA_NAMEREG_SINK, 1))) { - pa_strbuf_puts(buf, "No sink found by this name or index.\n"); - return -1; - } - - pa_sink_set_mute(sink, PA_MIXER_HARDWARE, mute); - return 0; -} - -static int pa_cli_command_source_mute(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n, *m; - pa_source *source; - int mute; - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n"); - return -1; - } - - if (!(m = pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "You need to specify a mute switch setting (0/1).\n"); - return -1; - } - - if (pa_atoi(m, &mute) < 0) { - pa_strbuf_puts(buf, "Failed to parse mute switch.\n"); - return -1; - } - - if (!(source = pa_namereg_get(c, n, PA_NAMEREG_SOURCE, 1))) { - pa_strbuf_puts(buf, "No sink found by this name or index.\n"); - return -1; - } - - pa_source_set_mute(source, PA_MIXER_HARDWARE, mute); - return 0; -} - -static int pa_cli_command_sink_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n; - assert(c && t); - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a sink either by its name or its index.\n"); - return -1; - } - - pa_namereg_set_default(c, n, PA_NAMEREG_SINK); - return 0; -} - -static int pa_cli_command_source_default(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n; - assert(c && t); - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a source either by its name or its index.\n"); - return -1; - } - - pa_namereg_set_default(c, n, PA_NAMEREG_SOURCE); - return 0; -} - -static int pa_cli_command_kill_client(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n; - pa_client *client; - uint32_t idx; - assert(c && t); - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a client by its index.\n"); - return -1; - } - - if ((idx = parse_index(n)) == PA_IDXSET_INVALID) { - pa_strbuf_puts(buf, "Failed to parse index.\n"); - return -1; - } - - if (!(client = pa_idxset_get_by_index(c->clients, idx))) { - pa_strbuf_puts(buf, "No client found by this index.\n"); - return -1; - } - - pa_client_kill(client); - return 0; -} - -static int pa_cli_command_kill_sink_input(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n; - pa_sink_input *sink_input; - uint32_t idx; - assert(c && t); - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a sink input by its index.\n"); - return -1; - } - - if ((idx = parse_index(n)) == PA_IDXSET_INVALID) { - pa_strbuf_puts(buf, "Failed to parse index.\n"); - return -1; - } - - if (!(sink_input = pa_idxset_get_by_index(c->sink_inputs, idx))) { - pa_strbuf_puts(buf, "No sink input found by this index.\n"); - return -1; - } - - pa_sink_input_kill(sink_input); - return 0; -} - -static int pa_cli_command_kill_source_output(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - const char *n; - pa_source_output *source_output; - uint32_t idx; - assert(c && t); - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a source output by its index.\n"); - return -1; - } - - if ((idx = parse_index(n)) == PA_IDXSET_INVALID) { - pa_strbuf_puts(buf, "Failed to parse index.\n"); - return -1; - } - - if (!(source_output = pa_idxset_get_by_index(c->source_outputs, idx))) { - pa_strbuf_puts(buf, "No source output found by this index.\n"); - return -1; - } - - pa_source_output_kill(source_output); - return 0; -} - -static int pa_cli_command_scache_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char *s; - assert(c && t); - s = pa_scache_list_to_string(c); - assert(s); - pa_strbuf_puts(buf, s); - pa_xfree(s); - return 0; -} - -static int pa_cli_command_scache_play(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - const char *n, *sink_name; - pa_sink *sink; - assert(c && t && buf && fail); - - if (!(n = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "You need to specify a sample name and a sink name.\n"); - return -1; - } - - if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK, 1))) { - pa_strbuf_puts(buf, "No sink by that name.\n"); - return -1; - } - - if (pa_scache_play_item(c, n, sink, PA_VOLUME_NORM) < 0) { - pa_strbuf_puts(buf, "Failed to play sample.\n"); - return -1; - } - - return 0; -} - -static int pa_cli_command_scache_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - const char *n; - assert(c && t && buf && fail); - - if (!(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a sample name.\n"); - return -1; - } - - if (pa_scache_remove_item(c, n) < 0) { - pa_strbuf_puts(buf, "Failed to remove sample.\n"); - return -1; - } - - return 0; -} - -static int pa_cli_command_scache_load(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - const char *fname, *n; - int r; - assert(c && t && buf && fail); - - if (!(fname = pa_tokenizer_get(t, 2)) || !(n = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a file name and a sample name.\n"); - return -1; - } - - if (strstr(pa_tokenizer_get(t, 0), "lazy")) - r = pa_scache_add_file_lazy(c, n, fname, NULL); - else - r = pa_scache_add_file(c, n, fname, NULL); - - if (r < 0) - pa_strbuf_puts(buf, "Failed to load sound file.\n"); - - return 0; -} - -static int pa_cli_command_scache_load_dir(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - const char *pname; - assert(c && t && buf && fail); - - if (!(pname = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a path name.\n"); - return -1; - } - - if (pa_scache_add_directory_lazy(c, pname) < 0) { - pa_strbuf_puts(buf, "Failed to load directory.\n"); - return -1; - } - - return 0; -} - -static int pa_cli_command_play_file(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - const char *fname, *sink_name; - pa_sink *sink; - assert(c && t && buf && fail); - - if (!(fname = pa_tokenizer_get(t, 1)) || !(sink_name = pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "You need to specify a file name and a sink name.\n"); - return -1; - } - - if (!(sink = pa_namereg_get(c, sink_name, PA_NAMEREG_SINK, 1))) { - pa_strbuf_puts(buf, "No sink by that name.\n"); - return -1; - } - - - return pa_play_file(sink, fname, NULL); -} - -static int pa_cli_command_autoload_add(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - const char *a, *b; - assert(c && t && buf && fail); - - if (!(a = pa_tokenizer_get(t, 1)) || !(b = pa_tokenizer_get(t, 2))) { - pa_strbuf_puts(buf, "You need to specify a device name, a filename or a module name and optionally module arguments\n"); - return -1; - } - - pa_autoload_add(c, a, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, b, pa_tokenizer_get(t, 3), NULL); - - return 0; -} - -static int pa_cli_command_autoload_remove(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, int *fail) { - const char *name; - assert(c && t && buf && fail); - - if (!(name = pa_tokenizer_get(t, 1))) { - pa_strbuf_puts(buf, "You need to specify a device name\n"); - return -1; - } - - if (pa_autoload_remove_by_name(c, name, strstr(pa_tokenizer_get(t, 0), "sink") ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE) < 0) { - pa_strbuf_puts(buf, "Failed to remove autload entry\n"); - return -1; - } - - return 0; -} - -static int pa_cli_command_autoload_list(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - char *s; - assert(c && t); - s = pa_autoload_list_to_string(c); - assert(s); - pa_strbuf_puts(buf, s); - pa_xfree(s); - return 0; -} - -static int pa_cli_command_list_props(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - assert(c && t); - pa_property_dump(c, buf); - return 0; -} - -static int pa_cli_command_dump(pa_core *c, pa_tokenizer *t, pa_strbuf *buf, PA_GCC_UNUSED int *fail) { - pa_module *m; - pa_sink *sink; - pa_source *source; - int nl; - const char *p; - uint32_t idx; - char txt[256]; - time_t now; - void *i; - pa_autoload_entry *a; - - assert(c && t); - - time(&now); - -#ifdef HAVE_CTIME_R - pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime_r(&now, txt)); -#else - pa_strbuf_printf(buf, "### Configuration dump generated at %s\n", ctime(&now)); -#endif - - - for (m = pa_idxset_first(c->modules, &idx); m; m = pa_idxset_next(c->modules, &idx)) { - if (m->auto_unload) - continue; - - pa_strbuf_printf(buf, "load-module %s", m->name); - - if (m->argument) - pa_strbuf_printf(buf, " %s", m->argument); - - pa_strbuf_puts(buf, "\n"); - } - - nl = 0; - - for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) { - if (sink->owner && sink->owner->auto_unload) - continue; - - if (!nl) { - pa_strbuf_puts(buf, "\n"); - nl = 1; - } - - pa_strbuf_printf(buf, "set-sink-volume %s 0x%03x\n", sink->name, pa_cvolume_avg(pa_sink_get_volume(sink, PA_MIXER_HARDWARE))); - pa_strbuf_printf(buf, "set-sink-mute %s %d\n", sink->name, pa_sink_get_mute(sink, PA_MIXER_HARDWARE)); - } - - for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) { - if (source->owner && source->owner->auto_unload) - continue; - - if (!nl) { - pa_strbuf_puts(buf, "\n"); - nl = 1; - } - - pa_strbuf_printf(buf, "set-source-volume %s 0x%03x\n", source->name, pa_cvolume_avg(pa_source_get_volume(source, PA_MIXER_HARDWARE))); - pa_strbuf_printf(buf, "set-source-mute %s %d\n", source->name, pa_source_get_mute(source, PA_MIXER_HARDWARE)); - } - - - if (c->autoload_hashmap) { - nl = 0; - - i = NULL; - while ((a = pa_hashmap_iterate(c->autoload_hashmap, &i, NULL))) { - - if (!nl) { - pa_strbuf_puts(buf, "\n"); - nl = 1; - } - - pa_strbuf_printf(buf, "add-autoload-%s %s %s", a->type == PA_NAMEREG_SINK ? "sink" : "source", a->name, a->module); - - if (a->argument) - pa_strbuf_printf(buf, " %s", a->argument); - - pa_strbuf_puts(buf, "\n"); - } - } - - nl = 0; - - if ((p = pa_namereg_get_default_sink_name(c))) { - if (!nl) { - pa_strbuf_puts(buf, "\n"); - nl = 1; - } - pa_strbuf_printf(buf, "set-default-sink %s\n", p); - } - - if ((p = pa_namereg_get_default_source_name(c))) { - if (!nl) { - pa_strbuf_puts(buf, "\n"); - nl = 1; - } - pa_strbuf_printf(buf, "set-default-source %s\n", p); - } - - pa_strbuf_puts(buf, "\n### EOF\n"); - - return 0; -} - - -int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, int *fail) { - const char *cs; - - cs = s+strspn(s, whitespace); - - if (*cs == '#' || !*cs) - return 0; - else if (*cs == '.') { - if (!strcmp(cs, FAIL_META)) - *fail = 1; - else if (!strcmp(cs, NOFAIL_META)) - *fail = 0; - else { - size_t l; - l = strcspn(cs, whitespace); - - if (l == sizeof(INCLUDE_META)-1 && !strncmp(cs, INCLUDE_META, l)) { - const char *filename = cs+l+strspn(cs+l, whitespace); - - if (pa_cli_command_execute_file(c, filename, buf, fail) < 0) - if (*fail) return -1; - } else { - pa_strbuf_printf(buf, "Invalid meta command: %s\n", cs); - if (*fail) return -1; - } - } - } else { - const struct command*command; - int unknown = 1; - size_t l; - - l = strcspn(cs, whitespace); - - for (command = commands; command->name; command++) - if (strlen(command->name) == l && !strncmp(cs, command->name, l)) { - int ret; - pa_tokenizer *t = pa_tokenizer_new(cs, command->args); - assert(t); - ret = command->proc(c, t, buf, fail); - pa_tokenizer_free(t); - unknown = 0; - - if (ret < 0 && *fail) - return -1; - - break; - } - - if (unknown) { - pa_strbuf_printf(buf, "Unknown command: %s\n", cs); - if (*fail) - return -1; - } - } - - return 0; -} - -int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, int *fail) { - char line[256]; - FILE *f = NULL; - int ret = -1; - assert(c && fn && buf); - - if (!(f = fopen(fn, "r"))) { - pa_strbuf_printf(buf, "open('%s') failed: %s\n", fn, pa_cstrerror(errno)); - if (!*fail) - ret = 0; - goto fail; - } - - while (fgets(line, sizeof(line), f)) { - char *e = line + strcspn(line, linebreak); - *e = 0; - - if (pa_cli_command_execute_line(c, line, buf, fail) < 0 && *fail) - goto fail; - } - - ret = 0; - -fail: - if (f) - fclose(f); - - return ret; -} - -int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, int *fail) { - const char *p; - assert(c && s && buf && fail); - - p = s; - while (*p) { - size_t l = strcspn(p, linebreak); - char *line = pa_xstrndup(p, l); - - if (pa_cli_command_execute_line(c, line, buf, fail) < 0&& *fail) { - pa_xfree(line); - return -1; - } - pa_xfree(line); - - p += l; - p += strspn(p, linebreak); - } - - return 0; -} diff --git a/src/polypcore/cli-command.h b/src/polypcore/cli-command.h deleted file mode 100644 index e7c70ecf..00000000 --- a/src/polypcore/cli-command.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef fooclicommandhfoo -#define fooclicommandhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/strbuf.h> -#include <polypcore/core.h> - -/* Execute a single CLI command. Write the results to the string - * buffer *buf. If *fail is non-zero the function will return -1 when - * one or more of the executed commands failed. *fail - * may be modified by the function call. */ -int pa_cli_command_execute_line(pa_core *c, const char *s, pa_strbuf *buf, int *fail); - -/* Execute a whole file of CLI commands */ -int pa_cli_command_execute_file(pa_core *c, const char *fn, pa_strbuf *buf, int *fail); - -/* Split the specified string into lines and run pa_cli_command_execute_line() for each. */ -int pa_cli_command_execute(pa_core *c, const char *s, pa_strbuf *buf, int *fail); - -#endif diff --git a/src/polypcore/cli-text.c b/src/polypcore/cli-text.c deleted file mode 100644 index 09ccaa00..00000000 --- a/src/polypcore/cli-text.c +++ /dev/null @@ -1,387 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <string.h> - -#include <polyp/volume.h> -#include <polyp/xmalloc.h> - -#include <polypcore/module.h> -#include <polypcore/client.h> -#include <polypcore/sink.h> -#include <polypcore/source.h> -#include <polypcore/sink-input.h> -#include <polypcore/source-output.h> -#include <polypcore/strbuf.h> -#include <polypcore/sample-util.h> -#include <polypcore/core-scache.h> -#include <polypcore/autoload.h> - -#include "cli-text.h" - -char *pa_module_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_module *m; - uint32_t idx = PA_IDXSET_INVALID; - assert(c); - - s = pa_strbuf_new(); - assert(s); - - pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(c->modules)); - - for (m = pa_idxset_first(c->modules, &idx); m; m = pa_idxset_next(c->modules, &idx)) - pa_strbuf_printf(s, " index: %u\n\tname: <%s>\n\targument: <%s>\n\tused: %i\n\tauto unload: %s\n", m->index, m->name, m->argument, m->n_used, m->auto_unload ? "yes" : "no"); - - return pa_strbuf_tostring_free(s); -} - -char *pa_client_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_client *client; - uint32_t idx = PA_IDXSET_INVALID; - assert(c); - - s = pa_strbuf_new(); - assert(s); - - pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(c->clients)); - - for (client = pa_idxset_first(c->clients, &idx); client; client = pa_idxset_next(c->clients, &idx)) { - pa_strbuf_printf(s, " index: %u\n\tname: <%s>\n\tdriver: <%s>\n", client->index, client->name, client->driver); - - if (client->owner) - pa_strbuf_printf(s, "\towner module: <%u>\n", client->owner->index); - } - - return pa_strbuf_tostring_free(s); -} - -char *pa_sink_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_sink *sink; - uint32_t idx = PA_IDXSET_INVALID; - assert(c); - - s = pa_strbuf_new(); - assert(s); - - pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks)); - - for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; - - pa_strbuf_printf( - s, - " %c index: %u\n" - "\tname: <%s>\n" - "\tdriver: <%s>\n" - "\tvolume: <%s>\n" - "\tlatency: <%0.0f usec>\n" - "\tmonitor_source: <%u>\n" - "\tsample spec: <%s>\n" - "\tchannel map: <%s>\n", - c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ', - sink->index, sink->name, - sink->driver, - pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, PA_MIXER_HARDWARE)), - (double) pa_sink_get_latency(sink), - sink->monitor_source->index, - pa_sample_spec_snprint(ss, sizeof(ss), &sink->sample_spec), - pa_channel_map_snprint(cm, sizeof(cm), &sink->channel_map)); - - if (sink->owner) - pa_strbuf_printf(s, "\towner module: <%u>\n", sink->owner->index); - if (sink->description) - pa_strbuf_printf(s, "\tdescription: <%s>\n", sink->description); - } - - return pa_strbuf_tostring_free(s); -} - -char *pa_source_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_source *source; - uint32_t idx = PA_IDXSET_INVALID; - assert(c); - - s = pa_strbuf_new(); - assert(s); - - pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources)); - - for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; - - - pa_strbuf_printf( - s, - " %c index: %u\n" - "\tname: <%s>\n" - "\tdriver: <%s>\n" - "\tlatency: <%0.0f usec>\n" - "\tsample spec: <%s>\n" - "\tchannel map: <%s>\n", - c->default_source_name && !strcmp(source->name, c->default_source_name) ? '*' : ' ', - source->index, - source->name, - source->driver, - (double) pa_source_get_latency(source), - pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec), - pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map)); - - if (source->monitor_of) - pa_strbuf_printf(s, "\tmonitor_of: <%u>\n", source->monitor_of->index); - if (source->owner) - pa_strbuf_printf(s, "\towner module: <%u>\n", source->owner->index); - if (source->description) - pa_strbuf_printf(s, "\tdescription: <%s>\n", source->description); - } - - return pa_strbuf_tostring_free(s); -} - - -char *pa_source_output_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_source_output *o; - uint32_t idx = PA_IDXSET_INVALID; - static const char* const state_table[] = { - "RUNNING", - "CORKED", - "DISCONNECTED" - }; - assert(c); - - s = pa_strbuf_new(); - assert(s); - - pa_strbuf_printf(s, "%u source outputs(s) available.\n", pa_idxset_size(c->source_outputs)); - - for (o = pa_idxset_first(c->source_outputs, &idx); o; o = pa_idxset_next(c->source_outputs, &idx)) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; - - assert(o->source); - - pa_strbuf_printf( - s, - " index: %u\n" - "\tname: '%s'\n" - "\tdriver: <%s>\n" - "\tstate: %s\n" - "\tsource: <%u> '%s'\n" - "\tsample spec: <%s>\n" - "\tchannel map: <%s>\n" - "\tresample method: %s\n", - o->index, - o->name, - o->driver, - state_table[o->state], - o->source->index, o->source->name, - pa_sample_spec_snprint(ss, sizeof(ss), &o->sample_spec), - pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map), - pa_resample_method_to_string(pa_source_output_get_resample_method(o))); - if (o->owner) - pa_strbuf_printf(s, "\towner module: <%u>\n", o->owner->index); - if (o->client) - pa_strbuf_printf(s, "\tclient: <%u> '%s'\n", o->client->index, o->client->name); - } - - return pa_strbuf_tostring_free(s); -} - -char *pa_sink_input_list_to_string(pa_core *c) { - pa_strbuf *s; - pa_sink_input *i; - uint32_t idx = PA_IDXSET_INVALID; - static const char* const state_table[] = { - "RUNNING", - "CORKED", - "DISCONNECTED" - }; - - assert(c); - s = pa_strbuf_new(); - assert(s); - - pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(c->sink_inputs)); - - for (i = pa_idxset_first(c->sink_inputs, &idx); i; i = pa_idxset_next(c->sink_inputs, &idx)) { - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX]; - - assert(i->sink); - - pa_strbuf_printf( - s, - " index: %u\n" - "\tname: <%s>\n" - "\tdriver: <%s>\n" - "\tstate: %s\n" - "\tsink: <%u> '%s'\n" - "\tvolume: <%s>\n" - "\tlatency: <%0.0f usec>\n" - "\tsample spec: <%s>\n" - "\tchannel map: <%s>\n" - "\tresample method: %s\n", - i->index, - i->name, - i->driver, - state_table[i->state], - i->sink->index, i->sink->name, - pa_cvolume_snprint(cv, sizeof(cv), pa_sink_input_get_volume(i)), - (double) pa_sink_input_get_latency(i), - pa_sample_spec_snprint(ss, sizeof(ss), &i->sample_spec), - pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map), - pa_resample_method_to_string(pa_sink_input_get_resample_method(i))); - - if (i->owner) - pa_strbuf_printf(s, "\towner module: <%u>\n", i->owner->index); - if (i->client) - pa_strbuf_printf(s, "\tclient: <%u> '%s'\n", i->client->index, i->client->name); - } - - return pa_strbuf_tostring_free(s); -} - -char *pa_scache_list_to_string(pa_core *c) { - pa_strbuf *s; - assert(c); - - s = pa_strbuf_new(); - assert(s); - - pa_strbuf_printf(s, "%u cache entries available.\n", c->scache ? pa_idxset_size(c->scache) : 0); - - if (c->scache) { - pa_scache_entry *e; - uint32_t idx = PA_IDXSET_INVALID; - - for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) { - double l = 0; - char ss[PA_SAMPLE_SPEC_SNPRINT_MAX] = "n/a", cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX] = "n/a"; - - if (e->memchunk.memblock) { - pa_sample_spec_snprint(ss, sizeof(ss), &e->sample_spec); - pa_channel_map_snprint(cm, sizeof(cm), &e->channel_map); - l = (double) e->memchunk.length / pa_bytes_per_second(&e->sample_spec); - } - - pa_strbuf_printf( - s, - " name: <%s>\n" - "\tindex: <%u>\n" - "\tsample spec: <%s>\n" - "\tchannel map: <%s>\n" - "\tlength: <%lu>\n" - "\tduration: <%0.1fs>\n" - "\tvolume: <%s>\n" - "\tlazy: %s\n" - "\tfilename: %s\n", - e->name, - e->index, - ss, - cm, - (long unsigned)(e->memchunk.memblock ? e->memchunk.length : 0), - l, - pa_cvolume_snprint(cv, sizeof(cv), &e->volume), - e->lazy ? "yes" : "no", - e->filename ? e->filename : "n/a"); - } - } - - return pa_strbuf_tostring_free(s); -} - -char *pa_autoload_list_to_string(pa_core *c) { - pa_strbuf *s; - assert(c); - - s = pa_strbuf_new(); - assert(s); - - pa_strbuf_printf(s, "%u autoload entries available.\n", c->autoload_hashmap ? pa_hashmap_size(c->autoload_hashmap) : 0); - - if (c->autoload_hashmap) { - pa_autoload_entry *e; - void *state = NULL; - - while ((e = pa_hashmap_iterate(c->autoload_hashmap, &state, NULL))) { - pa_strbuf_printf( - s, " name: <%s>\n\ttype: <%s>\n\tindex: <%u>\n\tmodule_name: <%s>\n\targuments: <%s>\n", - e->name, - e->type == PA_NAMEREG_SOURCE ? "source" : "sink", - e->index, - e->module, - e->argument); - - } - } - - return pa_strbuf_tostring_free(s); -} - -char *pa_full_status_string(pa_core *c) { - pa_strbuf *s; - int i; - - s = pa_strbuf_new(); - - for (i = 0; i < 8; i++) { - char *t = NULL; - - switch (i) { - case 0: - t = pa_sink_list_to_string(c); - break; - case 1: - t = pa_source_list_to_string(c); - break; - case 2: - t = pa_sink_input_list_to_string(c); - break; - case 3: - t = pa_source_output_list_to_string(c); - break; - case 4: - t = pa_client_list_to_string(c); - break; - case 5: - t = pa_module_list_to_string(c); - break; - case 6: - t = pa_scache_list_to_string(c); - break; - case 7: - t = pa_autoload_list_to_string(c); - break; - } - - pa_strbuf_puts(s, t); - pa_xfree(t); - } - - return pa_strbuf_tostring_free(s); -} diff --git a/src/polypcore/cli-text.h b/src/polypcore/cli-text.h deleted file mode 100644 index a8f40003..00000000 --- a/src/polypcore/cli-text.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef fooclitexthfoo -#define fooclitexthfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> - -/* Some functions to generate pretty formatted listings of - * entities. The returned strings have to be freed manually. */ - -char *pa_sink_input_list_to_string(pa_core *c); -char *pa_source_output_list_to_string(pa_core *c); -char *pa_sink_list_to_string(pa_core *core); -char *pa_source_list_to_string(pa_core *c); -char *pa_client_list_to_string(pa_core *c); -char *pa_module_list_to_string(pa_core *c); -char *pa_scache_list_to_string(pa_core *c); -char *pa_autoload_list_to_string(pa_core *c); - -char *pa_full_status_string(pa_core *c); - -#endif - diff --git a/src/polypcore/cli.c b/src/polypcore/cli.c deleted file mode 100644 index 683d29ec..00000000 --- a/src/polypcore/cli.c +++ /dev/null @@ -1,149 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <stdlib.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/ioline.h> -#include <polypcore/module.h> -#include <polypcore/sink.h> -#include <polypcore/source.h> -#include <polypcore/client.h> -#include <polypcore/sink-input.h> -#include <polypcore/source-output.h> -#include <polypcore/tokenizer.h> -#include <polypcore/strbuf.h> -#include <polypcore/namereg.h> -#include <polypcore/cli-text.h> -#include <polypcore/cli-command.h> -#include <polypcore/log.h> - -#include "cli.h" - -#define PROMPT ">>> " - -struct pa_cli { - pa_core *core; - pa_ioline *line; - - void (*eof_callback)(pa_cli *c, void *userdata); - void *userdata; - - pa_client *client; - - int fail, kill_requested, defer_kill; -}; - -static void line_callback(pa_ioline *line, const char *s, void *userdata); -static void client_kill(pa_client *c); - -pa_cli* pa_cli_new(pa_core *core, pa_iochannel *io, pa_module *m) { - char cname[256]; - pa_cli *c; - assert(io); - - c = pa_xmalloc(sizeof(pa_cli)); - c->core = core; - c->line = pa_ioline_new(io); - assert(c->line); - - c->userdata = NULL; - c->eof_callback = NULL; - - pa_iochannel_socket_peer_to_string(io, cname, sizeof(cname)); - c->client = pa_client_new(core, __FILE__, cname); - assert(c->client); - c->client->kill = client_kill; - c->client->userdata = c; - c->client->owner = m; - - pa_ioline_set_callback(c->line, line_callback, c); - pa_ioline_puts(c->line, "Welcome to polypaudio! Use \"help\" for usage information.\n"PROMPT); - - c->fail = c->kill_requested = c->defer_kill = 0; - - return c; -} - -void pa_cli_free(pa_cli *c) { - assert(c); - pa_ioline_close(c->line); - pa_ioline_unref(c->line); - pa_client_free(c->client); - pa_xfree(c); -} - -static void client_kill(pa_client *client) { - pa_cli *c; - assert(client && client->userdata); - c = client->userdata; - - pa_log_debug(__FILE__": CLI client killed."); - if (c->defer_kill) - c->kill_requested = 1; - else { - if (c->eof_callback) - c->eof_callback(c, c->userdata); - } -} - -static void line_callback(pa_ioline *line, const char *s, void *userdata) { - pa_strbuf *buf; - pa_cli *c = userdata; - char *p; - assert(line && c); - - if (!s) { - pa_log_debug(__FILE__": CLI got EOF from user."); - if (c->eof_callback) - c->eof_callback(c, c->userdata); - - return; - } - - buf = pa_strbuf_new(); - assert(buf); - c->defer_kill++; - pa_cli_command_execute_line(c->core, s, buf, &c->fail); - c->defer_kill--; - pa_ioline_puts(line, p = pa_strbuf_tostring_free(buf)); - pa_xfree(p); - - if (c->kill_requested) { - if (c->eof_callback) - c->eof_callback(c, c->userdata); - } else - pa_ioline_puts(line, PROMPT); -} - -void pa_cli_set_eof_callback(pa_cli *c, void (*cb)(pa_cli*c, void *userdata), void *userdata) { - assert(c); - c->eof_callback = cb; - c->userdata = userdata; -} diff --git a/src/polypcore/cli.h b/src/polypcore/cli.h deleted file mode 100644 index 12ffd848..00000000 --- a/src/polypcore/cli.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef fooclihfoo -#define fooclihfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/iochannel.h> -#include <polypcore/core.h> -#include <polypcore/module.h> - -typedef struct pa_cli pa_cli; - -/* Create a new command line session on the specified io channel owned by the specified module */ -pa_cli* pa_cli_new(pa_core *core, pa_iochannel *io, pa_module *m); -void pa_cli_free(pa_cli *cli); - -/* Set a callback function that is called whenever the command line session is terminated */ -void pa_cli_set_eof_callback(pa_cli *cli, void (*cb)(pa_cli*c, void *userdata), void *userdata); - -#endif diff --git a/src/polypcore/client.c b/src/polypcore/client.c deleted file mode 100644 index 4ece07a8..00000000 --- a/src/polypcore/client.c +++ /dev/null @@ -1,96 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/core-subscribe.h> -#include <polypcore/log.h> - -#include "client.h" - -pa_client *pa_client_new(pa_core *core, const char *driver, const char *name) { - pa_client *c; - int r; - assert(core); - - c = pa_xmalloc(sizeof(pa_client)); - c->name = pa_xstrdup(name); - c->driver = pa_xstrdup(driver); - c->owner = NULL; - c->core = core; - - c->kill = NULL; - c->userdata = NULL; - - r = pa_idxset_put(core->clients, c, &c->index); - assert(c->index != PA_IDXSET_INVALID && r >= 0); - - pa_log_info(__FILE__": created %u \"%s\"", c->index, c->name); - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_NEW, c->index); - - pa_core_check_quit(core); - - return c; -} - -void pa_client_free(pa_client *c) { - assert(c && c->core); - - pa_idxset_remove_by_data(c->core->clients, c, NULL); - - pa_core_check_quit(c->core); - - pa_log_info(__FILE__": freed %u \"%s\"", c->index, c->name); - pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_REMOVE, c->index); - pa_xfree(c->name); - pa_xfree(c->driver); - pa_xfree(c); -} - -void pa_client_kill(pa_client *c) { - assert(c); - if (!c->kill) { - pa_log_warn(__FILE__": kill() operation not implemented for client %u", c->index); - return; - } - - c->kill(c); -} - -void pa_client_set_name(pa_client *c, const char *name) { - assert(c); - - pa_log_info(__FILE__": client %u changed name from \"%s\" to \"%s\"", c->index, c->name, name); - - pa_xfree(c->name); - c->name = pa_xstrdup(name); - - pa_subscription_post(c->core, PA_SUBSCRIPTION_EVENT_CLIENT|PA_SUBSCRIPTION_EVENT_CHANGE, c->index); -} diff --git a/src/polypcore/client.h b/src/polypcore/client.h deleted file mode 100644 index f6ff935d..00000000 --- a/src/polypcore/client.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef fooclienthfoo -#define fooclienthfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> -#include <polypcore/module.h> - -/* Every connection to the server should have a pa_client - * attached. That way the user may generate a listing of all connected - * clients easily and kill them if he wants.*/ - -typedef struct pa_client pa_client; - -struct pa_client { - uint32_t index; - - pa_module *owner; - char *name, *driver; - pa_core *core; - - void (*kill)(pa_client *c); - void *userdata; -}; - -pa_client *pa_client_new(pa_core *c, const char *driver, const char *name); - -/* This function should be called only by the code that created the client */ -void pa_client_free(pa_client *c); - -/* Code that didn't create the client should call this function to - * request destruction of the client */ -void pa_client_kill(pa_client *c); - -/* Rename the client */ -void pa_client_set_name(pa_client *c, const char *name); - -#endif diff --git a/src/polypcore/conf-parser.c b/src/polypcore/conf-parser.c deleted file mode 100644 index d59bc555..00000000 --- a/src/polypcore/conf-parser.c +++ /dev/null @@ -1,181 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <string.h> -#include <stdio.h> -#include <errno.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/core-error.h> -#include <polypcore/log.h> -#include <polypcore/core-util.h> - -#include "conf-parser.h" - -#define WHITESPACE " \t\n" -#define COMMENTS "#;\n" - -/* Run the user supplied parser for an assignment */ -static int next_assignment(const char *filename, unsigned line, const pa_config_item *t, const char *lvalue, const char *rvalue, void *userdata) { - assert(filename && t && lvalue && rvalue); - - for (; t->parse; t++) - if (!strcmp(lvalue, t->lvalue)) - return t->parse(filename, line, lvalue, rvalue, t->data, userdata); - - pa_log(__FILE__": [%s:%u] Unknown lvalue '%s'.", filename, line, lvalue); - - return -1; -} - -/* Returns non-zero when c is contained in s */ -static int in_string(char c, const char *s) { - assert(s); - - for (; *s; s++) - if (*s == c) - return 1; - - return 0; -} - -/* Remove all whitepsapce from the beginning and the end of *s. *s may - * be modified. */ -static char *strip(char *s) { - char *b = s+strspn(s, WHITESPACE); - char *e, *l = NULL; - - for (e = b; *e; e++) - if (!in_string(*e, WHITESPACE)) - l = e; - - if (l) - *(l+1) = 0; - - return b; -} - -/* Parse a variable assignment line */ -static int parse_line(const char *filename, unsigned line, const pa_config_item *t, char *l, void *userdata) { - char *e, *c, *b = l+strspn(l, WHITESPACE); - - if ((c = strpbrk(b, COMMENTS))) - *c = 0; - - if (!*b) - return 0; - - if (!(e = strchr(b, '='))) { - pa_log(__FILE__": [%s:%u] Missing '='.", filename, line); - return -1; - } - - *e = 0; - e++; - - return next_assignment(filename, line, t, strip(b), strip(e), userdata); -} - -/* Go through the file and parse each line */ -int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata) { - int r = -1; - unsigned line = 0; - int do_close = !f; - assert(filename && t); - - if (!f && !(f = fopen(filename, "r"))) { - if (errno == ENOENT) { - r = 0; - goto finish; - } - - pa_log_warn(__FILE__": WARNING: failed to open configuration file '%s': %s", - filename, pa_cstrerror(errno)); - goto finish; - } - - while (!feof(f)) { - char l[256]; - if (!fgets(l, sizeof(l), f)) { - if (feof(f)) - break; - - pa_log_warn(__FILE__": WARNING: failed to read configuration file '%s': %s", - filename, pa_cstrerror(errno)); - goto finish; - } - - if (parse_line(filename, ++line, t, l, userdata) < 0) - goto finish; - } - - r = 0; - -finish: - - if (do_close && f) - fclose(f); - - return r; -} - -int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { - int *i = data; - int32_t k; - assert(filename && lvalue && rvalue && data); - - if (pa_atoi(rvalue, &k) < 0) { - pa_log(__FILE__": [%s:%u] Failed to parse numeric value: %s", filename, line, rvalue); - return -1; - } - - *i = (int) k; - return 0; -} - -int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { - int *b = data, k; - assert(filename && lvalue && rvalue && data); - - if ((k = pa_parse_boolean(rvalue)) < 0) { - pa_log(__FILE__": [%s:%u] Failed to parse boolean value: %s", filename, line, rvalue); - return -1; - } - - *b = k; - - return 0; -} - -int pa_config_parse_string(const char *filename, PA_GCC_UNUSED unsigned line, const char *lvalue, const char *rvalue, void *data, PA_GCC_UNUSED void *userdata) { - char **s = data; - assert(filename && lvalue && rvalue && data); - - pa_xfree(*s); - *s = *rvalue ? pa_xstrdup(rvalue) : NULL; - return 0; -} diff --git a/src/polypcore/conf-parser.h b/src/polypcore/conf-parser.h deleted file mode 100644 index 2dca3bce..00000000 --- a/src/polypcore/conf-parser.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef fooconfparserhfoo -#define fooconfparserhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <stdio.h> - -/* An abstract parser for simple, line based, shallow configuration - * files consisting of variable assignments only. */ - -/* Wraps info for parsing a specific configuration variable */ -typedef struct pa_config_item { - const char *lvalue; /* name of the variable */ - int (*parse)(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); /* Function that is called to parse the variable's value */ - void *data; /* Where to store the variable's data */ -} pa_config_item; - -/* The configuration file parsing routine. Expects a table of - * pa_config_items in *t that is terminated by an item where lvalue is - * NULL */ -int pa_config_parse(const char *filename, FILE *f, const pa_config_item *t, void *userdata); - -/* Generic parsers for integers, booleans and strings */ -int pa_config_parse_int(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); -int pa_config_parse_bool(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); -int pa_config_parse_string(const char *filename, unsigned line, const char *lvalue, const char *rvalue, void *data, void *userdata); - -#endif diff --git a/src/polypcore/core-def.h b/src/polypcore/core-def.h deleted file mode 100644 index 89cc47f1..00000000 --- a/src/polypcore/core-def.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef foocoredefhfoo -#define foocoredefhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef enum pa_mixer { - PA_MIXER_SOFTWARE, - PA_MIXER_HARDWARE -} pa_mixer_t; - -#endif diff --git a/src/polypcore/core-error.c b/src/polypcore/core-error.c deleted file mode 100644 index f2240a9f..00000000 --- a/src/polypcore/core-error.c +++ /dev/null @@ -1,205 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#ifdef HAVE_PTHREAD -#include <pthread.h> -#endif - -#ifdef HAVE_WINDOWS_H -#include <windows.h> -#endif - -#include <polyp/utf8.h> -#include <polyp/xmalloc.h> - -#include <polypcore/core-util.h> -#include <polypcore/native-common.h> - -#include "core-error.h" - -#ifdef HAVE_PTHREAD - -static pthread_once_t cstrerror_once = PTHREAD_ONCE_INIT; -static pthread_key_t tlsstr_key; - -static void inittls(void) { - int ret; - - ret = pthread_key_create(&tlsstr_key, pa_xfree); - if (ret) { - fprintf(stderr, __FILE__ ": CRITICAL: Unable to allocate TLS key (%d)\n", errno); - exit(-1); - } -} - -#elif HAVE_WINDOWS_H - -static DWORD tlsstr_key = TLS_OUT_OF_INDEXES; -static DWORD monitor_key = TLS_OUT_OF_INDEXES; - -static void inittls(void) { - HANDLE mutex; - char name[64]; - - sprintf(name, "polypaudio%d", (int)GetCurrentProcessId()); - - mutex = CreateMutex(NULL, FALSE, name); - if (!mutex) { - fprintf(stderr, __FILE__ ": CRITICAL: Unable to create named mutex (%d)\n", (int)GetLastError()); - exit(-1); - } - - WaitForSingleObject(mutex, INFINITE); - - if (tlsstr_key == TLS_OUT_OF_INDEXES) { - tlsstr_key = TlsAlloc(); - monitor_key = TlsAlloc(); - if ((tlsstr_key == TLS_OUT_OF_INDEXES) || (monitor_key == TLS_OUT_OF_INDEXES)) { - fprintf(stderr, __FILE__ ": CRITICAL: Unable to allocate TLS key (%d)\n", (int)GetLastError()); - exit(-1); - } - } - - ReleaseMutex(mutex); - - CloseHandle(mutex); -} - -/* - * This is incredibly brain dead, but this is necessary when dealing with - * the hell that is Win32. - */ -struct monitor_data { - HANDLE thread; - void *data; -}; - -static DWORD WINAPI monitor_thread(LPVOID param) { - struct monitor_data *data; - - data = (struct monitor_data*)param; - assert(data); - - WaitForSingleObject(data->thread, INFINITE); - - CloseHandle(data->thread); - pa_xfree(data->data); - pa_xfree(data); - - return 0; -} - -static void start_monitor(void) { - HANDLE thread; - struct monitor_data *data; - - data = pa_xnew(struct monitor_data, 1); - assert(data); - - DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &data->thread, 0, FALSE, DUPLICATE_SAME_ACCESS); - - thread = CreateThread(NULL, 0, monitor_thread, data, 0, NULL); - assert(thread); - - TlsSetValue(monitor_key, data); - - CloseHandle(thread); -} - -#else - -/* Unsafe, but we have no choice */ -static char *tlsstr; - -#endif - -const char* pa_cstrerror(int errnum) { - const char *origbuf; - -#ifdef HAVE_STRERROR_R - char errbuf[128]; -#endif - -#ifdef HAVE_PTHREAD - char *tlsstr; - - pthread_once(&cstrerror_once, inittls); - - tlsstr = pthread_getspecific(tlsstr_key); -#elif defined(HAVE_WINDOWS_H) - char *tlsstr; - struct monitor_data *data; - - inittls(); - - tlsstr = TlsGetValue(tlsstr_key); - if (!tlsstr) - start_monitor(); - data = TlsGetValue(monitor_key); -#endif - - if (tlsstr) - pa_xfree(tlsstr); - -#ifdef HAVE_STRERROR_R - -#ifdef __GLIBC__ - origbuf = strerror_r(errnum, errbuf, sizeof(errbuf)); - if (origbuf == NULL) - origbuf = ""; -#else - if (strerror_r(errnum, errbuf, sizeof(errbuf)) == 0) { - origbuf = errbuf; - errbuf[sizeof(errbuf) - 1] = '\0'; - } else - origbuf = ""; -#endif - -#else - /* This might not be thread safe, but we hope for the best */ - origbuf = strerror(errnum); -#endif - - tlsstr = pa_locale_to_utf8(origbuf); - if (!tlsstr) { - fprintf(stderr, "Unable to convert, filtering\n"); - tlsstr = pa_utf8_filter(origbuf); - } - -#ifdef HAVE_PTHREAD - pthread_setspecific(tlsstr_key, tlsstr); -#elif defined(HAVE_WINDOWS_H) - TlsSetValue(tlsstr_key, tlsstr); - data->data = tlsstr; -#endif - - return tlsstr; -} diff --git a/src/polypcore/core-error.h b/src/polypcore/core-error.h deleted file mode 100644 index 17595c98..00000000 --- a/src/polypcore/core-error.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef foocoreerrorhfoo -#define foocoreerrorhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> -#include <polyp/cdecl.h> - -/** \file - * Error management */ - -PA_C_DECL_BEGIN - -/** A wrapper around the standard strerror() function that converts the - * string to UTF-8. The function is thread safe but the returned string is - * only guaranteed to exist until the thread exits or pa_cstrerror() is - * called again from the same thread. */ -const char* pa_cstrerror(int errnum); - -PA_C_DECL_END - -#endif diff --git a/src/polypcore/core-scache.c b/src/polypcore/core-scache.c deleted file mode 100644 index b44a7e19..00000000 --- a/src/polypcore/core-scache.c +++ /dev/null @@ -1,412 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <sys/types.h> -#include <dirent.h> -#include <sys/stat.h> -#include <errno.h> -#include <limits.h> - -#ifdef HAVE_GLOB_H -#include <glob.h> -#endif - -#ifdef HAVE_WINDOWS_H -#include <windows.h> -#endif - -#include <polyp/mainloop.h> -#include <polyp/channelmap.h> -#include <polyp/timeval.h> -#include <polyp/util.h> -#include <polyp/volume.h> -#include <polyp/xmalloc.h> - -#include <polypcore/sink-input.h> -#include <polypcore/sample-util.h> -#include <polypcore/play-memchunk.h> -#include <polypcore/core-subscribe.h> -#include <polypcore/namereg.h> -#include <polypcore/sound-file.h> -#include <polypcore/core-util.h> -#include <polypcore/log.h> -#include <polypcore/core-error.h> - -#include "core-scache.h" - -#define UNLOAD_POLL_TIME 2 - -static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { - pa_core *c = userdata; - struct timeval ntv; - assert(c && c->mainloop == m && c->scache_auto_unload_event == e); - - pa_scache_unload_unused(c); - - pa_gettimeofday(&ntv); - ntv.tv_sec += UNLOAD_POLL_TIME; - m->time_restart(e, &ntv); -} - -static void free_entry(pa_scache_entry *e) { - assert(e); - pa_namereg_unregister(e->core, e->name); - pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_REMOVE, e->index); - pa_xfree(e->name); - pa_xfree(e->filename); - if (e->memchunk.memblock) - pa_memblock_unref(e->memchunk.memblock); - pa_xfree(e); -} - -static pa_scache_entry* scache_add_item(pa_core *c, const char *name) { - pa_scache_entry *e; - assert(c && name); - - if ((e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) { - if (e->memchunk.memblock) - pa_memblock_unref(e->memchunk.memblock); - - pa_xfree(e->filename); - - assert(e->core == c); - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); - } else { - e = pa_xmalloc(sizeof(pa_scache_entry)); - - if (!pa_namereg_register(c, name, PA_NAMEREG_SAMPLE, e, 1)) { - pa_xfree(e); - return NULL; - } - - e->name = pa_xstrdup(name); - e->core = c; - - if (!c->scache) { - c->scache = pa_idxset_new(pa_idxset_trivial_hash_func, pa_idxset_trivial_compare_func); - assert(c->scache); - } - - pa_idxset_put(c->scache, e, &e->index); - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_NEW, e->index); - } - - e->last_used_time = 0; - e->memchunk.memblock = NULL; - e->memchunk.index = e->memchunk.length = 0; - e->filename = NULL; - e->lazy = 0; - e->last_used_time = 0; - - memset(&e->sample_spec, 0, sizeof(e->sample_spec)); - pa_channel_map_init(&e->channel_map); - pa_cvolume_reset(&e->volume, PA_CHANNELS_MAX); - - return e; -} - -int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_memchunk *chunk, uint32_t *idx) { - pa_scache_entry *e; - assert(c && name); - - if (chunk && chunk->length > PA_SCACHE_ENTRY_SIZE_MAX) - return -1; - - if (!(e = scache_add_item(c, name))) - return -1; - - if (ss) { - e->sample_spec = *ss; - pa_channel_map_init_auto(&e->channel_map, ss->channels, PA_CHANNEL_MAP_DEFAULT); - e->volume.channels = e->sample_spec.channels; - } - - if (map) - e->channel_map = *map; - - if (chunk) { - e->memchunk = *chunk; - pa_memblock_ref(e->memchunk.memblock); - } - - if (idx) - *idx = e->index; - - return 0; -} - -int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint32_t *idx) { - pa_sample_spec ss; - pa_channel_map map; - pa_memchunk chunk; - int r; - -#ifdef OS_IS_WIN32 - char buf[MAX_PATH]; - - if (ExpandEnvironmentStrings(filename, buf, MAX_PATH)) - filename = buf; -#endif - - if (pa_sound_file_load(filename, &ss, &map, &chunk, c->memblock_stat) < 0) - return -1; - - r = pa_scache_add_item(c, name, &ss, &map, &chunk, idx); - pa_memblock_unref(chunk.memblock); - - return r; -} - -int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, uint32_t *idx) { - pa_scache_entry *e; - -#ifdef OS_IS_WIN32 - char buf[MAX_PATH]; - - if (ExpandEnvironmentStrings(filename, buf, MAX_PATH)) - filename = buf; -#endif - - assert(c && name); - - if (!(e = scache_add_item(c, name))) - return -1; - - e->lazy = 1; - e->filename = pa_xstrdup(filename); - - if (!c->scache_auto_unload_event) { - struct timeval ntv; - pa_gettimeofday(&ntv); - ntv.tv_sec += UNLOAD_POLL_TIME; - c->scache_auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c); - } - - if (idx) - *idx = e->index; - - return 0; -} - -int pa_scache_remove_item(pa_core *c, const char *name) { - pa_scache_entry *e; - assert(c && name); - - if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) - return -1; - - if (pa_idxset_remove_by_data(c->scache, e, NULL) != e) - assert(0); - - free_entry(e); - return 0; -} - -static void free_cb(void *p, PA_GCC_UNUSED void *userdata) { - pa_scache_entry *e = p; - assert(e); - free_entry(e); -} - -void pa_scache_free(pa_core *c) { - assert(c); - - if (c->scache) { - pa_idxset_free(c->scache, free_cb, NULL); - c->scache = NULL; - } - - if (c->scache_auto_unload_event) - c->mainloop->time_free(c->scache_auto_unload_event); -} - -int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t volume) { - pa_scache_entry *e; - char *t; - pa_cvolume r; - - assert(c); - assert(name); - assert(sink); - - if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 1))) - return -1; - - if (e->lazy && !e->memchunk.memblock) { - if (pa_sound_file_load(e->filename, &e->sample_spec, &e->channel_map, &e->memchunk, c->memblock_stat) < 0) - return -1; - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); - - if (e->volume.channels > e->sample_spec.channels) - e->volume.channels = e->sample_spec.channels; - } - - if (!e->memchunk.memblock) - return -1; - - t = pa_sprintf_malloc("sample:%s", name); - - pa_cvolume_set(&r, e->volume.channels, volume); - pa_sw_cvolume_multiply(&r, &r, &e->volume); - - if (pa_play_memchunk(sink, t, &e->sample_spec, &e->channel_map, &e->memchunk, &r) < 0) { - pa_xfree(t); - return -1; - } - - pa_xfree(t); - - if (e->lazy) - time(&e->last_used_time); - - return 0; -} - -const char * pa_scache_get_name_by_id(pa_core *c, uint32_t id) { - pa_scache_entry *e; - assert(c && id != PA_IDXSET_INVALID); - - if (!c->scache || !(e = pa_idxset_get_by_index(c->scache, id))) - return NULL; - - return e->name; -} - -uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name) { - pa_scache_entry *e; - assert(c && name); - - if (!(e = pa_namereg_get(c, name, PA_NAMEREG_SAMPLE, 0))) - return PA_IDXSET_INVALID; - - return e->index; -} - -uint32_t pa_scache_total_size(pa_core *c) { - pa_scache_entry *e; - uint32_t idx, sum = 0; - assert(c); - - if (!c->scache || !pa_idxset_size(c->scache)) - return 0; - - for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) - if (e->memchunk.memblock) - sum += e->memchunk.length; - - return sum; -} - -void pa_scache_unload_unused(pa_core *c) { - pa_scache_entry *e; - time_t now; - uint32_t idx; - assert(c); - - if (!c->scache || !pa_idxset_size(c->scache)) - return; - - time(&now); - - for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) { - - if (!e->lazy || !e->memchunk.memblock) - continue; - - if (e->last_used_time + c->scache_idle_time > now) - continue; - - pa_memblock_unref(e->memchunk.memblock); - e->memchunk.memblock = NULL; - e->memchunk.index = e->memchunk.length = 0; - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SAMPLE_CACHE|PA_SUBSCRIPTION_EVENT_CHANGE, e->index); - } -} - -static void add_file(pa_core *c, const char *pathname) { - struct stat st; - const char *e; - - e = pa_path_get_filename(pathname); - - if (stat(pathname, &st) < 0) { - pa_log(__FILE__": stat('%s'): %s", pathname, pa_cstrerror(errno)); - return; - } - -#if defined(S_ISREG) && defined(S_ISLNK) - if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) -#endif - pa_scache_add_file_lazy(c, e, pathname, NULL); -} - -int pa_scache_add_directory_lazy(pa_core *c, const char *pathname) { - DIR *dir; - assert(c && pathname); - - /* First try to open this as directory */ - if (!(dir = opendir(pathname))) { -#ifdef HAVE_GLOB_H - glob_t p; - unsigned int i; - /* If that fails, try to open it as shell glob */ - - if (glob(pathname, GLOB_ERR|GLOB_NOSORT, NULL, &p) < 0) { - pa_log(__FILE__": failed to open directory '%s': %s", pathname, pa_cstrerror(errno)); - return -1; - } - - for (i = 0; i < p.gl_pathc; i++) - add_file(c, p.gl_pathv[i]); - - globfree(&p); -#else - return -1; -#endif - } else { - struct dirent *e; - - while ((e = readdir(dir))) { - char p[PATH_MAX]; - - if (e->d_name[0] == '.') - continue; - - snprintf(p, sizeof(p), "%s/%s", pathname, e->d_name); - add_file(c, p); - } - } - - closedir(dir); - return 0; -} diff --git a/src/polypcore/core-scache.h b/src/polypcore/core-scache.h deleted file mode 100644 index 9ca05f8f..00000000 --- a/src/polypcore/core-scache.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef foocorescachehfoo -#define foocorescachehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> -#include <polypcore/memchunk.h> -#include <polypcore/sink.h> - -#define PA_SCACHE_ENTRY_SIZE_MAX (1024*1024*2) - -typedef struct pa_scache_entry { - pa_core *core; - uint32_t index; - char *name; - - pa_cvolume volume; - pa_sample_spec sample_spec; - pa_channel_map channel_map; - pa_memchunk memchunk; - - char *filename; - - int lazy; - time_t last_used_time; -} pa_scache_entry; - -int pa_scache_add_item(pa_core *c, const char *name, const pa_sample_spec *ss, const pa_channel_map *map, const pa_memchunk *chunk, uint32_t *idx); -int pa_scache_add_file(pa_core *c, const char *name, const char *filename, uint32_t *idx); -int pa_scache_add_file_lazy(pa_core *c, const char *name, const char *filename, uint32_t *idx); - -int pa_scache_add_directory_lazy(pa_core *c, const char *pathname); - -int pa_scache_remove_item(pa_core *c, const char *name); -int pa_scache_play_item(pa_core *c, const char *name, pa_sink *sink, pa_volume_t volume); -void pa_scache_free(pa_core *c); - -const char *pa_scache_get_name_by_id(pa_core *c, uint32_t id); -uint32_t pa_scache_get_id_by_name(pa_core *c, const char *name); - -uint32_t pa_scache_total_size(pa_core *c); - -void pa_scache_unload_unused(pa_core *c); - -#endif diff --git a/src/polypcore/core-subscribe.c b/src/polypcore/core-subscribe.c deleted file mode 100644 index 52babb7a..00000000 --- a/src/polypcore/core-subscribe.c +++ /dev/null @@ -1,233 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <assert.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/queue.h> -#include <polypcore/log.h> - -#include "core-subscribe.h" - -/* The subscription subsystem may be used to be notified whenever an - * entity (sink, source, ...) is created or deleted. Modules may - * register a callback function that is called whenever an event - * matching a subscription mask happens. The execution of the callback - * function is postponed to the next main loop iteration, i.e. is not - * called from within the stack frame the entity was created in. */ - -struct pa_subscription { - pa_core *core; - int dead; - void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata); - void *userdata; - pa_subscription_mask_t mask; - - pa_subscription *prev, *next; -}; - -struct pa_subscription_event { - pa_subscription_event_type_t type; - uint32_t index; -}; - -static void sched_event(pa_core *c); - -/* Allocate a new subscription object for the given subscription mask. Use the specified callback function and user data */ -pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata), void *userdata) { - pa_subscription *s; - assert(c); - - s = pa_xmalloc(sizeof(pa_subscription)); - s->core = c; - s->dead = 0; - s->callback = callback; - s->userdata = userdata; - s->mask = m; - - if ((s->next = c->subscriptions)) - s->next->prev = s; - s->prev = NULL; - c->subscriptions = s; - return s; -} - -/* Free a subscription object, effectively marking it for deletion */ -void pa_subscription_free(pa_subscription*s) { - assert(s && !s->dead); - s->dead = 1; - sched_event(s->core); -} - -static void free_item(pa_subscription *s) { - assert(s && s->core); - - if (s->prev) - s->prev->next = s->next; - else - s->core->subscriptions = s->next; - - if (s->next) - s->next->prev = s->prev; - - pa_xfree(s); -} - -/* Free all subscription objects */ -void pa_subscription_free_all(pa_core *c) { - pa_subscription_event *e; - assert(c); - - while (c->subscriptions) - free_item(c->subscriptions); - - if (c->subscription_event_queue) { - while ((e = pa_queue_pop(c->subscription_event_queue))) - pa_xfree(e); - - pa_queue_free(c->subscription_event_queue, NULL, NULL); - c->subscription_event_queue = NULL; - } - - if (c->subscription_defer_event) { - c->mainloop->defer_free(c->subscription_defer_event); - c->subscription_defer_event = NULL; - } -} - -#if 0 -static void dump_event(pa_subscription_event*e) { - switch (e->type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { - case PA_SUBSCRIPTION_EVENT_SINK: - pa_log(__FILE__": SINK_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_SOURCE: - pa_log(__FILE__": SOURCE_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_SINK_INPUT: - pa_log(__FILE__": SINK_INPUT_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT: - pa_log(__FILE__": SOURCE_OUTPUT_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_MODULE: - pa_log(__FILE__": MODULE_EVENT"); - break; - case PA_SUBSCRIPTION_EVENT_CLIENT: - pa_log(__FILE__": CLIENT_EVENT"); - break; - default: - pa_log(__FILE__": OTHER"); - break; - } - - switch (e->type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) { - case PA_SUBSCRIPTION_EVENT_NEW: - pa_log(__FILE__": NEW"); - break; - case PA_SUBSCRIPTION_EVENT_CHANGE: - pa_log(__FILE__": CHANGE"); - break; - case PA_SUBSCRIPTION_EVENT_REMOVE: - pa_log(__FILE__": REMOVE"); - break; - default: - pa_log(__FILE__": OTHER"); - break; - } - - pa_log(__FILE__": %u", e->index); -} -#endif - -/* Deferred callback for dispatching subscirption events */ -static void defer_cb(pa_mainloop_api *m, pa_defer_event *de, void *userdata) { - pa_core *c = userdata; - pa_subscription *s; - assert(c && c->subscription_defer_event == de && c->mainloop == m); - - c->mainloop->defer_enable(c->subscription_defer_event, 0); - - /* Dispatch queued events */ - - if (c->subscription_event_queue) { - pa_subscription_event *e; - - while ((e = pa_queue_pop(c->subscription_event_queue))) { - - for (s = c->subscriptions; s; s = s->next) { - - if (!s->dead && pa_subscription_match_flags(s->mask, e->type)) - s->callback(c, e->type, e->index, s->userdata); - } - - pa_xfree(e); - } - } - - /* Remove dead subscriptions */ - - s = c->subscriptions; - while (s) { - pa_subscription *n = s->next; - if (s->dead) - free_item(s); - s = n; - } -} - -/* Schedule an mainloop event so that a pending subscription event is dispatched */ -static void sched_event(pa_core *c) { - assert(c); - - if (!c->subscription_defer_event) { - c->subscription_defer_event = c->mainloop->defer_new(c->mainloop, defer_cb, c); - assert(c->subscription_defer_event); - } - - c->mainloop->defer_enable(c->subscription_defer_event, 1); -} - -/* Append a new subscription event to the subscription event queue and schedule a main loop event */ -void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t index) { - pa_subscription_event *e; - assert(c); - - e = pa_xmalloc(sizeof(pa_subscription_event)); - e->type = t; - e->index = index; - - if (!c->subscription_event_queue) { - c->subscription_event_queue = pa_queue_new(); - assert(c->subscription_event_queue); - } - - pa_queue_push(c->subscription_event_queue, e); - sched_event(c); -} - - diff --git a/src/polypcore/core-subscribe.h b/src/polypcore/core-subscribe.h deleted file mode 100644 index 7c856954..00000000 --- a/src/polypcore/core-subscribe.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef foocoresubscribehfoo -#define foocoresubscribehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef struct pa_subscription pa_subscription; -typedef struct pa_subscription_event pa_subscription_event; - -#include <polypcore/core.h> -#include <polypcore/native-common.h> - -pa_subscription* pa_subscription_new(pa_core *c, pa_subscription_mask_t m, void (*callback)(pa_core *c, pa_subscription_event_type_t t, uint32_t index, void *userdata), void *userdata); -void pa_subscription_free(pa_subscription*s); -void pa_subscription_free_all(pa_core *c); - -void pa_subscription_post(pa_core *c, pa_subscription_event_type_t t, uint32_t idx); - -#endif diff --git a/src/polypcore/core-util.c b/src/polypcore/core-util.c deleted file mode 100644 index dfa41f57..00000000 --- a/src/polypcore/core-util.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdarg.h> -#include <stdlib.h> -#include <signal.h> -#include <errno.h> -#include <assert.h> -#include <string.h> -#include <stdio.h> -#include <fcntl.h> -#include <unistd.h> -#include <limits.h> -#include <time.h> -#include <ctype.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/time.h> - -#ifdef HAVE_SCHED_H -#include <sched.h> -#endif - -#ifdef HAVE_SYS_RESOURCE_H -#include <sys/resource.h> -#endif - -#ifdef HAVE_PTHREAD -#include <pthread.h> -#endif - -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif - -#ifdef HAVE_WINDOWS_H -#include <windows.h> -#endif - -#ifdef HAVE_PWD_H -#include <pwd.h> -#endif - -#ifdef HAVE_GRP_H -#include <grp.h> -#endif - -#include <samplerate.h> - -#include <polyp/xmalloc.h> -#include <polyp/util.h> - -#include <polypcore/core-error.h> -#include <polypcore/winsock.h> -#include <polypcore/log.h> - -#include "core-util.h" - -#ifndef OS_IS_WIN32 -#define PA_RUNTIME_PATH_PREFIX "/tmp/polypaudio-" -#define PATH_SEP '/' -#else -#define PA_RUNTIME_PATH_PREFIX "%TEMP%\\polypaudio-" -#define PATH_SEP '\\' -#endif - -#ifdef OS_IS_WIN32 - -#define POLYP_ROOTENV "POLYP_ROOT" - -int pa_set_root(HANDLE handle) { - char library_path[MAX_PATH + sizeof(POLYP_ROOTENV) + 1], *sep; - - strcpy(library_path, POLYP_ROOTENV "="); - - if (!GetModuleFileName(handle, library_path + sizeof(POLYP_ROOTENV), MAX_PATH)) - return 0; - - sep = strrchr(library_path, '\\'); - if (sep) - *sep = '\0'; - - if (_putenv(library_path) < 0) - return 0; - - return 1; -} - -#endif - -/** Make a file descriptor nonblock. Doesn't do any error checking */ -void pa_make_nonblock_fd(int fd) { -#ifdef O_NONBLOCK - int v; - assert(fd >= 0); - - if ((v = fcntl(fd, F_GETFL)) >= 0) - if (!(v & O_NONBLOCK)) - fcntl(fd, F_SETFL, v|O_NONBLOCK); -#elif defined(OS_IS_WIN32) - u_long arg = 1; - if (ioctlsocket(fd, FIONBIO, &arg) < 0) { - if (WSAGetLastError() == WSAENOTSOCK) - pa_log_warn(__FILE__": WARNING: Only sockets can be made non-blocking!"); - } -#else - pa_log_warn(__FILE__": WARNING: Non-blocking I/O not supported.!"); -#endif -} - -/** Creates a directory securely */ -int pa_make_secure_dir(const char* dir) { - struct stat st; - assert(dir); - -#ifdef OS_IS_WIN32 - if (mkdir(dir) < 0) -#else - if (mkdir(dir, 0700) < 0) -#endif - if (errno != EEXIST) - return -1; - -#ifdef HAVE_CHOWN - chown(dir, getuid(), getgid()); -#endif -#ifdef HAVE_CHMOD - chmod(dir, 0700); -#endif - -#ifdef HAVE_LSTAT - if (lstat(dir, &st) < 0) -#else - if (stat(dir, &st) < 0) -#endif - goto fail; - -#ifndef OS_IS_WIN32 - if (!S_ISDIR(st.st_mode) || (st.st_uid != getuid()) || ((st.st_mode & 0777) != 0700)) - goto fail; -#else - fprintf(stderr, "FIXME: pa_make_secure_dir()\n"); -#endif - - return 0; - -fail: - rmdir(dir); - return -1; -} - -/* Return a newly allocated sting containing the parent directory of the specified file */ -char *pa_parent_dir(const char *fn) { - char *slash, *dir = pa_xstrdup(fn); - - slash = (char*) pa_path_get_filename(dir); - if (slash == fn) - return NULL; - - *(slash-1) = 0; - return dir; -} - -/* Creates a the parent directory of the specified path securely */ -int pa_make_secure_parent_dir(const char *fn) { - int ret = -1; - char *dir; - - if (!(dir = pa_parent_dir(fn))) - goto finish; - - if (pa_make_secure_dir(dir) < 0) - goto finish; - - ret = 0; - -finish: - pa_xfree(dir); - return ret; -} - -/** Platform independent read function. Necessary since not all systems - * treat all file descriptors equal. */ -ssize_t pa_read(int fd, void *buf, size_t count) { - ssize_t r; - -#ifdef OS_IS_WIN32 - r = recv(fd, buf, count, 0); - if (r < 0) { - if (WSAGetLastError() != WSAENOTSOCK) { - errno = WSAGetLastError(); - return r; - } - } - - if (r < 0) -#endif - r = read(fd, buf, count); - - return r; -} - -/** Similar to pa_read(), but handles writes */ -ssize_t pa_write(int fd, const void *buf, size_t count) { - ssize_t r; - -#ifdef OS_IS_WIN32 - r = send(fd, buf, count, 0); - if (r < 0) { - if (WSAGetLastError() != WSAENOTSOCK) { - errno = WSAGetLastError(); - return r; - } - } - - if (r < 0) -#endif - r = write(fd, buf, count); - - return r; -} - -/** Calls read() in a loop. Makes sure that as much as 'size' bytes, - * unless EOF is reached or an error occured */ -ssize_t pa_loop_read(int fd, void*data, size_t size) { - ssize_t ret = 0; - assert(fd >= 0 && data && size); - - while (size > 0) { - ssize_t r; - - if ((r = pa_read(fd, data, size)) < 0) - return r; - - if (r == 0) - break; - - ret += r; - data = (uint8_t*) data + r; - size -= r; - } - - return ret; -} - -/** Similar to pa_loop_read(), but wraps write() */ -ssize_t pa_loop_write(int fd, const void*data, size_t size) { - ssize_t ret = 0; - assert(fd >= 0 && data && size); - - while (size > 0) { - ssize_t r; - - if ((r = pa_write(fd, data, size)) < 0) - return r; - - if (r == 0) - break; - - ret += r; - data = (const uint8_t*) data + r; - size -= r; - } - - return ret; -} - -/* Print a warning messages in case that the given signal is not - * blocked or trapped */ -void pa_check_signal_is_blocked(int sig) { -#ifdef HAVE_SIGACTION - struct sigaction sa; - sigset_t set; - - /* If POSIX threads are supported use thread-aware - * pthread_sigmask() function, to check if the signal is - * blocked. Otherwise fall back to sigprocmask() */ - -#ifdef HAVE_PTHREAD - if (pthread_sigmask(SIG_SETMASK, NULL, &set) < 0) { -#endif - if (sigprocmask(SIG_SETMASK, NULL, &set) < 0) { - pa_log(__FILE__": sigprocmask(): %s", pa_cstrerror(errno)); - return; - } -#ifdef HAVE_PTHREAD - } -#endif - - if (sigismember(&set, sig)) - return; - - /* Check whether the signal is trapped */ - - if (sigaction(sig, NULL, &sa) < 0) { - pa_log(__FILE__": sigaction(): %s", pa_cstrerror(errno)); - return; - } - - if (sa.sa_handler != SIG_DFL) - return; - - pa_log(__FILE__": WARNING: %s is not trapped. This might cause malfunction!", pa_strsignal(sig)); -#else /* HAVE_SIGACTION */ - pa_log(__FILE__": WARNING: %s might not be trapped. This might cause malfunction!", pa_strsignal(sig)); -#endif -} - -/* The following function is based on an example from the GNU libc - * documentation. This function is similar to GNU's asprintf(). */ -char *pa_sprintf_malloc(const char *format, ...) { - int size = 100; - char *c = NULL; - - assert(format); - - for(;;) { - int r; - va_list ap; - - c = pa_xrealloc(c, size); - - va_start(ap, format); - r = vsnprintf(c, size, format, ap); - va_end(ap); - - if (r > -1 && r < size) - return c; - - if (r > -1) /* glibc 2.1 */ - size = r+1; - else /* glibc 2.0 */ - size *= 2; - } -} - -/* Same as the previous function, but use a va_list instead of an - * ellipsis */ -char *pa_vsprintf_malloc(const char *format, va_list ap) { - int size = 100; - char *c = NULL; - - assert(format); - - for(;;) { - int r; - va_list aq; - - va_copy(aq, ap); - - c = pa_xrealloc(c, size); - r = vsnprintf(c, size, format, aq); - - va_end(aq); - - if (r > -1 && r < size) - return c; - - if (r > -1) /* glibc 2.1 */ - size = r+1; - else /* glibc 2.0 */ - size *= 2; - } -} - -/* Similar to OpenBSD's strlcpy() function */ -char *pa_strlcpy(char *b, const char *s, size_t l) { - assert(b && s && l > 0); - - strncpy(b, s, l); - b[l-1] = 0; - return b; -} - -#define NICE_LEVEL (-15) - -/* Raise the priority of the current process as much as possible and -sensible: set the nice level to -15 and enable realtime scheduling if -supported.*/ -void pa_raise_priority(void) { - -#ifdef HAVE_SYS_RESOURCE_H - if (setpriority(PRIO_PROCESS, 0, NICE_LEVEL) < 0) - pa_log_warn(__FILE__": setpriority(): %s", pa_cstrerror(errno)); - else - pa_log_info(__FILE__": Successfully gained nice level %i.", NICE_LEVEL); -#endif - -#ifdef _POSIX_PRIORITY_SCHEDULING - { - struct sched_param sp; - - if (sched_getparam(0, &sp) < 0) { - pa_log(__FILE__": sched_getparam(): %s", pa_cstrerror(errno)); - return; - } - - sp.sched_priority = 1; - if (sched_setscheduler(0, SCHED_FIFO, &sp) < 0) { - pa_log_warn(__FILE__": sched_setscheduler(): %s", pa_cstrerror(errno)); - return; - } - - pa_log_info(__FILE__": Successfully enabled SCHED_FIFO scheduling."); - } -#endif - -#ifdef OS_IS_WIN32 - if (!SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) - pa_log_warn(__FILE__": SetPriorityClass() failed: 0x%08X", GetLastError()); - else - pa_log_info(__FILE__": Successfully gained high priority class."); -#endif -} - -/* Reset the priority to normal, inverting the changes made by pa_raise_priority() */ -void pa_reset_priority(void) { -#ifdef OS_IS_WIN32 - SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); -#endif - -#ifdef _POSIX_PRIORITY_SCHEDULING - { - struct sched_param sp; - sched_getparam(0, &sp); - sp.sched_priority = 0; - sched_setscheduler(0, SCHED_OTHER, &sp); - } -#endif - -#ifdef HAVE_SYS_RESOURCE_H - setpriority(PRIO_PROCESS, 0, 0); -#endif -} - -/* Set the FD_CLOEXEC flag for a fd */ -int pa_fd_set_cloexec(int fd, int b) { - -#ifdef FD_CLOEXEC - int v; - assert(fd >= 0); - - if ((v = fcntl(fd, F_GETFD, 0)) < 0) - return -1; - - v = (v & ~FD_CLOEXEC) | (b ? FD_CLOEXEC : 0); - - if (fcntl(fd, F_SETFD, v) < 0) - return -1; -#endif - - return 0; -} - -/* Try to parse a boolean string value.*/ -int pa_parse_boolean(const char *v) { - - if (!strcmp(v, "1") || v[0] == 'y' || v[0] == 'Y' || v[0] == 't' || v[0] == 'T' || !strcasecmp(v, "on")) - return 1; - else if (!strcmp(v, "0") || v[0] == 'n' || v[0] == 'N' || v[0] == 'f' || v[0] == 'F' || !strcasecmp(v, "off")) - return 0; - - return -1; -} - -/* Split the specified string wherever one of the strings in delimiter - * occurs. Each time it is called returns a newly allocated string - * with pa_xmalloc(). The variable state points to, should be - * initiallized to NULL before the first call. */ -char *pa_split(const char *c, const char *delimiter, const char**state) { - const char *current = *state ? *state : c; - size_t l; - - if (!*current) - return NULL; - - l = strcspn(current, delimiter); - *state = current+l; - - if (**state) - (*state)++; - - return pa_xstrndup(current, l); -} - -/* What is interpreted as whitespace? */ -#define WHITESPACE " \t\n" - -/* Split a string into words. Otherwise similar to pa_split(). */ -char *pa_split_spaces(const char *c, const char **state) { - const char *current = *state ? *state : c; - size_t l; - - if (!*current || *c == 0) - return NULL; - - current += strspn(current, WHITESPACE); - l = strcspn(current, WHITESPACE); - - *state = current+l; - - return pa_xstrndup(current, l); -} - -/* Return the name of an UNIX signal. Similar to GNU's strsignal() */ -const char *pa_strsignal(int sig) { - switch(sig) { - case SIGINT: return "SIGINT"; - case SIGTERM: return "SIGTERM"; -#ifdef SIGUSR1 - case SIGUSR1: return "SIGUSR1"; -#endif -#ifdef SIGUSR2 - case SIGUSR2: return "SIGUSR2"; -#endif -#ifdef SIGXCPU - case SIGXCPU: return "SIGXCPU"; -#endif -#ifdef SIGPIPE - case SIGPIPE: return "SIGPIPE"; -#endif -#ifdef SIGCHLD - case SIGCHLD: return "SIGCHLD"; -#endif -#ifdef SIGHUP - case SIGHUP: return "SIGHUP"; -#endif - default: return "UNKNOWN SIGNAL"; - } -} - -#ifdef HAVE_GRP_H - -/* Check whether the specified GID and the group name match */ -static int is_group(gid_t gid, const char *name) { - struct group group, *result = NULL; - long n; - void *data; - int r = -1; - -#ifdef HAVE_GETGRGID_R -#ifdef _SC_GETGR_R_SIZE_MAX - n = sysconf(_SC_GETGR_R_SIZE_MAX); -#else - n = -1; -#endif - if (n < 0) n = 512; - data = pa_xmalloc(n); - - if (getgrgid_r(gid, &group, data, n, &result) < 0 || !result) { - pa_log(__FILE__": getgrgid_r(%u): %s", (unsigned)gid, pa_cstrerror(errno)); - goto finish; - } - - r = strcmp(name, result->gr_name) == 0; - -finish: - pa_xfree(data); -#else - /* XXX Not thread-safe, but needed on OSes (e.g. FreeBSD 4.X) that do not - * support getgrgid_r. */ - if ((result = getgrgid(gid)) == NULL) { - pa_log(__FILE__": getgrgid(%u): %s", gid, pa_cstrerror(errno)); - goto finish; - } - - r = strcmp(name, result->gr_name) == 0; - -finish: -#endif - - return r; -} - -/* Check the current user is member of the specified group */ -int pa_own_uid_in_group(const char *name, gid_t *gid) { - GETGROUPS_T *gids, tgid; - int n = sysconf(_SC_NGROUPS_MAX); - int r = -1, i; - - assert(n > 0); - - gids = pa_xmalloc(sizeof(GETGROUPS_T)*n); - - if ((n = getgroups(n, gids)) < 0) { - pa_log(__FILE__": getgroups(): %s", pa_cstrerror(errno)); - goto finish; - } - - for (i = 0; i < n; i++) { - if (is_group(gids[i], name) > 0) { - *gid = gids[i]; - r = 1; - goto finish; - } - } - - if (is_group(tgid = getgid(), name) > 0) { - *gid = tgid; - r = 1; - goto finish; - } - - r = 0; - -finish: - - pa_xfree(gids); - return r; -} - -int pa_uid_in_group(uid_t uid, const char *name) { - char *g_buf, *p_buf; - long g_n, p_n; - struct group grbuf, *gr; - char **i; - int r = -1; - - g_n = sysconf(_SC_GETGR_R_SIZE_MAX); - g_buf = pa_xmalloc(g_n); - - p_n = sysconf(_SC_GETPW_R_SIZE_MAX); - p_buf = pa_xmalloc(p_n); - - if (getgrnam_r(name, &grbuf, g_buf, (size_t) g_n, &gr) != 0 || !gr) - goto finish; - - r = 0; - for (i = gr->gr_mem; *i; i++) { - struct passwd pwbuf, *pw; - - if (getpwnam_r(*i, &pwbuf, p_buf, (size_t) p_n, &pw) != 0 || !pw) - continue; - - if (pw->pw_uid == uid) { - r = 1; - break; - } - } - -finish: - pa_xfree(g_buf); - pa_xfree(p_buf); - - return r; -} - -#else /* HAVE_GRP_H */ - -int pa_own_uid_in_group(const char *name, gid_t *gid) { - return -1; - -} - -int pa_uid_in_group(uid_t uid, const char *name) { - return -1; -} - -#endif - -/* Lock or unlock a file entirely. - (advisory on UNIX, mandatory on Windows) */ -int pa_lock_fd(int fd, int b) { -#ifdef F_SETLKW - struct flock flock; - - /* Try a R/W lock first */ - - flock.l_type = b ? F_WRLCK : F_UNLCK; - flock.l_whence = SEEK_SET; - flock.l_start = 0; - flock.l_len = 0; - - if (fcntl(fd, F_SETLKW, &flock) >= 0) - return 0; - - /* Perhaps the file descriptor qas opened for read only, than try again with a read lock. */ - if (b && errno == EBADF) { - flock.l_type = F_RDLCK; - if (fcntl(fd, F_SETLKW, &flock) >= 0) - return 0; - } - - pa_log(__FILE__": %slock: %s", !b? "un" : "", - pa_cstrerror(errno)); -#endif - -#ifdef OS_IS_WIN32 - HANDLE h = (HANDLE)_get_osfhandle(fd); - - if (b && LockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF)) - return 0; - if (!b && UnlockFile(h, 0, 0, 0xFFFFFFFF, 0xFFFFFFFF)) - return 0; - - pa_log(__FILE__": %slock failed: 0x%08X", !b ? "un" : "", GetLastError()); -#endif - - return -1; -} - -/* Remove trailing newlines from a string */ -char* pa_strip_nl(char *s) { - assert(s); - - s[strcspn(s, "\r\n")] = 0; - return s; -} - -/* Create a temporary lock file and lock it. */ -int pa_lock_lockfile(const char *fn) { - int fd = -1; - assert(fn); - - for (;;) { - struct stat st; - - if ((fd = open(fn, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR)) < 0) { - pa_log(__FILE__": failed to create lock file '%s': %s", fn, - pa_cstrerror(errno)); - goto fail; - } - - if (pa_lock_fd(fd, 1) < 0) { - pa_log(__FILE__": failed to lock file '%s'.", fn); - goto fail; - } - - if (fstat(fd, &st) < 0) { - pa_log(__FILE__": failed to fstat() file '%s'.", fn); - goto fail; - } - - /* Check wheter the file has been removed meanwhile. When yes, restart this loop, otherwise, we're done */ - if (st.st_nlink >= 1) - break; - - if (pa_lock_fd(fd, 0) < 0) { - pa_log(__FILE__": failed to unlock file '%s'.", fn); - goto fail; - } - - if (close(fd) < 0) { - pa_log(__FILE__": failed to close file '%s'.", fn); - goto fail; - } - - fd = -1; - } - - return fd; - -fail: - - if (fd >= 0) - close(fd); - - return -1; -} - -/* Unlock a temporary lcok file */ -int pa_unlock_lockfile(const char *fn, int fd) { - int r = 0; - assert(fn && fd >= 0); - - if (unlink(fn) < 0) { - pa_log_warn(__FILE__": WARNING: unable to remove lock file '%s': %s", - fn, pa_cstrerror(errno)); - r = -1; - } - - if (pa_lock_fd(fd, 0) < 0) { - pa_log_warn(__FILE__": WARNING: failed to unlock file '%s'.", fn); - r = -1; - } - - if (close(fd) < 0) { - pa_log_warn(__FILE__": WARNING: failed to close lock file '%s': %s", - fn, pa_cstrerror(errno)); - r = -1; - } - - return r; -} - -/* Try to open a configuration file. If "env" is specified, open the - * value of the specified environment variable. Otherwise look for a - * file "local" in the home directory or a file "global" in global - * file system. If "result" is non-NULL, a pointer to a newly - * allocated buffer containing the used configuration file is - * stored there.*/ -FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result, const char *mode) { - const char *fn; - char h[PATH_MAX]; - -#ifdef OS_IS_WIN32 - char buf[PATH_MAX]; - - if (!getenv(POLYP_ROOTENV)) - pa_set_root(NULL); -#endif - - if (env && (fn = getenv(env))) { -#ifdef OS_IS_WIN32 - if (!ExpandEnvironmentStrings(fn, buf, PATH_MAX)) - return NULL; - fn = buf; -#endif - - if (result) - *result = pa_xstrdup(fn); - - return fopen(fn, mode); - } - - if (local && pa_get_home_dir(h, sizeof(h))) { - FILE *f; - char *lfn; - - fn = lfn = pa_sprintf_malloc("%s/%s", h, local); - -#ifdef OS_IS_WIN32 - if (!ExpandEnvironmentStrings(lfn, buf, PATH_MAX)) - return NULL; - fn = buf; -#endif - - f = fopen(fn, mode); - - if (f || errno != ENOENT) { - if (result) - *result = pa_xstrdup(fn); - pa_xfree(lfn); - return f; - } - - pa_xfree(lfn); - } - - if (!global) { - if (result) - *result = NULL; - errno = ENOENT; - return NULL; - } - -#ifdef OS_IS_WIN32 - if (!ExpandEnvironmentStrings(global, buf, PATH_MAX)) - return NULL; - global = buf; -#endif - - if (result) - *result = pa_xstrdup(global); - - return fopen(global, mode); -} - -/* Format the specified data as a hexademical string */ -char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength) { - size_t i = 0, j = 0; - const char hex[] = "0123456789abcdef"; - assert(d && s && slength > 0); - - while (i < dlength && j+3 <= slength) { - s[j++] = hex[*d >> 4]; - s[j++] = hex[*d & 0xF]; - - d++; - i++; - } - - s[j < slength ? j : slength] = 0; - return s; -} - -/* Convert a hexadecimal digit to a number or -1 if invalid */ -static int hexc(char c) { - if (c >= '0' && c <= '9') - return c - '0'; - - if (c >= 'A' && c <= 'F') - return c - 'A' + 10; - - if (c >= 'a' && c <= 'f') - return c - 'a' + 10; - - return -1; -} - -/* Parse a hexadecimal string as created by pa_hexstr() to a BLOB */ -size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength) { - size_t j = 0; - assert(p && d); - - while (j < dlength && *p) { - int b; - - if ((b = hexc(*(p++))) < 0) - return (size_t) -1; - - d[j] = (uint8_t) (b << 4); - - if (!*p) - return (size_t) -1; - - if ((b = hexc(*(p++))) < 0) - return (size_t) -1; - - d[j] |= (uint8_t) b; - j++; - } - - return j; -} - -/* Returns nonzero when *s starts with *pfx */ -int pa_startswith(const char *s, const char *pfx) { - size_t l; - - assert(s); - assert(pfx); - - l = strlen(pfx); - - return strlen(s) >= l && strncmp(s, pfx, l) == 0; -} - -/* Returns nonzero when *s ends with *sfx */ -int pa_endswith(const char *s, const char *sfx) { - size_t l1, l2; - - assert(s); - assert(sfx); - - l1 = strlen(s); - l2 = strlen(sfx); - - return l1 >= l2 && strcmp(s+l1-l2, sfx) == 0; -} - -/* if fn is null return the polypaudio run time path in s (/tmp/polypaudio) - * if fn is non-null and starts with / return fn in s - * otherwise append fn to the run time path and return it in s */ -char *pa_runtime_path(const char *fn, char *s, size_t l) { - char u[256]; - -#ifndef OS_IS_WIN32 - if (fn && *fn == '/') -#else - if (fn && strlen(fn) >= 3 && isalpha(fn[0]) && fn[1] == ':' && fn[2] == '\\') -#endif - return pa_strlcpy(s, fn, l); - - if (fn) - snprintf(s, l, "%s%s%c%s", PA_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u)), PATH_SEP, fn); - else - snprintf(s, l, "%s%s", PA_RUNTIME_PATH_PREFIX, pa_get_user_name(u, sizeof(u))); - -#ifdef OS_IS_WIN32 - { - char buf[l]; - strcpy(buf, s); - ExpandEnvironmentStrings(buf, s, l); - } -#endif - - return s; -} - -/* Convert the string s to a signed integer in *ret_i */ -int pa_atoi(const char *s, int32_t *ret_i) { - char *x = NULL; - long l; - assert(s && ret_i); - - l = strtol(s, &x, 0); - - if (!x || *x) - return -1; - - *ret_i = (int32_t) l; - - return 0; -} - -/* Convert the string s to an unsigned integer in *ret_u */ -int pa_atou(const char *s, uint32_t *ret_u) { - char *x = NULL; - unsigned long l; - assert(s && ret_u); - - l = strtoul(s, &x, 0); - - if (!x || *x) - return -1; - - *ret_u = (uint32_t) l; - - return 0; -} diff --git a/src/polypcore/core-util.h b/src/polypcore/core-util.h deleted file mode 100644 index 989f8c16..00000000 --- a/src/polypcore/core-util.h +++ /dev/null @@ -1,88 +0,0 @@ -#ifndef foocoreutilhfoo -#define foocoreutilhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <sys/types.h> -#include <inttypes.h> -#include <stdarg.h> -#include <stdio.h> - -#include <polypcore/gccmacro.h> - -struct timeval; - -void pa_make_nonblock_fd(int fd); - -int pa_make_secure_dir(const char* dir); -int pa_make_secure_parent_dir(const char *fn); - -ssize_t pa_read(int fd, void *buf, size_t count); -ssize_t pa_write(int fd, const void *buf, size_t count); -ssize_t pa_loop_read(int fd, void*data, size_t size); -ssize_t pa_loop_write(int fd, const void*data, size_t size); - -void pa_check_signal_is_blocked(int sig); - -char *pa_sprintf_malloc(const char *format, ...) PA_GCC_PRINTF_ATTR(1,2); -char *pa_vsprintf_malloc(const char *format, va_list ap); - -char *pa_strlcpy(char *b, const char *s, size_t l); - -char *pa_parent_dir(const char *fn); - -void pa_raise_priority(void); -void pa_reset_priority(void); - -int pa_fd_set_cloexec(int fd, int b); - -int pa_parse_boolean(const char *s); - -char *pa_split(const char *c, const char*delimiters, const char **state); -char *pa_split_spaces(const char *c, const char **state); - -char *pa_strip_nl(char *s); - -const char *pa_strsignal(int sig); - -int pa_own_uid_in_group(const char *name, gid_t *gid); -int pa_uid_in_group(uid_t uid, const char *name); - -int pa_lock_fd(int fd, int b); - -int pa_lock_lockfile(const char *fn); -int pa_unlock_lockfile(const char *fn, int fd); - -FILE *pa_open_config_file(const char *global, const char *local, const char *env, char **result, const char *mode); - -char *pa_hexstr(const uint8_t* d, size_t dlength, char *s, size_t slength); -size_t pa_parsehex(const char *p, uint8_t *d, size_t dlength); - -int pa_startswith(const char *s, const char *pfx); -int pa_endswith(const char *s, const char *sfx); - -char *pa_runtime_path(const char *fn, char *s, size_t l); - -int pa_atoi(const char *s, int32_t *ret_i); -int pa_atou(const char *s, uint32_t *ret_u); - -#endif diff --git a/src/polypcore/core.c b/src/polypcore/core.c deleted file mode 100644 index 09d023dc..00000000 --- a/src/polypcore/core.c +++ /dev/null @@ -1,160 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <assert.h> -#include <stdio.h> -#include <signal.h> - -#include <polyp/timeval.h> -#include <polyp/xmalloc.h> - -#include <polypcore/module.h> -#include <polypcore/sink.h> -#include <polypcore/source.h> -#include <polypcore/namereg.h> -#include <polypcore/core-util.h> -#include <polypcore/core-scache.h> -#include <polypcore/autoload.h> -#include <polypcore/core-subscribe.h> -#include <polypcore/props.h> -#include <polypcore/random.h> - -#include "core.h" - -pa_core* pa_core_new(pa_mainloop_api *m) { - pa_core* c; - c = pa_xmalloc(sizeof(pa_core)); - - c->mainloop = m; - c->clients = pa_idxset_new(NULL, NULL); - c->sinks = pa_idxset_new(NULL, NULL); - c->sources = pa_idxset_new(NULL, NULL); - c->source_outputs = pa_idxset_new(NULL, NULL); - c->sink_inputs = pa_idxset_new(NULL, NULL); - - c->default_source_name = c->default_sink_name = NULL; - - c->modules = NULL; - c->namereg = NULL; - c->scache = NULL; - c->autoload_idxset = NULL; - c->autoload_hashmap = NULL; - c->running_as_daemon = 0; - - c->default_sample_spec.format = PA_SAMPLE_S16NE; - c->default_sample_spec.rate = 44100; - c->default_sample_spec.channels = 2; - - c->module_auto_unload_event = NULL; - c->module_defer_unload_event = NULL; - c->scache_auto_unload_event = NULL; - - c->subscription_defer_event = NULL; - c->subscription_event_queue = NULL; - c->subscriptions = NULL; - - c->memblock_stat = pa_memblock_stat_new(); - - c->disallow_module_loading = 0; - - c->quit_event = NULL; - - c->exit_idle_time = -1; - c->module_idle_time = 20; - c->scache_idle_time = 20; - - c->resample_method = PA_RESAMPLER_SRC_SINC_FASTEST; - - pa_property_init(c); - - pa_random(&c->cookie, sizeof(c->cookie)); - -#ifdef SIGPIPE - pa_check_signal_is_blocked(SIGPIPE); -#endif - return c; -} - -void pa_core_free(pa_core *c) { - assert(c); - - pa_module_unload_all(c); - assert(!c->modules); - - assert(pa_idxset_isempty(c->clients)); - pa_idxset_free(c->clients, NULL, NULL); - - assert(pa_idxset_isempty(c->sinks)); - pa_idxset_free(c->sinks, NULL, NULL); - - assert(pa_idxset_isempty(c->sources)); - pa_idxset_free(c->sources, NULL, NULL); - - assert(pa_idxset_isempty(c->source_outputs)); - pa_idxset_free(c->source_outputs, NULL, NULL); - - assert(pa_idxset_isempty(c->sink_inputs)); - pa_idxset_free(c->sink_inputs, NULL, NULL); - - pa_scache_free(c); - pa_namereg_free(c); - pa_autoload_free(c); - pa_subscription_free_all(c); - - if (c->quit_event) - c->mainloop->time_free(c->quit_event); - - pa_xfree(c->default_source_name); - pa_xfree(c->default_sink_name); - - pa_memblock_stat_unref(c->memblock_stat); - - pa_property_cleanup(c); - - pa_xfree(c); -} - -static void quit_callback(pa_mainloop_api*m, pa_time_event *e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { - pa_core *c = userdata; - assert(c->quit_event = e); - - m->quit(m, 0); -} - -void pa_core_check_quit(pa_core *c) { - assert(c); - - if (!c->quit_event && c->exit_idle_time >= 0 && pa_idxset_size(c->clients) == 0) { - struct timeval tv; - pa_gettimeofday(&tv); - tv.tv_sec+= c->exit_idle_time; - c->quit_event = c->mainloop->time_new(c->mainloop, &tv, quit_callback, c); - } else if (c->quit_event && pa_idxset_size(c->clients) > 0) { - c->mainloop->time_free(c->quit_event); - c->quit_event = NULL; - } -} - diff --git a/src/polypcore/core.h b/src/polypcore/core.h deleted file mode 100644 index a323ae8e..00000000 --- a/src/polypcore/core.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef foocorehfoo -#define foocorehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef struct pa_core pa_core; - -#include <polypcore/idxset.h> -#include <polypcore/hashmap.h> -#include <polyp/mainloop-api.h> -#include <polyp/sample.h> -#include <polypcore/memblock.h> -#include <polypcore/resampler.h> -#include <polypcore/queue.h> -#include <polypcore/core-subscribe.h> - -/* The core structure of polypaudio. Every polypaudio daemon contains - * exactly one of these. It is used for storing kind of global - * variables for the daemon. */ - -struct pa_core { - /* A random value which may be used to identify this instance of - * polypaudio. Not cryptographically secure in any way. */ - uint32_t cookie; - - pa_mainloop_api *mainloop; - - /* idxset of all kinds of entities */ - pa_idxset *clients, *sinks, *sources, *sink_inputs, *source_outputs, *modules, *scache, *autoload_idxset; - - /* Some hashmaps for all sorts of entities */ - pa_hashmap *namereg, *autoload_hashmap, *properties; - - /* The name of the default sink/source */ - char *default_source_name, *default_sink_name; - - pa_sample_spec default_sample_spec; - pa_time_event *module_auto_unload_event; - pa_defer_event *module_defer_unload_event; - - pa_defer_event *subscription_defer_event; - pa_queue *subscription_event_queue; - pa_subscription *subscriptions; - - pa_memblock_stat *memblock_stat; - - int disallow_module_loading, running_as_daemon; - int exit_idle_time, module_idle_time, scache_idle_time; - - pa_time_event *quit_event; - - pa_time_event *scache_auto_unload_event; - - pa_resample_method_t resample_method; -}; - -pa_core* pa_core_new(pa_mainloop_api *m); -void pa_core_free(pa_core*c); - -/* Check whether noone is connected to this core */ -void pa_core_check_quit(pa_core *c); - -#endif diff --git a/src/polypcore/dllmain.c b/src/polypcore/dllmain.c deleted file mode 100644 index 95473b06..00000000 --- a/src/polypcore/dllmain.c +++ /dev/null @@ -1,55 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#ifdef OS_IS_WIN32 - -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <windows.h> - -extern pa_set_root(HANDLE handle); - -BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { - WSADATA data; - - switch (fdwReason) { - - case DLL_PROCESS_ATTACH: - if (!pa_set_root(hinstDLL)) - return FALSE; - WSAStartup(MAKEWORD(2, 0), &data); - break; - - case DLL_PROCESS_DETACH: - WSACleanup(); - break; - - } - return TRUE; -} - -#endif /* OS_IS_WIN32 */ diff --git a/src/polypcore/dynarray.c b/src/polypcore/dynarray.c deleted file mode 100644 index 234c2c03..00000000 --- a/src/polypcore/dynarray.c +++ /dev/null @@ -1,103 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <assert.h> -#include <stdlib.h> - -#include <polyp/xmalloc.h> - -#include "dynarray.h" - -/* If the array becomes to small, increase its size by 100 entries */ -#define INCREASE_BY 100 - -struct pa_dynarray { - void **data; - unsigned n_allocated, n_entries; -}; - -pa_dynarray* pa_dynarray_new(void) { - pa_dynarray *a; - a = pa_xnew(pa_dynarray, 1); - a->data = NULL; - a->n_entries = 0; - a->n_allocated = 0; - return a; -} - -void pa_dynarray_free(pa_dynarray* a, void (*func)(void *p, void *userdata), void *userdata) { - unsigned i; - assert(a); - - if (func) - for (i = 0; i < a->n_entries; i++) - if (a->data[i]) - func(a->data[i], userdata); - - pa_xfree(a->data); - pa_xfree(a); -} - -void pa_dynarray_put(pa_dynarray*a, unsigned i, void *p) { - assert(a); - - if (i >= a->n_allocated) { - unsigned n; - - if (!p) - return; - - n = i+INCREASE_BY; - a->data = pa_xrealloc(a->data, sizeof(void*)*n); - memset(a->data+a->n_allocated, 0, sizeof(void*)*(n-a->n_allocated)); - a->n_allocated = n; - } - - a->data[i] = p; - - if (i >= a->n_entries) - a->n_entries = i+1; -} - -unsigned pa_dynarray_append(pa_dynarray*a, void *p) { - unsigned i = a->n_entries; - pa_dynarray_put(a, i, p); - return i; -} - -void *pa_dynarray_get(pa_dynarray*a, unsigned i) { - assert(a); - if (i >= a->n_allocated) - return NULL; - - assert(a->data); - return a->data[i]; -} - -unsigned pa_dynarray_size(pa_dynarray*a) { - assert(a); - return a->n_entries; -} diff --git a/src/polypcore/dynarray.h b/src/polypcore/dynarray.h deleted file mode 100644 index 9b1601ba..00000000 --- a/src/polypcore/dynarray.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef foodynarrayhfoo -#define foodynarrayhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef struct pa_dynarray pa_dynarray; - -/* Implementation of a simple dynamically sized array. The array - * expands if required, but doesn't shrink if possible. Memory - * management of the array's entries is the user's job. */ - -pa_dynarray* pa_dynarray_new(void); - -/* Free the array calling the specified function for every entry in - * the array. The function may be NULL. */ -void pa_dynarray_free(pa_dynarray* a, void (*func)(void *p, void *userdata), void *userdata); - -/* Store p at position i in the array */ -void pa_dynarray_put(pa_dynarray*a, unsigned i, void *p); - -/* Store p a the first free position in the array. Returns the index - * of that entry. If entries are removed from the array their position - * are not filled any more by this function. */ -unsigned pa_dynarray_append(pa_dynarray*a, void *p); - -void *pa_dynarray_get(pa_dynarray*a, unsigned i); - -unsigned pa_dynarray_size(pa_dynarray*a); - -#endif diff --git a/src/polypcore/endianmacros.h b/src/polypcore/endianmacros.h deleted file mode 100644 index 3ab1826a..00000000 --- a/src/polypcore/endianmacros.h +++ /dev/null @@ -1,77 +0,0 @@ -#ifndef fooendianmacroshfoo -#define fooendianmacroshfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#define INT16_SWAP(x) ( (int16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) -#define UINT16_SWAP(x) ( (uint16_t) ( ((uint16_t) x >> 8) | ((uint16_t) x << 8) ) ) -#define INT32_SWAP(x) ( (int32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) -#define UINT32_SWAP(x) ( (uint32_t) ( ((uint32_t) x >> 24) | ((uint32_t) x << 24) | (((uint32_t) x & 0xFF00) << 8) | ((((uint32_t) x) >> 8) & 0xFF00) ) ) - -#define MAYBE_INT32_SWAP(c,x) ((c) ? INT32_SWAP(x) : x) -#define MAYBE_UINT32_SWAP(c,x) ((c) ? UINT32_SWAP(x) : x) - -#ifdef WORDS_BIGENDIAN - #define INT16_FROM_LE(x) INT16_SWAP(x) - #define INT16_FROM_BE(x) ((int16_t)(x)) - - #define INT16_TO_LE(x) INT16_SWAP(x) - #define INT16_TO_BE(x) ((int16_t)(x)) - - #define UINT16_FROM_LE(x) UINT16_SWAP(x) - #define UINT16_FROM_BE(x) ((uint16_t)(x)) - - #define INT32_FROM_LE(x) INT32_SWAP(x) - #define INT32_FROM_BE(x) ((int32_t)(x)) - - #define UINT32_FROM_LE(x) UINT32_SWAP(x) - #define UINT32_FROM_BE(x) ((uint32_t)(x)) - - #define UINT32_TO_LE(x) UINT32_SWAP(x) - #define UINT32_TO_BE(x) ((uint32_t)(x)) -#else - #define INT16_FROM_LE(x) ((int16_t)(x)) - #define INT16_FROM_BE(x) INT16_SWAP(x) - - #define INT16_TO_LE(x) ((int16_t)(x)) - #define INT16_TO_BE(x) INT16_SWAP(x) - - #define UINT16_FROM_LE(x) ((uint16_t)(x)) - #define UINT16_FROM_BE(x) UINT16_SWAP(x) - - #define INT32_FROM_LE(x) ((int32_t)(x)) - #define INT32_FROM_BE(x) INT32_SWAP(x) - - #define UINT32_FROM_LE(x) ((uint32_t)(x)) - #define UINT32_FROM_BE(x) UINT32_SWAP(x) - - #define UINT32_TO_LE(x) ((uint32_t)(x)) - #define UINT32_TO_BE(x) UINT32_SWAP(x) -#endif - -#endif diff --git a/src/polypcore/esound.h b/src/polypcore/esound.h deleted file mode 100644 index 9c507ef9..00000000 --- a/src/polypcore/esound.h +++ /dev/null @@ -1,209 +0,0 @@ -#ifndef fooesoundhfoo -#define fooesoundhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -/* Most of the following is blatantly stolen from esound. */ - - -/* path and name of the default EsounD domain socket */ -#define ESD_UNIX_SOCKET_DIR "/tmp/.esd" -#define ESD_UNIX_SOCKET_NAME "/tmp/.esd/socket" - -/* length of the audio buffer size */ -#define ESD_BUF_SIZE (4 * 1024) -/* maximum size we can write(). Otherwise we might overflow */ -#define ESD_MAX_WRITE_SIZE (21 * 4096) - -/* length of the authorization key, octets */ -#define ESD_KEY_LEN (16) - -/* default port for the EsounD server */ -#define ESD_DEFAULT_PORT (16001) - -/* default sample rate for the EsounD server */ -#define ESD_DEFAULT_RATE (44100) - -/* maximum length of a stream/sample name */ -#define ESD_NAME_MAX (128) - -/* a magic number to identify the relative endianness of a client */ -#define ESD_ENDIAN_KEY ((uint32_t) (('E' << 24) + ('N' << 16) + ('D' << 8) + ('N'))) - -#define ESD_VOLUME_BASE (256) - - -/*************************************/ -/* what can we do to/with the EsounD */ -enum esd_proto { - ESD_PROTO_CONNECT, /* implied on inital client connection */ - - /* pseudo "security" functionality */ - ESD_PROTO_LOCK, /* disable "foreign" client connections */ - ESD_PROTO_UNLOCK, /* enable "foreign" client connections */ - - /* stream functionality: play, record, monitor */ - ESD_PROTO_STREAM_PLAY, /* play all following data as a stream */ - ESD_PROTO_STREAM_REC, /* record data from card as a stream */ - ESD_PROTO_STREAM_MON, /* send mixed buffer output as a stream */ - - /* sample functionality: cache, free, play, loop, EOL, kill */ - ESD_PROTO_SAMPLE_CACHE, /* cache a sample in the server */ - ESD_PROTO_SAMPLE_FREE, /* release a sample in the server */ - ESD_PROTO_SAMPLE_PLAY, /* play a cached sample */ - ESD_PROTO_SAMPLE_LOOP, /* loop a cached sample, til eoloop */ - ESD_PROTO_SAMPLE_STOP, /* stop a looping sample when done */ - ESD_PROTO_SAMPLE_KILL, /* stop the looping sample immed. */ - - /* free and reclaim /dev/dsp functionality */ - ESD_PROTO_STANDBY, /* release /dev/dsp and ignore all data */ - ESD_PROTO_RESUME, /* reclaim /dev/dsp and play sounds again */ - - /* TODO: move these to a more logical place. NOTE: will break the protocol */ - ESD_PROTO_SAMPLE_GETID, /* get the ID for an already-cached sample */ - ESD_PROTO_STREAM_FILT, /* filter mixed buffer output as a stream */ - - /* esd remote management */ - ESD_PROTO_SERVER_INFO, /* get server info (ver, sample rate, format) */ - ESD_PROTO_ALL_INFO, /* get all info (server info, players, samples) */ - ESD_PROTO_SUBSCRIBE, /* track new and removed players and samples */ - ESD_PROTO_UNSUBSCRIBE, /* stop tracking updates */ - - /* esd remote control */ - ESD_PROTO_STREAM_PAN, /* set stream panning */ - ESD_PROTO_SAMPLE_PAN, /* set default sample panning */ - - /* esd status */ - ESD_PROTO_STANDBY_MODE, /* see if server is in standby, autostandby, etc */ - - /* esd latency */ - ESD_PROTO_LATENCY, /* retrieve latency between write()'s and output */ - - ESD_PROTO_MAX /* for bounds checking */ -}; - -/******************/ -/* The EsounD api */ - -/* the properties of a sound buffer are logically or'd */ - -/* bits of stream/sample data */ -#define ESD_MASK_BITS ( 0x000F ) -#define ESD_BITS8 ( 0x0000 ) -#define ESD_BITS16 ( 0x0001 ) - -/* how many interleaved channels of data */ -#define ESD_MASK_CHAN ( 0x00F0 ) -#define ESD_MONO ( 0x0010 ) -#define ESD_STEREO ( 0x0020 ) - -/* whether it's a stream or a sample */ -#define ESD_MASK_MODE ( 0x0F00 ) -#define ESD_STREAM ( 0x0000 ) -#define ESD_SAMPLE ( 0x0100 ) -#define ESD_ADPCM ( 0x0200 ) /* TODO: anyone up for this? =P */ - -/* the function of the stream/sample, and common functions */ -#define ESD_MASK_FUNC ( 0xF000 ) -#define ESD_PLAY ( 0x1000 ) -/* functions for streams only */ -#define ESD_MONITOR ( 0x0000 ) -#define ESD_RECORD ( 0x2000 ) -/* functions for samples only */ -#define ESD_STOP ( 0x0000 ) -#define ESD_LOOP ( 0x2000 ) - -typedef int esd_format_t; -typedef int esd_proto_t; - -/*******************************************************************/ -/* esdmgr.c - functions to implement a "sound manager" for esd */ - -/* structures to retrieve information about streams/samples from the server */ -typedef struct esd_server_info { - - int version; /* server version encoded as an int */ - esd_format_t format; /* magic int with the format info */ - int rate; /* sample rate */ - -} esd_server_info_t; - -typedef struct esd_player_info { - - struct esd_player_info *next; /* point to next entry in list */ - esd_server_info_t *server; /* the server that contains this stream */ - - int source_id; /* either a stream fd or sample id */ - char name[ ESD_NAME_MAX ]; /* name of stream for remote control */ - int rate; /* sample rate */ - int left_vol_scale; /* volume scaling */ - int right_vol_scale; - - esd_format_t format; /* magic int with the format info */ - -} esd_player_info_t; - -typedef struct esd_sample_info { - - struct esd_sample_info *next; /* point to next entry in list */ - esd_server_info_t *server; /* the server that contains this sample */ - - int sample_id; /* either a stream fd or sample id */ - char name[ ESD_NAME_MAX ]; /* name of stream for remote control */ - int rate; /* sample rate */ - int left_vol_scale; /* volume scaling */ - int right_vol_scale; - - esd_format_t format; /* magic int with the format info */ - int length; /* total buffer length */ - -} esd_sample_info_t; - -typedef struct esd_info { - - esd_server_info_t *server; - esd_player_info_t *player_list; - esd_sample_info_t *sample_list; - -} esd_info_t; - -enum esd_standby_mode { - ESM_ERROR, ESM_ON_STANDBY, ESM_ON_AUTOSTANDBY, ESM_RUNNING -}; -typedef int esd_standby_mode_t; - -enum esd_client_state { - ESD_STREAMING_DATA, /* data from here on is streamed data */ - ESD_CACHING_SAMPLE, /* midway through caching a sample */ - ESD_NEEDS_REQDATA, /* more data needed to complere request */ - ESD_NEXT_REQUEST, /* proceed to next request */ - ESD_CLIENT_STATE_MAX /* place holder */ -}; -typedef int esd_client_state_t; - -/* the endian key is transferred in binary, if it's read into int, */ -/* and matches ESD_ENDIAN_KEY (ENDN), then the endianness of the */ -/* server and the client match; if it's SWAP_ENDIAN_KEY, swap data */ -#define ESD_SWAP_ENDIAN_KEY (UINT32_SWAP(ESD_ENDIAN_KEY)) - - -#endif diff --git a/src/polypcore/g711.c b/src/polypcore/g711.c deleted file mode 100644 index 55a82396..00000000 --- a/src/polypcore/g711.c +++ /dev/null @@ -1,2531 +0,0 @@ -/*
- * This source code is a product of Sun Microsystems, Inc. and is provided
- * for unrestricted use. Users may copy or modify this source code without
- * charge.
- *
- * SUN SOURCE CODE IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING
- * THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
- *
- * Sun source code is provided with no support and without any obligation on
- * the part of Sun Microsystems, Inc. to assist in its use, correction,
- * modification or enhancement.
- *
- * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
- * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY THIS SOFTWARE
- * OR ANY PART THEREOF.
- *
- * In no event will Sun Microsystems, Inc. be liable for any lost revenue
- * or profits or other special, indirect and consequential damages, even if
- * Sun has been advised of the possibility of such damages.
- *
- * Sun Microsystems, Inc.
- * 2550 Garcia Avenue
- * Mountain View, California 94043
- */
-
-/*
- * g711.c
- *
- * u-law, A-law and linear PCM conversions.
- */
-
-/*
- * December 30, 1994:
- * Functions linear2alaw, linear2ulaw have been updated to correctly
- * convert unquantized 16 bit values.
- * Tables for direct u- to A-law and A- to u-law conversions have been
- * corrected.
- * Borge Lindberg, Center for PersonKommunikation, Aalborg University.
- * bli@cpk.auc.dk
- *
- */
-
-#include "g711.h"
-
-#define SIGN_BIT (0x80) /* Sign bit for a A-law byte. */
-#define QUANT_MASK (0xf) /* Quantization field mask. */
-#define NSEGS (8) /* Number of A-law segments. */
-#define SEG_SHIFT (4) /* Left shift for segment number. */
-#define SEG_MASK (0x70) /* Segment field mask. */
-
-#if !defined(FAST_ALAW_CONVERSION) || !defined(FAST_ULAW_CONVERSION)
-static int16_t seg_aend[8] = {0x1F, 0x3F, 0x7F, 0xFF,
- 0x1FF, 0x3FF, 0x7FF, 0xFFF};
-static int16_t seg_uend[8] = {0x3F, 0x7F, 0xFF, 0x1FF,
- 0x3FF, 0x7FF, 0xFFF, 0x1FFF};
-
-static int16_t search(
- int16_t val,
- int16_t *table,
- int size)
-{
- int i;
-
- for (i = 0; i < size; i++) {
- if (val <= *table++)
- return (i);
- }
- return (size);
-}
-#endif /* !FAST_*_CONVERSION */
-
-#ifndef FAST_ALAW_CONVERSION
-/*
- * linear2alaw() accepts an 13-bit signed integer and encodes it as A-law data
- * stored in a unsigned char. This function should only be called with
- * the data shifted such that it only contains information in the lower
- * 13-bits.
- *
- * Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 0000000wxyza 000wxyz
- * 0000001wxyza 001wxyz
- * 000001wxyzab 010wxyz
- * 00001wxyzabc 011wxyz
- * 0001wxyzabcd 100wxyz
- * 001wxyzabcde 101wxyz
- * 01wxyzabcdef 110wxyz
- * 1wxyzabcdefg 111wxyz
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-unsigned char st_13linear2alaw(
- int16_t pcm_val) /* 2's complement (13-bit range) */
-{
- int16_t mask;
- short seg;
- unsigned char aval;
-
- /* Have calling software do it since its already doing a shift
- * from 32-bits down to 16-bits.
- */
- /* pcm_val = pcm_val >> 3; */
-
- /* A-law using even bit inversion */
- if (pcm_val >= 0) {
- mask = 0xD5; /* sign (7th) bit = 1 */
- } else {
- mask = 0x55; /* sign bit = 0 */
- pcm_val = -pcm_val - 1;
- }
-
- /* Convert the scaled magnitude to segment number. */
- seg = search(pcm_val, seg_aend, 8);
-
- /* Combine the sign, segment, and quantization bits. */
-
- if (seg >= 8) /* out of range, return maximum value. */
- return (unsigned char) (0x7F ^ mask);
- else {
- aval = (unsigned char) seg << SEG_SHIFT;
- if (seg < 2)
- aval |= (pcm_val >> 1) & QUANT_MASK;
- else
- aval |= (pcm_val >> seg) & QUANT_MASK;
- return (aval ^ mask);
- }
-}
-
-/*
- * alaw2linear() - Convert an A-law value to 16-bit signed linear PCM
- *
- */
-int16_t st_alaw2linear16(
- unsigned char a_val)
-{
- int16_t t;
- int16_t seg;
-
- a_val ^= 0x55;
-
- t = (a_val & QUANT_MASK) << 4;
- seg = ((unsigned)a_val & SEG_MASK) >> SEG_SHIFT;
- switch (seg) {
- case 0:
- t += 8;
- break;
- case 1:
- t += 0x108;
- break;
- default:
- t += 0x108;
- t <<= seg - 1;
- }
- return ((a_val & SIGN_BIT) ? t : -t);
-}
-#endif /* !FAST_ALAW_CONVERSION */
-
-#define BIAS (0x84) /* Bias for linear code. */
-#define CLIP 8159
-
-#ifndef FAST_ULAW_CONVERSION
-/*
- * linear2ulaw() accepts a 14-bit signed integer and encodes it as u-law data
- * stored in a unsigned char. This function should only be called with
- * the data shifted such that it only contains information in the lower
- * 14-bits.
- *
- * In order to simplify the encoding process, the original linear magnitude
- * is biased by adding 33 which shifts the encoding range from (0 - 8158) to
- * (33 - 8191). The result can be seen in the following encoding table:
- *
- * Biased Linear Input Code Compressed Code
- * ------------------------ ---------------
- * 00000001wxyza 000wxyz
- * 0000001wxyzab 001wxyz
- * 000001wxyzabc 010wxyz
- * 00001wxyzabcd 011wxyz
- * 0001wxyzabcde 100wxyz
- * 001wxyzabcdef 101wxyz
- * 01wxyzabcdefg 110wxyz
- * 1wxyzabcdefgh 111wxyz
- *
- * Each biased linear code has a leading 1 which identifies the segment
- * number. The value of the segment number is equal to 7 minus the number
- * of leading 0's. The quantization interval is directly available as the
- * four bits wxyz. * The trailing bits (a - h) are ignored.
- *
- * Ordinarily the complement of the resulting code word is used for
- * transmission, and so the code word is complemented before it is returned.
- *
- * For further information see John C. Bellamy's Digital Telephony, 1982,
- * John Wiley & Sons, pps 98-111 and 472-476.
- */
-unsigned char st_14linear2ulaw(
- int16_t pcm_val) /* 2's complement (14-bit range) */
-{
- int16_t mask;
- int16_t seg;
- unsigned char uval;
-
- /* Have calling software do it since its already doing a shift
- * from 32-bits down to 16-bits.
- */
- /* pcm_val = pcm_val >> 2; */
-
- /* u-law inverts all bits */
- /* Get the sign and the magnitude of the value. */
- if (pcm_val < 0) {
- pcm_val = -pcm_val;
- mask = 0x7F;
- } else {
- mask = 0xFF;
- }
- if ( pcm_val > CLIP ) pcm_val = CLIP; /* clip the magnitude */
- pcm_val += (BIAS >> 2);
-
- /* Convert the scaled magnitude to segment number. */
- seg = search(pcm_val, seg_uend, 8);
-
- /*
- * Combine the sign, segment, quantization bits;
- * and complement the code word.
- */
- if (seg >= 8) /* out of range, return maximum value. */
- return (unsigned char) (0x7F ^ mask);
- else {
- uval = (unsigned char) (seg << 4) | ((pcm_val >> (seg + 1)) & 0xF);
- return (uval ^ mask);
- }
-
-}
-
-/*
- * ulaw2linear() - Convert a u-law value to 16-bit linear PCM
- *
- * First, a biased linear code is derived from the code word. An unbiased
- * output can then be obtained by subtracting 33 from the biased code.
- *
- * Note that this function expects to be passed the complement of the
- * original code word. This is in keeping with ISDN conventions.
- */
-int16_t st_ulaw2linear16(
- unsigned char u_val)
-{
- int16_t t;
-
- /* Complement to obtain normal u-law value. */
- u_val = ~u_val;
-
- /*
- * Extract and bias the quantization bits. Then
- * shift up by the segment number and subtract out the bias.
- */
- t = ((u_val & QUANT_MASK) << 3) + BIAS;
- t <<= ((unsigned)u_val & SEG_MASK) >> SEG_SHIFT;
-
- return ((u_val & SIGN_BIT) ? (BIAS - t) : (t - BIAS));
-}
-#endif /* !FAST_ULAW_CONVERSION */
-
-#ifdef FAST_ALAW_CONVERSION
-
-int16_t _st_alaw2linear16[256] = {
- -5504, -5248, -6016, -5760, -4480, -4224, -4992,
- -4736, -7552, -7296, -8064, -7808, -6528, -6272,
- -7040, -6784, -2752, -2624, -3008, -2880, -2240,
- -2112, -2496, -2368, -3776, -3648, -4032, -3904,
- -3264, -3136, -3520, -3392, -22016, -20992, -24064,
- -23040, -17920, -16896, -19968, -18944, -30208, -29184,
- -32256, -31232, -26112, -25088, -28160, -27136, -11008,
- -10496, -12032, -11520, -8960, -8448, -9984, -9472,
- -15104, -14592, -16128, -15616, -13056, -12544, -14080,
- -13568, -344, -328, -376, -360, -280, -264,
- -312, -296, -472, -456, -504, -488, -408,
- -392, -440, -424, -88, -72, -120, -104,
- -24, -8, -56, -40, -216, -200, -248,
- -232, -152, -136, -184, -168, -1376, -1312,
- -1504, -1440, -1120, -1056, -1248, -1184, -1888,
- -1824, -2016, -1952, -1632, -1568, -1760, -1696,
- -688, -656, -752, -720, -560, -528, -624,
- -592, -944, -912, -1008, -976, -816, -784,
- -880, -848, 5504, 5248, 6016, 5760, 4480,
- 4224, 4992, 4736, 7552, 7296, 8064, 7808,
- 6528, 6272, 7040, 6784, 2752, 2624, 3008,
- 2880, 2240, 2112, 2496, 2368, 3776, 3648,
- 4032, 3904, 3264, 3136, 3520, 3392, 22016,
- 20992, 24064, 23040, 17920, 16896, 19968, 18944,
- 30208, 29184, 32256, 31232, 26112, 25088, 28160,
- 27136, 11008, 10496, 12032, 11520, 8960, 8448,
- 9984, 9472, 15104, 14592, 16128, 15616, 13056,
- 12544, 14080, 13568, 344, 328, 376, 360,
- 280, 264, 312, 296, 472, 456, 504,
- 488, 408, 392, 440, 424, 88, 72,
- 120, 104, 24, 8, 56, 40, 216,
- 200, 248, 232, 152, 136, 184, 168,
- 1376, 1312, 1504, 1440, 1120, 1056, 1248,
- 1184, 1888, 1824, 2016, 1952, 1632, 1568,
- 1760, 1696, 688, 656, 752, 720, 560,
- 528, 624, 592, 944, 912, 1008, 976,
- 816, 784, 880, 848
-};
-
-uint8_t _st_13linear2alaw[0x2000] = {
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x3a, 0x3a, 0x3a, 0x3a,
- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
- 0x3e, 0x3e, 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3c, 0x3c, 0x3c, 0x3c,
- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x33, 0x33, 0x33, 0x33,
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35,
- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b,
- 0x6b, 0x6b, 0x6b, 0x6b, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68,
- 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x69, 0x6e, 0x6e, 0x6e, 0x6e,
- 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f, 0x6f,
- 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d,
- 0x6d, 0x6d, 0x6d, 0x6d, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62, 0x62,
- 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x60, 0x60, 0x60, 0x60,
- 0x60, 0x60, 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61, 0x61,
- 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x67, 0x67, 0x67, 0x67,
- 0x67, 0x67, 0x67, 0x67, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64, 0x64,
- 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x65, 0x7a, 0x7a, 0x7a, 0x7a,
- 0x7b, 0x7b, 0x7b, 0x7b, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x79,
- 0x7e, 0x7e, 0x7e, 0x7e, 0x7f, 0x7f, 0x7f, 0x7f, 0x7c, 0x7c, 0x7c, 0x7c,
- 0x7d, 0x7d, 0x7d, 0x7d, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x73,
- 0x70, 0x70, 0x70, 0x70, 0x71, 0x71, 0x71, 0x71, 0x76, 0x76, 0x76, 0x76,
- 0x77, 0x77, 0x77, 0x77, 0x74, 0x74, 0x74, 0x74, 0x75, 0x75, 0x75, 0x75,
- 0x4a, 0x4a, 0x4b, 0x4b, 0x48, 0x48, 0x49, 0x49, 0x4e, 0x4e, 0x4f, 0x4f,
- 0x4c, 0x4c, 0x4d, 0x4d, 0x42, 0x42, 0x43, 0x43, 0x40, 0x40, 0x41, 0x41,
- 0x46, 0x46, 0x47, 0x47, 0x44, 0x44, 0x45, 0x45, 0x5a, 0x5a, 0x5b, 0x5b,
- 0x58, 0x58, 0x59, 0x59, 0x5e, 0x5e, 0x5f, 0x5f, 0x5c, 0x5c, 0x5d, 0x5d,
- 0x52, 0x52, 0x53, 0x53, 0x50, 0x50, 0x51, 0x51, 0x56, 0x56, 0x57, 0x57,
- 0x54, 0x54, 0x55, 0x55, 0xd5, 0xd5, 0xd4, 0xd4, 0xd7, 0xd7, 0xd6, 0xd6,
- 0xd1, 0xd1, 0xd0, 0xd0, 0xd3, 0xd3, 0xd2, 0xd2, 0xdd, 0xdd, 0xdc, 0xdc,
- 0xdf, 0xdf, 0xde, 0xde, 0xd9, 0xd9, 0xd8, 0xd8, 0xdb, 0xdb, 0xda, 0xda,
- 0xc5, 0xc5, 0xc4, 0xc4, 0xc7, 0xc7, 0xc6, 0xc6, 0xc1, 0xc1, 0xc0, 0xc0,
- 0xc3, 0xc3, 0xc2, 0xc2, 0xcd, 0xcd, 0xcc, 0xcc, 0xcf, 0xcf, 0xce, 0xce,
- 0xc9, 0xc9, 0xc8, 0xc8, 0xcb, 0xcb, 0xca, 0xca, 0xf5, 0xf5, 0xf5, 0xf5,
- 0xf4, 0xf4, 0xf4, 0xf4, 0xf7, 0xf7, 0xf7, 0xf7, 0xf6, 0xf6, 0xf6, 0xf6,
- 0xf1, 0xf1, 0xf1, 0xf1, 0xf0, 0xf0, 0xf0, 0xf0, 0xf3, 0xf3, 0xf3, 0xf3,
- 0xf2, 0xf2, 0xf2, 0xf2, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfc,
- 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xf9, 0xf9, 0xf9, 0xf9,
- 0xf8, 0xf8, 0xf8, 0xf8, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa,
- 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4, 0xe4, 0xe4, 0xe4,
- 0xe4, 0xe4, 0xe4, 0xe4, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7, 0xe7,
- 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe6, 0xe1, 0xe1, 0xe1, 0xe1,
- 0xe1, 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0,
- 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2,
- 0xe2, 0xe2, 0xe2, 0xe2, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed, 0xed,
- 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xec, 0xef, 0xef, 0xef, 0xef,
- 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,
- 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8,
- 0xe8, 0xe8, 0xe8, 0xe8, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb, 0xeb,
- 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0xea, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa
-};
-
-#endif /* FAST_ALAW_CONVERSION */
-
-#ifdef FAST_ULAW_CONVERSION
-
-int16_t _st_ulaw2linear16[256] = {
- -32124, -31100, -30076, -29052, -28028, -27004, -25980,
- -24956, -23932, -22908, -21884, -20860, -19836, -18812,
- -17788, -16764, -15996, -15484, -14972, -14460, -13948,
- -13436, -12924, -12412, -11900, -11388, -10876, -10364,
- -9852, -9340, -8828, -8316, -7932, -7676, -7420,
- -7164, -6908, -6652, -6396, -6140, -5884, -5628,
- -5372, -5116, -4860, -4604, -4348, -4092, -3900,
- -3772, -3644, -3516, -3388, -3260, -3132, -3004,
- -2876, -2748, -2620, -2492, -2364, -2236, -2108,
- -1980, -1884, -1820, -1756, -1692, -1628, -1564,
- -1500, -1436, -1372, -1308, -1244, -1180, -1116,
- -1052, -988, -924, -876, -844, -812, -780,
- -748, -716, -684, -652, -620, -588, -556,
- -524, -492, -460, -428, -396, -372, -356,
- -340, -324, -308, -292, -276, -260, -244,
- -228, -212, -196, -180, -164, -148, -132,
- -120, -112, -104, -96, -88, -80, -72,
- -64, -56, -48, -40, -32, -24, -16,
- -8, 0, 32124, 31100, 30076, 29052, 28028,
- 27004, 25980, 24956, 23932, 22908, 21884, 20860,
- 19836, 18812, 17788, 16764, 15996, 15484, 14972,
- 14460, 13948, 13436, 12924, 12412, 11900, 11388,
- 10876, 10364, 9852, 9340, 8828, 8316, 7932,
- 7676, 7420, 7164, 6908, 6652, 6396, 6140,
- 5884, 5628, 5372, 5116, 4860, 4604, 4348,
- 4092, 3900, 3772, 3644, 3516, 3388, 3260,
- 3132, 3004, 2876, 2748, 2620, 2492, 2364,
- 2236, 2108, 1980, 1884, 1820, 1756, 1692,
- 1628, 1564, 1500, 1436, 1372, 1308, 1244,
- 1180, 1116, 1052, 988, 924, 876, 844,
- 812, 780, 748, 716, 684, 652, 620,
- 588, 556, 524, 492, 460, 428, 396,
- 372, 356, 340, 324, 308, 292, 276,
- 260, 244, 228, 212, 196, 180, 164,
- 148, 132, 120, 112, 104, 96, 88,
- 80, 72, 64, 56, 48, 40, 32,
- 24, 16, 8, 0
-};
-
-uint8_t _st_14linear2ulaw[0x4000] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
- 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
- 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
- 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
- 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
- 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
- 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
- 0x09, 0x09, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a,
- 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b,
- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c,
- 0x0c, 0x0c, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d,
- 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0d, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e,
- 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0e, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11,
- 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12, 0x12,
- 0x12, 0x12, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13,
- 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x14,
- 0x14, 0x14, 0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15,
- 0x15, 0x15, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16,
- 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17,
- 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
- 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19,
- 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a,
- 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b,
- 0x1b, 0x1b, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c,
- 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d,
- 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e,
- 0x1e, 0x1e, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f,
- 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
- 0x20, 0x20, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21,
- 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23, 0x23,
- 0x23, 0x23, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24,
- 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25,
- 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x25, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26,
- 0x26, 0x26, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x27,
- 0x27, 0x27, 0x27, 0x27, 0x27, 0x27, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28,
- 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x28, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0x29,
- 0x29, 0x29, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a,
- 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2a, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,
- 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,
- 0x2c, 0x2c, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
- 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e,
- 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f,
- 0x2f, 0x2f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
- 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31,
- 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33,
- 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x34, 0x34,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34,
- 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
- 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35, 0x35,
- 0x35, 0x35, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
- 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37,
- 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38, 0x38,
- 0x38, 0x38, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39,
- 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x39, 0x3a, 0x3a,
- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a,
- 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3a, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
- 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b, 0x3b,
- 0x3b, 0x3b, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c,
- 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3c, 0x3d, 0x3d,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d,
- 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3d, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
- 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e, 0x3e,
- 0x3e, 0x3e, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f,
- 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x40, 0x40,
- 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40,
- 0x40, 0x40, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x41,
- 0x41, 0x41, 0x41, 0x41, 0x41, 0x41, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42,
- 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x43, 0x43,
- 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43, 0x43,
- 0x43, 0x43, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
- 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45,
- 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x45, 0x46, 0x46,
- 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46, 0x46,
- 0x46, 0x46, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47,
- 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48,
- 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x48, 0x49, 0x49,
- 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49, 0x49,
- 0x49, 0x49, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a,
- 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4a, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b,
- 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4b, 0x4c, 0x4c,
- 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c, 0x4c,
- 0x4c, 0x4c, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d,
- 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4d, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e,
- 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4e, 0x4f, 0x4f,
- 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f, 0x4f,
- 0x4f, 0x4f, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x51, 0x51,
- 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x52, 0x52, 0x52, 0x52, 0x52, 0x52,
- 0x52, 0x52, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x53, 0x54, 0x54,
- 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
- 0x55, 0x55, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x56, 0x57, 0x57,
- 0x57, 0x57, 0x57, 0x57, 0x57, 0x57, 0x58, 0x58, 0x58, 0x58, 0x58, 0x58,
- 0x58, 0x58, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x59, 0x5a, 0x5a,
- 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5a, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b, 0x5b,
- 0x5b, 0x5b, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5d, 0x5d,
- 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e, 0x5e,
- 0x5e, 0x5e, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x5f, 0x60, 0x60,
- 0x60, 0x60, 0x61, 0x61, 0x61, 0x61, 0x62, 0x62, 0x62, 0x62, 0x63, 0x63,
- 0x63, 0x63, 0x64, 0x64, 0x64, 0x64, 0x65, 0x65, 0x65, 0x65, 0x66, 0x66,
- 0x66, 0x66, 0x67, 0x67, 0x67, 0x67, 0x68, 0x68, 0x68, 0x68, 0x69, 0x69,
- 0x69, 0x69, 0x6a, 0x6a, 0x6a, 0x6a, 0x6b, 0x6b, 0x6b, 0x6b, 0x6c, 0x6c,
- 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0x6e, 0x6e, 0x6e, 0x6e, 0x6f, 0x6f,
- 0x6f, 0x6f, 0x70, 0x70, 0x71, 0x71, 0x72, 0x72, 0x73, 0x73, 0x74, 0x74,
- 0x75, 0x75, 0x76, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7a, 0x7a,
- 0x7b, 0x7b, 0x7c, 0x7c, 0x7d, 0x7d, 0x7e, 0x7e, 0xff, 0xfe, 0xfe, 0xfd,
- 0xfd, 0xfc, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf9, 0xf8, 0xf8, 0xf7,
- 0xf7, 0xf6, 0xf6, 0xf5, 0xf5, 0xf4, 0xf4, 0xf3, 0xf3, 0xf2, 0xf2, 0xf1,
- 0xf1, 0xf0, 0xf0, 0xef, 0xef, 0xef, 0xef, 0xee, 0xee, 0xee, 0xee, 0xed,
- 0xed, 0xed, 0xed, 0xec, 0xec, 0xec, 0xec, 0xeb, 0xeb, 0xeb, 0xeb, 0xea,
- 0xea, 0xea, 0xea, 0xe9, 0xe9, 0xe9, 0xe9, 0xe8, 0xe8, 0xe8, 0xe8, 0xe7,
- 0xe7, 0xe7, 0xe7, 0xe6, 0xe6, 0xe6, 0xe6, 0xe5, 0xe5, 0xe5, 0xe5, 0xe4,
- 0xe4, 0xe4, 0xe4, 0xe3, 0xe3, 0xe3, 0xe3, 0xe2, 0xe2, 0xe2, 0xe2, 0xe1,
- 0xe1, 0xe1, 0xe1, 0xe0, 0xe0, 0xe0, 0xe0, 0xdf, 0xdf, 0xdf, 0xdf, 0xdf,
- 0xdf, 0xdf, 0xdf, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xde, 0xdd,
- 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdc, 0xdc, 0xdc, 0xdc, 0xdc,
- 0xdc, 0xdc, 0xdc, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xda,
- 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xda, 0xd9, 0xd9, 0xd9, 0xd9, 0xd9,
- 0xd9, 0xd9, 0xd9, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd7,
- 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd7, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6,
- 0xd6, 0xd6, 0xd6, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd5, 0xd4,
- 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd4, 0xd3, 0xd3, 0xd3, 0xd3, 0xd3,
- 0xd3, 0xd3, 0xd3, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd2, 0xd1,
- 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd1, 0xd0, 0xd0, 0xd0, 0xd0, 0xd0,
- 0xd0, 0xd0, 0xd0, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf,
- 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xcf, 0xce, 0xce, 0xce, 0xce, 0xce,
- 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xce, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd, 0xcd,
- 0xcd, 0xcd, 0xcd, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc,
- 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb,
- 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xcb, 0xca,
- 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca, 0xca,
- 0xca, 0xca, 0xca, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9,
- 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc9, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8,
- 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc8, 0xc7,
- 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7, 0xc7,
- 0xc7, 0xc7, 0xc7, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
- 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5,
- 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc5, 0xc4,
- 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4, 0xc4,
- 0xc4, 0xc4, 0xc4, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3,
- 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2,
- 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc2, 0xc1,
- 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1, 0xc1,
- 0xc1, 0xc1, 0xc1, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0,
- 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf, 0xbf,
- 0xbf, 0xbf, 0xbf, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe,
- 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbe, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd,
- 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbd, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc, 0xbc,
- 0xbc, 0xbc, 0xbc, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb,
- 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba,
- 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xba, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9, 0xb9,
- 0xb9, 0xb9, 0xb9, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8,
- 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb8, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7,
- 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb7, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6, 0xb6,
- 0xb6, 0xb6, 0xb6, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5,
- 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4,
- 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb4, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3, 0xb3,
- 0xb3, 0xb3, 0xb3, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2,
- 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb2, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1,
- 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb1, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0, 0xb0,
- 0xb0, 0xb0, 0xb0, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf,
- 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xaf, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae,
- 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xae, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad, 0xad,
- 0xad, 0xad, 0xad, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac,
- 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xac, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab,
- 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xab, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa,
- 0xaa, 0xaa, 0xaa, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9,
- 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa9, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8,
- 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa8, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6,
- 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5,
- 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4, 0xa4,
- 0xa4, 0xa4, 0xa4, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3,
- 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa3, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2,
- 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1, 0xa1,
- 0xa1, 0xa1, 0xa1, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0,
- 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f, 0x9f,
- 0x9f, 0x9f, 0x9f, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d,
- 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9d, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c, 0x9c,
- 0x9c, 0x9c, 0x9c, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b,
- 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9b, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a,
- 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99,
- 0x99, 0x99, 0x99, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98,
- 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x98, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97,
- 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x97, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96, 0x96,
- 0x96, 0x96, 0x96, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95,
- 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94,
- 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x94, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93, 0x93,
- 0x93, 0x93, 0x93, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92,
- 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91,
- 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x91, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f,
- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e,
- 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8e, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d, 0x8d,
- 0x8d, 0x8d, 0x8d, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c,
- 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8c, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b,
- 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8b, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a, 0x8a,
- 0x8a, 0x8a, 0x8a, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89,
- 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x89, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88,
- 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87,
- 0x87, 0x87, 0x87, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86,
- 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85,
- 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x85, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84, 0x84,
- 0x84, 0x84, 0x84, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
- 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82,
- 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81,
- 0x81, 0x81, 0x81, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
- 0x80, 0x80, 0x80, 0x80
-};
-
-#endif /* FAST_ULAW_CONVERSION */
-
-/* The following code was used to generate the lookup tables */
-#if 0
-int main()
-{
- int x, y, find2a = 0;
-
- y = 0;
- printf("int16_t _st_alaw2linear16[256] = {\n ");
- for (x = 0; x < 256; x++)
- {
- printf("%8d,", st_alaw2linear16(x));
- y++;
- if (y == 7)
- {
- y = 0;
- printf("\n ");
- }
- }
-
- printf("\n};\n\nuint8_t _st_13linear2alaw[0x2000] = {\n ");
- y = 0;
- for (x = 0; x < 0x2000; x++)
- {
- printf(" 0x%02x,", st_13linear2alaw((-0x1000)+x));
- y++;
- if (y == 12)
- {
- y = 0;
- printf("\n ");
- }
- }
-
- printf("\n};\n\nint16_t _st_ulaw2linear16[256] = {\n ");
- y = 0;
- for (x = 0; x < 256; x++)
- {
- printf("%8d,", st_ulaw2linear16(x));
- y++;
- if (y == 7)
- {
- y = 0;
- printf("\n ");
- }
- }
-
- printf("\n};\n\nuint8_t _st_14linear2ulaw[0x4000] = {\n ");
- y = 0;
- for (x = 0; x < 0x4000; x++)
- {
- printf(" 0x%02x,", st_14linear2ulaw((-0x2000)+x));
- y++;
- if (y == 12)
- {
- y = 0;
- printf("\n ");
- }
- }
- printf("\n};\n");
-
-}
-#endif
-
-/* The following is not used by SoX but kept for reference */
-#if 0
-/* copy from CCITT G.711 specifications */
-unsigned char _u2a[128] = { /* u- to A-law conversions */
- 1, 1, 2, 2, 3, 3, 4, 4,
- 5, 5, 6, 6, 7, 7, 8, 8,
- 9, 10, 11, 12, 13, 14, 15, 16,
- 17, 18, 19, 20, 21, 22, 23, 24,
- 25, 27, 29, 31, 33, 34, 35, 36,
- 37, 38, 39, 40, 41, 42, 43, 44,
- 46, 48, 49, 50, 51, 52, 53, 54,
- 55, 56, 57, 58, 59, 60, 61, 62,
- 64, 65, 66, 67, 68, 69, 70, 71,
- 72, 73, 74, 75, 76, 77, 78, 79,
-/* corrected:
- 81, 82, 83, 84, 85, 86, 87, 88,
- should be: */
- 80, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 91, 92, 93, 94, 95, 96,
- 97, 98, 99, 100, 101, 102, 103, 104,
- 105, 106, 107, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 117, 118, 119, 120,
- 121, 122, 123, 124, 125, 126, 127, 128};
-
-unsigned char _a2u[128] = { /* A- to u-law conversions */
- 1, 3, 5, 7, 9, 11, 13, 15,
- 16, 17, 18, 19, 20, 21, 22, 23,
- 24, 25, 26, 27, 28, 29, 30, 31,
- 32, 32, 33, 33, 34, 34, 35, 35,
- 36, 37, 38, 39, 40, 41, 42, 43,
- 44, 45, 46, 47, 48, 48, 49, 49,
- 50, 51, 52, 53, 54, 55, 56, 57,
- 58, 59, 60, 61, 62, 63, 64, 64,
- 65, 66, 67, 68, 69, 70, 71, 72,
-/* corrected:
- 73, 74, 75, 76, 77, 78, 79, 79,
- should be: */
- 73, 74, 75, 76, 77, 78, 79, 80,
-
- 80, 81, 82, 83, 84, 85, 86, 87,
- 88, 89, 90, 91, 92, 93, 94, 95,
- 96, 97, 98, 99, 100, 101, 102, 103,
- 104, 105, 106, 107, 108, 109, 110, 111,
- 112, 113, 114, 115, 116, 117, 118, 119,
- 120, 121, 122, 123, 124, 125, 126, 127};
-
-/* A-law to u-law conversion */
-unsigned char st_alaw2ulaw(
- unsigned char aval)
-{
- aval &= 0xff;
- return (unsigned char) ((aval & 0x80) ? (0xFF ^ _a2u[aval ^ 0xD5]) :
- (0x7F ^ _a2u[aval ^ 0x55]));
-}
-
-/* u-law to A-law conversion */
-unsigned char st_ulaw2alaw(
- unsigned char uval)
-{
- uval &= 0xff;
- return (unsigned char) ((uval & 0x80) ? (0xD5 ^ (_u2a[0xFF ^ uval] - 1)) :
- (unsigned char) (0x55 ^ (_u2a[0x7F ^ uval] - 1)));
-}
-#endif
diff --git a/src/polypcore/g711.h b/src/polypcore/g711.h deleted file mode 100644 index 97cedf81..00000000 --- a/src/polypcore/g711.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef foog711hfoo -#define foog711hfoo - -/* g711.h - include for G711 u-law and a-law conversion routines -** -** Copyright (C) 2001 Chris Bagwell -** -** Permission to use, copy, modify, and distribute this software and its -** documentation for any purpose and without fee is hereby granted, provided -** that the above copyright notice appear in all copies and that both that -** copyright notice and this permission notice appear in supporting -** documentation. This software is provided "as is" without express or -** implied warranty. -*/ - -/** Copied from sox -- Lennart Poettring*/ - -#include <inttypes.h> - -#ifdef FAST_ALAW_CONVERSION -extern uint8_t _st_13linear2alaw[0x2000]; -extern int16_t _st_alaw2linear16[256]; -#define st_13linear2alaw(sw) (_st_13linear2alaw[(sw + 0x1000)]) -#define st_alaw2linear16(uc) (_st_alaw2linear16[uc]) -#else -unsigned char st_13linear2alaw(int16_t pcm_val); -int16_t st_alaw2linear16(unsigned char); -#endif - -#ifdef FAST_ULAW_CONVERSION -extern uint8_t _st_14linear2ulaw[0x4000]; -extern int16_t _st_ulaw2linear16[256]; -#define st_14linear2ulaw(sw) (_st_14linear2ulaw[(sw + 0x2000)]) -#define st_ulaw2linear16(uc) (_st_ulaw2linear16[uc]) -#else -unsigned char st_14linear2ulaw(int16_t pcm_val); -int16_t st_ulaw2linear16(unsigned char); -#endif - -#endif diff --git a/src/polypcore/gccmacro.h b/src/polypcore/gccmacro.h deleted file mode 100644 index 9e212f2e..00000000 --- a/src/polypcore/gccmacro.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef foogccmacrohfoo -#define foogccmacrohfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef __GNUC__ -#define PA_GCC_PRINTF_ATTR(a,b) __attribute__ ((format (printf, a, b))) -#else -/** If we're in GNU C, use some magic for detecting invalid format strings */ -#define PA_GCC_PRINTF_ATTR(a,b) -#endif - -#if defined(__GNUC__) && (__GNUC__ >= 4) -#define PA_GCC_SENTINEL __attribute__ ((sentinel)) -#else -/** Macro for usage of GCC's sentinel compilation warnings */ -#define PA_GCC_SENTINEL -#endif - -#ifdef __GNUC__ -#define PA_GCC_NORETURN __attribute__((noreturn)) -#else -/** Macro for no-return functions */ -#define PA_GCC_NORETURN -#endif - -#ifdef __GNUC__ -#define PA_GCC_UNUSED __attribute__ ((unused)) -#else -/** Macro for not used parameter */ -#define PA_GCC_UNUSED -#endif - -#endif diff --git a/src/polypcore/hashmap.c b/src/polypcore/hashmap.c deleted file mode 100644 index adc322f0..00000000 --- a/src/polypcore/hashmap.c +++ /dev/null @@ -1,196 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <assert.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/idxset.h> -#include <polypcore/log.h> - -#include "hashmap.h" - -#define BUCKETS 1023 - -struct hashmap_entry { - struct hashmap_entry *next, *previous, *bucket_next, *bucket_previous; - unsigned hash; - const void *key; - void *value; -}; - -struct pa_hashmap { - unsigned size; - struct hashmap_entry **data; - struct hashmap_entry *first_entry; - - unsigned n_entries; - unsigned (*hash_func) (const void *p); - int (*compare_func) (const void*a, const void*b); -}; - -pa_hashmap *pa_hashmap_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b)) { - pa_hashmap *h; - h = pa_xmalloc(sizeof(pa_hashmap)); - h->data = pa_xmalloc0(sizeof(struct hashmap_entry*)*(h->size = BUCKETS)); - h->first_entry = NULL; - h->n_entries = 0; - h->hash_func = hash_func ? hash_func : pa_idxset_trivial_hash_func; - h->compare_func = compare_func ? compare_func : pa_idxset_trivial_compare_func; - return h; -} - -static void remove(pa_hashmap *h, struct hashmap_entry *e) { - assert(e); - - if (e->next) - e->next->previous = e->previous; - if (e->previous) - e->previous->next = e->next; - else - h->first_entry = e->next; - - if (e->bucket_next) - e->bucket_next->bucket_previous = e->bucket_previous; - if (e->bucket_previous) - e->bucket_previous->bucket_next = e->bucket_next; - else { - assert(e->hash < h->size); - h->data[e->hash] = e->bucket_next; - } - - pa_xfree(e); - h->n_entries--; -} - -void pa_hashmap_free(pa_hashmap*h, void (*free_func)(void *p, void *userdata), void *userdata) { - assert(h); - - while (h->first_entry) { - if (free_func) - free_func(h->first_entry->value, userdata); - remove(h, h->first_entry); - } - - pa_xfree(h->data); - pa_xfree(h); -} - -static struct hashmap_entry *get(pa_hashmap *h, unsigned hash, const void *key) { - struct hashmap_entry *e; - assert(h && hash < h->size); - - for (e = h->data[hash]; e; e = e->bucket_next) - if (h->compare_func(e->key, key) == 0) - return e; - - return NULL; -} - -int pa_hashmap_put(pa_hashmap *h, const void *key, void *value) { - struct hashmap_entry *e; - unsigned hash; - assert(h); - - hash = h->hash_func(key) % h->size; - - if ((e = get(h, hash, key))) - return -1; - - e = pa_xmalloc(sizeof(struct hashmap_entry)); - e->hash = hash; - e->key = key; - e->value = value; - - e->previous = NULL; - e->next = h->first_entry; - if (h->first_entry) - h->first_entry->previous = e; - h->first_entry = e; - - e->bucket_previous = NULL; - e->bucket_next = h->data[hash]; - if (h->data[hash]) - h->data[hash]->bucket_previous = e; - h->data[hash] = e; - - h->n_entries ++; - return 0; -} - -void* pa_hashmap_get(pa_hashmap *h, const void *key) { - unsigned hash; - struct hashmap_entry *e; - assert(h && key); - - hash = h->hash_func(key) % h->size; - - if (!(e = get(h, hash, key))) - return NULL; - - return e->value; -} - -void* pa_hashmap_remove(pa_hashmap *h, const void *key) { - struct hashmap_entry *e; - unsigned hash; - void *data; - assert(h && key); - - hash = h->hash_func(key) % h->size; - - if (!(e = get(h, hash, key))) - return NULL; - - data = e->value; - remove(h, e); - return data; -} - -unsigned pa_hashmap_size(pa_hashmap *h) { - return h->n_entries; -} - -void *pa_hashmap_iterate(pa_hashmap *h, void **state, const void **key) { - assert(h && state); - - if (!*state) - *state = h->first_entry; - else - *state = ((struct hashmap_entry*) *state)->next; - - if (!*state) { - if (key) - *key = NULL; - return NULL; - } - - if (key) - *key = ((struct hashmap_entry*) *state)->key; - - return ((struct hashmap_entry*) *state)->value; -} diff --git a/src/polypcore/hashmap.h b/src/polypcore/hashmap.h deleted file mode 100644 index 14f82705..00000000 --- a/src/polypcore/hashmap.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef foohashmaphfoo -#define foohashmaphfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -/* Simple Implementation of a hash table. Memory management is the - * user's job. It's a good idea to have the key pointer point to a - * string in the value data. */ - -typedef struct pa_hashmap pa_hashmap; - -/* Create a new hashmap. Use the specified functions for hashing and comparing objects in the map */ -pa_hashmap *pa_hashmap_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b)); - -/* Free the hash table. Calls the specified function for every value in the table. The function may be NULL */ -void pa_hashmap_free(pa_hashmap*, void (*free_func)(void *p, void *userdata), void *userdata); - -/* Returns non-zero when the entry already exists */ -int pa_hashmap_put(pa_hashmap *h, const void *key, void *value); -void* pa_hashmap_get(pa_hashmap *h, const void *key); - -/* Returns the data of the entry while removing */ -void* pa_hashmap_remove(pa_hashmap *h, const void *key); - -unsigned pa_hashmap_size(pa_hashmap *h); - -/* May be used to iterate through the hashmap. Initially the opaque - pointer *state has to be set to NULL. The hashmap may not be - modified during iteration. The key of the entry is returned in - *key, if key is non-NULL. After the last entry in the hashmap NULL - is returned. */ -void *pa_hashmap_iterate(pa_hashmap *h, void **state, const void**key); - -#endif diff --git a/src/polypcore/idxset.c b/src/polypcore/idxset.c deleted file mode 100644 index bde5c279..00000000 --- a/src/polypcore/idxset.c +++ /dev/null @@ -1,391 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include "idxset.h" - -typedef struct idxset_entry { - void *data; - uint32_t index; - unsigned hash_value; - - struct idxset_entry *hash_prev, *hash_next; - struct idxset_entry* iterate_prev, *iterate_next; -} idxset_entry; - -struct pa_idxset { - unsigned (*hash_func) (const void *p); - int (*compare_func)(const void *a, const void *b); - - unsigned hash_table_size, n_entries; - idxset_entry **hash_table, **array, *iterate_list_head, *iterate_list_tail; - uint32_t index, start_index, array_size; -}; - -unsigned pa_idxset_string_hash_func(const void *p) { - unsigned hash = 0; - const char *c; - - for (c = p; *c; c++) - hash = 31 * hash + *c; - - return hash; -} - -int pa_idxset_string_compare_func(const void *a, const void *b) { - return strcmp(a, b); -} - -unsigned pa_idxset_trivial_hash_func(const void *p) { - return (unsigned) (long) p; -} - -int pa_idxset_trivial_compare_func(const void *a, const void *b) { - return a != b; -} - -pa_idxset* pa_idxset_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b)) { - pa_idxset *s; - - s = pa_xnew(pa_idxset, 1); - s->hash_func = hash_func ? hash_func : pa_idxset_trivial_hash_func; - s->compare_func = compare_func ? compare_func : pa_idxset_trivial_compare_func; - s->hash_table_size = 1023; - s->hash_table = pa_xmalloc0(sizeof(idxset_entry*)*s->hash_table_size); - s->array = NULL; - s->array_size = 0; - s->index = 0; - s->start_index = 0; - s->n_entries = 0; - - s->iterate_list_head = s->iterate_list_tail = NULL; - - return s; -} - -void pa_idxset_free(pa_idxset *s, void (*free_func) (void *p, void *userdata), void *userdata) { - assert(s); - - while (s->iterate_list_head) { - idxset_entry *e = s->iterate_list_head; - s->iterate_list_head = s->iterate_list_head->iterate_next; - - if (free_func) - free_func(e->data, userdata); - pa_xfree(e); - } - - pa_xfree(s->hash_table); - pa_xfree(s->array); - pa_xfree(s); -} - -static idxset_entry* hash_scan(pa_idxset *s, idxset_entry* e, const void *p) { - assert(p); - - assert(s->compare_func); - for (; e; e = e->hash_next) - if (s->compare_func(e->data, p) == 0) - return e; - - return NULL; -} - -static void extend_array(pa_idxset *s, uint32_t idx) { - uint32_t i, j, l; - idxset_entry** n; - assert(idx >= s->start_index); - - if (idx < s->start_index + s->array_size) - return; - - for (i = 0; i < s->array_size; i++) - if (s->array[i]) - break; - - l = idx - s->start_index - i + 100; - n = pa_xnew0(idxset_entry*, l); - - for (j = 0; j < s->array_size-i; j++) - n[j] = s->array[i+j]; - - pa_xfree(s->array); - - s->array = n; - s->array_size = l; - s->start_index += i; -} - -static idxset_entry** array_index(pa_idxset*s, uint32_t idx) { - if (idx >= s->start_index + s->array_size) - return NULL; - - if (idx < s->start_index) - return NULL; - - return s->array + (idx - s->start_index); -} - -int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx) { - unsigned h; - idxset_entry *e, **a; - assert(s && p); - - assert(s->hash_func); - h = s->hash_func(p) % s->hash_table_size; - - assert(s->hash_table); - if ((e = hash_scan(s, s->hash_table[h], p))) { - if (idx) - *idx = e->index; - - return -1; - } - - e = pa_xmalloc(sizeof(idxset_entry)); - e->data = p; - e->index = s->index++; - e->hash_value = h; - - /* Insert into hash table */ - e->hash_next = s->hash_table[h]; - e->hash_prev = NULL; - if (s->hash_table[h]) - s->hash_table[h]->hash_prev = e; - s->hash_table[h] = e; - - /* Insert into array */ - extend_array(s, e->index); - a = array_index(s, e->index); - assert(a && !*a); - *a = e; - - /* Insert into linked list */ - e->iterate_next = NULL; - e->iterate_prev = s->iterate_list_tail; - if (s->iterate_list_tail) { - assert(s->iterate_list_head); - s->iterate_list_tail->iterate_next = e; - } else { - assert(!s->iterate_list_head); - s->iterate_list_head = e; - } - s->iterate_list_tail = e; - - s->n_entries++; - assert(s->n_entries >= 1); - - if (idx) - *idx = e->index; - - return 0; -} - -void* pa_idxset_get_by_index(pa_idxset*s, uint32_t idx) { - idxset_entry **a; - assert(s); - - if (!(a = array_index(s, idx))) - return NULL; - - if (!*a) - return NULL; - - return (*a)->data; -} - -void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx) { - unsigned h; - idxset_entry *e; - assert(s && p); - - assert(s->hash_func); - h = s->hash_func(p) % s->hash_table_size; - - assert(s->hash_table); - if (!(e = hash_scan(s, s->hash_table[h], p))) - return NULL; - - if (idx) - *idx = e->index; - - return e->data; -} - -static void remove_entry(pa_idxset *s, idxset_entry *e) { - idxset_entry **a; - assert(s && e); - - /* Remove from array */ - a = array_index(s, e->index); - assert(a && *a && *a == e); - *a = NULL; - - /* Remove from linked list */ - if (e->iterate_next) - e->iterate_next->iterate_prev = e->iterate_prev; - else - s->iterate_list_tail = e->iterate_prev; - - if (e->iterate_prev) - e->iterate_prev->iterate_next = e->iterate_next; - else - s->iterate_list_head = e->iterate_next; - - /* Remove from hash table */ - if (e->hash_next) - e->hash_next->hash_prev = e->hash_prev; - - if (e->hash_prev) - e->hash_prev->hash_next = e->hash_next; - else - s->hash_table[e->hash_value] = e->hash_next; - - pa_xfree(e); - - assert(s->n_entries >= 1); - s->n_entries--; -} - -void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx) { - idxset_entry **a; - void *data; - - assert(s); - - if (!(a = array_index(s, idx))) - return NULL; - - data = (*a)->data; - remove_entry(s, *a); - - return data; -} - -void* pa_idxset_remove_by_data(pa_idxset*s, const void *data, uint32_t *idx) { - idxset_entry *e; - unsigned h; - void *r; - - assert(s->hash_func); - h = s->hash_func(data) % s->hash_table_size; - - assert(s->hash_table); - if (!(e = hash_scan(s, s->hash_table[h], data))) - return NULL; - - r = e->data; - if (idx) - *idx = e->index; - - remove_entry(s, e); - - return r; -} - -void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx) { - idxset_entry **a, *e = NULL; - assert(s && idx); - - if ((a = array_index(s, *idx)) && *a) - e = (*a)->iterate_next; - - if (!e) - e = s->iterate_list_head; - - if (!e) - return NULL; - - *idx = e->index; - return e->data; -} - -void* pa_idxset_first(pa_idxset *s, uint32_t *idx) { - assert(s); - - if (!s->iterate_list_head) - return NULL; - - if (idx) - *idx = s->iterate_list_head->index; - return s->iterate_list_head->data; -} - -void *pa_idxset_next(pa_idxset *s, uint32_t *idx) { - idxset_entry **a, *e = NULL; - assert(s && idx); - - if ((a = array_index(s, *idx)) && *a) - e = (*a)->iterate_next; - - if (e) { - *idx = e->index; - return e->data; - } else { - *idx = PA_IDXSET_INVALID; - return NULL; - } -} - - -int pa_idxset_foreach(pa_idxset*s, int (*func)(void *p, uint32_t idx, int *del, void*userdata), void *userdata) { - idxset_entry *e; - assert(s && func); - - e = s->iterate_list_head; - while (e) { - int del = 0, r; - idxset_entry *n = e->iterate_next; - - r = func(e->data, e->index, &del, userdata); - - if (del) - remove_entry(s, e); - - if (r < 0) - return r; - - e = n; - } - - return 0; -} - -unsigned pa_idxset_size(pa_idxset*s) { - assert(s); - return s->n_entries; -} - -int pa_idxset_isempty(pa_idxset *s) { - assert(s); - return s->n_entries == 0; -} - diff --git a/src/polypcore/idxset.h b/src/polypcore/idxset.h deleted file mode 100644 index 17ae16cb..00000000 --- a/src/polypcore/idxset.h +++ /dev/null @@ -1,94 +0,0 @@ -#ifndef fooidxsethfoo -#define fooidxsethfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> - -/* A combination of a set and a dynamic array. Entries are indexable - * both through a numeric automatically generated index and the entry's - * data pointer. As usual, memory management is the user's job. */ - -/* A special index value denoting the invalid index. */ -#define PA_IDXSET_INVALID ((uint32_t) -1) - -/* Generic implementations for hash and comparison functions. Just - * compares the pointer or calculates the hash value directly from the - * pointer value. */ -unsigned pa_idxset_trivial_hash_func(const void *p); -int pa_idxset_trivial_compare_func(const void *a, const void *b); - -/* Generic implementations for hash and comparison functions for strings. */ -unsigned pa_idxset_string_hash_func(const void *p); -int pa_idxset_string_compare_func(const void *a, const void *b); - -typedef struct pa_idxset pa_idxset; - -/* Instantiate a new idxset with the specified hash and comparison functions */ -pa_idxset* pa_idxset_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b)); - -/* Free the idxset. When the idxset is not empty the specified function is called for every entry contained */ -void pa_idxset_free(pa_idxset *s, void (*free_func) (void *p, void *userdata), void *userdata); - -/* Store a new item in the idxset. The index of the item is returned in *idx */ -int pa_idxset_put(pa_idxset*s, void *p, uint32_t *idx); - -/* Get the entry by its idx */ -void* pa_idxset_get_by_index(pa_idxset*s, uint32_t idx); - -/* Get the entry by its data. The idx is returned in *index */ -void* pa_idxset_get_by_data(pa_idxset*s, const void *p, uint32_t *idx); - -/* Similar to pa_idxset_get_by_index(), but removes the entry from the idxset. */ -void* pa_idxset_remove_by_index(pa_idxset*s, uint32_t idx); - -/* Similar to pa_idxset_get_by_data(), but removes the entry from the idxset */ -void* pa_idxset_remove_by_data(pa_idxset*s, const void *p, uint32_t *idx); - -/* This may be used to iterate through all entries. When called with - an invalid index value it returns the first entry, otherwise the - next following. The function is best called with *idx = - PA_IDXSET_VALID first. It is safe to manipulate the idxset between - the calls. It is not guaranteed that all entries have already been - returned before the an entry is returned the second time.*/ -void* pa_idxset_rrobin(pa_idxset *s, uint32_t *idx); - -/* Return the oldest entry in the idxset. Fill in its index in *idx. */ -void* pa_idxset_first(pa_idxset *s, uint32_t *idx); - -/* Return the entry following the entry indexed by *idx. After the - * call *index contains the index of the returned - * object. pa_idxset_first() and pa_idxset_next() may be used to - * iterate through the set.*/ -void *pa_idxset_next(pa_idxset *s, uint32_t *idx); - -/* Call a function for every item in the set. If the callback function - returns -1, the loop is terminated. If *del is set to non-zero that - specific item is removed. It is not safe to call any other - functions on the idxset while pa_idxset_foreach is executed. */ -int pa_idxset_foreach(pa_idxset*s, int (*func)(void *p, uint32_t idx, int *del, void*userdata), void *userdata); - -unsigned pa_idxset_size(pa_idxset*s); - -int pa_idxset_isempty(pa_idxset *s); - -#endif diff --git a/src/polypcore/inet_ntop.c b/src/polypcore/inet_ntop.c deleted file mode 100644 index a25c3c95..00000000 --- a/src/polypcore/inet_ntop.c +++ /dev/null @@ -1,80 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <assert.h> - -#ifndef HAVE_INET_NTOP - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#include "winsock.h" - -#include "inet_ntop.h" - -const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { - struct in_addr *in = (struct in_addr*)src; - struct in6_addr *in6 = (struct in6_addr*)src; - - assert(src && dst); - - switch (af) { - case AF_INET: - snprintf(dst, cnt, "%d.%d.%d.%d", -#ifdef WORDS_BIGENDIAN - (int)(in->s_addr >> 24) & 0xff, - (int)(in->s_addr >> 16) & 0xff, - (int)(in->s_addr >> 8) & 0xff, - (int)(in->s_addr >> 0) & 0xff); -#else - (int)(in->s_addr >> 0) & 0xff, - (int)(in->s_addr >> 8) & 0xff, - (int)(in->s_addr >> 16) & 0xff, - (int)(in->s_addr >> 24) & 0xff); -#endif - break; - case AF_INET6: - snprintf(dst, cnt, "%x:%x:%x:%x:%x:%x:%x:%x", - in6->s6_addr[ 0] << 8 | in6->s6_addr[ 1], - in6->s6_addr[ 2] << 8 | in6->s6_addr[ 3], - in6->s6_addr[ 4] << 8 | in6->s6_addr[ 5], - in6->s6_addr[ 6] << 8 | in6->s6_addr[ 7], - in6->s6_addr[ 8] << 8 | in6->s6_addr[ 9], - in6->s6_addr[10] << 8 | in6->s6_addr[11], - in6->s6_addr[12] << 8 | in6->s6_addr[13], - in6->s6_addr[14] << 8 | in6->s6_addr[15]); - break; - default: - errno = EAFNOSUPPORT; - return NULL; - } - - return dst; -} - -#endif /* INET_NTOP */ diff --git a/src/polypcore/inet_ntop.h b/src/polypcore/inet_ntop.h deleted file mode 100644 index 7fb67b44..00000000 --- a/src/polypcore/inet_ntop.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef fooinet_ntophfoo -#define fooinet_ntophfoo - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#include "winsock.h" - -const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt); - -#endif diff --git a/src/polypcore/inet_pton.c b/src/polypcore/inet_pton.c deleted file mode 100644 index 17860f6d..00000000 --- a/src/polypcore/inet_pton.c +++ /dev/null @@ -1,62 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <errno.h> -#include <assert.h> - -#ifndef HAVE_INET_PTON - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#include "winsock.h" - -#include "inet_pton.h" - -int inet_pton(int af, const char *src, void *dst) { - struct in_addr *in = (struct in_addr*)dst; - struct in6_addr *in6 = (struct in6_addr*)dst; - - assert(src && dst); - - switch (af) { - case AF_INET: - in->s_addr = inet_addr(src); - if (in->s_addr == INADDR_NONE) - return 0; - break; - case AF_INET6: - /* FIXME */ - default: - errno = EAFNOSUPPORT; - return -1; - } - - return 1; -} - -#endif /* INET_PTON */ diff --git a/src/polypcore/inet_pton.h b/src/polypcore/inet_pton.h deleted file mode 100644 index 111b4a07..00000000 --- a/src/polypcore/inet_pton.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef fooinet_ptonhfoo -#define fooinet_ptonhfoo - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#include "winsock.h" - -int inet_pton(int af, const char *src, void *dst); - -#endif diff --git a/src/polypcore/iochannel.c b/src/polypcore/iochannel.c deleted file mode 100644 index 106c413e..00000000 --- a/src/polypcore/iochannel.c +++ /dev/null @@ -1,417 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <assert.h> -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_SYS_UN_H -#include <sys/un.h> -#endif - -#include "winsock.h" - -#include <polyp/xmalloc.h> - -#include <polypcore/core-error.h> -#include <polypcore/core-util.h> -#include <polypcore/socket-util.h> -#include <polypcore/log.h> - -#include "iochannel.h" - -struct pa_iochannel { - int ifd, ofd; - pa_mainloop_api* mainloop; - - pa_iochannel_cb_t callback; - void*userdata; - - int readable; - int writable; - int hungup; - - int no_close; - - pa_io_event* input_event, *output_event; -}; - -static void enable_mainloop_sources(pa_iochannel *io) { - assert(io); - - if (io->input_event == io->output_event && io->input_event) { - pa_io_event_flags_t f = PA_IO_EVENT_NULL; - assert(io->input_event); - - if (!io->readable) - f |= PA_IO_EVENT_INPUT; - if (!io->writable) - f |= PA_IO_EVENT_OUTPUT; - - io->mainloop->io_enable(io->input_event, f); - } else { - if (io->input_event) - io->mainloop->io_enable(io->input_event, io->readable ? PA_IO_EVENT_NULL : PA_IO_EVENT_INPUT); - if (io->output_event) - io->mainloop->io_enable(io->output_event, io->writable ? PA_IO_EVENT_NULL : PA_IO_EVENT_OUTPUT); - } -} - -static void callback(pa_mainloop_api* m, pa_io_event *e, int fd, pa_io_event_flags_t f, void *userdata) { - pa_iochannel *io = userdata; - int changed = 0; - - assert(m); - assert(e); - assert(fd >= 0); - assert(userdata); - - if ((f & (PA_IO_EVENT_HANGUP|PA_IO_EVENT_ERROR)) && !io->hungup) { - io->hungup = 1; - changed = 1; - } - - if ((f & PA_IO_EVENT_INPUT) && !io->readable) { - io->readable = 1; - changed = 1; - assert(e == io->input_event); - } - - if ((f & PA_IO_EVENT_OUTPUT) && !io->writable) { - io->writable = 1; - changed = 1; - assert(e == io->output_event); - } - - if (changed) { - enable_mainloop_sources(io); - - if (io->callback) - io->callback(io, io->userdata); - } -} - -pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd) { - pa_iochannel *io; - - assert(m); - assert(ifd >= 0 || ofd >= 0); - - io = pa_xnew(pa_iochannel, 1); - io->ifd = ifd; - io->ofd = ofd; - io->mainloop = m; - - io->userdata = NULL; - io->callback = NULL; - io->readable = 0; - io->writable = 0; - io->hungup = 0; - io->no_close = 0; - - io->input_event = io->output_event = NULL; - - if (ifd == ofd) { - assert(ifd >= 0); - pa_make_nonblock_fd(io->ifd); - io->input_event = io->output_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT|PA_IO_EVENT_OUTPUT, callback, io); - } else { - - if (ifd >= 0) { - pa_make_nonblock_fd(io->ifd); - io->input_event = m->io_new(m, ifd, PA_IO_EVENT_INPUT, callback, io); - } - - if (ofd >= 0) { - pa_make_nonblock_fd(io->ofd); - io->output_event = m->io_new(m, ofd, PA_IO_EVENT_OUTPUT, callback, io); - } - } - - return io; -} - -void pa_iochannel_free(pa_iochannel*io) { - assert(io); - - if (io->input_event) - io->mainloop->io_free(io->input_event); - - if (io->output_event && (io->output_event != io->input_event)) - io->mainloop->io_free(io->output_event); - - if (!io->no_close) { - if (io->ifd >= 0) - - close(io->ifd); - if (io->ofd >= 0 && io->ofd != io->ifd) - close(io->ofd); - } - - pa_xfree(io); -} - -int pa_iochannel_is_readable(pa_iochannel*io) { - assert(io); - - return io->readable || io->hungup; -} - -int pa_iochannel_is_writable(pa_iochannel*io) { - assert(io); - - return io->writable && !io->hungup; -} - -int pa_iochannel_is_hungup(pa_iochannel*io) { - assert(io); - - return io->hungup; -} - -ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l) { - ssize_t r; - - assert(io); - assert(data); - assert(l); - assert(io->ofd >= 0); - - r = pa_write(io->ofd, data, l); - if (r >= 0) { - io->writable = 0; - enable_mainloop_sources(io); - } - - return r; -} - -ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l) { - ssize_t r; - - assert(io); - assert(data); - assert(io->ifd >= 0); - - r = pa_read(io->ifd, data, l); - if (r >= 0) { - io->readable = 0; - enable_mainloop_sources(io); - } - - return r; -} - -#ifdef SCM_CREDENTIALS - -int pa_iochannel_creds_supported(pa_iochannel *io) { - struct sockaddr_un sa; - socklen_t l; - - assert(io); - assert(io->ifd >= 0); - assert(io->ofd == io->ifd); - - l = sizeof(sa); - - if (getsockname(io->ifd, (struct sockaddr*) &sa, &l) < 0) - return 0; - - return sa.sun_family == AF_UNIX; -} - -int pa_iochannel_creds_enable(pa_iochannel *io) { - int t = 1; - - assert(io); - assert(io->ifd >= 0); - - if (setsockopt(io->ifd, SOL_SOCKET, SO_PASSCRED, &t, sizeof(t)) < 0) { - pa_log_error("setsockopt(SOL_SOCKET, SO_PASSCRED): %s", pa_cstrerror(errno)); - return -1; - } - - return 0; -} - -ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l) { - ssize_t r; - struct msghdr mh; - struct iovec iov; - uint8_t cmsg_data[CMSG_SPACE(sizeof(struct ucred))]; - struct ucred *ucred; - struct cmsghdr *cmsg; - - assert(io); - assert(data); - assert(l); - assert(io->ofd >= 0); - - memset(&iov, 0, sizeof(iov)); - iov.iov_base = (void*) data; - iov.iov_len = l; - - memset(cmsg_data, 0, sizeof(cmsg_data)); - cmsg = (struct cmsghdr*) cmsg_data; - cmsg->cmsg_len = CMSG_LEN(sizeof(struct ucred)); - cmsg->cmsg_level = SOL_SOCKET; - cmsg->cmsg_type = SCM_CREDENTIALS; - - ucred = (struct ucred*) CMSG_DATA(cmsg); - ucred->pid = getpid(); - ucred->uid = getuid(); - ucred->gid = getgid(); - - memset(&mh, 0, sizeof(mh)); - mh.msg_name = NULL; - mh.msg_namelen = 0; - mh.msg_iov = &iov; - mh.msg_iovlen = 1; - mh.msg_control = cmsg_data; - mh.msg_controllen = sizeof(cmsg_data); - mh.msg_flags = 0; - - if ((r = sendmsg(io->ofd, &mh, MSG_NOSIGNAL)) >= 0) { - io->writable = 0; - enable_mainloop_sources(io); - } - - return r; -} - -ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid) { - ssize_t r; - struct msghdr mh; - struct iovec iov; - uint8_t cmsg_data[CMSG_SPACE(sizeof(struct ucred))]; - - assert(io); - assert(data); - assert(l); - assert(io->ifd >= 0); - assert(ucred); - assert(creds_valid); - - memset(&iov, 0, sizeof(iov)); - iov.iov_base = data; - iov.iov_len = l; - - memset(cmsg_data, 0, sizeof(cmsg_data)); - - memset(&mh, 0, sizeof(mh)); - mh.msg_name = NULL; - mh.msg_namelen = 0; - mh.msg_iov = &iov; - mh.msg_iovlen = 1; - mh.msg_control = cmsg_data; - mh.msg_controllen = sizeof(cmsg_data); - mh.msg_flags = 0; - - if ((r = recvmsg(io->ifd, &mh, MSG_NOSIGNAL)) >= 0) { - struct cmsghdr *cmsg; - - *creds_valid = 0; - - for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg)) { - - if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) { - assert(cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))); - memcpy(ucred, CMSG_DATA(cmsg), sizeof(struct ucred)); - *creds_valid = 1; - break; - } - } - - io->readable = 0; - enable_mainloop_sources(io); - } - - return r; -} -#else /* SCM_CREDENTIALS */ - -int pa_iochannel_creds_supported(pa_iochannel *io) { - return 0; -} - -int pa_iochannel_creds_enable(pa_iochannel *io) { - return -1; -} - -ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l) { - pa_log_error("pa_iochannel_write_with_creds() not supported."); - return -1; -} - -ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid) { - pa_log_error("pa_iochannel_read_with_creds() not supported."); - return -1; -} - -#endif /* SCM_CREDENTIALS */ - -void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t _callback, void *userdata) { - assert(io); - - io->callback = _callback; - io->userdata = userdata; -} - -void pa_iochannel_set_noclose(pa_iochannel*io, int b) { - assert(io); - - io->no_close = b; -} - -void pa_iochannel_socket_peer_to_string(pa_iochannel*io, char*s, size_t l) { - assert(io); - assert(s); - assert(l); - - pa_socket_peer_to_string(io->ifd, s, l); -} - -int pa_iochannel_socket_set_rcvbuf(pa_iochannel *io, size_t l) { - assert(io); - - return pa_socket_set_rcvbuf(io->ifd, l); -} - -int pa_iochannel_socket_set_sndbuf(pa_iochannel *io, size_t l) { - assert(io); - - return pa_socket_set_sndbuf(io->ofd, l); -} - -pa_mainloop_api* pa_iochannel_get_mainloop_api(pa_iochannel *io) { - assert(io); - - return io->mainloop; -} diff --git a/src/polypcore/iochannel.h b/src/polypcore/iochannel.h deleted file mode 100644 index fe7cc0ce..00000000 --- a/src/polypcore/iochannel.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef fooiochannelhfoo -#define fooiochannelhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <sys/types.h> - -#include <polyp/mainloop-api.h> - -/* A wrapper around UNIX file descriptors for attaching them to the a - main event loop. Everytime new data may be read or be written to - the channel a callback function is called. It is safe to destroy - the calling iochannel object from the callback */ - -/* When pa_iochannel_is_readable() returns non-zero, the user has to - * call this function in a loop until it is no longer set or EOF - * reached. Otherwise strange things may happen when an EOF is - * reached. */ - -typedef struct pa_iochannel pa_iochannel; - -/* Create a new IO channel for the specified file descriptors for -input resp. output. It is safe to pass the same file descriptor for -both parameters (in case of full-duplex channels). For a simplex -channel specify -1 for the other direction. */ - -pa_iochannel* pa_iochannel_new(pa_mainloop_api*m, int ifd, int ofd); -void pa_iochannel_free(pa_iochannel*io); - -ssize_t pa_iochannel_write(pa_iochannel*io, const void*data, size_t l); -ssize_t pa_iochannel_read(pa_iochannel*io, void*data, size_t l); - -int pa_iochannel_creds_supported(pa_iochannel *io); -int pa_iochannel_creds_enable(pa_iochannel *io); - -struct ucred; - -ssize_t pa_iochannel_write_with_creds(pa_iochannel*io, const void*data, size_t l); -ssize_t pa_iochannel_read_with_creds(pa_iochannel*io, void*data, size_t l, struct ucred *ucred, int *creds_valid); - -int pa_iochannel_is_readable(pa_iochannel*io); -int pa_iochannel_is_writable(pa_iochannel*io); -int pa_iochannel_is_hungup(pa_iochannel*io); - -/* Don't close the file descirptors when the io channel is freed. By - * default the file descriptors are closed. */ -void pa_iochannel_set_noclose(pa_iochannel*io, int b); - -/* Set the callback function that is called whenever data becomes available for read or write */ -typedef void (*pa_iochannel_cb_t)(pa_iochannel*io, void *userdata); -void pa_iochannel_set_callback(pa_iochannel*io, pa_iochannel_cb_t callback, void *userdata); - -/* In case the file descriptor is a socket, return a pretty-printed string in *s which describes the peer connected */ -void pa_iochannel_socket_peer_to_string(pa_iochannel*io, char*s, size_t l); - -/* Use setsockopt() to tune the recieve and send buffers of TCP sockets */ -int pa_iochannel_socket_set_rcvbuf(pa_iochannel*io, size_t l); -int pa_iochannel_socket_set_sndbuf(pa_iochannel*io, size_t l); - -pa_mainloop_api* pa_iochannel_get_mainloop_api(pa_iochannel *io); - -#endif diff --git a/src/polypcore/ioline.c b/src/polypcore/ioline.c deleted file mode 100644 index b908f967..00000000 --- a/src/polypcore/ioline.c +++ /dev/null @@ -1,394 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/core-error.h> -#include <polypcore/log.h> - -#include "ioline.h" - -#define BUFFER_LIMIT (64*1024) -#define READ_SIZE (1024) - -struct pa_ioline { - pa_iochannel *io; - pa_defer_event *defer_event; - pa_mainloop_api *mainloop; - int ref; - int dead; - - char *wbuf; - size_t wbuf_length, wbuf_index, wbuf_valid_length; - - char *rbuf; - size_t rbuf_length, rbuf_index, rbuf_valid_length; - - void (*callback)(pa_ioline*io, const char *s, void *userdata); - void *userdata; - - int defer_close; -}; - -static void io_callback(pa_iochannel*io, void *userdata); -static void defer_callback(pa_mainloop_api*m, pa_defer_event*e, void *userdata); - -pa_ioline* pa_ioline_new(pa_iochannel *io) { - pa_ioline *l; - assert(io); - - l = pa_xnew(pa_ioline, 1); - l->io = io; - l->dead = 0; - - l->wbuf = NULL; - l->wbuf_length = l->wbuf_index = l->wbuf_valid_length = 0; - - l->rbuf = NULL; - l->rbuf_length = l->rbuf_index = l->rbuf_valid_length = 0; - - l->callback = NULL; - l->userdata = NULL; - l->ref = 1; - - l->mainloop = pa_iochannel_get_mainloop_api(io); - - l->defer_event = l->mainloop->defer_new(l->mainloop, defer_callback, l); - l->mainloop->defer_enable(l->defer_event, 0); - - l->defer_close = 0; - - pa_iochannel_set_callback(io, io_callback, l); - - return l; -} - -static void ioline_free(pa_ioline *l) { - assert(l); - - if (l->io) - pa_iochannel_free(l->io); - - if (l->defer_event) - l->mainloop->defer_free(l->defer_event); - - pa_xfree(l->wbuf); - pa_xfree(l->rbuf); - pa_xfree(l); -} - -void pa_ioline_unref(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); - - if ((--l->ref) <= 0) - ioline_free(l); -} - -pa_ioline* pa_ioline_ref(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); - - l->ref++; - return l; -} - -void pa_ioline_close(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); - - l->dead = 1; - - if (l->io) { - pa_iochannel_free(l->io); - l->io = NULL; - } - - if (l->defer_event) { - l->mainloop->defer_free(l->defer_event); - l->defer_event = NULL; - } - - if (l->callback) - l->callback = NULL; -} - -void pa_ioline_puts(pa_ioline *l, const char *c) { - size_t len; - - assert(l); - assert(l->ref >= 1); - assert(c); - - if (l->dead) - return; - - len = strlen(c); - if (len > BUFFER_LIMIT - l->wbuf_valid_length) - len = BUFFER_LIMIT - l->wbuf_valid_length; - - if (len) { - assert(l->wbuf_length >= l->wbuf_valid_length); - - /* In case the allocated buffer is too small, enlarge it. */ - if (l->wbuf_valid_length + len > l->wbuf_length) { - size_t n = l->wbuf_valid_length+len; - char *new = pa_xmalloc(n); - if (l->wbuf) { - memcpy(new, l->wbuf+l->wbuf_index, l->wbuf_valid_length); - pa_xfree(l->wbuf); - } - l->wbuf = new; - l->wbuf_length = n; - l->wbuf_index = 0; - } else if (l->wbuf_index + l->wbuf_valid_length + len > l->wbuf_length) { - - /* In case the allocated buffer fits, but the current index is too far from the start, move it to the front. */ - memmove(l->wbuf, l->wbuf+l->wbuf_index, l->wbuf_valid_length); - l->wbuf_index = 0; - } - - assert(l->wbuf_index + l->wbuf_valid_length + len <= l->wbuf_length); - - /* Append the new string */ - memcpy(l->wbuf + l->wbuf_index + l->wbuf_valid_length, c, len); - l->wbuf_valid_length += len; - - l->mainloop->defer_enable(l->defer_event, 1); - } -} - -void pa_ioline_set_callback(pa_ioline*l, void (*callback)(pa_ioline*io, const char *s, void *userdata), void *userdata) { - assert(l); - assert(l->ref >= 1); - - l->callback = callback; - l->userdata = userdata; -} - -static void failure(pa_ioline *l, int process_leftover) { - assert(l); - assert(l->ref >= 1); - assert(!l->dead); - - if (process_leftover && l->rbuf_valid_length > 0) { - /* Pass the last missing bit to the client */ - - if (l->callback) { - char *p = pa_xstrndup(l->rbuf+l->rbuf_index, l->rbuf_valid_length); - l->callback(l, p, l->userdata); - pa_xfree(p); - } - } - - if (l->callback) { - l->callback(l, NULL, l->userdata); - l->callback = NULL; - } - - pa_ioline_close(l); -} - -static void scan_for_lines(pa_ioline *l, size_t skip) { - assert(l && l->ref >= 1 && skip < l->rbuf_valid_length); - - while (!l->dead && l->rbuf_valid_length > skip) { - char *e, *p; - size_t m; - - if (!(e = memchr(l->rbuf + l->rbuf_index + skip, '\n', l->rbuf_valid_length - skip))) - break; - - *e = 0; - - p = l->rbuf + l->rbuf_index; - m = strlen(p); - - l->rbuf_index += m+1; - l->rbuf_valid_length -= m+1; - - /* A shortcut for the next time */ - if (l->rbuf_valid_length == 0) - l->rbuf_index = 0; - - if (l->callback) - l->callback(l, p, l->userdata); - - skip = 0; - } - - /* If the buffer became too large and still no newline was found, drop it. */ - if (l->rbuf_valid_length >= BUFFER_LIMIT) - l->rbuf_index = l->rbuf_valid_length = 0; -} - -static int do_write(pa_ioline *l); - -static int do_read(pa_ioline *l) { - assert(l && l->ref >= 1); - - while (!l->dead && pa_iochannel_is_readable(l->io)) { - ssize_t r; - size_t len; - - len = l->rbuf_length - l->rbuf_index - l->rbuf_valid_length; - - /* Check if we have to enlarge the read buffer */ - if (len < READ_SIZE) { - size_t n = l->rbuf_valid_length+READ_SIZE; - - if (n >= BUFFER_LIMIT) - n = BUFFER_LIMIT; - - if (l->rbuf_length >= n) { - /* The current buffer is large enough, let's just move the data to the front */ - if (l->rbuf_valid_length) - memmove(l->rbuf, l->rbuf+l->rbuf_index, l->rbuf_valid_length); - } else { - /* Enlarge the buffer */ - char *new = pa_xmalloc(n); - if (l->rbuf_valid_length) - memcpy(new, l->rbuf+l->rbuf_index, l->rbuf_valid_length); - pa_xfree(l->rbuf); - l->rbuf = new; - l->rbuf_length = n; - } - - l->rbuf_index = 0; - } - - len = l->rbuf_length - l->rbuf_index - l->rbuf_valid_length; - - assert(len >= READ_SIZE); - - /* Read some data */ - if ((r = pa_iochannel_read(l->io, l->rbuf+l->rbuf_index+l->rbuf_valid_length, len)) <= 0) { - if (r < 0) { - pa_log(__FILE__": read(): %s", pa_cstrerror(errno)); - failure(l, 0); - } else - failure(l, 1); - - return -1; - } - - l->rbuf_valid_length += r; - - /* Look if a line has been terminated in the newly read data */ - scan_for_lines(l, l->rbuf_valid_length - r); - } - - return 0; -} - -/* Try to flush the buffer */ -static int do_write(pa_ioline *l) { - ssize_t r; - assert(l && l->ref >= 1); - - while (!l->dead && pa_iochannel_is_writable(l->io) && l->wbuf_valid_length) { - - if ((r = pa_iochannel_write(l->io, l->wbuf+l->wbuf_index, l->wbuf_valid_length)) < 0) { - pa_log(__FILE__": write(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); - failure(l, 0); - return -1; - } - - l->wbuf_index += r; - l->wbuf_valid_length -= r; - - /* A shortcut for the next time */ - if (l->wbuf_valid_length == 0) - l->wbuf_index = 0; - } - - return 0; -} - -/* Try to flush read/write data */ -static void do_work(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); - - pa_ioline_ref(l); - - l->mainloop->defer_enable(l->defer_event, 0); - - if (!l->dead) - do_read(l); - - if (!l->dead) - do_write(l); - - if (l->defer_close && !l->wbuf_valid_length) - failure(l, 1); - - pa_ioline_unref(l); -} - -static void io_callback(pa_iochannel*io, void *userdata) { - pa_ioline *l = userdata; - assert(io && l && l->ref >= 1); - - do_work(l); -} - -static void defer_callback(pa_mainloop_api*m, pa_defer_event*e, void *userdata) { - pa_ioline *l = userdata; - assert(l && l->ref >= 1 && l->mainloop == m && l->defer_event == e); - - do_work(l); -} - -void pa_ioline_defer_close(pa_ioline *l) { - assert(l); - assert(l->ref >= 1); - - l->defer_close = 1; - - if (!l->wbuf_valid_length) - l->mainloop->defer_enable(l->defer_event, 1); -} - -void pa_ioline_printf(pa_ioline *l, const char *format, ...) { - char *t; - va_list ap; - - assert(l); - assert(l->ref >= 1); - - va_start(ap, format); - t = pa_vsprintf_malloc(format, ap); - va_end(ap); - - pa_ioline_puts(l, t); - pa_xfree(t); -} diff --git a/src/polypcore/ioline.h b/src/polypcore/ioline.h deleted file mode 100644 index 77bf8761..00000000 --- a/src/polypcore/ioline.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef fooiolinehfoo -#define fooiolinehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/iochannel.h> -#include <polypcore/core-util.h> - -/* An ioline wraps an iochannel for line based communication. A - * callback function is called whenever a new line has been recieved - * from the client */ - -typedef struct pa_ioline pa_ioline; - -pa_ioline* pa_ioline_new(pa_iochannel *io); -void pa_ioline_unref(pa_ioline *l); -pa_ioline* pa_ioline_ref(pa_ioline *l); -void pa_ioline_close(pa_ioline *l); - -/* Write a string to the channel */ -void pa_ioline_puts(pa_ioline *s, const char *c); - -/* Write a string to the channel */ -void pa_ioline_printf(pa_ioline *s, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3); - -/* Set the callback function that is called for every recieved line */ -void pa_ioline_set_callback(pa_ioline*io, void (*callback)(pa_ioline*io, const char *s, void *userdata), void *userdata); - -/* Make sure to close the ioline object as soon as the send buffer is emptied */ -void pa_ioline_defer_close(pa_ioline *io); - -#endif diff --git a/src/polypcore/llist.h b/src/polypcore/llist.h deleted file mode 100644 index c54742d3..00000000 --- a/src/polypcore/llist.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef foollistfoo -#define foollistfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -/* Some macros for maintaining doubly linked lists */ - -/* The head of the linked list. Use this in the structure that shall - * contain the head of the linked list */ -#define PA_LLIST_HEAD(t,name) t *name - -/* The pointers in the linked list's items. Use this in the item structure */ -#define PA_LLIST_FIELDS(t) t *next, *prev - -/* Initialize the list's head */ -#define PA_LLIST_HEAD_INIT(t,item) do { (item) = NULL; } while(0) - -/* Initialize a list item */ -#define PA_LLIST_INIT(t,item) do { \ - t *_item = (item); \ - assert(_item); \ - _item->prev = _item->next = NULL; \ - } while(0) - -/* Prepend an item to the list */ -#define PA_LLIST_PREPEND(t,head,item) do { \ - t **_head = &(head), *_item = (item); \ - assert(_item); \ - if ((_item->next = *_head)) \ - _item->next->prev = _item; \ - _item->prev = NULL; \ - *_head = _item; \ - } while (0) - -/* Remove an item from the list */ -#define PA_LLIST_REMOVE(t,head,item) do { \ - t **_head = &(head), *_item = (item); \ - assert(_item); \ - if (_item->next) \ - _item->next->prev = _item->prev; \ - if (_item->prev) \ - _item->prev->next = _item->next; \ - else {\ - assert(*_head == _item); \ - *_head = _item->next; \ - } \ - _item->next = _item->prev = NULL; \ - } while(0) - -#define PA_LLIST_FIND_HEAD(t,item,head) \ -do { \ - t **_head = (head), *_item = (item); \ - *_head = _item; \ - assert(_head); \ - while ((*_head)->prev) \ - *_head = (*_head)->prev; \ -} while (0) \ - - -#endif diff --git a/src/polypcore/log.c b/src/polypcore/log.c deleted file mode 100644 index 6cdffa51..00000000 --- a/src/polypcore/log.c +++ /dev/null @@ -1,211 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdarg.h> -#include <stdio.h> -#include <unistd.h> -#include <string.h> - -#ifdef HAVE_SYSLOG_H -#include <syslog.h> -#endif - -#include <polyp/utf8.h> -#include <polyp/xmalloc.h> - -#include <polypcore/core-util.h> - -#include "log.h" - -#define ENV_LOGLEVEL "POLYP_LOG" - -static char *log_ident = NULL, *log_ident_local = NULL; -static pa_log_target_t log_target = PA_LOG_STDERR; -static void (*user_log_func)(pa_log_level_t l, const char *s) = NULL; -static pa_log_level_t maximal_level = PA_LOG_NOTICE; - -#ifdef HAVE_SYSLOG_H -static const int level_to_syslog[] = { - [PA_LOG_ERROR] = LOG_ERR, - [PA_LOG_WARN] = LOG_WARNING, - [PA_LOG_NOTICE] = LOG_NOTICE, - [PA_LOG_INFO] = LOG_INFO, - [PA_LOG_DEBUG] = LOG_DEBUG -}; -#endif - -void pa_log_set_ident(const char *p) { - if (log_ident) - pa_xfree(log_ident); - if (log_ident_local) - pa_xfree(log_ident_local); - - log_ident = pa_xstrdup(p); - log_ident_local = pa_utf8_to_locale(log_ident); - if (!log_ident_local) - log_ident_local = pa_xstrdup(log_ident); -} - -void pa_log_set_maximal_level(pa_log_level_t l) { - assert(l < PA_LOG_LEVEL_MAX); - maximal_level = l; -} - -void pa_log_set_target(pa_log_target_t t, void (*func)(pa_log_level_t l, const char*s)) { - assert(t == PA_LOG_USER || !func); - log_target = t; - user_log_func = func; -} - -void pa_log_levelv(pa_log_level_t level, const char *format, va_list ap) { - const char *e; - char *text, *t, *n; - - assert(level < PA_LOG_LEVEL_MAX); - - if ((e = getenv(ENV_LOGLEVEL))) - maximal_level = atoi(e); - - if (level > maximal_level) - return; - - text = pa_vsprintf_malloc(format, ap); - - if (!pa_utf8_valid(text)) - pa_log_level(level, __FILE__": invalid UTF-8 string following below:"); - - for (t = text; t; t = n) { - if ((n = strchr(t, '\n'))) { - *n = 0; - n++; - } - - if (!*t) - continue; - - switch (log_target) { - case PA_LOG_STDERR: { - const char *prefix = "", *suffix = ""; - char *local_t; - -#ifndef OS_IS_WIN32 - /* Yes indeed. Useless, but fun! */ - if (isatty(STDERR_FILENO)) { - if (level <= PA_LOG_ERROR) { - prefix = "\x1B[1;31m"; - suffix = "\x1B[0m"; - } else if (level <= PA_LOG_WARN) { - prefix = "\x1B[1m"; - suffix = "\x1B[0m"; - } - } -#endif - - local_t = pa_utf8_to_locale(t); - if (!local_t) - fprintf(stderr, "%s%s%s\n", prefix, t, suffix); - else { - fprintf(stderr, "%s%s%s\n", prefix, local_t, suffix); - pa_xfree(local_t); - } - - break; - } - -#ifdef HAVE_SYSLOG_H - case PA_LOG_SYSLOG: { - char *local_t; - - openlog(log_ident_local ? log_ident_local : "???", LOG_PID, LOG_USER); - - local_t = pa_utf8_to_locale(t); - if (!local_t) - syslog(level_to_syslog[level], "%s", t); - else { - syslog(level_to_syslog[level], "%s", local_t); - pa_xfree(local_t); - } - - closelog(); - break; - } -#endif - - case PA_LOG_USER: - user_log_func(level, t); - break; - - case PA_LOG_NULL: - default: - break; - } - } - - pa_xfree(text); - -} - -void pa_log_level(pa_log_level_t level, const char *format, ...) { - va_list ap; - va_start(ap, format); - pa_log_levelv(level, format, ap); - va_end(ap); -} - -void pa_log_debug(const char *format, ...) { - va_list ap; - va_start(ap, format); - pa_log_levelv(PA_LOG_DEBUG, format, ap); - va_end(ap); -} - -void pa_log_info(const char *format, ...) { - va_list ap; - va_start(ap, format); - pa_log_levelv(PA_LOG_INFO, format, ap); - va_end(ap); -} - -void pa_log_notice(const char *format, ...) { - va_list ap; - va_start(ap, format); - pa_log_levelv(PA_LOG_INFO, format, ap); - va_end(ap); -} - -void pa_log_warn(const char *format, ...) { - va_list ap; - va_start(ap, format); - pa_log_levelv(PA_LOG_WARN, format, ap); - va_end(ap); -} - -void pa_log_error(const char *format, ...) { - va_list ap; - va_start(ap, format); - pa_log_levelv(PA_LOG_ERROR, format, ap); - va_end(ap); -} diff --git a/src/polypcore/log.h b/src/polypcore/log.h deleted file mode 100644 index c306acaf..00000000 --- a/src/polypcore/log.h +++ /dev/null @@ -1,69 +0,0 @@ -#ifndef foologhfoo -#define foologhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <stdarg.h> -#include <polypcore/gccmacro.h> - -/* A simple logging subsystem */ - -/* Where to log to */ -typedef enum pa_log_target { - PA_LOG_STDERR, /* default */ - PA_LOG_SYSLOG, - PA_LOG_USER, /* to user specified function */ - PA_LOG_NULL /* to /dev/null */ -} pa_log_target_t; - -typedef enum pa_log_level { - PA_LOG_ERROR = 0, /* Error messages */ - PA_LOG_WARN = 1, /* Warning messages */ - PA_LOG_NOTICE = 2, /* Notice messages */ - PA_LOG_INFO = 3, /* Info messages */ - PA_LOG_DEBUG = 4, /* debug message */ - PA_LOG_LEVEL_MAX -} pa_log_level_t; - -/* Set an identification for the current daemon. Used when logging to syslog. */ -void pa_log_set_ident(const char *p); - -/* Set another log target. If t is PA_LOG_USER you may specify a function that is called every log string */ -void pa_log_set_target(pa_log_target_t t, void (*func)(pa_log_level_t t, const char*s)); - -/* Minimal log level */ -void pa_log_set_maximal_level(pa_log_level_t l); - -/* Do a log line */ -void pa_log_debug(const char *format, ...) PA_GCC_PRINTF_ATTR(1,2); -void pa_log_info(const char *format, ...) PA_GCC_PRINTF_ATTR(1,2); -void pa_log_notice(const char *format, ...) PA_GCC_PRINTF_ATTR(1,2); -void pa_log_warn(const char *format, ...) PA_GCC_PRINTF_ATTR(1,2); -void pa_log_error(const char *format, ...) PA_GCC_PRINTF_ATTR(1,2); - -void pa_log_level(pa_log_level_t level, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3); - -void pa_log_levelv(pa_log_level_t level, const char *format, va_list ap); - -#define pa_log pa_log_error - -#endif diff --git a/src/polypcore/mcalign.c b/src/polypcore/mcalign.c deleted file mode 100644 index d9267f99..00000000 --- a/src/polypcore/mcalign.c +++ /dev/null @@ -1,206 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include "mcalign.h" - -struct pa_mcalign { - size_t base; - pa_memchunk leftover, current; - pa_memblock_stat *memblock_stat; -}; - -pa_mcalign *pa_mcalign_new(size_t base, pa_memblock_stat *s) { - pa_mcalign *m; - assert(base); - - m = pa_xnew(pa_mcalign, 1); - - m->base = base; - pa_memchunk_reset(&m->leftover); - pa_memchunk_reset(&m->current); - m->memblock_stat = s; - - return m; -} - -void pa_mcalign_free(pa_mcalign *m) { - assert(m); - - if (m->leftover.memblock) - pa_memblock_unref(m->leftover.memblock); - - if (m->current.memblock) - pa_memblock_unref(m->current.memblock); - - pa_xfree(m); -} - -void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c) { - assert(m); - assert(c); - - assert(c->memblock); - assert(c->length > 0); - - assert(!m->current.memblock); - - /* Append to the leftover memory block */ - if (m->leftover.memblock) { - - /* Try to merge */ - if (m->leftover.memblock == c->memblock && - m->leftover.index + m->leftover.length == c->index) { - - /* Merge */ - m->leftover.length += c->length; - - /* If the new chunk is larger than m->base, move it to current */ - if (m->leftover.length >= m->base) { - m->current = m->leftover; - pa_memchunk_reset(&m->leftover); - } - - } else { - size_t l; - - /* We have to copy */ - assert(m->leftover.length < m->base); - l = m->base - m->leftover.length; - - if (l > c->length) - l = c->length; - - /* Can we use the current block? */ - pa_memchunk_make_writable(&m->leftover, m->memblock_stat, m->base); - - memcpy((uint8_t*) m->leftover.memblock->data + m->leftover.index + m->leftover.length, (uint8_t*) c->memblock->data + c->index, l); - m->leftover.length += l; - - assert(m->leftover.length <= m->base && m->leftover.length <= m->leftover.memblock->length); - - if (c->length > l) { - /* Save the remainder of the memory block */ - m->current = *c; - m->current.index += l; - m->current.length -= l; - pa_memblock_ref(m->current.memblock); - } - } - } else { - /* Nothing to merge or copy, just store it */ - - if (c->length >= m->base) - m->current = *c; - else - m->leftover = *c; - - pa_memblock_ref(c->memblock); - } -} - -int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c) { - assert(m); - assert(c); - - /* First test if there's a leftover memory block available */ - if (m->leftover.memblock) { - assert(m->leftover.length > 0 && m->leftover.length <= m->base); - - /* The leftover memory block is not yet complete */ - if (m->leftover.length < m->base) - return -1; - - /* Return the leftover memory block */ - *c = m->leftover; - pa_memchunk_reset(&m->leftover); - - /* If the current memblock is too small move it the leftover */ - if (m->current.memblock && m->current.length < m->base) { - m->leftover = m->current; - pa_memchunk_reset(&m->current); - } - - return 0; - } - - /* Now let's see if there is other data available */ - if (m->current.memblock) { - size_t l; - assert(m->current.length >= m->base); - - /* The length of the returned memory block */ - l = m->current.length; - l /= m->base; - l *= m->base; - assert(l > 0); - - /* Prepare the returned block */ - *c = m->current; - pa_memblock_ref(c->memblock); - c->length = l; - - /* Drop that from the current memory block */ - assert(l <= m->current.length); - m->current.index += l; - m->current.length -= l; - - /* In case the whole block was dropped ... */ - if (m->current.length == 0) - pa_memblock_unref(m->current.memblock); - else { - /* Move the raimainder to leftover */ - assert(m->current.length < m->base && !m->leftover.memblock); - - m->leftover = m->current; - } - - pa_memchunk_reset(&m->current); - - return 0; - } - - /* There's simply nothing */ - return -1; - -} - -size_t pa_mcalign_csize(pa_mcalign *m, size_t l) { - assert(m); - assert(l > 0); - - assert(!m->current.memblock); - - if (m->leftover.memblock) - l += m->leftover.length; - - return (l/m->base)*m->base; -} diff --git a/src/polypcore/mcalign.h b/src/polypcore/mcalign.h deleted file mode 100644 index 58019462..00000000 --- a/src/polypcore/mcalign.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef foomcalignhfoo -#define foomcalignhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/memblock.h> -#include <polypcore/memchunk.h> - -/* An alignment object, used for aligning memchunks to multiples of - * the frame size. */ - -/* Method of operation: the user creates a new mcalign object by - * calling pa_mcalign_new() with the appropriate aligning - * granularity. After that he may call pa_mcalign_push() for an input - * memchunk. After exactly one memchunk the user has to call - * pa_mcalign_pop() until it returns -1. If pa_mcalign_pop() returns - * 0, the memchunk *c is valid and aligned to the granularity. Some - * pseudocode illustrating this: - * - * pa_mcalign *a = pa_mcalign_new(4, NULL); - * - * for (;;) { - * pa_memchunk input; - * - * ... fill input ... - * - * pa_mcalign_push(m, &input); - * pa_memblock_unref(input.memblock); - * - * for (;;) { - * pa_memchunk output; - * - * if (pa_mcalign_pop(m, &output) < 0) - * break; - * - * ... consume output ... - * - * pa_memblock_unref(output.memblock); - * } - * } - * - * pa_memchunk_free(a); - * */ - -typedef struct pa_mcalign pa_mcalign; - -pa_mcalign *pa_mcalign_new(size_t base, pa_memblock_stat *s); -void pa_mcalign_free(pa_mcalign *m); - -/* Push a new memchunk into the aligner. The caller of this routine - * has to free the memchunk by himself. */ -void pa_mcalign_push(pa_mcalign *m, const pa_memchunk *c); - -/* Pop a new memchunk from the aligner. Returns 0 when sucessful, - * nonzero otherwise. */ -int pa_mcalign_pop(pa_mcalign *m, pa_memchunk *c); - -/* If we pass l bytes in now, how many bytes would we get out? */ -size_t pa_mcalign_csize(pa_mcalign *m, size_t l); - -#endif diff --git a/src/polypcore/memblock.c b/src/polypcore/memblock.c deleted file mode 100644 index a0e5135b..00000000 --- a/src/polypcore/memblock.c +++ /dev/null @@ -1,173 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include "memblock.h" - -static void stat_add(pa_memblock*m, pa_memblock_stat *s) { - assert(m); - - if (!s) { - m->stat = NULL; - return; - } - - m->stat = pa_memblock_stat_ref(s); - s->total++; - s->allocated++; - s->total_size += m->length; - s->allocated_size += m->length; -} - -static void stat_remove(pa_memblock *m) { - assert(m); - - if (!m->stat) - return; - - m->stat->total--; - m->stat->total_size -= m->length; - - pa_memblock_stat_unref(m->stat); - m->stat = NULL; -} - -pa_memblock *pa_memblock_new(size_t length, pa_memblock_stat*s) { - pa_memblock *b = pa_xmalloc(sizeof(pa_memblock)+length); - b->type = PA_MEMBLOCK_APPENDED; - b->ref = 1; - b->length = length; - b->data = b+1; - b->free_cb = NULL; - b->read_only = 0; - stat_add(b, s); - return b; -} - -pa_memblock *pa_memblock_new_dynamic(void *d, size_t length, pa_memblock_stat*s) { - pa_memblock *b = pa_xmalloc(sizeof(pa_memblock)); - b->type = PA_MEMBLOCK_DYNAMIC; - b->ref = 1; - b->length = length; - b->data = d; - b->free_cb = NULL; - b->read_only = 0; - stat_add(b, s); - return b; -} - -pa_memblock *pa_memblock_new_fixed(void *d, size_t length, int read_only, pa_memblock_stat*s) { - pa_memblock *b = pa_xmalloc(sizeof(pa_memblock)); - b->type = PA_MEMBLOCK_FIXED; - b->ref = 1; - b->length = length; - b->data = d; - b->free_cb = NULL; - b->read_only = read_only; - stat_add(b, s); - return b; -} - -pa_memblock *pa_memblock_new_user(void *d, size_t length, void (*free_cb)(void *p), int read_only, pa_memblock_stat*s) { - pa_memblock *b; - assert(d && length && free_cb); - b = pa_xmalloc(sizeof(pa_memblock)); - b->type = PA_MEMBLOCK_USER; - b->ref = 1; - b->length = length; - b->data = d; - b->free_cb = free_cb; - b->read_only = read_only; - stat_add(b, s); - return b; -} - -pa_memblock* pa_memblock_ref(pa_memblock*b) { - assert(b); - assert(b->ref >= 1); - - b->ref++; - return b; -} - -void pa_memblock_unref(pa_memblock*b) { - assert(b); - assert(b->ref >= 1); - - if ((--(b->ref)) == 0) { - stat_remove(b); - - if (b->type == PA_MEMBLOCK_USER) { - assert(b->free_cb); - b->free_cb(b->data); - } else if (b->type == PA_MEMBLOCK_DYNAMIC) - pa_xfree(b->data); - - pa_xfree(b); - } -} - -void pa_memblock_unref_fixed(pa_memblock *b) { - assert(b && b->ref >= 1 && b->type == PA_MEMBLOCK_FIXED); - - if (b->ref == 1) - pa_memblock_unref(b); - else { - b->data = pa_xmemdup(b->data, b->length); - b->type = PA_MEMBLOCK_DYNAMIC; - b->ref--; - } -} - -pa_memblock_stat* pa_memblock_stat_new(void) { - pa_memblock_stat *s; - - s = pa_xmalloc(sizeof(pa_memblock_stat)); - s->ref = 1; - s->total = s->total_size = s->allocated = s->allocated_size = 0; - - return s; -} - -void pa_memblock_stat_unref(pa_memblock_stat *s) { - assert(s && s->ref >= 1); - - if (!(--(s->ref))) { - assert(!s->total); - pa_xfree(s); - } -} - -pa_memblock_stat * pa_memblock_stat_ref(pa_memblock_stat *s) { - assert(s); - s->ref++; - return s; -} diff --git a/src/polypcore/memblock.h b/src/polypcore/memblock.h deleted file mode 100644 index 9471278a..00000000 --- a/src/polypcore/memblock.h +++ /dev/null @@ -1,86 +0,0 @@ -#ifndef foomemblockhfoo -#define foomemblockhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <sys/types.h> -#include <inttypes.h> - -/* A pa_memblock is a reference counted memory block. Polypaudio - * passed references to pa_memblocks around instead of copying - * data. See pa_memchunk for a structure that describes parts of - * memory blocks. */ - -/* The type of memory this block points to */ -typedef enum pa_memblock_type { - PA_MEMBLOCK_FIXED, /* data is a pointer to fixed memory that needs not to be freed */ - PA_MEMBLOCK_APPENDED, /* The most common kind: the data is appended to the memory block */ - PA_MEMBLOCK_DYNAMIC, /* data is a pointer to some memory allocated with pa_xmalloc() */ - PA_MEMBLOCK_USER /* User supplied memory, to be freed with free_cb */ -} pa_memblock_type_t; - -/* A structure of keeping memory block statistics */ -/* Maintains statistics about memory blocks */ -typedef struct pa_memblock_stat { - int ref; - unsigned total; - unsigned total_size; - unsigned allocated; - unsigned allocated_size; -} pa_memblock_stat; - -typedef struct pa_memblock { - pa_memblock_type_t type; - unsigned ref; /* the reference counter */ - int read_only; /* boolean */ - size_t length; - void *data; - void (*free_cb)(void *p); /* If type == PA_MEMBLOCK_USER this points to a function for freeing this memory block */ - pa_memblock_stat *stat; -} pa_memblock; - -/* Allocate a new memory block of type PA_MEMBLOCK_APPENDED */ -pa_memblock *pa_memblock_new(size_t length, pa_memblock_stat*s); - -/* Allocate a new memory block of type PA_MEMBLOCK_DYNAMIC. The pointer data is to be maintained be the memory block */ -pa_memblock *pa_memblock_new_dynamic(void *data, size_t length, pa_memblock_stat*s); - -/* Allocate a new memory block of type PA_MEMBLOCK_FIXED */ -pa_memblock *pa_memblock_new_fixed(void *data, size_t length, int read_only, pa_memblock_stat*s); - -/* Allocate a new memory block of type PA_MEMBLOCK_USER */ -pa_memblock *pa_memblock_new_user(void *data, size_t length, void (*free_cb)(void *p), int read_only, pa_memblock_stat*s); - -void pa_memblock_unref(pa_memblock*b); -pa_memblock* pa_memblock_ref(pa_memblock*b); - -/* This special unref function has to be called by the owner of the -memory of a static memory block when he wants to release all -references to the memory. This causes the memory to be copied and -converted into a PA_MEMBLOCK_DYNAMIC type memory block */ -void pa_memblock_unref_fixed(pa_memblock*b); - -pa_memblock_stat* pa_memblock_stat_new(void); -void pa_memblock_stat_unref(pa_memblock_stat *s); -pa_memblock_stat * pa_memblock_stat_ref(pa_memblock_stat *s); - -#endif diff --git a/src/polypcore/memblockq.c b/src/polypcore/memblockq.c deleted file mode 100644 index 8ed358fa..00000000 --- a/src/polypcore/memblockq.c +++ /dev/null @@ -1,636 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/time.h> -#include <time.h> -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/log.h> -#include <polypcore/mcalign.h> - -#include "memblockq.h" - -struct memblock_list { - struct memblock_list *next, *prev; - int64_t index; - pa_memchunk chunk; -}; - -struct pa_memblockq { - struct memblock_list *blocks, *blocks_tail; - unsigned n_blocks; - size_t maxlength, tlength, base, prebuf, minreq; - int64_t read_index, write_index; - enum { PREBUF, RUNNING } state; - pa_memblock_stat *memblock_stat; - pa_memblock *silence; - pa_mcalign *mcalign; -}; - -pa_memblockq* pa_memblockq_new( - int64_t idx, - size_t maxlength, - size_t tlength, - size_t base, - size_t prebuf, - size_t minreq, - pa_memblock *silence, - pa_memblock_stat *s) { - - pa_memblockq* bq; - - assert(base > 0); - assert(maxlength >= base); - - bq = pa_xnew(pa_memblockq, 1); - bq->blocks = bq->blocks_tail = NULL; - bq->n_blocks = 0; - - bq->base = base; - bq->read_index = bq->write_index = idx; - bq->memblock_stat = s; - - pa_log_debug(__FILE__": memblockq requested: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu", - (unsigned long)maxlength, (unsigned long)tlength, (unsigned long)base, (unsigned long)prebuf, (unsigned long)minreq); - - bq->maxlength = ((maxlength+base-1)/base)*base; - assert(bq->maxlength >= base); - - bq->tlength = ((tlength+base-1)/base)*base; - if (!bq->tlength || bq->tlength >= bq->maxlength) - bq->tlength = bq->maxlength; - - bq->prebuf = (prebuf == (size_t) -1) ? bq->tlength/2 : prebuf; - bq->prebuf = ((bq->prebuf+base-1)/base)*base; - if (bq->prebuf > bq->maxlength) - bq->prebuf = bq->maxlength; - - bq->minreq = (minreq/base)*base; - - if (bq->minreq > bq->tlength - bq->prebuf) - bq->minreq = bq->tlength - bq->prebuf; - - if (!bq->minreq) - bq->minreq = 1; - - pa_log_debug(__FILE__": memblockq sanitized: maxlength=%lu, tlength=%lu, base=%lu, prebuf=%lu, minreq=%lu", - (unsigned long)bq->maxlength, (unsigned long)bq->tlength, (unsigned long)bq->base, (unsigned long)bq->prebuf, (unsigned long)bq->minreq); - - bq->state = bq->prebuf ? PREBUF : RUNNING; - bq->silence = silence ? pa_memblock_ref(silence) : NULL; - bq->mcalign = NULL; - - return bq; -} - -void pa_memblockq_free(pa_memblockq* bq) { - assert(bq); - - pa_memblockq_flush(bq); - - if (bq->silence) - pa_memblock_unref(bq->silence); - - if (bq->mcalign) - pa_mcalign_free(bq->mcalign); - - pa_xfree(bq); -} - -static void drop_block(pa_memblockq *bq, struct memblock_list *q) { - assert(bq); - assert(q); - - assert(bq->n_blocks >= 1); - - if (q->prev) - q->prev->next = q->next; - else - bq->blocks = q->next; - - if (q->next) - q->next->prev = q->prev; - else - bq->blocks_tail = q->prev; - - pa_memblock_unref(q->chunk.memblock); - pa_xfree(q); - - bq->n_blocks--; -} - -static int can_push(pa_memblockq *bq, size_t l) { - int64_t end; - - assert(bq); - - if (bq->read_index > bq->write_index) { - size_t d = bq->read_index - bq->write_index; - - if (l > d) - l -= d; - else - return 1; - } - - end = bq->blocks_tail ? bq->blocks_tail->index + bq->blocks_tail->chunk.length : 0; - - /* Make sure that the list doesn't get too long */ - if (bq->write_index + (int64_t)l > end) - if (bq->write_index + l - bq->read_index > bq->maxlength) - return 0; - - return 1; -} - -int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *uchunk) { - - struct memblock_list *q, *n; - pa_memchunk chunk; - - assert(bq); - assert(uchunk); - assert(uchunk->memblock); - assert(uchunk->length > 0); - assert(uchunk->index + uchunk->length <= uchunk->memblock->length); - - if (uchunk->length % bq->base) - return -1; - - if (!can_push(bq, uchunk->length)) - return -1; - - chunk = *uchunk; - - if (bq->read_index > bq->write_index) { - - /* We currently have a buffer underflow, we need to drop some - * incoming data */ - - size_t d = bq->read_index - bq->write_index; - - if (chunk.length > d) { - chunk.index += d; - chunk.length -= d; - bq->write_index = bq->read_index; - } else { - /* We drop the incoming data completely */ - bq->write_index += chunk.length; - return 0; - } - } - - /* We go from back to front to look for the right place to add - * this new entry. Drop data we will overwrite on the way */ - - q = bq->blocks_tail; - while (q) { - - if (bq->write_index >= q->index + (int64_t)q->chunk.length) - /* We found the entry where we need to place the new entry immediately after */ - break; - else if (bq->write_index + (int64_t)chunk.length <= q->index) { - /* This entry isn't touched at all, let's skip it */ - q = q->prev; - } else if (bq->write_index <= q->index && - bq->write_index + chunk.length >= q->index + q->chunk.length) { - - /* This entry is fully replaced by the new entry, so let's drop it */ - - struct memblock_list *p; - p = q; - q = q->prev; - drop_block(bq, p); - } else if (bq->write_index >= q->index) { - /* The write index points into this memblock, so let's - * truncate or split it */ - - if (bq->write_index + chunk.length < q->index + q->chunk.length) { - - /* We need to save the end of this memchunk */ - struct memblock_list *p; - size_t d; - - /* Create a new list entry for the end of thie memchunk */ - p = pa_xnew(struct memblock_list, 1); - p->chunk = q->chunk; - pa_memblock_ref(p->chunk.memblock); - - /* Calculate offset */ - d = bq->write_index + chunk.length - q->index; - assert(d > 0); - - /* Drop it from the new entry */ - p->index = q->index + d; - p->chunk.length -= d; - - /* Add it to the list */ - p->prev = q; - if ((p->next = q->next)) - q->next->prev = p; - else - bq->blocks_tail = p; - q->next = p; - - bq->n_blocks++; - } - - /* Truncate the chunk */ - if (!(q->chunk.length = bq->write_index - q->index)) { - struct memblock_list *p; - p = q; - q = q->prev; - drop_block(bq, p); - } - - /* We had to truncate this block, hence we're now at the right position */ - break; - } else { - size_t d; - - assert(bq->write_index + (int64_t)chunk.length > q->index && - bq->write_index + (int64_t)chunk.length < q->index + (int64_t)q->chunk.length && - bq->write_index < q->index); - - /* The job overwrites the current entry at the end, so let's drop the beginning of this entry */ - - d = bq->write_index + chunk.length - q->index; - q->index += d; - q->chunk.index += d; - q->chunk.length -= d; - - q = q->prev; - } - - } - - if (q) { - assert(bq->write_index >= q->index + (int64_t)q->chunk.length); - assert(!q->next || (bq->write_index + (int64_t)chunk.length <= q->next->index)); - - /* Try to merge memory blocks */ - - if (q->chunk.memblock == chunk.memblock && - q->chunk.index + (int64_t)q->chunk.length == chunk.index && - bq->write_index == q->index + (int64_t)q->chunk.length) { - - q->chunk.length += chunk.length; - bq->write_index += chunk.length; - return 0; - } - } else - assert(!bq->blocks || (bq->write_index + (int64_t)chunk.length <= bq->blocks->index)); - - - n = pa_xnew(struct memblock_list, 1); - n->chunk = chunk; - pa_memblock_ref(n->chunk.memblock); - n->index = bq->write_index; - bq->write_index += n->chunk.length; - - n->next = q ? q->next : bq->blocks; - n->prev = q; - - if (n->next) - n->next->prev = n; - else - bq->blocks_tail = n; - - if (n->prev) - n->prev->next = n; - else - bq->blocks = n; - - bq->n_blocks++; - return 0; -} - -int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk) { - assert(bq); - assert(chunk); - - if (bq->state == PREBUF) { - - /* We need to pre-buffer */ - if (pa_memblockq_get_length(bq) < bq->prebuf) - return -1; - - bq->state = RUNNING; - - } else if (bq->prebuf > 0 && bq->read_index >= bq->write_index) { - - /* Buffer underflow protection */ - bq->state = PREBUF; - return -1; - } - - /* Do we need to spit out silence? */ - if (!bq->blocks || bq->blocks->index > bq->read_index) { - - size_t length; - - /* How much silence shall we return? */ - length = bq->blocks ? bq->blocks->index - bq->read_index : 0; - - /* We need to return silence, since no data is yet available */ - if (bq->silence) { - chunk->memblock = pa_memblock_ref(bq->silence); - - if (!length || length > chunk->memblock->length) - length = chunk->memblock->length; - - chunk->length = length; - } else { - chunk->memblock = NULL; - chunk->length = length; - } - - chunk->index = 0; - return 0; - } - - /* Ok, let's pass real data to the caller */ - assert(bq->blocks->index == bq->read_index); - - *chunk = bq->blocks->chunk; - pa_memblock_ref(chunk->memblock); - - return 0; -} - -void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length) { - assert(bq); - assert(length % bq->base == 0); - - assert(!chunk || length <= chunk->length); - - if (chunk) { - - if (bq->blocks && bq->blocks->index == bq->read_index) { - /* The first item in queue is valid */ - - /* Does the chunk match with what the user supplied us? */ - if (memcmp(chunk, &bq->blocks->chunk, sizeof(pa_memchunk)) != 0) - return; - - } else { - size_t l; - - /* The first item in the queue is not yet relevant */ - - assert(!bq->blocks || bq->blocks->index > bq->read_index); - l = bq->blocks ? bq->blocks->index - bq->read_index : 0; - - if (bq->silence) { - - if (!l || l > bq->silence->length) - l = bq->silence->length; - - } - - /* Do the entries still match? */ - if (chunk->index != 0 || chunk->length != l || chunk->memblock != bq->silence) - return; - } - } - - while (length > 0) { - - if (bq->blocks) { - size_t d; - - assert(bq->blocks->index >= bq->read_index); - - d = (size_t) (bq->blocks->index - bq->read_index); - - if (d >= length) { - /* The first block is too far in the future */ - - bq->read_index += length; - break; - } else { - - length -= d; - bq->read_index += d; - } - - assert(bq->blocks->index == bq->read_index); - - if (bq->blocks->chunk.length <= length) { - /* We need to drop the full block */ - - length -= bq->blocks->chunk.length; - bq->read_index += bq->blocks->chunk.length; - - drop_block(bq, bq->blocks); - } else { - /* Only the start of this block needs to be dropped */ - - bq->blocks->chunk.index += length; - bq->blocks->chunk.length -= length; - bq->blocks->index += length; - bq->read_index += length; - break; - } - - } else { - - /* The list is empty, there's nothing we could drop */ - bq->read_index += length; - break; - } - } -} - -int pa_memblockq_is_readable(pa_memblockq *bq) { - assert(bq); - - if (bq->prebuf > 0) { - size_t l = pa_memblockq_get_length(bq); - - if (bq->state == PREBUF && l < bq->prebuf) - return 0; - - if (l <= 0) - return 0; - } - - return 1; -} - -int pa_memblockq_is_writable(pa_memblockq *bq, size_t length) { - assert(bq); - - if (length % bq->base) - return 0; - - return pa_memblockq_get_length(bq) + length <= bq->tlength; -} - -size_t pa_memblockq_get_length(pa_memblockq *bq) { - assert(bq); - - if (bq->write_index <= bq->read_index) - return 0; - - return (size_t) (bq->write_index - bq->read_index); -} - -size_t pa_memblockq_missing(pa_memblockq *bq) { - size_t l; - assert(bq); - - if ((l = pa_memblockq_get_length(bq)) >= bq->tlength) - return 0; - - l = bq->tlength - l; - return (l >= bq->minreq) ? l : 0; -} - -size_t pa_memblockq_get_minreq(pa_memblockq *bq) { - assert(bq); - - return bq->minreq; -} - -void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek) { - assert(bq); - - switch (seek) { - case PA_SEEK_RELATIVE: - bq->write_index += offset; - return; - case PA_SEEK_ABSOLUTE: - bq->write_index = offset; - return; - case PA_SEEK_RELATIVE_ON_READ: - bq->write_index = bq->read_index + offset; - return; - case PA_SEEK_RELATIVE_END: - bq->write_index = (bq->blocks_tail ? bq->blocks_tail->index + (int64_t)bq->blocks_tail->chunk.length : bq->read_index) + offset; - return; - } - - assert(0); -} - -void pa_memblockq_flush(pa_memblockq *bq) { - assert(bq); - - while (bq->blocks) - drop_block(bq, bq->blocks); - - assert(bq->n_blocks == 0); - - bq->write_index = bq->read_index; - - pa_memblockq_prebuf_force(bq); -} - -size_t pa_memblockq_get_tlength(pa_memblockq *bq) { - assert(bq); - - return bq->tlength; -} - -int64_t pa_memblockq_get_read_index(pa_memblockq *bq) { - assert(bq); - return bq->read_index; -} - -int64_t pa_memblockq_get_write_index(pa_memblockq *bq) { - assert(bq); - return bq->write_index; -} - -int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk) { - pa_memchunk rchunk; - - assert(bq); - assert(chunk && bq->base); - - if (bq->base == 1) - return pa_memblockq_push(bq, chunk); - - if (!bq->mcalign) - bq->mcalign = pa_mcalign_new(bq->base, bq->memblock_stat); - - if (!can_push(bq, pa_mcalign_csize(bq->mcalign, chunk->length))) - return -1; - - pa_mcalign_push(bq->mcalign, chunk); - - while (pa_mcalign_pop(bq->mcalign, &rchunk) >= 0) { - int r; - r = pa_memblockq_push(bq, &rchunk); - pa_memblock_unref(rchunk.memblock); - - if (r < 0) - return -1; - } - - return 0; -} - -void pa_memblockq_shorten(pa_memblockq *bq, size_t length) { - size_t l; - assert(bq); - - l = pa_memblockq_get_length(bq); - - if (l > length) - pa_memblockq_drop(bq, NULL, l - length); -} - -void pa_memblockq_prebuf_disable(pa_memblockq *bq) { - assert(bq); - - if (bq->state == PREBUF) - bq->state = RUNNING; -} - -void pa_memblockq_prebuf_force(pa_memblockq *bq) { - assert(bq); - - if (bq->state == RUNNING && bq->prebuf > 0) - bq->state = PREBUF; -} - -size_t pa_memblockq_get_maxlength(pa_memblockq *bq) { - assert(bq); - - return bq->maxlength; -} - -size_t pa_memblockq_get_prebuf(pa_memblockq *bq) { - assert(bq); - - return bq->prebuf; -} diff --git a/src/polypcore/memblockq.h b/src/polypcore/memblockq.h deleted file mode 100644 index 74fb00ee..00000000 --- a/src/polypcore/memblockq.h +++ /dev/null @@ -1,140 +0,0 @@ -#ifndef foomemblockqhfoo -#define foomemblockqhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <sys/types.h> -#include <inttypes.h> - -#include <polypcore/memblock.h> -#include <polypcore/memchunk.h> -#include <polyp/def.h> - -/* A memblockq is a queue of pa_memchunks (yepp, the name is not - * perfect). It is similar to the ring buffers used by most other - * audio software. In contrast to a ring buffer this memblockq data - * type doesn't need to copy any data around, it just maintains - * references to reference counted memory blocks. */ - -typedef struct pa_memblockq pa_memblockq; - - -/* Parameters: - - - idx: start value for both read and write index - - - maxlength: maximum length of queue. If more data is pushed into - the queue, the operation will fail. Must not be 0. - - - tlength: the target length of the queue. Pass 0 for the default. - - - base: a base value for all metrics. Only multiples of this value - are popped from the queue or should be pushed into - it. Must not be 0. - - - prebuf: If the queue runs empty wait until this many bytes are in - queue again before passing the first byte out. If set - to 0 pa_memblockq_pop() will return a silence memblock - if no data is in the queue and will never fail. Pass - (size_t) -1 for the default. - - - minreq: pa_memblockq_missing() will only return values greater - than this value. Pass 0 for the default. - - - silence: return this memblock whzen reading unitialized data -*/ -pa_memblockq* pa_memblockq_new( - int64_t idx, - size_t maxlength, - size_t tlength, - size_t base, - size_t prebuf, - size_t minreq, - pa_memblock *silence, - pa_memblock_stat *s); - -void pa_memblockq_free(pa_memblockq*bq); - -/* Push a new memory chunk into the queue. */ -int pa_memblockq_push(pa_memblockq* bq, const pa_memchunk *chunk); - -/* Push a new memory chunk into the queue, but filter it through a - * pa_mcalign object. Don't mix this with pa_memblockq_seek() unless - * you know what you do. */ -int pa_memblockq_push_align(pa_memblockq* bq, const pa_memchunk *chunk); - -/* Return a copy of the next memory chunk in the queue. It is not removed from the queue */ -int pa_memblockq_peek(pa_memblockq* bq, pa_memchunk *chunk); - -/* Drop the specified bytes from the queue, but only if the first - * chunk in the queue matches the one passed here. If NULL is passed, - * this check isn't done. */ -void pa_memblockq_drop(pa_memblockq *bq, const pa_memchunk *chunk, size_t length); - -/* Test if the pa_memblockq is currently readable, that is, more data than base */ -int pa_memblockq_is_readable(pa_memblockq *bq); - -/* Test if the pa_memblockq is currently writable for the specified amount of bytes */ -int pa_memblockq_is_writable(pa_memblockq *bq, size_t length); - -/* Return the length of the queue in bytes */ -size_t pa_memblockq_get_length(pa_memblockq *bq); - -/* Return how many bytes are missing in queue to the specified fill amount */ -size_t pa_memblockq_missing(pa_memblockq *bq); - -/* Returns the minimal request value */ -size_t pa_memblockq_get_minreq(pa_memblockq *bq); - -/* Manipulate the write pointer */ -void pa_memblockq_seek(pa_memblockq *bq, int64_t offset, pa_seek_mode_t seek); - -/* Set the queue to silence, set write index to read index */ -void pa_memblockq_flush(pa_memblockq *bq); - -/* Get Target length */ -size_t pa_memblockq_get_tlength(pa_memblockq *bq); - -/* Return the current read index */ -int64_t pa_memblockq_get_read_index(pa_memblockq *bq); - -/* Return the current write index */ -int64_t pa_memblockq_get_write_index(pa_memblockq *bq); - -/* Shorten the pa_memblockq to the specified length by dropping data - * at the read end of the queue. The read index is increased until the - * queue has the specified length */ -void pa_memblockq_shorten(pa_memblockq *bq, size_t length); - -/* Ignore prebuf for now */ -void pa_memblockq_prebuf_disable(pa_memblockq *bq); - -/* Force prebuf */ -void pa_memblockq_prebuf_force(pa_memblockq *bq); - -/* Return the maximum length of the queue in bytes */ -size_t pa_memblockq_get_maxlength(pa_memblockq *bq); - -/* Return the prebuffer length in bytes */ -size_t pa_memblockq_get_prebuf(pa_memblockq *bq); - -#endif diff --git a/src/polypcore/memchunk.c b/src/polypcore/memchunk.c deleted file mode 100644 index 918b3f0f..00000000 --- a/src/polypcore/memchunk.c +++ /dev/null @@ -1,59 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include "memchunk.h" - -void pa_memchunk_make_writable(pa_memchunk *c, pa_memblock_stat *s, size_t min) { - pa_memblock *n; - size_t l; - assert(c && c->memblock && c->memblock->ref >= 1); - - if (c->memblock->ref == 1 && !c->memblock->read_only && c->memblock->length >= c->index+min) - return; - - l = c->length; - if (l < min) - l = min; - - n = pa_memblock_new(l, s); - memcpy(n->data, (uint8_t*) c->memblock->data + c->index, c->length); - pa_memblock_unref(c->memblock); - c->memblock = n; - c->index = 0; -} - -void pa_memchunk_reset(pa_memchunk *c) { - assert(c); - - c->memblock = NULL; - c->length = c->index = 0; -} diff --git a/src/polypcore/memchunk.h b/src/polypcore/memchunk.h deleted file mode 100644 index 3ddb28ee..00000000 --- a/src/polypcore/memchunk.h +++ /dev/null @@ -1,45 +0,0 @@ -#ifndef foomemchunkhfoo -#define foomemchunkhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/memblock.h> - -/* A memchunk describes a part of a memblock. In contrast to the memblock, a - * memchunk is not allocated dynamically or reference counted, instead - * it is usually stored on the stack and copied around */ - -typedef struct pa_memchunk { - pa_memblock *memblock; - size_t index, length; -} pa_memchunk; - -/* Make a memchunk writable, i.e. make sure that the caller may have - * exclusive access to the memblock and it is not read_only. If needed - * the memblock in the structure is replaced by a copy. */ -void pa_memchunk_make_writable(pa_memchunk *c, pa_memblock_stat *s, size_t min); - -/* Invalidate a memchunk. This does not free the cotaining memblock, - * but sets all members to zero. */ -void pa_memchunk_reset(pa_memchunk *c); - -#endif diff --git a/src/polypcore/modargs.c b/src/polypcore/modargs.c deleted file mode 100644 index 5d046d26..00000000 --- a/src/polypcore/modargs.c +++ /dev/null @@ -1,310 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ctype.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/hashmap.h> -#include <polypcore/idxset.h> -#include <polypcore/sample-util.h> -#include <polypcore/namereg.h> -#include <polypcore/sink.h> -#include <polypcore/source.h> -#include <polypcore/core-util.h> - -#include "modargs.h" - -struct entry { - char *key, *value; -}; - -static int add_key_value(pa_hashmap *map, char *key, char *value, const char* const valid_keys[]) { - struct entry *e; - assert(map && key && value); - - if (valid_keys) { - const char*const* v; - for (v = valid_keys; *v; v++) - if (strcmp(*v, key) == 0) - break; - - if (!*v) { - pa_xfree(key); - pa_xfree(value); - return -1; - } - } - - e = pa_xmalloc(sizeof(struct entry)); - e->key = key; - e->value = value; - pa_hashmap_put(map, key, e); - return 0; -} - -pa_modargs *pa_modargs_new(const char *args, const char* const* valid_keys) { - pa_hashmap *map = NULL; - - map = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - assert(map); - - if (args) { - enum { WHITESPACE, KEY, VALUE_START, VALUE_SIMPLE, VALUE_DOUBLE_QUOTES, VALUE_TICKS } state; - const char *p, *key, *value; - size_t key_len = 0, value_len = 0; - - key = value = NULL; - state = WHITESPACE; - for (p = args; *p; p++) { - switch (state) { - case WHITESPACE: - if (*p == '=') - goto fail; - else if (!isspace(*p)) { - key = p; - state = KEY; - key_len = 1; - } - break; - case KEY: - if (*p == '=') - state = VALUE_START; - else - key_len++; - break; - case VALUE_START: - if (*p == '\'') { - state = VALUE_TICKS; - value = p+1; - value_len = 0; - } else if (*p == '"') { - state = VALUE_DOUBLE_QUOTES; - value = p+1; - value_len = 0; - } else if (isspace(*p)) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0) - goto fail; - state = WHITESPACE; - } else { - state = VALUE_SIMPLE; - value = p; - value_len = 1; - } - break; - case VALUE_SIMPLE: - if (isspace(*p)) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) - goto fail; - state = WHITESPACE; - } else - value_len++; - break; - case VALUE_DOUBLE_QUOTES: - if (*p == '"') { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) - goto fail; - state = WHITESPACE; - } else - value_len++; - break; - case VALUE_TICKS: - if (*p == '\'') { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrndup(value, value_len), valid_keys) < 0) - goto fail; - state = WHITESPACE; - } else - value_len++; - break; - } - } - - if (state == VALUE_START) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(""), valid_keys) < 0) - goto fail; - } else if (state == VALUE_SIMPLE) { - if (add_key_value(map, pa_xstrndup(key, key_len), pa_xstrdup(value), valid_keys) < 0) - goto fail; - } else if (state != WHITESPACE) - goto fail; - } - - return (pa_modargs*) map; - -fail: - - if (map) - pa_modargs_free((pa_modargs*) map); - - return NULL; -} - - -static void free_func(void *p, PA_GCC_UNUSED void*userdata) { - struct entry *e = p; - assert(e); - pa_xfree(e->key); - pa_xfree(e->value); - pa_xfree(e); -} - -void pa_modargs_free(pa_modargs*ma) { - pa_hashmap *map = (pa_hashmap*) ma; - pa_hashmap_free(map, free_func, NULL); -} - -const char *pa_modargs_get_value(pa_modargs *ma, const char *key, const char *def) { - pa_hashmap *map = (pa_hashmap*) ma; - struct entry*e; - - if (!(e = pa_hashmap_get(map, key))) - return def; - - return e->value; -} - -int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value) { - const char *v; - assert(ma && key && value); - - if (!(v = pa_modargs_get_value(ma, key, NULL))) - return 0; - - if (pa_atou(v, value) < 0) - return -1; - - return 0; -} - -int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value) { - const char *v; - assert(ma && key && value); - - if (!(v = pa_modargs_get_value(ma, key, NULL))) - return 0; - - if (pa_atoi(v, value) < 0) - return -1; - - return 0; -} - -int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, int *value) { - const char *v; - int r; - assert(ma && key && value); - - if (!(v = pa_modargs_get_value(ma, key, NULL))) - return 0; - - if (!*v) - return -1; - - if ((r = pa_parse_boolean(v)) < 0) - return -1; - - *value = r; - return 0; -} - -int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *rss) { - const char *format; - uint32_t channels; - pa_sample_spec ss; - assert(ma && rss); - -/* DEBUG_TRAP;*/ - - ss = *rss; - if ((pa_modargs_get_value_u32(ma, "rate", &ss.rate)) < 0) - return -1; - - channels = ss.channels; - if ((pa_modargs_get_value_u32(ma, "channels", &channels)) < 0) - return -1; - ss.channels = (uint8_t) channels; - - if ((format = pa_modargs_get_value(ma, "format", NULL))) - if ((ss.format = pa_parse_sample_format(format)) < 0) - return -1; - - if (!pa_sample_spec_valid(&ss)) - return -1; - - *rss = ss; - - return 0; -} - -int pa_modargs_get_channel_map(pa_modargs *ma, pa_channel_map *rmap) { - pa_channel_map map; - const char *cm; - - assert(ma); - assert(rmap); - - map = *rmap; - - if ((cm = pa_modargs_get_value(ma, "channel_map", NULL))) - if (!pa_channel_map_parse(&map, cm)) - return -1; - - if (!pa_channel_map_valid(&map)) - return -1; - - *rmap = map; - return 0; -} - -int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *rss, pa_channel_map *rmap, pa_channel_map_def_t def) { - pa_sample_spec ss; - pa_channel_map map; - - assert(ma); - assert(rss); - assert(rmap); - - ss = *rss; - - if (pa_modargs_get_sample_spec(ma, &ss) < 0) - return -1; - - if (!pa_channel_map_init_auto(&map, ss.channels, def)) - map.channels = 0; - - if (pa_modargs_get_channel_map(ma, &map) < 0) - return -1; - - if (map.channels != ss.channels) - return -1; - - *rmap = map; - *rss = ss; - - return 0; -} diff --git a/src/polypcore/modargs.h b/src/polypcore/modargs.h deleted file mode 100644 index b6977d37..00000000 --- a/src/polypcore/modargs.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef foomodargshfoo -#define foomodargshfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> -#include <polyp/sample.h> -#include <polyp/channelmap.h> -#include <polypcore/core.h> - -typedef struct pa_modargs pa_modargs; - -/* A generic parser for module arguments */ - -/* Parse the string args. The NULL-terminated array keys contains all valid arguments. */ -pa_modargs *pa_modargs_new(const char *args, const char* const keys[]); -void pa_modargs_free(pa_modargs*ma); - -/* Return the module argument for the specified name as a string. If - * the argument was not specified, return def instead.*/ -const char *pa_modargs_get_value(pa_modargs *ma, const char *key, const char *def); - -/* Return a module argument as unsigned 32bit value in *value */ -int pa_modargs_get_value_u32(pa_modargs *ma, const char *key, uint32_t *value); -int pa_modargs_get_value_s32(pa_modargs *ma, const char *key, int32_t *value); -int pa_modargs_get_value_boolean(pa_modargs *ma, const char *key, int *value); - -/* Return sample spec data from the three arguments "rate", "format" and "channels" */ -int pa_modargs_get_sample_spec(pa_modargs *ma, pa_sample_spec *ss); - -/* Return channel map data from the argument "channel_map" */ -int pa_modargs_get_channel_map(pa_modargs *ma, pa_channel_map *map); - -/* Combination of pa_modargs_get_sample_spec() and -pa_modargs_get_channel_map(). Not always suitable, since this routine -initializes the map parameter based on the channels field of the ss -structure if no channel_map is found, using pa_channel_map_init_auto() */ - -int pa_modargs_get_sample_spec_and_channel_map(pa_modargs *ma, pa_sample_spec *ss, pa_channel_map *map, pa_channel_map_def_t def); - -#endif diff --git a/src/polypcore/modinfo.c b/src/polypcore/modinfo.c deleted file mode 100644 index a2fffb01..00000000 --- a/src/polypcore/modinfo.c +++ /dev/null @@ -1,93 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <ltdl.h> -#include <assert.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/core-util.h> -#include <polypcore/log.h> - -#include "modinfo.h" - -#define PA_SYMBOL_AUTHOR "pa__get_author" -#define PA_SYMBOL_DESCRIPTION "pa__get_description" -#define PA_SYMBOL_USAGE "pa__get_usage" -#define PA_SYMBOL_VERSION "pa__get_version" - -/* lt_dlsym() violates ISO C, so confide the breakage into this function to - * avoid warnings. */ -typedef void (*fnptr)(void); -static inline fnptr lt_dlsym_fn(lt_dlhandle handle, const char *symbol) { - return (fnptr) (long) lt_dlsym(handle, symbol); -} - -pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl) { - pa_modinfo *i; - const char* (*func)(void); - assert(dl); - - i = pa_xnew0(pa_modinfo, 1); - - if ((func = (const char* (*)(void)) lt_dlsym_fn(dl, PA_SYMBOL_AUTHOR))) - i->author = pa_xstrdup(func()); - - if ((func = (const char* (*)(void)) lt_dlsym_fn(dl, PA_SYMBOL_DESCRIPTION))) - i->description = pa_xstrdup(func()); - - if ((func = (const char* (*)(void)) lt_dlsym_fn(dl, PA_SYMBOL_USAGE))) - i->usage = pa_xstrdup(func()); - - if ((func = (const char* (*)(void)) lt_dlsym_fn(dl, PA_SYMBOL_VERSION))) - i->version = pa_xstrdup(func()); - - return i; -} - -pa_modinfo *pa_modinfo_get_by_name(const char *name) { - lt_dlhandle dl; - pa_modinfo *i; - assert(name); - - if (!(dl = lt_dlopenext(name))) { - pa_log(__FILE__": Failed to open module \"%s\": %s", name, lt_dlerror()); - return NULL; - } - - i = pa_modinfo_get_by_handle(dl); - lt_dlclose(dl); - - return i; -} - -void pa_modinfo_free(pa_modinfo *i) { - assert(i); - pa_xfree(i->author); - pa_xfree(i->description); - pa_xfree(i->usage); - pa_xfree(i->version); - pa_xfree(i); -} diff --git a/src/polypcore/modinfo.h b/src/polypcore/modinfo.h deleted file mode 100644 index 53176147..00000000 --- a/src/polypcore/modinfo.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef foomodinfohfoo -#define foomodinfohfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -/* Some functions for reading module meta data from Polypaudio modules */ - -typedef struct pa_modinfo { - char *author; - char *description; - char *usage; - char *version; -} pa_modinfo; - -/* Read meta data from an libtool handle */ -pa_modinfo *pa_modinfo_get_by_handle(lt_dlhandle dl); - -/* Read meta data from a module file */ -pa_modinfo *pa_modinfo_get_by_name(const char *name); - -/* Free meta data */ -void pa_modinfo_free(pa_modinfo *i); - -#endif diff --git a/src/polypcore/module.c b/src/polypcore/module.c deleted file mode 100644 index 47a878fb..00000000 --- a/src/polypcore/module.c +++ /dev/null @@ -1,319 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> - -#include <polyp/timeval.h> -#include <polyp/xmalloc.h> - -#include <polypcore/core-subscribe.h> -#include <polypcore/log.h> -#include <polypcore/core-util.h> - -#include "module.h" - -#define PA_SYMBOL_INIT "pa__init" -#define PA_SYMBOL_DONE "pa__done" - -#define UNLOAD_POLL_TIME 2 - -/* lt_dlsym() violates ISO C, so confide the breakage into this function to - * avoid warnings. */ -typedef void (*fnptr)(void); -static inline fnptr lt_dlsym_fn(lt_dlhandle handle, const char *symbol) { - return (fnptr) (long) lt_dlsym(handle, symbol); -} - -static void timeout_callback(pa_mainloop_api *m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { - pa_core *c = userdata; - struct timeval ntv; - assert(c && c->mainloop == m && c->module_auto_unload_event == e); - - pa_module_unload_unused(c); - - pa_gettimeofday(&ntv); - ntv.tv_sec += UNLOAD_POLL_TIME; - m->time_restart(e, &ntv); -} - -static inline fnptr load_sym(lt_dlhandle handle, const char *module, const char *symbol) { - char *buffer, *ch; - size_t buflen; - fnptr res; - - res = lt_dlsym_fn(handle, symbol); - if (res) - return res; - - /* As the .la files might have been cleansed from the system, we should - * try with the ltdl prefix as well. */ - - buflen = strlen(symbol) + strlen(module) + strlen("_LTX_") + 1; - buffer = pa_xmalloc(buflen); - assert(buffer); - - strcpy(buffer, module); - - for (ch = buffer;*ch != '\0';ch++) { - if (!isalnum(*ch)) - *ch = '_'; - } - - strcat(buffer, "_LTX_"); - strcat(buffer, symbol); - - res = lt_dlsym_fn(handle, buffer); - - pa_xfree(buffer); - - return res; -} - -pa_module* pa_module_load(pa_core *c, const char *name, const char *argument) { - pa_module *m = NULL; - int r; - - assert(c && name); - - if (c->disallow_module_loading) - goto fail; - - m = pa_xmalloc(sizeof(pa_module)); - - m->name = pa_xstrdup(name); - m->argument = pa_xstrdup(argument); - - if (!(m->dl = lt_dlopenext(name))) { - pa_log(__FILE__": Failed to open module \"%s\": %s", name, lt_dlerror()); - goto fail; - } - - if (!(m->init = (int (*)(pa_core *_c, pa_module*_m)) load_sym(m->dl, name, PA_SYMBOL_INIT))) { - pa_log(__FILE__": Failed to load module \"%s\": symbol \""PA_SYMBOL_INIT"\" not found.", name); - goto fail; - } - - if (!(m->done = (void (*)(pa_core *_c, pa_module*_m)) load_sym(m->dl, name, PA_SYMBOL_DONE))) { - pa_log(__FILE__": Failed to load module \"%s\": symbol \""PA_SYMBOL_DONE"\" not found.", name); - goto fail; - } - - m->userdata = NULL; - m->core = c; - m->n_used = -1; - m->auto_unload = 0; - m->unload_requested = 0; - - assert(m->init); - if (m->init(c, m) < 0) { - pa_log_error(__FILE__": Failed to load module \"%s\" (argument: \"%s\"): initialization failed.", name, argument ? argument : ""); - goto fail; - } - - if (!c->modules) - c->modules = pa_idxset_new(NULL, NULL); - - if (!c->module_auto_unload_event) { - struct timeval ntv; - pa_gettimeofday(&ntv); - ntv.tv_sec += UNLOAD_POLL_TIME; - c->module_auto_unload_event = c->mainloop->time_new(c->mainloop, &ntv, timeout_callback, c); - } - assert(c->module_auto_unload_event); - - assert(c->modules); - r = pa_idxset_put(c->modules, m, &m->index); - assert(r >= 0 && m->index != PA_IDXSET_INVALID); - - pa_log_info(__FILE__": Loaded \"%s\" (index: #%u; argument: \"%s\").", m->name, m->index, m->argument ? m->argument : ""); - - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_NEW, m->index); - - return m; - -fail: - - if (m) { - pa_xfree(m->argument); - pa_xfree(m->name); - - if (m->dl) - lt_dlclose(m->dl); - - pa_xfree(m); - } - - return NULL; -} - -static void pa_module_free(pa_module *m) { - assert(m && m->done && m->core); - - if (m->core->disallow_module_loading) - return; - - pa_log_info(__FILE__": Unloading \"%s\" (index: #%u).", m->name, m->index); - - m->done(m->core, m); - - lt_dlclose(m->dl); - - pa_log_info(__FILE__": Unloaded \"%s\" (index: #%u).", m->name, m->index); - - pa_subscription_post(m->core, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_REMOVE, m->index); - - pa_xfree(m->name); - pa_xfree(m->argument); - pa_xfree(m); -} - -void pa_module_unload(pa_core *c, pa_module *m) { - assert(c && m); - - assert(c->modules); - if (!(m = pa_idxset_remove_by_data(c->modules, m, NULL))) - return; - - pa_module_free(m); -} - -void pa_module_unload_by_index(pa_core *c, uint32_t idx) { - pa_module *m; - assert(c && idx != PA_IDXSET_INVALID); - - assert(c->modules); - if (!(m = pa_idxset_remove_by_index(c->modules, idx))) - return; - - pa_module_free(m); -} - -static void free_callback(void *p, PA_GCC_UNUSED void *userdata) { - pa_module *m = p; - assert(m); - pa_module_free(m); -} - -void pa_module_unload_all(pa_core *c) { - assert(c); - - if (!c->modules) - return; - - pa_idxset_free(c->modules, free_callback, NULL); - c->modules = NULL; - - if (c->module_auto_unload_event) { - c->mainloop->time_free(c->module_auto_unload_event); - c->module_auto_unload_event = NULL; - } - - if (c->module_defer_unload_event) { - c->mainloop->defer_free(c->module_defer_unload_event); - c->module_defer_unload_event = NULL; - } -} - -static int unused_callback(void *p, PA_GCC_UNUSED uint32_t idx, int *del, void *userdata) { - pa_module *m = p; - time_t *now = userdata; - assert(p && del && now); - - if (m->n_used == 0 && m->auto_unload && m->last_used_time+m->core->module_idle_time <= *now) { - pa_module_free(m); - *del = 1; - } - - return 0; -} - -void pa_module_unload_unused(pa_core *c) { - time_t now; - assert(c); - - if (!c->modules) - return; - - time(&now); - pa_idxset_foreach(c->modules, unused_callback, &now); -} - -static int unload_callback(void *p, PA_GCC_UNUSED uint32_t idx, int *del, PA_GCC_UNUSED void *userdata) { - pa_module *m = p; - assert(m); - - if (m->unload_requested) { - pa_module_free(m); - *del = 1; - } - - return 0; -} - -static void defer_cb(pa_mainloop_api*api, pa_defer_event *e, void *userdata) { - pa_core *core = userdata; - api->defer_enable(e, 0); - - if (!core->modules) - return; - - pa_idxset_foreach(core->modules, unload_callback, NULL); - -} - -void pa_module_unload_request(pa_module *m) { - assert(m); - - m->unload_requested = 1; - - if (!m->core->module_defer_unload_event) - m->core->module_defer_unload_event = m->core->mainloop->defer_new(m->core->mainloop, defer_cb, m->core); - - m->core->mainloop->defer_enable(m->core->module_defer_unload_event, 1); -} - -void pa_module_set_used(pa_module*m, int used) { - assert(m); - - if (m->n_used != used) - pa_subscription_post(m->core, PA_SUBSCRIPTION_EVENT_MODULE|PA_SUBSCRIPTION_EVENT_CHANGE, m->index); - - if (m->n_used != used && used == 0) - time(&m->last_used_time); - - m->n_used = used; -} - -pa_modinfo *pa_module_get_info(pa_module *m) { - assert(m); - - return pa_modinfo_get_by_handle(m->dl); -} diff --git a/src/polypcore/module.h b/src/polypcore/module.h deleted file mode 100644 index 03b9bc87..00000000 --- a/src/polypcore/module.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef foomodulehfoo -#define foomodulehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> -#include <ltdl.h> - -#include <polypcore/core.h> -#include <polypcore/modinfo.h> - -typedef struct pa_module pa_module; - -struct pa_module { - pa_core *core; - char *name, *argument; - uint32_t index; - - lt_dlhandle dl; - - int (*init)(pa_core *c, pa_module*m); - void (*done)(pa_core *c, pa_module*m); - - void *userdata; - - int n_used; - int auto_unload; - time_t last_used_time; - - int unload_requested; -}; - -pa_module* pa_module_load(pa_core *c, const char *name, const char*argument); -void pa_module_unload(pa_core *c, pa_module *m); -void pa_module_unload_by_index(pa_core *c, uint32_t idx); - -void pa_module_unload_all(pa_core *c); -void pa_module_unload_unused(pa_core *c); - -void pa_module_unload_request(pa_module *m); - -void pa_module_set_used(pa_module*m, int used); - -#define PA_MODULE_AUTHOR(s) const char * pa__get_author(void) { return s; } -#define PA_MODULE_DESCRIPTION(s) const char * pa__get_description(void) { return s; } -#define PA_MODULE_USAGE(s) const char * pa__get_usage(void) { return s; } -#define PA_MODULE_VERSION(s) const char * pa__get_version(void) { return s; } - -pa_modinfo *pa_module_get_info(pa_module *m); - -#endif diff --git a/src/polypcore/namereg.c b/src/polypcore/namereg.c deleted file mode 100644 index 17d75146..00000000 --- a/src/polypcore/namereg.c +++ /dev/null @@ -1,214 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <assert.h> -#include <string.h> -#include <stdio.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/autoload.h> -#include <polypcore/source.h> -#include <polypcore/sink.h> -#include <polypcore/core-subscribe.h> -#include <polypcore/core-util.h> - -#include "namereg.h" - -struct namereg_entry { - pa_namereg_type_t type; - char *name; - void *data; -}; - -void pa_namereg_free(pa_core *c) { - assert(c); - if (!c->namereg) - return; - assert(pa_hashmap_size(c->namereg) == 0); - pa_hashmap_free(c->namereg, NULL, NULL); -} - -const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, int fail) { - struct namereg_entry *e; - char *n = NULL; - int r; - - assert(c && name && data); - - if (!c->namereg) { - c->namereg = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); - assert(c->namereg); - } - - if ((e = pa_hashmap_get(c->namereg, name)) && fail) - return NULL; - - if (!e) - n = pa_xstrdup(name); - else { - unsigned i; - size_t l = strlen(name); - n = pa_xmalloc(l+3); - - for (i = 1; i <= 99; i++) { - snprintf(n, l+2, "%s%u", name, i); - - if (!(e = pa_hashmap_get(c->namereg, n))) - break; - } - - if (e) { - pa_xfree(n); - return NULL; - } - } - - assert(n); - e = pa_xmalloc(sizeof(struct namereg_entry)); - e->type = type; - e->name = n; - e->data = data; - - r = pa_hashmap_put(c->namereg, e->name, e); - assert (r >= 0); - - return e->name; - -} - -void pa_namereg_unregister(pa_core *c, const char *name) { - struct namereg_entry *e; - assert(c && name); - - e = pa_hashmap_remove(c->namereg, name); - assert(e); - - pa_xfree(e->name); - pa_xfree(e); -} - -void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type, int autoload) { - struct namereg_entry *e; - uint32_t idx; - assert(c); - - if (!name) { - if (type == PA_NAMEREG_SOURCE) - name = pa_namereg_get_default_source_name(c); - else if (type == PA_NAMEREG_SINK) - name = pa_namereg_get_default_sink_name(c); - } - - if (!name) - return NULL; - - if (c->namereg && (e = pa_hashmap_get(c->namereg, name))) - if (e->type == type) - return e->data; - - if (pa_atou(name, &idx) < 0) { - - if (autoload) { - pa_autoload_request(c, name, type); - - if (c->namereg && (e = pa_hashmap_get(c->namereg, name))) - if (e->type == type) - return e->data; - } - - return NULL; - } - - if (type == PA_NAMEREG_SINK) - return pa_idxset_get_by_index(c->sinks, idx); - else if (type == PA_NAMEREG_SOURCE) - return pa_idxset_get_by_index(c->sources, idx); - else if (type == PA_NAMEREG_SAMPLE && c->scache) - return pa_idxset_get_by_index(c->scache, idx); - - return NULL; -} - -void pa_namereg_set_default(pa_core*c, const char *name, pa_namereg_type_t type) { - char **s; - assert(c && (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE)); - - s = type == PA_NAMEREG_SINK ? &c->default_sink_name : &c->default_source_name; - assert(s); - - if (!name && !*s) - return; - - if (name && *s && !strcmp(name, *s)) - return; - - pa_xfree(*s); - *s = pa_xstrdup(name); - pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX); -} - -const char *pa_namereg_get_default_sink_name(pa_core *c) { - pa_sink *s; - assert(c); - - if (c->default_sink_name) - return c->default_sink_name; - - if ((s = pa_idxset_first(c->sinks, NULL))) - pa_namereg_set_default(c, s->name, PA_NAMEREG_SINK); - - if (c->default_sink_name) - return c->default_sink_name; - - return NULL; -} - -const char *pa_namereg_get_default_source_name(pa_core *c) { - pa_source *s; - uint32_t idx; - - assert(c); - - if (c->default_source_name) - return c->default_source_name; - - for (s = pa_idxset_first(c->sources, &idx); s; s = pa_idxset_next(c->sources, &idx)) - if (!s->monitor_of) { - pa_namereg_set_default(c, s->name, PA_NAMEREG_SOURCE); - break; - } - - if (!c->default_source_name) - if ((s = pa_idxset_first(c->sources, NULL))) - pa_namereg_set_default(c, s->name, PA_NAMEREG_SOURCE); - - if (c->default_source_name) - return c->default_source_name; - - return NULL; -} diff --git a/src/polypcore/namereg.h b/src/polypcore/namereg.h deleted file mode 100644 index a98295ff..00000000 --- a/src/polypcore/namereg.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef foonamereghfoo -#define foonamereghfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> - -typedef enum pa_namereg_type { - PA_NAMEREG_SINK, - PA_NAMEREG_SOURCE, - PA_NAMEREG_SAMPLE -} pa_namereg_type_t; - -void pa_namereg_free(pa_core *c); - -const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, int fail); -void pa_namereg_unregister(pa_core *c, const char *name); -void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type, int autoload); -void pa_namereg_set_default(pa_core*c, const char *name, pa_namereg_type_t type); - -const char *pa_namereg_get_default_sink_name(pa_core *c); -const char *pa_namereg_get_default_source_name(pa_core *c); - -#endif diff --git a/src/polypcore/native-common.h b/src/polypcore/native-common.h deleted file mode 100644 index 1107da55..00000000 --- a/src/polypcore/native-common.h +++ /dev/null @@ -1,127 +0,0 @@ -#ifndef foonativecommonhfoo -#define foonativecommonhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polyp/cdecl.h> -#include <polyp/def.h> - -PA_C_DECL_BEGIN - -enum { - /* Generic commands */ - PA_COMMAND_ERROR, - PA_COMMAND_TIMEOUT, /* pseudo command */ - PA_COMMAND_REPLY, - - /* Commands from client to server */ - PA_COMMAND_CREATE_PLAYBACK_STREAM, - PA_COMMAND_DELETE_PLAYBACK_STREAM, - PA_COMMAND_CREATE_RECORD_STREAM, - PA_COMMAND_DELETE_RECORD_STREAM, - PA_COMMAND_EXIT, - PA_COMMAND_AUTH, - PA_COMMAND_SET_CLIENT_NAME, - PA_COMMAND_LOOKUP_SINK, - PA_COMMAND_LOOKUP_SOURCE, - PA_COMMAND_DRAIN_PLAYBACK_STREAM, - PA_COMMAND_STAT, - PA_COMMAND_GET_PLAYBACK_LATENCY, - PA_COMMAND_CREATE_UPLOAD_STREAM, - PA_COMMAND_DELETE_UPLOAD_STREAM, - PA_COMMAND_FINISH_UPLOAD_STREAM, - PA_COMMAND_PLAY_SAMPLE, - PA_COMMAND_REMOVE_SAMPLE, - - PA_COMMAND_GET_SERVER_INFO, - PA_COMMAND_GET_SINK_INFO, - PA_COMMAND_GET_SINK_INFO_LIST, - PA_COMMAND_GET_SOURCE_INFO, - PA_COMMAND_GET_SOURCE_INFO_LIST, - PA_COMMAND_GET_MODULE_INFO, - PA_COMMAND_GET_MODULE_INFO_LIST, - PA_COMMAND_GET_CLIENT_INFO, - PA_COMMAND_GET_CLIENT_INFO_LIST, - PA_COMMAND_GET_SINK_INPUT_INFO, - PA_COMMAND_GET_SINK_INPUT_INFO_LIST, - PA_COMMAND_GET_SOURCE_OUTPUT_INFO, - PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST, - PA_COMMAND_GET_SAMPLE_INFO, - PA_COMMAND_GET_SAMPLE_INFO_LIST, - PA_COMMAND_SUBSCRIBE, - - PA_COMMAND_SET_SINK_VOLUME, - PA_COMMAND_SET_SINK_INPUT_VOLUME, - PA_COMMAND_SET_SOURCE_VOLUME, - - PA_COMMAND_SET_SINK_MUTE, - PA_COMMAND_SET_SOURCE_MUTE, - - PA_COMMAND_CORK_PLAYBACK_STREAM, - PA_COMMAND_FLUSH_PLAYBACK_STREAM, - PA_COMMAND_TRIGGER_PLAYBACK_STREAM, - - PA_COMMAND_SET_DEFAULT_SINK, - PA_COMMAND_SET_DEFAULT_SOURCE, - - PA_COMMAND_SET_PLAYBACK_STREAM_NAME, - PA_COMMAND_SET_RECORD_STREAM_NAME, - - PA_COMMAND_KILL_CLIENT, - PA_COMMAND_KILL_SINK_INPUT, - PA_COMMAND_KILL_SOURCE_OUTPUT, - PA_COMMAND_LOAD_MODULE, - PA_COMMAND_UNLOAD_MODULE, - PA_COMMAND_ADD_AUTOLOAD, - PA_COMMAND_REMOVE_AUTOLOAD, - PA_COMMAND_GET_AUTOLOAD_INFO, - PA_COMMAND_GET_AUTOLOAD_INFO_LIST, - PA_COMMAND_GET_RECORD_LATENCY, - PA_COMMAND_CORK_RECORD_STREAM, - PA_COMMAND_FLUSH_RECORD_STREAM, - PA_COMMAND_PREBUF_PLAYBACK_STREAM, - - /* Commands from server to client */ - PA_COMMAND_REQUEST, - PA_COMMAND_OVERFLOW, - PA_COMMAND_UNDERFLOW, - PA_COMMAND_PLAYBACK_STREAM_KILLED, - PA_COMMAND_RECORD_STREAM_KILLED, - PA_COMMAND_SUBSCRIBE_EVENT, - - PA_COMMAND_MAX -}; - -#define PA_NATIVE_COOKIE_LENGTH 256 -#define PA_NATIVE_COOKIE_FILE ".polypaudio-cookie" - -#define PA_NATIVE_DEFAULT_PORT 4713 - -#define PA_NATIVE_COOKIE_PROPERTY_NAME "protocol-native-cookie" -#define PA_NATIVE_SERVER_PROPERTY_NAME "protocol-native-server" - -#define PA_NATIVE_DEFAULT_UNIX_SOCKET "native" - - -PA_C_DECL_END - -#endif diff --git a/src/polypcore/packet.c b/src/polypcore/packet.c deleted file mode 100644 index 646b59e0..00000000 --- a/src/polypcore/packet.c +++ /dev/null @@ -1,79 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> - -#include <polyp/xmalloc.h> - -#include "packet.h" - -pa_packet* pa_packet_new(size_t length) { - pa_packet *p; - - assert(length); - - p = pa_xmalloc(sizeof(pa_packet)+length); - p->ref = 1; - p->length = length; - p->data = (uint8_t*) (p+1); - p->type = PA_PACKET_APPENDED; - - return p; -} - -pa_packet* pa_packet_new_dynamic(void* data, size_t length) { - pa_packet *p; - - assert(data); - assert(length); - - p = pa_xnew(pa_packet, 1); - p->ref = 1; - p->length = length; - p->data = data; - p->type = PA_PACKET_DYNAMIC; - - return p; -} - -pa_packet* pa_packet_ref(pa_packet *p) { - assert(p); - assert(p->ref >= 1); - - p->ref++; - return p; -} - -void pa_packet_unref(pa_packet *p) { - assert(p); - assert(p->ref >= 1); - - if (--p->ref == 0) { - if (p->type == PA_PACKET_DYNAMIC) - pa_xfree(p->data); - pa_xfree(p); - } -} diff --git a/src/polypcore/packet.h b/src/polypcore/packet.h deleted file mode 100644 index fbc58232..00000000 --- a/src/polypcore/packet.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef foopackethfoo -#define foopackethfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <sys/types.h> -#include <inttypes.h> - -typedef struct pa_packet { - enum { PA_PACKET_APPENDED, PA_PACKET_DYNAMIC } type; - unsigned ref; - size_t length; - uint8_t *data; -} pa_packet; - -pa_packet* pa_packet_new(size_t length); -pa_packet* pa_packet_new_dynamic(void* data, size_t length); - -pa_packet* pa_packet_ref(pa_packet *p); -void pa_packet_unref(pa_packet *p); - -#endif diff --git a/src/polypcore/parseaddr.c b/src/polypcore/parseaddr.c deleted file mode 100644 index d0687b05..00000000 --- a/src/polypcore/parseaddr.c +++ /dev/null @@ -1,115 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <assert.h> -#include <stdlib.h> - -#include <polyp/xmalloc.h> - -#include <polyp/util.h> -#include <polypcore/core-util.h> - -#include "parseaddr.h" - -/* Parse addresses in one of the following forms: - * HOSTNAME - * HOSTNAME:PORT - * [HOSTNAME] - * [HOSTNAME]:PORT - * - * Return a newly allocated string of the hostname and fill in *ret_port if specified */ - -static char *parse_host(const char *s, uint16_t *ret_port) { - assert(s && ret_port); - if (*s == '[') { - char *e; - if (!(e = strchr(s+1, ']'))) - return NULL; - - if (e[1] == ':') - *ret_port = atoi(e+2); - else if (e[1] != 0) - return NULL; - - return pa_xstrndup(s+1, e-s-1); - } else { - char *e; - - if (!(e = strrchr(s, ':'))) - return pa_xstrdup(s); - - *ret_port = atoi(e+1); - return pa_xstrndup(s, e-s); - } -} - -int pa_parse_address(const char *name, pa_parsed_address *ret_p) { - const char *p; - assert(name && ret_p); - memset(ret_p, 0, sizeof(pa_parsed_address)); - ret_p->type = PA_PARSED_ADDRESS_TCP_AUTO; - - if (*name == '{') { - char hn[256], *pfx; - /* The URL starts with a host specification for detecting local connections */ - - if (!pa_get_host_name(hn, sizeof(hn))) - return -1; - - pfx = pa_sprintf_malloc("{%s}", hn); - if (!pa_startswith(name, pfx)) { - pa_xfree(pfx); - /* Not local */ - return -1; - } - - p = name + strlen(pfx); - pa_xfree(pfx); - } else - p = name; - - if (*p == '/') - ret_p->type = PA_PARSED_ADDRESS_UNIX; - else if (pa_startswith(p, "unix:")) { - ret_p->type = PA_PARSED_ADDRESS_UNIX; - p += sizeof("unix:")-1; - } else if (pa_startswith(p, "tcp:") || pa_startswith(p, "tcp4:")) { - ret_p->type = PA_PARSED_ADDRESS_TCP4; - p += sizeof("tcp:")-1; - } else if (pa_startswith(p, "tcp6:")) { - ret_p->type = PA_PARSED_ADDRESS_TCP6; - p += sizeof("tcp6:")-1; - } - - if (ret_p->type == PA_PARSED_ADDRESS_UNIX) - ret_p->path_or_host = pa_xstrdup(p); - else - if (!(ret_p->path_or_host = parse_host(p, &ret_p->port))) - return -1; - - - return 0; -} diff --git a/src/polypcore/parseaddr.h b/src/polypcore/parseaddr.h deleted file mode 100644 index eff9dd3b..00000000 --- a/src/polypcore/parseaddr.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef fooparseaddrhfoo -#define fooparseaddrhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> - -typedef enum pa_parsed_address_type { - PA_PARSED_ADDRESS_UNIX, - PA_PARSED_ADDRESS_TCP4, - PA_PARSED_ADDRESS_TCP6, - PA_PARSED_ADDRESS_TCP_AUTO -} pa_parsed_address_type_t; - -typedef struct pa_parsed_address { - pa_parsed_address_type_t type; - char *path_or_host; - uint16_t port; -} pa_parsed_address; - -int pa_parse_address(const char *a, pa_parsed_address *ret_p); - -#endif diff --git a/src/polypcore/pdispatch.c b/src/polypcore/pdispatch.c deleted file mode 100644 index c6f90bac..00000000 --- a/src/polypcore/pdispatch.c +++ /dev/null @@ -1,318 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> - -#include <polyp/timeval.h> -#include <polyp/xmalloc.h> - -#include <polypcore/native-common.h> -#include <polypcore/llist.h> -#include <polypcore/log.h> -#include <polypcore/core-util.h> - -#include "pdispatch.h" - -/*#define DEBUG_OPCODES */ - -#ifdef DEBUG_OPCODES - -static const char *command_names[PA_COMMAND_MAX] = { - [PA_COMMAND_ERROR] = "ERROR", - [PA_COMMAND_TIMEOUT] = "TIMEOUT", - [PA_COMMAND_REPLY] = "REPLY", - [PA_COMMAND_CREATE_PLAYBACK_STREAM] = "CREATE_PLAYBACK_STREAM", - [PA_COMMAND_DELETE_PLAYBACK_STREAM] = "DELETE_PLAYBACK_STREAM", - [PA_COMMAND_CREATE_RECORD_STREAM] = "CREATE_RECORD_STREAM", - [PA_COMMAND_DELETE_RECORD_STREAM] = "DELETE_RECORD_STREAM", - [PA_COMMAND_AUTH] = "AUTH", - [PA_COMMAND_REQUEST] = "REQUEST", - [PA_COMMAND_EXIT] = "EXIT", - [PA_COMMAND_SET_CLIENT_NAME] = "SET_CLIENT_NAME", - [PA_COMMAND_LOOKUP_SINK] = "LOOKUP_SINK", - [PA_COMMAND_LOOKUP_SOURCE] = "LOOKUP_SOURCE", - [PA_COMMAND_DRAIN_PLAYBACK_STREAM] = "DRAIN_PLAYBACK_STREAM", - [PA_COMMAND_PLAYBACK_STREAM_KILLED] = "PLAYBACK_STREAM_KILLED", - [PA_COMMAND_RECORD_STREAM_KILLED] = "RECORD_STREAM_KILLED", - [PA_COMMAND_STAT] = "STAT", - [PA_COMMAND_GET_PLAYBACK_LATENCY] = "PLAYBACK_LATENCY", - [PA_COMMAND_CREATE_UPLOAD_STREAM] = "CREATE_UPLOAD_STREAM", - [PA_COMMAND_DELETE_UPLOAD_STREAM] = "DELETE_UPLOAD_STREAM", - [PA_COMMAND_FINISH_UPLOAD_STREAM] = "FINISH_UPLOAD_STREAM", - [PA_COMMAND_PLAY_SAMPLE] = "PLAY_SAMPLE", - [PA_COMMAND_REMOVE_SAMPLE] = "REMOVE_SAMPLE", - [PA_COMMAND_GET_SERVER_INFO] = "GET_SERVER_INFO", - [PA_COMMAND_GET_SINK_INFO] = "GET_SINK_INFO", - [PA_COMMAND_GET_SINK_INFO_LIST] = "GET_SINK_INFO_LIST", - [PA_COMMAND_GET_SOURCE_INFO] = "GET_SOURCE_INFO", - [PA_COMMAND_GET_SOURCE_INFO_LIST] = "GET_SOURCE_INFO_LIST", - [PA_COMMAND_GET_MODULE_INFO] = "GET_MODULE_INFO", - [PA_COMMAND_GET_MODULE_INFO_LIST] = "GET_MODULE_INFO_LIST", - [PA_COMMAND_GET_CLIENT_INFO] = "GET_CLIENT_INFO", - [PA_COMMAND_GET_CLIENT_INFO_LIST] = "GET_CLIENT_INFO_LIST", - [PA_COMMAND_GET_SAMPLE_INFO] = "GET_SAMPLE_INFO", - [PA_COMMAND_GET_SAMPLE_INFO_LIST] = "GET_SAMPLE_INFO_LIST", - [PA_COMMAND_GET_SINK_INPUT_INFO] = "GET_SINK_INPUT_INFO", - [PA_COMMAND_GET_SINK_INPUT_INFO_LIST] = "GET_SINK_INPUT_INFO_LIST", - [PA_COMMAND_GET_SOURCE_OUTPUT_INFO] = "GET_SOURCE_OUTPUT_INFO", - [PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST] = "GET_SOURCE_OUTPUT_INFO_LIST", - [PA_COMMAND_SUBSCRIBE] = "SUBSCRIBE", - [PA_COMMAND_SUBSCRIBE_EVENT] = "SUBSCRIBE_EVENT", - [PA_COMMAND_SET_SINK_VOLUME] = "SET_SINK_VOLUME", - [PA_COMMAND_SET_SINK_INPUT_VOLUME] = "SET_SINK_INPUT_VOLUME", - [PA_COMMAND_SET_SOURCE_VOLUME] = "SET_SOURCE_VOLME", - [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = "TRIGGER_PLAYBACK_STREAM", - [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = "FLUSH_PLAYBACK_STREAM", - [PA_COMMAND_CORK_PLAYBACK_STREAM] = "CORK_PLAYBACK_STREAM", - [PA_COMMAND_GET_AUTOLOAD_INFO] = "GET_AUTOLOAD_INFO", - [PA_COMMAND_GET_AUTOLOAD_INFO_LIST] = "GET_AUTOLOAD_INFO_LIST", -}; - -#endif - -struct reply_info { - pa_pdispatch *pdispatch; - PA_LLIST_FIELDS(struct reply_info); - pa_pdispatch_cb_t callback; - void *userdata; - pa_free_cb_t free_cb; - uint32_t tag; - pa_time_event *time_event; -}; - -struct pa_pdispatch { - int ref; - pa_mainloop_api *mainloop; - const pa_pdispatch_cb_t *callback_table; - unsigned n_commands; - PA_LLIST_HEAD(struct reply_info, replies); - pa_pdispatch_drain_callback drain_callback; - void *drain_userdata; - const void *creds; -}; - -static void reply_info_free(struct reply_info *r) { - assert(r && r->pdispatch && r->pdispatch->mainloop); - - if (r->time_event) - r->pdispatch->mainloop->time_free(r->time_event); - - PA_LLIST_REMOVE(struct reply_info, r->pdispatch->replies, r); - - pa_xfree(r); -} - -pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *mainloop, const pa_pdispatch_cb_t*table, unsigned entries) { - pa_pdispatch *pd; - assert(mainloop); - - assert((entries && table) || (!entries && !table)); - - pd = pa_xmalloc(sizeof(pa_pdispatch)); - pd->ref = 1; - pd->mainloop = mainloop; - pd->callback_table = table; - pd->n_commands = entries; - PA_LLIST_HEAD_INIT(pa_reply_info, pd->replies); - pd->drain_callback = NULL; - pd->drain_userdata = NULL; - pd->creds = NULL; - - return pd; -} - -static void pdispatch_free(pa_pdispatch *pd) { - assert(pd); - - while (pd->replies) { - if (pd->replies->free_cb) - pd->replies->free_cb(pd->replies->userdata); - - reply_info_free(pd->replies); - } - - pa_xfree(pd); -} - -static void run_action(pa_pdispatch *pd, struct reply_info *r, uint32_t command, pa_tagstruct *ts) { - pa_pdispatch_cb_t callback; - void *userdata; - uint32_t tag; - assert(r); - - pa_pdispatch_ref(pd); - - callback = r->callback; - userdata = r->userdata; - tag = r->tag; - - reply_info_free(r); - - callback(pd, command, tag, ts, userdata); - - if (pd->drain_callback && !pa_pdispatch_is_pending(pd)) - pd->drain_callback(pd, pd->drain_userdata); - - pa_pdispatch_unref(pd); -} - -int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*packet, const void *creds, void *userdata) { - uint32_t tag, command; - pa_tagstruct *ts = NULL; - int ret = -1; - assert(pd && packet && packet->data); - - pa_pdispatch_ref(pd); - - if (packet->length <= 8) - goto finish; - - ts = pa_tagstruct_new(packet->data, packet->length); - assert(ts); - - if (pa_tagstruct_getu32(ts, &command) < 0 || - pa_tagstruct_getu32(ts, &tag) < 0) - goto finish; - -#ifdef DEBUG_OPCODES -{ - char t[256]; - char const *p; - if (!(p = command_names[command])) - snprintf((char*) (p = t), sizeof(t), "%u", command); - - pa_log(__FILE__": Recieved opcode <%s>", p); -} -#endif - - pd->creds = creds; - - if (command == PA_COMMAND_ERROR || command == PA_COMMAND_REPLY) { - struct reply_info *r; - - for (r = pd->replies; r; r = r->next) - if (r->tag == tag) - break; - - if (r) - run_action(pd, r, command, ts); - - } else if (pd->callback_table && (command < pd->n_commands) && pd->callback_table[command]) { - const pa_pdispatch_cb_t *c = pd->callback_table+command; - - (*c)(pd, command, tag, ts, userdata); - } else { - pa_log(__FILE__": Recieved unsupported command %u", command); - goto finish; - } - - ret = 0; - -finish: - pd->creds = NULL; - - if (ts) - pa_tagstruct_free(ts); - - pa_pdispatch_unref(pd); - - return ret; -} - -static void timeout_callback(pa_mainloop_api*m, pa_time_event*e, PA_GCC_UNUSED const struct timeval *tv, void *userdata) { - struct reply_info*r = userdata; - assert(r && r->time_event == e && r->pdispatch && r->pdispatch->mainloop == m && r->callback); - - run_action(r->pdispatch, r, PA_COMMAND_TIMEOUT, NULL); -} - -void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t cb, void *userdata, pa_free_cb_t free_cb) { - struct reply_info *r; - struct timeval tv; - assert(pd && pd->ref >= 1 && cb); - - r = pa_xmalloc(sizeof(struct reply_info)); - r->pdispatch = pd; - r->callback = cb; - r->userdata = userdata; - r->free_cb = free_cb; - r->tag = tag; - - pa_gettimeofday(&tv); - tv.tv_sec += timeout; - - r->time_event = pd->mainloop->time_new(pd->mainloop, &tv, timeout_callback, r); - assert(r->time_event); - - PA_LLIST_PREPEND(struct reply_info, pd->replies, r); -} - -int pa_pdispatch_is_pending(pa_pdispatch *pd) { - assert(pd); - - return !!pd->replies; -} - -void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, void (*cb)(pa_pdispatch *pd, void *userdata), void *userdata) { - assert(pd); - assert(!cb || pa_pdispatch_is_pending(pd)); - - pd->drain_callback = cb; - pd->drain_userdata = userdata; -} - -void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata) { - struct reply_info *r, *n; - assert(pd); - - for (r = pd->replies; r; r = n) { - n = r->next; - - if (r->userdata == userdata) - reply_info_free(r); - } -} - -void pa_pdispatch_unref(pa_pdispatch *pd) { - assert(pd && pd->ref >= 1); - - if (!(--(pd->ref))) - pdispatch_free(pd); -} - -pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd) { - assert(pd && pd->ref >= 1); - pd->ref++; - return pd; -} - -const void * pa_pdispatch_creds(pa_pdispatch *pd) { - assert(pd); - assert(pd->ref >= 1); - - return pd->creds; -} diff --git a/src/polypcore/pdispatch.h b/src/polypcore/pdispatch.h deleted file mode 100644 index 0074e8b3..00000000 --- a/src/polypcore/pdispatch.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef foopdispatchhfoo -#define foopdispatchhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> -#include <polyp/mainloop-api.h> -#include <polyp/def.h> -#include <polypcore/tagstruct.h> -#include <polypcore/packet.h> - -typedef struct pa_pdispatch pa_pdispatch; - -typedef void (*pa_pdispatch_cb_t)(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -typedef void (*pa_pdispatch_drain_callback)(pa_pdispatch *pd, void *userdata); - -pa_pdispatch* pa_pdispatch_new(pa_mainloop_api *m, const pa_pdispatch_cb_t*table, unsigned entries); -void pa_pdispatch_unref(pa_pdispatch *pd); -pa_pdispatch* pa_pdispatch_ref(pa_pdispatch *pd); - -int pa_pdispatch_run(pa_pdispatch *pd, pa_packet*p, const void*creds, void *userdata); - -void pa_pdispatch_register_reply(pa_pdispatch *pd, uint32_t tag, int timeout, pa_pdispatch_cb_t callback, void *userdata, pa_free_cb_t free_cb); - -int pa_pdispatch_is_pending(pa_pdispatch *pd); - -void pa_pdispatch_set_drain_callback(pa_pdispatch *pd, pa_pdispatch_drain_callback callback, void *userdata); - -/* Remove all reply slots with the give userdata parameter */ -void pa_pdispatch_unregister_reply(pa_pdispatch *pd, void *userdata); - -const void * pa_pdispatch_creds(pa_pdispatch *pd); - -#endif diff --git a/src/polypcore/pid.c b/src/polypcore/pid.c deleted file mode 100644 index a5c0ef0b..00000000 --- a/src/polypcore/pid.c +++ /dev/null @@ -1,304 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <string.h> -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <limits.h> -#include <signal.h> - -#ifdef HAVE_WINDOWS_H -#include <windows.h> -#endif - -#include <polyp/xmalloc.h> - -#include <polypcore/core-error.h> -#include <polypcore/core-util.h> -#include <polypcore/log.h> - -#include "pid.h" - -/* Read the PID data from the file descriptor fd, and return it. If no - * pid could be read, return 0, on failure (pid_t) -1 */ -static pid_t read_pid(const char *fn, int fd) { - ssize_t r; - char t[20], *e; - uint32_t pid; - - assert(fn && fd >= 0); - - if ((r = pa_loop_read(fd, t, sizeof(t)-1)) < 0) { - pa_log_warn(__FILE__": WARNING: failed to read PID file '%s': %s", - fn, pa_cstrerror(errno)); - return (pid_t) -1; - } - - if (r == 0) - return (pid_t) 0; - - t[r] = 0; - if ((e = strchr(t, '\n'))) - *e = 0; - - if (pa_atou(t, &pid) < 0) { - pa_log(__FILE__": WARNING: failed to parse PID file '%s'", fn); - return (pid_t) -1; - } - - return (pid_t) pid; -} - -static int open_pid_file(const char *fn, int mode) { - int fd = -1; - int lock = -1; - - for (;;) { - struct stat st; - - pa_make_secure_parent_dir(fn); - - if ((fd = open(fn, mode, S_IRUSR|S_IWUSR)) < 0) { - if (mode != O_RDONLY || errno != ENOENT) - pa_log_warn(__FILE__": WARNING: failed to open PID file '%s': %s", - fn, pa_cstrerror(errno)); - goto fail; - } - - /* Try to lock the file. If that fails, go without */ - if (pa_lock_fd(fd, 1) < 0) - goto fail; - - if (fstat(fd, &st) < 0) { - pa_log_warn(__FILE__": WARNING: failed to fstat() PID file '%s': %s", - fn, pa_cstrerror(errno)); - goto fail; - } - - /* Does the file still exist in the file system? When ye, w're done, otherwise restart */ - if (st.st_nlink >= 1) - break; - - if (pa_lock_fd(fd, 0) < 0) - goto fail; - - if (close(fd) < 0) { - pa_log_warn(__FILE__": WARNING: failed to close file '%s': %s", - fn, pa_cstrerror(errno)); - goto fail; - } - - fd = -1; - } - - return fd; - -fail: - - if (fd < 0) { - if (lock >= 0) - pa_lock_fd(fd, 0); - - close(fd); - } - - return -1; -} - -/* Create a new PID file for the current process. */ -int pa_pid_file_create(void) { - int fd = -1; - int ret = -1; - char fn[PATH_MAX]; - char t[20]; - pid_t pid; - size_t l; - -#ifdef OS_IS_WIN32 - HANDLE process; -#endif - - pa_runtime_path("pid", fn, sizeof(fn)); - - if ((fd = open_pid_file(fn, O_CREAT|O_RDWR)) < 0) - goto fail; - - if ((pid = read_pid(fn, fd)) == (pid_t) -1) - pa_log(__FILE__": corrupt PID file, overwriting."); - else if (pid > 0) { -#ifdef OS_IS_WIN32 - if ((process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)) != NULL) { - CloseHandle(process); -#else - if (kill(pid, 0) >= 0 || errno != ESRCH) { -#endif - pa_log(__FILE__": daemon already running."); - goto fail; - } - - pa_log(__FILE__": stale PID file, overwriting."); - } - - /* Overwrite the current PID file */ - if (lseek(fd, 0, SEEK_SET) == (off_t) -1 || ftruncate(fd, 0) < 0) { - pa_log(__FILE__": failed to truncate PID file '%s': %s", - fn, pa_cstrerror(errno)); - goto fail; - } - - snprintf(t, sizeof(t), "%lu\n", (unsigned long) getpid()); - l = strlen(t); - - if (pa_loop_write(fd, t, l) != (ssize_t) l) { - pa_log(__FILE__": failed to write PID file."); - goto fail; - } - - ret = 0; - -fail: - if (fd >= 0) { - pa_lock_fd(fd, 0); - close(fd); - } - - return ret; -} - -/* Remove the PID file, if it is ours */ -int pa_pid_file_remove(void) { - int fd = -1; - char fn[PATH_MAX]; - int ret = -1; - pid_t pid; - char *p; - - pa_runtime_path("pid", fn, sizeof(fn)); - - if ((fd = open_pid_file(fn, O_RDWR)) < 0) { - pa_log_warn(__FILE__": WARNING: failed to open PID file '%s': %s", - fn, pa_cstrerror(errno)); - goto fail; - } - - if ((pid = read_pid(fn, fd)) == (pid_t) -1) - goto fail; - - if (pid != getpid()) { - pa_log(__FILE__": WARNING: PID file '%s' not mine!", fn); - goto fail; - } - - if (ftruncate(fd, 0) < 0) { - pa_log_warn(__FILE__": WARNING: failed to truncate PID file '%s': %s", - fn, pa_cstrerror(errno)); - goto fail; - } - -#ifdef OS_IS_WIN32 - pa_lock_fd(fd, 0); - close(fd); - fd = -1; -#endif - - if (unlink(fn) < 0) { - pa_log_warn(__FILE__": WARNING: failed to remove PID file '%s': %s", - fn, pa_cstrerror(errno)); - goto fail; - } - - if ((p = pa_parent_dir(fn))) { - rmdir(p); - pa_xfree(p); - } - - ret = 0; - -fail: - - if (fd >= 0) { - pa_lock_fd(fd, 0); - close(fd); - } - - return ret; -} - -/* Check whether the daemon is currently running, i.e. if a PID file - * exists and the PID therein too. Returns 0 on succcess, -1 - * otherwise. If pid is non-NULL and a running daemon was found, - * return its PID therein */ -int pa_pid_file_check_running(pid_t *pid) { - return pa_pid_file_kill(0, pid); -} - -#ifndef OS_IS_WIN32 - -/* Kill a current running daemon. Return non-zero on success, -1 - * otherwise. If successful *pid contains the PID of the daemon - * process. */ -int pa_pid_file_kill(int sig, pid_t *pid) { - int fd = -1; - char fn[PATH_MAX]; - int ret = -1; - pid_t _pid; - - if (!pid) - pid = &_pid; - - pa_runtime_path("pid", fn, sizeof(fn)); - - if ((fd = open_pid_file(fn, O_RDONLY)) < 0) - goto fail; - - if ((*pid = read_pid(fn, fd)) == (pid_t) -1) - goto fail; - - ret = kill(*pid, sig); - -fail: - - if (fd >= 0) { - pa_lock_fd(fd, 0); - close(fd); - } - - return ret; - -} - -#else /* OS_IS_WIN32 */ - -int pa_pid_file_kill(int sig, pid_t *pid) { - return -1; -} - -#endif diff --git a/src/polypcore/pid.h b/src/polypcore/pid.h deleted file mode 100644 index 906ab6da..00000000 --- a/src/polypcore/pid.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef foopidhfoo -#define foopidhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -int pa_pid_file_create(void); -int pa_pid_file_remove(void); -int pa_pid_file_check_running(pid_t *pid); -int pa_pid_file_kill(int sig, pid_t *pid); - -#endif diff --git a/src/polypcore/pipe.c b/src/polypcore/pipe.c deleted file mode 100644 index eef6d533..00000000 --- a/src/polypcore/pipe.c +++ /dev/null @@ -1,160 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with polypaudio; If not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> - -#include <sys/types.h> - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif - -#include "winsock.h" - -#include "pipe.h" - -#ifndef HAVE_PIPE - -static int set_block(int fd, int blocking) { -#ifdef O_NONBLOCK - - int v; - - assert(fd >= 0); - - if ((v = fcntl(fd, F_GETFL)) < 0) - return -1; - - if (blocking) - v &= ~O_NONBLOCK; - else - v |= O_NONBLOCK; - - if (fcntl(fd, F_SETFL, v) < 0) - return -1; - - return 0; - -#elif defined(OS_IS_WIN32) - - u_long arg; - - arg = !blocking; - - if (ioctlsocket(fd, FIONBIO, &arg) < 0) - return -1; - - return 0; - -#else - - return -1; - -#endif -} - -int pipe(int filedes[2]) { - int listener; - struct sockaddr_in addr, peer; - socklen_t len; - - listener = -1; - filedes[0] = -1; - filedes[1] = -1; - - listener = socket(PF_INET, SOCK_STREAM, 0); - if (listener < 0) - goto error; - - filedes[0] = socket(PF_INET, SOCK_STREAM, 0); - if (filedes[0] < 0) - goto error; - - filedes[1] = socket(PF_INET, SOCK_STREAM, 0); - if (filedes[1] < 0) - goto error; - - /* Make non-blocking so that connect() won't block */ - if (set_block(filedes[0], 0) < 0) - goto error; - - addr.sin_family = AF_INET; - addr.sin_port = 0; - addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - - if (bind(listener, (struct sockaddr*)&addr, sizeof(addr)) < 0) - goto error; - - if (listen(listener, 1) < 0) - goto error; - - len = sizeof(addr); - if (getsockname(listener, (struct sockaddr*)&addr, &len) < 0) - goto error; - - if (connect(filedes[0], (struct sockaddr*)&addr, sizeof(addr)) < 0) { -#ifdef OS_IS_WIN32 - if (WSAGetLastError() != EWOULDBLOCK) -#else - if (errno != EINPROGRESS) -#endif - goto error; - } - - len = sizeof(peer); - filedes[1] = accept(listener, (struct sockaddr*)&peer, &len); - if (filedes[1] < 0) - goto error; - - /* Restore blocking */ - if (set_block(filedes[0], 1) < 0) - goto error; - - len = sizeof(addr); - if (getsockname(filedes[0], (struct sockaddr*)&addr, &len) < 0) - goto error; - - /* Check that someone else didn't steal the connection */ - if ((addr.sin_port != peer.sin_port) || (addr.sin_addr.s_addr != peer.sin_addr.s_addr)) - goto error; - - close(listener); - - return 0; - -error: - if (listener >= 0) - close(listener); - if (filedes[0] >= 0) - close(filedes[0]); - if (filedes[1] >= 0) - close(filedes[0]); - - return -1; -} - -#endif /* HAVE_PIPE */ diff --git a/src/polypcore/pipe.h b/src/polypcore/pipe.h deleted file mode 100644 index 276b072d..00000000 --- a/src/polypcore/pipe.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef foopipehfoo -#define foopipehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with polypaudio; If not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. -***/ - -#ifndef HAVE_PIPE - -int pipe(int filedes[2]); - -#endif - -#endif diff --git a/src/polypcore/play-memchunk.c b/src/polypcore/play-memchunk.c deleted file mode 100644 index 982cedc7..00000000 --- a/src/polypcore/play-memchunk.c +++ /dev/null @@ -1,117 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <assert.h> -#include <stdio.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/sink-input.h> -#include <polypcore/gccmacro.h> - -#include "play-memchunk.h" - -static void sink_input_kill(pa_sink_input *i) { - pa_memchunk *c; - assert(i && i->userdata); - c = i->userdata; - - pa_sink_input_disconnect(i); - pa_sink_input_unref(i); - - pa_memblock_unref(c->memblock); - pa_xfree(c); -} - -static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { - pa_memchunk *c; - assert(i && chunk && i->userdata); - c = i->userdata; - - if (c->length <= 0) - return -1; - - assert(c->memblock && c->memblock->length); - *chunk = *c; - pa_memblock_ref(c->memblock); - - return 0; -} - -static void si_kill(PA_GCC_UNUSED pa_mainloop_api *m, void *i) { - sink_input_kill(i); -} - -static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, size_t length) { - pa_memchunk *c; - assert(i && length && i->userdata); - c = i->userdata; - - assert(!memcmp(chunk, c, sizeof(chunk))); - assert(length <= c->length); - - c->length -= length; - c->index += length; - - if (c->length <= 0) - pa_mainloop_api_once(i->sink->core->mainloop, si_kill, i); -} - -int pa_play_memchunk( - pa_sink *sink, - const char *name, - const pa_sample_spec *ss, - const pa_channel_map *map, - const pa_memchunk *chunk, - pa_cvolume *cvolume) { - - pa_sink_input *si; - pa_memchunk *nchunk; - - assert(sink); - assert(ss); - assert(chunk); - - if (cvolume && pa_cvolume_is_muted(cvolume)) - return 0; - - if (!(si = pa_sink_input_new(sink, name, __FILE__, ss, map, cvolume, 0, PA_RESAMPLER_INVALID))) - return -1; - - si->peek = sink_input_peek; - si->drop = sink_input_drop; - si->kill = sink_input_kill; - - si->userdata = nchunk = pa_xnew(pa_memchunk, 1); - *nchunk = *chunk; - - pa_memblock_ref(chunk->memblock); - - pa_sink_notify(sink); - - return 0; -} diff --git a/src/polypcore/play-memchunk.h b/src/polypcore/play-memchunk.h deleted file mode 100644 index 72aeda95..00000000 --- a/src/polypcore/play-memchunk.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef fooplaychunkhfoo -#define fooplaychunkhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/sink.h> -#include <polypcore/memchunk.h> - -int pa_play_memchunk( - pa_sink *sink, - const char *name, - const pa_sample_spec *ss, - const pa_channel_map *map, - const pa_memchunk *chunk, - pa_cvolume *cvolume); - -#endif diff --git a/src/polypcore/poll.c b/src/polypcore/poll.c deleted file mode 100644 index 7b1ed438..00000000 --- a/src/polypcore/poll.c +++ /dev/null @@ -1,191 +0,0 @@ -/* $Id$ */ - -/*** - Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc. - Copyright (C) 2005, Cendio AB. - This file is part of polypaudio. - Based on work for the GNU C Library. - - polypaudio is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with polypaudio; If not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. -***/ - -/* Poll the file descriptors described by the NFDS structures starting at - FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for - an event to occur; if TIMEOUT is -1, block until an event occurs. - Returns the number of file descriptors with events, zero if timed out, - or -1 for errors. */ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> - -#ifdef HAVE_SYS_SELECT_H -#include <sys/select.h> -#endif - -#include "winsock.h" - -#ifndef HAVE_SYS_POLL_H - -#include <polypcore/core-util.h> - -#include "poll.h" - -int poll (struct pollfd *fds, unsigned long int nfds, int timeout) { - struct timeval tv; - fd_set rset, wset, xset; - struct pollfd *f; - int ready; - int maxfd = 0; - char data[64]; - - FD_ZERO (&rset); - FD_ZERO (&wset); - FD_ZERO (&xset); - - if (nfds == 0) { - if (timeout >= 0) { - pa_msleep(timeout); - return 0; - } - -#ifdef OS_IS_WIN32 - /* - * Windows does not support signals properly so waiting for them would - * mean a deadlock. - */ - pa_msleep(100); - return 0; -#else - return select(0, NULL, NULL, NULL, NULL); -#endif - } - - for (f = fds; f < &fds[nfds]; ++f) { - if (f->fd != -1) { - if (f->events & POLLIN) - FD_SET (f->fd, &rset); - if (f->events & POLLOUT) - FD_SET (f->fd, &wset); - if (f->events & POLLPRI) - FD_SET (f->fd, &xset); - if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI))) - maxfd = f->fd; - } - } - - tv.tv_sec = timeout / 1000; - tv.tv_usec = (timeout % 1000) * 1000; - - ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset, - SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset, - SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv)); - if ((ready == -1) && (errno == EBADF)) { - ready = 0; - - FD_ZERO (&rset); - FD_ZERO (&wset); - FD_ZERO (&xset); - - maxfd = -1; - - for (f = fds; f < &fds[nfds]; ++f) { - if (f->fd != -1) { - fd_set sngl_rset, sngl_wset, sngl_xset; - - FD_ZERO (&sngl_rset); - FD_ZERO (&sngl_wset); - FD_ZERO (&sngl_xset); - - if (f->events & POLLIN) - FD_SET (f->fd, &sngl_rset); - if (f->events & POLLOUT) - FD_SET (f->fd, &sngl_wset); - if (f->events & POLLPRI) - FD_SET (f->fd, &sngl_xset); - if (f->events & (POLLIN|POLLOUT|POLLPRI)) { - struct timeval singl_tv; - - singl_tv.tv_sec = 0; - singl_tv.tv_usec = 0; - - if (select((SELECT_TYPE_ARG1) f->fd, SELECT_TYPE_ARG234 &rset, - SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset, - SELECT_TYPE_ARG5 &singl_tv) != -1) { - if (f->events & POLLIN) - FD_SET (f->fd, &rset); - if (f->events & POLLOUT) - FD_SET (f->fd, &wset); - if (f->events & POLLPRI) - FD_SET (f->fd, &xset); - if (f->fd > maxfd && (f->events & (POLLIN|POLLOUT|POLLPRI))) - maxfd = f->fd; - ++ready; - } else if (errno == EBADF) - f->revents |= POLLNVAL; - } - } - } - - if (ready) { - /* Linux alters the tv struct... but it shouldn't matter here ... - * as we're going to be a little bit out anyway as we've just eaten - * more than a couple of cpu cycles above */ - ready = select ((SELECT_TYPE_ARG1) maxfd + 1, SELECT_TYPE_ARG234 &rset, - SELECT_TYPE_ARG234 &wset, SELECT_TYPE_ARG234 &xset, - SELECT_TYPE_ARG5 (timeout == -1 ? NULL : &tv)); - } - } - -#ifdef OS_IS_WIN32 - errno = WSAGetLastError(); -#endif - - if (ready > 0) { - ready = 0; - for (f = fds; f < &fds[nfds]; ++f) { - f->revents = 0; - if (f->fd != -1) { - if (FD_ISSET (f->fd, &rset)) { - /* support for POLLHUP. An hung up descriptor does not - increase the return value! */ - if (recv (f->fd, data, 64, MSG_PEEK) == -1) { - if (errno == ESHUTDOWN || errno == ECONNRESET || - errno == ECONNABORTED || errno == ENETRESET) { - fprintf(stderr, "Hangup\n"); - f->revents |= POLLHUP; - } - } - - if (f->revents == 0) - f->revents |= POLLIN; - } - if (FD_ISSET (f->fd, &wset)) - f->revents |= POLLOUT; - if (FD_ISSET (f->fd, &xset)) - f->revents |= POLLPRI; - } - if (f->revents) - ready++; - } - } - - return ready; -} - -#endif /* HAVE_SYS_POLL_H */ diff --git a/src/polypcore/poll.h b/src/polypcore/poll.h deleted file mode 100644 index c201014e..00000000 --- a/src/polypcore/poll.h +++ /dev/null @@ -1,57 +0,0 @@ -/* $Id$ */ - -/*** - Compatibility definitions for System V `poll' interface. - Copyright (C) 1994,96,97,98,99,2000,2001,2004 Free Software Foundation, Inc. - Copyright (C) 2005, Cendio AB. - This file is part of polypaudio. - Based on work for the GNU C Library. - - polypaudio is free software; you can redistribute it and/or modify it - under the terms of the GNU Library General Public License as published - by the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with polypaudio; If not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - USA. -***/ - -/* Event types that can be polled for. These bits may be set in `events' - to indicate the interesting event types; they will appear in `revents' - to indicate the status of the file descriptor. */ -#define POLLIN 0x001 /* There is data to read. */ -#define POLLPRI 0x002 /* There is urgent data to read. */ -#define POLLOUT 0x004 /* Writing now will not block. */ - -/* Event types always implicitly polled for. These bits need not be set in - `events', but they will appear in `revents' to indicate the status of - the file descriptor. */ -#define POLLERR 0x008 /* Error condition. */ -#define POLLHUP 0x010 /* Hung up. */ -#define POLLNVAL 0x020 /* Invalid polling request. */ - - -/* Type used for the number of file descriptors. */ -typedef unsigned long int nfds_t; - -/* Data structure describing a polling request. */ -struct pollfd - { - int fd; /* File descriptor to poll. */ - short int events; /* Types of events poller cares about. */ - short int revents; /* Types of events that actually occurred. */ - }; - -/* Poll the file descriptors described by the NFDS structures starting at - FDS. If TIMEOUT is nonzero and not -1, allow TIMEOUT milliseconds for - an event to occur; if TIMEOUT is -1, block until an event occurs. - Returns the number of file descriptors with events, zero if timed out, - or -1 for errors. */ -extern int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout); diff --git a/src/polypcore/props.c b/src/polypcore/props.c deleted file mode 100644 index 1db44ee7..00000000 --- a/src/polypcore/props.c +++ /dev/null @@ -1,121 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <assert.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/log.h> - -#include "props.h" - -typedef struct pa_property { - char *name; /* Points to memory allocated by the property subsystem */ - void *data; /* Points to memory maintained by the caller */ -} pa_property; - -/* Allocate a new property object */ -static pa_property* property_new(const char *name, void *data) { - pa_property* p; - assert(name && data); - - p = pa_xmalloc(sizeof(pa_property)); - p->name = pa_xstrdup(name); - p->data = data; - - return p; -} - -/* Free a property object */ -static void property_free(pa_property *p) { - assert(p); - - pa_xfree(p->name); - pa_xfree(p); -} - -void* pa_property_get(pa_core *c, const char *name) { - pa_property *p; - assert(c && name && c->properties); - - if (!(p = pa_hashmap_get(c->properties, name))) - return NULL; - - return p->data; -} - -int pa_property_set(pa_core *c, const char *name, void *data) { - pa_property *p; - assert(c && name && data && c->properties); - - if (pa_hashmap_get(c->properties, name)) - return -1; - - p = property_new(name, data); - pa_hashmap_put(c->properties, p->name, p); - return 0; -} - -int pa_property_remove(pa_core *c, const char *name) { - pa_property *p; - assert(c && name && c->properties); - - if (!(p = pa_hashmap_remove(c->properties, name))) - return -1; - - property_free(p); - return 0; -} - -void pa_property_init(pa_core *c) { - assert(c); - - c->properties = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func); -} - -void pa_property_cleanup(pa_core *c) { - assert(c); - - if (!c->properties) - return; - - assert(!pa_hashmap_size(c->properties)); - - pa_hashmap_free(c->properties, NULL, NULL); - c->properties = NULL; - -} - -void pa_property_dump(pa_core *c, pa_strbuf *s) { - void *state = NULL; - pa_property *p; - assert(c && s); - - while ((p = pa_hashmap_iterate(c->properties, &state, NULL))) - pa_strbuf_printf(s, "[%s] -> [%p]\n", p->name, p->data); -} - -int pa_property_replace(pa_core *c, const char *name, void *data) { - assert(c && name); - - pa_property_remove(c, name); - return pa_property_set(c, name, data); -} diff --git a/src/polypcore/props.h b/src/polypcore/props.h deleted file mode 100644 index 9430db5e..00000000 --- a/src/polypcore/props.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef foopropshfoo -#define foopropshfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> -#include <polypcore/strbuf.h> - -/* The property subsystem is to be used to share data between - * modules. Consider them to be kind of "global" variables for a - * core. Why not use the hashmap functions directly? The hashmap - * functions copy neither the key nor value, while this property - * system copies the key. Users of this system have to think about - * reference counting themselves. */ - -/* Return a pointer to the value of the specified property. */ -void* pa_property_get(pa_core *c, const char *name); - -/* Set the property 'name' to 'data'. This function fails in case a - * property by this name already exists. The property data is not - * copied or reference counted. This is the caller's job. */ -int pa_property_set(pa_core *c, const char *name, void *data); - -/* Remove the specified property. Return non-zero on failure */ -int pa_property_remove(pa_core *c, const char *name); - -/* A combination of pa_property_remove() and pa_property_set() */ -int pa_property_replace(pa_core *c, const char *name, void *data); - -/* Free all memory used by the property system */ -void pa_property_cleanup(pa_core *c); - -/* Initialize the properties subsystem */ -void pa_property_init(pa_core *c); - -/* Dump the current set of properties */ -void pa_property_dump(pa_core *c, pa_strbuf *s); - -#endif diff --git a/src/polypcore/protocol-cli.c b/src/polypcore/protocol-cli.c deleted file mode 100644 index 076411cf..00000000 --- a/src/polypcore/protocol-cli.c +++ /dev/null @@ -1,97 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/cli.h> -#include <polypcore/log.h> - -#include "protocol-cli.h" - -/* Don't allow more than this many concurrent connections */ -#define MAX_CONNECTIONS 25 - -struct pa_protocol_cli { - pa_module *module; - pa_core *core; - pa_socket_server*server; - pa_idxset *connections; -}; - -static void cli_eof_cb(pa_cli*c, void*userdata) { - pa_protocol_cli *p = userdata; - assert(p); - pa_idxset_remove_by_data(p->connections, c, NULL); - pa_cli_free(c); -} - -static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) { - pa_protocol_cli *p = userdata; - pa_cli *c; - assert(s && io && p); - - if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { - pa_log(__FILE__": Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); - pa_iochannel_free(io); - return; - } - - c = pa_cli_new(p->core, io, p->module); - assert(c); - pa_cli_set_eof_callback(c, cli_eof_cb, p); - - pa_idxset_put(p->connections, c, NULL); -} - -pa_protocol_cli* pa_protocol_cli_new(pa_core *core, pa_socket_server *server, pa_module *m, PA_GCC_UNUSED pa_modargs *ma) { - pa_protocol_cli* p; - assert(core && server); - - p = pa_xmalloc(sizeof(pa_protocol_cli)); - p->module = m; - p->core = core; - p->server = server; - p->connections = pa_idxset_new(NULL, NULL); - - pa_socket_server_set_callback(p->server, on_connection, p); - - return p; -} - -static void free_connection(void *p, PA_GCC_UNUSED void *userdata) { - assert(p); - pa_cli_free(p); -} - -void pa_protocol_cli_free(pa_protocol_cli *p) { - assert(p); - - pa_idxset_free(p->connections, free_connection, NULL); - pa_socket_server_unref(p->server); - pa_xfree(p); -} diff --git a/src/polypcore/protocol-cli.h b/src/polypcore/protocol-cli.h deleted file mode 100644 index c47b14d6..00000000 --- a/src/polypcore/protocol-cli.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef fooprotocolclihfoo -#define fooprotocolclihfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> -#include <polypcore/socket-server.h> -#include <polypcore/module.h> -#include <polypcore/modargs.h> - -typedef struct pa_protocol_cli pa_protocol_cli; - -pa_protocol_cli* pa_protocol_cli_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma); -void pa_protocol_cli_free(pa_protocol_cli *n); - -#endif diff --git a/src/polypcore/protocol-esound.c b/src/polypcore/protocol-esound.c deleted file mode 100644 index c9bc504d..00000000 --- a/src/polypcore/protocol-esound.c +++ /dev/null @@ -1,1253 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <errno.h> -#include <string.h> -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <limits.h> - -#include <polyp/sample.h> -#include <polyp/timeval.h> -#include <polyp/utf8.h> -#include <polyp/xmalloc.h> - -#include <polypcore/esound.h> -#include <polypcore/memblock.h> -#include <polypcore/client.h> -#include <polypcore/sink-input.h> -#include <polypcore/sink.h> -#include <polypcore/source-output.h> -#include <polypcore/source.h> -#include <polypcore/core-scache.h> -#include <polypcore/sample-util.h> -#include <polypcore/authkey.h> -#include <polypcore/namereg.h> -#include <polypcore/log.h> -#include <polypcore/core-util.h> -#include <polypcore/core-error.h> - -#include "endianmacros.h" - -#include "protocol-esound.h" - -/* Don't accept more connection than this */ -#define MAX_CONNECTIONS 10 - -/* Kick a client if it doesn't authenticate within this time */ -#define AUTH_TIMEOUT 5 - -#define DEFAULT_COOKIE_FILE ".esd_auth" - -#define PLAYBACK_BUFFER_SECONDS (.25) -#define PLAYBACK_BUFFER_FRAGMENTS (10) -#define RECORD_BUFFER_SECONDS (5) -#define RECORD_BUFFER_FRAGMENTS (100) - -#define MAX_CACHE_SAMPLE_SIZE (1024000) - -#define SCACHE_PREFIX "esound." - -/* This is heavily based on esound's code */ - -struct connection { - uint32_t index; - int dead; - pa_protocol_esound *protocol; - pa_iochannel *io; - pa_client *client; - int authorized, swap_byte_order; - void *write_data; - size_t write_data_alloc, write_data_index, write_data_length; - void *read_data; - size_t read_data_alloc, read_data_length; - esd_proto_t request; - esd_client_state_t state; - pa_sink_input *sink_input; - pa_source_output *source_output; - pa_memblockq *input_memblockq, *output_memblockq; - pa_defer_event *defer_event; - - char *original_name; - - struct { - pa_memblock *current_memblock; - size_t memblock_index, fragment_size; - } playback; - - struct { - pa_memchunk memchunk; - char *name; - pa_sample_spec sample_spec; - } scache; - - pa_time_event *auth_timeout_event; -}; - -struct pa_protocol_esound { - int public; - pa_module *module; - pa_core *core; - pa_socket_server *server; - pa_idxset *connections; - char *sink_name, *source_name; - unsigned n_player; - uint8_t esd_key[ESD_KEY_LEN]; -}; - -typedef struct proto_handler { - size_t data_length; - int (*proc)(struct connection *c, esd_proto_t request, const void *data, size_t length); - const char *description; -} esd_proto_handler_info_t; - -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length); -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk); -static void sink_input_kill_cb(pa_sink_input *i); -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i); -static pa_usec_t source_output_get_latency_cb(pa_source_output *o); - -static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk); -static void source_output_kill_cb(pa_source_output *o); - -static int esd_proto_connect(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_stream_play(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_stream_record(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_get_latency(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_server_info(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_all_info(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_stream_pan(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_sample_cache(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_sample_free_or_play(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_sample_get_id(struct connection *c, esd_proto_t request, const void *data, size_t length); -static int esd_proto_standby_or_resume(struct connection *c, esd_proto_t request, const void *data, size_t length); - -/* the big map of protocol handler info */ -static struct proto_handler proto_map[ESD_PROTO_MAX] = { - { ESD_KEY_LEN + sizeof(int), esd_proto_connect, "connect" }, - { ESD_KEY_LEN + sizeof(int), NULL, "lock" }, - { ESD_KEY_LEN + sizeof(int), NULL, "unlock" }, - - { ESD_NAME_MAX + 2 * sizeof(int), esd_proto_stream_play, "stream play" }, - { ESD_NAME_MAX + 2 * sizeof(int), esd_proto_stream_record, "stream rec" }, - { ESD_NAME_MAX + 2 * sizeof(int), esd_proto_stream_record, "stream mon" }, - - { ESD_NAME_MAX + 3 * sizeof(int), esd_proto_sample_cache, "sample cache" }, /* 6 */ - { sizeof(int), esd_proto_sample_free_or_play, "sample free" }, - { sizeof(int), esd_proto_sample_free_or_play, "sample play" }, /* 8 */ - { sizeof(int), NULL, "sample loop" }, - { sizeof(int), NULL, "sample stop" }, - { -1, NULL, "TODO: sample kill" }, - - { ESD_KEY_LEN + sizeof(int), esd_proto_standby_or_resume, "standby" }, /* NOOP! */ - { ESD_KEY_LEN + sizeof(int), esd_proto_standby_or_resume, "resume" }, /* NOOP! */ /* 13 */ - - { ESD_NAME_MAX, esd_proto_sample_get_id, "sample getid" }, /* 14 */ - { ESD_NAME_MAX + 2 * sizeof(int), NULL, "stream filter" }, - - { sizeof(int), esd_proto_server_info, "server info" }, - { sizeof(int), esd_proto_all_info, "all info" }, - { -1, NULL, "TODO: subscribe" }, - { -1, NULL, "TODO: unsubscribe" }, - - { 3 * sizeof(int), esd_proto_stream_pan, "stream pan"}, - { 3 * sizeof(int), NULL, "sample pan" }, - - { sizeof(int), NULL, "standby mode" }, - { 0, esd_proto_get_latency, "get latency" } -}; - -static void connection_free(struct connection *c) { - assert(c); - pa_idxset_remove_by_data(c->protocol->connections, c, NULL); - - if (c->state == ESD_STREAMING_DATA) - c->protocol->n_player--; - - pa_client_free(c->client); - - if (c->sink_input) { - pa_sink_input_disconnect(c->sink_input); - pa_sink_input_unref(c->sink_input); - } - - if (c->source_output) { - pa_source_output_disconnect(c->source_output); - pa_source_output_unref(c->source_output); - } - - if (c->input_memblockq) - pa_memblockq_free(c->input_memblockq); - if (c->output_memblockq) - pa_memblockq_free(c->output_memblockq); - - if (c->playback.current_memblock) - pa_memblock_unref(c->playback.current_memblock); - - pa_xfree(c->read_data); - pa_xfree(c->write_data); - - if (c->io) - pa_iochannel_free(c->io); - - if (c->defer_event) - c->protocol->core->mainloop->defer_free(c->defer_event); - - if (c->scache.memchunk.memblock) - pa_memblock_unref(c->scache.memchunk.memblock); - pa_xfree(c->scache.name); - - if (c->auth_timeout_event) - c->protocol->core->mainloop->time_free(c->auth_timeout_event); - - pa_xfree(c->original_name); - pa_xfree(c); -} - -static void connection_write_prepare(struct connection *c, size_t length) { - size_t t; - assert(c); - - t = c->write_data_length+length; - - if (c->write_data_alloc < t) - c->write_data = pa_xrealloc(c->write_data, c->write_data_alloc = t); - - assert(c->write_data); -} - -static void connection_write(struct connection *c, const void *data, size_t length) { - size_t i; - assert(c); - - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); - c->protocol->core->mainloop->defer_enable(c->defer_event, 1); - - connection_write_prepare(c, length); - - assert(c->write_data); - - i = c->write_data_length; - c->write_data_length += length; - - memcpy((char*)c->write_data + i, data, length); -} - -static void format_esd2native(int format, int swap_bytes, pa_sample_spec *ss) { - assert(ss); - - ss->channels = ((format & ESD_MASK_CHAN) == ESD_STEREO) ? 2 : 1; - if ((format & ESD_MASK_BITS) == ESD_BITS16) - ss->format = swap_bytes ? PA_SAMPLE_S16RE : PA_SAMPLE_S16NE; - else - ss->format = PA_SAMPLE_U8; -} - -static int format_native2esd(pa_sample_spec *ss) { - int format = 0; - - format = (ss->format == PA_SAMPLE_U8) ? ESD_BITS8 : ESD_BITS16; - format |= (ss->channels >= 2) ? ESD_STEREO : ESD_MONO; - - return format; -} - -#define CHECK_VALIDITY(expression, string) do { \ - if (!(expression)) { \ - pa_log_warn(__FILE__ ": " string); \ - return -1; \ - } \ -} while(0); - -/*** esound commands ***/ - -static int esd_proto_connect(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { - uint32_t ekey; - int ok; - - assert(length == (ESD_KEY_LEN + sizeof(uint32_t))); - - if (!c->authorized) { - if (memcmp(data, c->protocol->esd_key, ESD_KEY_LEN) != 0) { - pa_log(__FILE__": kicked client with invalid authorization key."); - return -1; - } - - c->authorized = 1; - if (c->auth_timeout_event) { - c->protocol->core->mainloop->time_free(c->auth_timeout_event); - c->auth_timeout_event = NULL; - } - } - - data = (const char*)data + ESD_KEY_LEN; - - memcpy(&ekey, data, sizeof(uint32_t)); - if (ekey == ESD_ENDIAN_KEY) - c->swap_byte_order = 0; - else if (ekey == ESD_SWAP_ENDIAN_KEY) - c->swap_byte_order = 1; - else { - pa_log(__FILE__": client sent invalid endian key"); - return -1; - } - - ok = 1; - connection_write(c, &ok, sizeof(int)); - return 0; -} - -static int esd_proto_stream_play(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { - char name[ESD_NAME_MAX], *utf8_name; - int32_t format, rate; - pa_sink *sink; - pa_sample_spec ss; - size_t l; - - assert(c && length == (sizeof(int32_t)*2+ESD_NAME_MAX)); - - memcpy(&format, data, sizeof(int32_t)); - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); - data = (const char*)data + sizeof(int32_t); - - memcpy(&rate, data, sizeof(int32_t)); - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); - data = (const char*)data + sizeof(int32_t); - - ss.rate = rate; - format_esd2native(format, c->swap_byte_order, &ss); - - CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification"); - sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1); - CHECK_VALIDITY(sink, "No such sink"); - - strncpy(name, data, sizeof(name)); - name[sizeof(name)-1] = 0; - utf8_name = pa_utf8_filter(name); - - pa_client_set_name(c->client, utf8_name); - c->original_name = pa_xstrdup(name); - - assert(!c->sink_input && !c->input_memblockq); - - c->sink_input = pa_sink_input_new(sink, __FILE__, utf8_name, &ss, NULL, NULL, 0, -1); - - pa_xfree(utf8_name); - - CHECK_VALIDITY(c->sink_input, "Failed to create sink input."); - - l = (size_t) (pa_bytes_per_second(&ss)*PLAYBACK_BUFFER_SECONDS); - c->input_memblockq = pa_memblockq_new( - 0, - l, - 0, - pa_frame_size(&ss), - (size_t) -1, - l/PLAYBACK_BUFFER_FRAGMENTS, - NULL, - c->protocol->core->memblock_stat); - pa_iochannel_socket_set_rcvbuf(c->io, l/PLAYBACK_BUFFER_FRAGMENTS*2); - c->playback.fragment_size = l/10; - - c->sink_input->owner = c->protocol->module; - c->sink_input->client = c->client; - c->sink_input->peek = sink_input_peek_cb; - c->sink_input->drop = sink_input_drop_cb; - c->sink_input->kill = sink_input_kill_cb; - c->sink_input->get_latency = sink_input_get_latency_cb; - c->sink_input->userdata = c; - - c->state = ESD_STREAMING_DATA; - - c->protocol->n_player++; - - return 0; -} - -static int esd_proto_stream_record(struct connection *c, esd_proto_t request, const void *data, size_t length) { - char name[ESD_NAME_MAX], *utf8_name; - int32_t format, rate; - pa_source *source; - pa_sample_spec ss; - size_t l; - - assert(c && length == (sizeof(int32_t)*2+ESD_NAME_MAX)); - - memcpy(&format, data, sizeof(int32_t)); - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); - data = (const char*)data + sizeof(int32_t); - - memcpy(&rate, data, sizeof(int32_t)); - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); - data = (const char*)data + sizeof(int32_t); - - ss.rate = rate; - format_esd2native(format, c->swap_byte_order, &ss); - - CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification."); - - if (request == ESD_PROTO_STREAM_MON) { - pa_sink* sink; - - if (!(sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1))) { - pa_log(__FILE__": no such sink."); - return -1; - } - - if (!(source = sink->monitor_source)) { - pa_log(__FILE__": no such monitor source."); - return -1; - } - } else { - assert(request == ESD_PROTO_STREAM_REC); - - if (!(source = pa_namereg_get(c->protocol->core, c->protocol->source_name, PA_NAMEREG_SOURCE, 1))) { - pa_log(__FILE__": no such source."); - return -1; - } - } - - strncpy(name, data, sizeof(name)); - name[sizeof(name)-1] = 0; - - utf8_name = pa_utf8_filter(name); - pa_client_set_name(c->client, utf8_name); - pa_xfree(utf8_name); - - c->original_name = pa_xstrdup(name); - - assert(!c->output_memblockq && !c->source_output); - - if (!(c->source_output = pa_source_output_new(source, __FILE__, c->client->name, &ss, NULL, -1))) { - pa_log(__FILE__": failed to create source output"); - return -1; - } - - l = (size_t) (pa_bytes_per_second(&ss)*RECORD_BUFFER_SECONDS); - c->output_memblockq = pa_memblockq_new( - 0, - l, - 0, - pa_frame_size(&ss), - 1, - 0, - NULL, - c->protocol->core->memblock_stat); - pa_iochannel_socket_set_sndbuf(c->io, l/RECORD_BUFFER_FRAGMENTS*2); - - c->source_output->owner = c->protocol->module; - c->source_output->client = c->client; - c->source_output->push = source_output_push_cb; - c->source_output->kill = source_output_kill_cb; - c->source_output->get_latency = source_output_get_latency_cb; - c->source_output->userdata = c; - - c->state = ESD_STREAMING_DATA; - - c->protocol->n_player++; - - return 0; -} - -static int esd_proto_get_latency(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { - pa_sink *sink; - int32_t latency; - - assert(c && !data && length == 0); - - if (!(sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1))) - latency = 0; - else { - double usec = pa_sink_get_latency(sink); - latency = (int) ((usec*44100)/1000000); - } - - latency = MAYBE_INT32_SWAP(c->swap_byte_order, latency); - connection_write(c, &latency, sizeof(int32_t)); - return 0; -} - -static int esd_proto_server_info(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { - int32_t rate = 44100, format = ESD_STEREO|ESD_BITS16; - int32_t response; - pa_sink *sink; - - assert(c && data && length == sizeof(int32_t)); - - if ((sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1))) { - rate = sink->sample_spec.rate; - format = format_native2esd(&sink->sample_spec); - } - - connection_write_prepare(c, sizeof(int32_t) * 3); - - response = 0; - connection_write(c, &response, sizeof(int32_t)); - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); - connection_write(c, &rate, sizeof(int32_t)); - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); - connection_write(c, &format, sizeof(int32_t)); - - return 0; -} - -static int esd_proto_all_info(struct connection *c, esd_proto_t request, const void *data, size_t length) { - size_t t, k, s; - struct connection *conn; - uint32_t idx = PA_IDXSET_INVALID; - unsigned nsamples; - char terminator[sizeof(int32_t)*6+ESD_NAME_MAX]; - - assert(c && data && length == sizeof(int32_t)); - - if (esd_proto_server_info(c, request, data, length) < 0) - return -1; - - k = sizeof(int32_t)*5+ESD_NAME_MAX; - s = sizeof(int32_t)*6+ESD_NAME_MAX; - nsamples = c->protocol->core->scache ? pa_idxset_size(c->protocol->core->scache) : 0; - t = s*(nsamples+1) + k*(c->protocol->n_player+1); - - connection_write_prepare(c, t); - - memset(terminator, 0, sizeof(terminator)); - - for (conn = pa_idxset_first(c->protocol->connections, &idx); conn; conn = pa_idxset_next(c->protocol->connections, &idx)) { - int32_t id, format = ESD_BITS16 | ESD_STEREO, rate = 44100, lvolume = ESD_VOLUME_BASE, rvolume = ESD_VOLUME_BASE; - char name[ESD_NAME_MAX]; - - if (conn->state != ESD_STREAMING_DATA) - continue; - - assert(t >= k*2+s); - - if (conn->sink_input) { - pa_cvolume volume = *pa_sink_input_get_volume(conn->sink_input); - rate = conn->sink_input->sample_spec.rate; - lvolume = (volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM; - rvolume = (volume.values[1]*ESD_VOLUME_BASE)/PA_VOLUME_NORM; - format = format_native2esd(&conn->sink_input->sample_spec); - } - - /* id */ - id = MAYBE_INT32_SWAP(c->swap_byte_order, (int32_t) (conn->index+1)); - connection_write(c, &id, sizeof(int32_t)); - - /* name */ - memset(name, 0, ESD_NAME_MAX); /* don't leak old data */ - if (conn->original_name) - strncpy(name, conn->original_name, ESD_NAME_MAX); - else if (conn->client && conn->client->name) - strncpy(name, conn->client->name, ESD_NAME_MAX); - connection_write(c, name, ESD_NAME_MAX); - - /* rate */ - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); - connection_write(c, &rate, sizeof(int32_t)); - - /* left */ - lvolume = MAYBE_INT32_SWAP(c->swap_byte_order, lvolume); - connection_write(c, &lvolume, sizeof(int32_t)); - - /*right*/ - rvolume = MAYBE_INT32_SWAP(c->swap_byte_order, rvolume); - connection_write(c, &rvolume, sizeof(int32_t)); - - /*format*/ - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); - connection_write(c, &format, sizeof(int32_t)); - - t -= k; - } - - assert(t == s*(nsamples+1)+k); - t -= k; - - connection_write(c, terminator, k); - - if (nsamples) { - pa_scache_entry *ce; - - idx = PA_IDXSET_INVALID; - for (ce = pa_idxset_first(c->protocol->core->scache, &idx); ce; ce = pa_idxset_next(c->protocol->core->scache, &idx)) { - int32_t id, rate, lvolume, rvolume, format, len; - char name[ESD_NAME_MAX]; - - assert(t >= s*2); - - /* id */ - id = MAYBE_INT32_SWAP(c->swap_byte_order, (int) (ce->index+1)); - connection_write(c, &id, sizeof(int32_t)); - - /* name */ - memset(name, 0, ESD_NAME_MAX); /* don't leak old data */ - if (strncmp(ce->name, SCACHE_PREFIX, sizeof(SCACHE_PREFIX)-1) == 0) - strncpy(name, ce->name+sizeof(SCACHE_PREFIX)-1, ESD_NAME_MAX); - else - snprintf(name, ESD_NAME_MAX, "native.%s", ce->name); - connection_write(c, name, ESD_NAME_MAX); - - /* rate */ - rate = MAYBE_UINT32_SWAP(c->swap_byte_order, ce->sample_spec.rate); - connection_write(c, &rate, sizeof(int32_t)); - - /* left */ - lvolume = MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); - connection_write(c, &lvolume, sizeof(int32_t)); - - /*right*/ - rvolume = MAYBE_UINT32_SWAP(c->swap_byte_order, (ce->volume.values[0]*ESD_VOLUME_BASE)/PA_VOLUME_NORM); - connection_write(c, &rvolume, sizeof(int32_t)); - - /*format*/ - format = MAYBE_INT32_SWAP(c->swap_byte_order, format_native2esd(&ce->sample_spec)); - connection_write(c, &format, sizeof(int32_t)); - - /*length*/ - len = MAYBE_INT32_SWAP(c->swap_byte_order, (int) ce->memchunk.length); - connection_write(c, &len, sizeof(int32_t)); - - t -= s; - } - } - - assert(t == s); - - connection_write(c, terminator, s); - - return 0; -} - -static int esd_proto_stream_pan(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { - int32_t ok; - uint32_t idx, lvolume, rvolume; - struct connection *conn; - - assert(c && data && length == sizeof(int32_t)*3); - - memcpy(&idx, data, sizeof(uint32_t)); - idx = MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1; - data = (const char*)data + sizeof(uint32_t); - - memcpy(&lvolume, data, sizeof(uint32_t)); - lvolume = MAYBE_UINT32_SWAP(c->swap_byte_order, lvolume); - data = (const char*)data + sizeof(uint32_t); - - memcpy(&rvolume, data, sizeof(uint32_t)); - rvolume = MAYBE_UINT32_SWAP(c->swap_byte_order, rvolume); - data = (const char*)data + sizeof(uint32_t); - - if ((conn = pa_idxset_get_by_index(c->protocol->connections, idx)) && conn->sink_input) { - pa_cvolume volume; - volume.values[0] = (lvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE; - volume.values[1] = (rvolume*PA_VOLUME_NORM)/ESD_VOLUME_BASE; - volume.channels = 2; - pa_sink_input_set_volume(conn->sink_input, &volume); - ok = 1; - } else - ok = 0; - - connection_write(c, &ok, sizeof(int32_t)); - - return 0; -} - -static int esd_proto_sample_cache(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { - pa_sample_spec ss; - int32_t format, rate, sc_length; - uint32_t idx; - char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1]; - - assert(c && data && length == (ESD_NAME_MAX+3*sizeof(int32_t))); - - memcpy(&format, data, sizeof(int32_t)); - format = MAYBE_INT32_SWAP(c->swap_byte_order, format); - data = (const char*)data + sizeof(int32_t); - - memcpy(&rate, data, sizeof(int32_t)); - rate = MAYBE_INT32_SWAP(c->swap_byte_order, rate); - data = (const char*)data + sizeof(int32_t); - - ss.rate = rate; - format_esd2native(format, c->swap_byte_order, &ss); - - CHECK_VALIDITY(pa_sample_spec_valid(&ss), "Invalid sample specification."); - - memcpy(&sc_length, data, sizeof(int32_t)); - sc_length = MAYBE_INT32_SWAP(c->swap_byte_order, sc_length); - data = (const char*)data + sizeof(int32_t); - - CHECK_VALIDITY(sc_length <= MAX_CACHE_SAMPLE_SIZE, "Sample too large."); - - strcpy(name, SCACHE_PREFIX); - strncpy(name+sizeof(SCACHE_PREFIX)-1, data, ESD_NAME_MAX); - name[sizeof(name)-1] = 0; - - CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name."); - - assert(!c->scache.memchunk.memblock); - c->scache.memchunk.memblock = pa_memblock_new(sc_length, c->protocol->core->memblock_stat); - c->scache.memchunk.index = 0; - c->scache.memchunk.length = sc_length; - c->scache.sample_spec = ss; - assert(!c->scache.name); - c->scache.name = pa_xstrdup(name); - - c->state = ESD_CACHING_SAMPLE; - - pa_scache_add_item(c->protocol->core, c->scache.name, NULL, NULL, NULL, &idx); - - idx += 1; - connection_write(c, &idx, sizeof(uint32_t)); - - return 0; -} - -static int esd_proto_sample_get_id(struct connection *c, PA_GCC_UNUSED esd_proto_t request, const void *data, size_t length) { - int32_t ok; - uint32_t idx; - char name[ESD_NAME_MAX+sizeof(SCACHE_PREFIX)-1]; - - assert(c && data && length == ESD_NAME_MAX); - - strcpy(name, SCACHE_PREFIX); - strncpy(name+sizeof(SCACHE_PREFIX)-1, data, ESD_NAME_MAX); - name[sizeof(name)-1] = 0; - - CHECK_VALIDITY(pa_utf8_valid(name), "Invalid UTF8 in sample name."); - - ok = -1; - if ((idx = pa_scache_get_id_by_name(c->protocol->core, name)) != PA_IDXSET_INVALID) - ok = idx + 1; - - connection_write(c, &ok, sizeof(int32_t)); - - return 0; -} - -static int esd_proto_sample_free_or_play(struct connection *c, esd_proto_t request, const void *data, size_t length) { - int32_t ok; - const char *name; - uint32_t idx; - - assert(c && data && length == sizeof(int32_t)); - - memcpy(&idx, data, sizeof(uint32_t)); - idx = MAYBE_UINT32_SWAP(c->swap_byte_order, idx) - 1; - - ok = 0; - - if ((name = pa_scache_get_name_by_id(c->protocol->core, idx))) { - if (request == ESD_PROTO_SAMPLE_PLAY) { - pa_sink *sink; - - if ((sink = pa_namereg_get(c->protocol->core, c->protocol->sink_name, PA_NAMEREG_SINK, 1))) - if (pa_scache_play_item(c->protocol->core, name, sink, PA_VOLUME_NORM) >= 0) - ok = idx + 1; - } else { - assert(request == ESD_PROTO_SAMPLE_FREE); - - if (pa_scache_remove_item(c->protocol->core, name) >= 0) - ok = idx + 1; - } - } - - connection_write(c, &ok, sizeof(int32_t)); - - return 0; -} - -static int esd_proto_standby_or_resume(struct connection *c, PA_GCC_UNUSED esd_proto_t request, PA_GCC_UNUSED const void *data, PA_GCC_UNUSED size_t length) { - int32_t ok; - - connection_write_prepare(c, sizeof(int32_t) * 2); - - ok = 1; - connection_write(c, &ok, sizeof(int32_t)); - connection_write(c, &ok, sizeof(int32_t)); - - return 0; -} - -/*** client callbacks ***/ - -static void client_kill_cb(pa_client *c) { - assert(c && c->userdata); - connection_free(c->userdata); -} - -/*** pa_iochannel callbacks ***/ - -static int do_read(struct connection *c) { - assert(c && c->io); - -/* pa_log("READ"); */ - - if (c->state == ESD_NEXT_REQUEST) { - ssize_t r; - assert(c->read_data_length < sizeof(c->request)); - - if ((r = pa_iochannel_read(c->io, ((uint8_t*) &c->request) + c->read_data_length, sizeof(c->request) - c->read_data_length)) <= 0) { - pa_log_debug(__FILE__": read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); - return -1; - } - - if ((c->read_data_length+= r) >= sizeof(c->request)) { - struct proto_handler *handler; - - c->request = MAYBE_INT32_SWAP(c->swap_byte_order, c->request); - - if (c->request < ESD_PROTO_CONNECT || c->request > ESD_PROTO_MAX) { - pa_log(__FILE__": recieved invalid request."); - return -1; - } - - handler = proto_map+c->request; - -/* pa_log(__FILE__": executing request #%u", c->request); */ - - if (!handler->proc) { - pa_log(__FILE__": recieved unimplemented request #%u.", c->request); - return -1; - } - - if (handler->data_length == 0) { - c->read_data_length = 0; - - if (handler->proc(c, c->request, NULL, 0) < 0) - return -1; - - } else { - if (c->read_data_alloc < handler->data_length) - c->read_data = pa_xrealloc(c->read_data, c->read_data_alloc = handler->data_length); - assert(c->read_data); - - c->state = ESD_NEEDS_REQDATA; - c->read_data_length = 0; - } - } - - } else if (c->state == ESD_NEEDS_REQDATA) { - ssize_t r; - struct proto_handler *handler = proto_map+c->request; - - assert(handler->proc); - - assert(c->read_data && c->read_data_length < handler->data_length); - - if ((r = pa_iochannel_read(c->io, (uint8_t*) c->read_data + c->read_data_length, handler->data_length - c->read_data_length)) <= 0) { - pa_log_debug(__FILE__": read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); - return -1; - } - - if ((c->read_data_length += r) >= handler->data_length) { - size_t l = c->read_data_length; - assert(handler->proc); - - c->state = ESD_NEXT_REQUEST; - c->read_data_length = 0; - - if (handler->proc(c, c->request, c->read_data, l) < 0) - return -1; - } - } else if (c->state == ESD_CACHING_SAMPLE) { - ssize_t r; - - assert(c->scache.memchunk.memblock && c->scache.name && c->scache.memchunk.index < c->scache.memchunk.length); - - if ((r = pa_iochannel_read(c->io, (uint8_t*) c->scache.memchunk.memblock->data+c->scache.memchunk.index, c->scache.memchunk.length-c->scache.memchunk.index)) <= 0) { - pa_log_debug(__FILE__": read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); - return -1; - } - - c->scache.memchunk.index += r; - assert(c->scache.memchunk.index <= c->scache.memchunk.length); - - if (c->scache.memchunk.index == c->scache.memchunk.length) { - uint32_t idx; - - c->scache.memchunk.index = 0; - pa_scache_add_item(c->protocol->core, c->scache.name, &c->scache.sample_spec, NULL, &c->scache.memchunk, &idx); - - pa_memblock_unref(c->scache.memchunk.memblock); - c->scache.memchunk.memblock = NULL; - c->scache.memchunk.index = c->scache.memchunk.length = 0; - - pa_xfree(c->scache.name); - c->scache.name = NULL; - - c->state = ESD_NEXT_REQUEST; - - idx += 1; - connection_write(c, &idx, sizeof(uint32_t)); - } - - } else if (c->state == ESD_STREAMING_DATA && c->sink_input) { - pa_memchunk chunk; - ssize_t r; - size_t l; - - assert(c->input_memblockq); - -/* pa_log("STREAMING_DATA"); */ - - if (!(l = pa_memblockq_missing(c->input_memblockq))) - return 0; - - if (l > c->playback.fragment_size) - l = c->playback.fragment_size; - - if (c->playback.current_memblock) - if (c->playback.current_memblock->length - c->playback.memblock_index < l) { - pa_memblock_unref(c->playback.current_memblock); - c->playback.current_memblock = NULL; - c->playback.memblock_index = 0; - } - - if (!c->playback.current_memblock) { - c->playback.current_memblock = pa_memblock_new(c->playback.fragment_size*2, c->protocol->core->memblock_stat); - assert(c->playback.current_memblock && c->playback.current_memblock->length >= l); - c->playback.memblock_index = 0; - } - - if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { - pa_log_debug(__FILE__": read(): %s", r < 0 ? pa_cstrerror(errno) : "EOF"); - return -1; - } - - chunk.memblock = c->playback.current_memblock; - chunk.index = c->playback.memblock_index; - chunk.length = r; - assert(chunk.memblock); - - c->playback.memblock_index += r; - - assert(c->input_memblockq); - pa_memblockq_push_align(c->input_memblockq, &chunk); - assert(c->sink_input); - pa_sink_notify(c->sink_input->sink); - } - - return 0; -} - -static int do_write(struct connection *c) { - assert(c && c->io); - -/* pa_log("WRITE"); */ - - if (c->write_data_length) { - ssize_t r; - - assert(c->write_data_index < c->write_data_length); - if ((r = pa_iochannel_write(c->io, (uint8_t*) c->write_data+c->write_data_index, c->write_data_length-c->write_data_index)) < 0) { - pa_log(__FILE__": write(): %s", pa_cstrerror(errno)); - return -1; - } - - if ((c->write_data_index +=r) >= c->write_data_length) - c->write_data_length = c->write_data_index = 0; - - } else if (c->state == ESD_STREAMING_DATA && c->source_output) { - pa_memchunk chunk; - ssize_t r; - - assert(c->output_memblockq); - if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) - return 0; - - assert(chunk.memblock && chunk.length); - - if ((r = pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+chunk.index, chunk.length)) < 0) { - pa_memblock_unref(chunk.memblock); - pa_log(__FILE__": write(): %s", pa_cstrerror(errno)); - return -1; - } - - pa_memblockq_drop(c->output_memblockq, &chunk, r); - pa_memblock_unref(chunk.memblock); - - pa_source_notify(c->source_output->source); - } - - return 0; -} - -static void do_work(struct connection *c) { - assert(c); - - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); - c->protocol->core->mainloop->defer_enable(c->defer_event, 0); - - if (c->dead) - return; - - if (pa_iochannel_is_readable(c->io)) { - if (do_read(c) < 0) - goto fail; - } - - if (c->state == ESD_STREAMING_DATA && c->source_output && pa_iochannel_is_hungup(c->io)) - /* In case we are in capture mode we will never call read() - * on the socket, hence we need to detect the hangup manually - * here, instead of simply waiting for read() to return 0. */ - goto fail; - - if (pa_iochannel_is_writable(c->io)) - if (do_write(c) < 0) - goto fail; - - return; - -fail: - - if (c->state == ESD_STREAMING_DATA && c->sink_input) { - c->dead = 1; - - pa_iochannel_free(c->io); - c->io = NULL; - - pa_memblockq_prebuf_disable(c->input_memblockq); - pa_sink_notify(c->sink_input->sink); - } else - connection_free(c); -} - -static void io_callback(pa_iochannel*io, void *userdata) { - struct connection *c = userdata; - assert(io && c && c->io == io); - - do_work(c); -} - -/*** defer callback ***/ - -static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) { - struct connection *c = userdata; - assert(a && c && c->defer_event == e); - -/* pa_log("DEFER"); */ - - do_work(c); -} - -/*** sink_input callbacks ***/ - -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - struct connection*c; - assert(i && i->userdata && chunk); - c = i->userdata; - - if (pa_memblockq_peek(c->input_memblockq, chunk) < 0) { - - if (c->dead) - connection_free(c); - - return -1; - } - - return 0; -} - -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - struct connection*c = i->userdata; - assert(i && c && length); - -/* pa_log("DROP"); */ - - pa_memblockq_drop(c->input_memblockq, chunk, length); - - /* do something */ - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); - - if (!c->dead) - c->protocol->core->mainloop->defer_enable(c->defer_event, 1); - -/* assert(pa_memblockq_get_length(c->input_memblockq) > 2048); */ -} - -static void sink_input_kill_cb(pa_sink_input *i) { - assert(i && i->userdata); - connection_free((struct connection *) i->userdata); -} - -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i) { - struct connection*c = i->userdata; - assert(i && c); - return pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec); -} - -/*** source_output callbacks ***/ - -static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { - struct connection *c = o->userdata; - assert(o && c && chunk); - - pa_memblockq_push(c->output_memblockq, chunk); - - /* do something */ - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); - - if (!c->dead) - c->protocol->core->mainloop->defer_enable(c->defer_event, 1); -} - -static void source_output_kill_cb(pa_source_output *o) { - assert(o && o->userdata); - connection_free((struct connection *) o->userdata); -} - -static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { - struct connection*c = o->userdata; - assert(o && c); - return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec); -} - -/*** socket server callback ***/ - -static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { - struct connection *c = userdata; - assert(m && tv && c && c->auth_timeout_event == e); - - if (!c->authorized) - connection_free(c); -} - -static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) { - struct connection *c; - pa_protocol_esound *p = userdata; - char cname[256], pname[128]; - assert(s && io && p); - - if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { - pa_log(__FILE__": Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); - pa_iochannel_free(io); - return; - } - - c = pa_xnew(struct connection, 1); - c->protocol = p; - c->io = io; - pa_iochannel_set_callback(c->io, io_callback, c); - - pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); - snprintf(cname, sizeof(cname), "EsounD client (%s)", pname); - assert(p->core); - c->client = pa_client_new(p->core, __FILE__, cname); - assert(c->client); - c->client->owner = p->module; - c->client->kill = client_kill_cb; - c->client->userdata = c; - - c->authorized = p->public; - c->swap_byte_order = 0; - c->dead = 0; - - c->read_data_length = 0; - c->read_data = pa_xmalloc(c->read_data_alloc = proto_map[ESD_PROTO_CONNECT].data_length); - - c->write_data_length = c->write_data_index = c->write_data_alloc = 0; - c->write_data = NULL; - - c->state = ESD_NEEDS_REQDATA; - c->request = ESD_PROTO_CONNECT; - - c->sink_input = NULL; - c->input_memblockq = NULL; - - c->source_output = NULL; - c->output_memblockq = NULL; - - c->playback.current_memblock = NULL; - c->playback.memblock_index = 0; - c->playback.fragment_size = 0; - - c->scache.memchunk.length = c->scache.memchunk.index = 0; - c->scache.memchunk.memblock = NULL; - c->scache.name = NULL; - - c->original_name = NULL; - - if (!c->authorized) { - struct timeval tv; - pa_gettimeofday(&tv); - tv.tv_sec += AUTH_TIMEOUT; - c->auth_timeout_event = p->core->mainloop->time_new(p->core->mainloop, &tv, auth_timeout, c); - } else - c->auth_timeout_event = NULL; - - c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c); - assert(c->defer_event); - p->core->mainloop->defer_enable(c->defer_event, 0); - - pa_idxset_put(p->connections, c, &c->index); -} - -/*** entry points ***/ - -pa_protocol_esound* pa_protocol_esound_new(pa_core*core, pa_socket_server *server, pa_module *m, pa_modargs *ma) { - pa_protocol_esound *p; - int public = 0; - assert(core && server && ma); - - p = pa_xnew(pa_protocol_esound, 1); - - if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &public) < 0) { - pa_log(__FILE__": auth-anonymous= expects a boolean argument."); - return NULL; - } - - if (pa_authkey_load_auto(pa_modargs_get_value(ma, "cookie", DEFAULT_COOKIE_FILE), p->esd_key, sizeof(p->esd_key)) < 0) { - pa_xfree(p); - return NULL; - } - - p->module = m; - p->public = public; - p->server = server; - pa_socket_server_set_callback(p->server, on_connection, p); - p->core = core; - p->connections = pa_idxset_new(NULL, NULL); - assert(p->connections); - - p->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); - p->source_name = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL)); - p->n_player = 0; - - return p; -} - -void pa_protocol_esound_free(pa_protocol_esound *p) { - struct connection *c; - assert(p); - - while ((c = pa_idxset_first(p->connections, NULL))) - connection_free(c); - - pa_idxset_free(p->connections, NULL, NULL); - pa_socket_server_unref(p->server); - pa_xfree(p); -} diff --git a/src/polypcore/protocol-esound.h b/src/polypcore/protocol-esound.h deleted file mode 100644 index a94d1c72..00000000 --- a/src/polypcore/protocol-esound.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef fooprotocolesoundhfoo -#define fooprotocolesoundhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> -#include <polypcore/socket-server.h> -#include <polypcore/module.h> -#include <polypcore/modargs.h> - -typedef struct pa_protocol_esound pa_protocol_esound; - -pa_protocol_esound* pa_protocol_esound_new(pa_core*core, pa_socket_server *server, pa_module *m, pa_modargs *ma); -void pa_protocol_esound_free(pa_protocol_esound *p); - -#endif diff --git a/src/polypcore/protocol-http.c b/src/polypcore/protocol-http.c deleted file mode 100644 index 86ea3b15..00000000 --- a/src/polypcore/protocol-http.c +++ /dev/null @@ -1,268 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> - -#include <polyp/util.h> -#include <polyp/xmalloc.h> - -#include <polypcore/ioline.h> -#include <polypcore/log.h> -#include <polypcore/namereg.h> -#include <polypcore/cli-text.h> - -#include "protocol-http.h" - -/* Don't allow more than this many concurrent connections */ -#define MAX_CONNECTIONS 10 - -#define internal_server_error(c) http_message((c), 500, "Internal Server Error", NULL) - -#define URL_ROOT "/" -#define URL_CSS "/style" -#define URL_STATUS "/status" - -struct connection { - pa_protocol_http *protocol; - pa_ioline *line; - enum { REQUEST_LINE, MIME_HEADER, DATA } state; - char *url; -}; - -struct pa_protocol_http { - pa_module *module; - pa_core *core; - pa_socket_server*server; - pa_idxset *connections; -}; - -static void http_response(struct connection *c, int code, const char *msg, const char *mime) { - char s[256]; - assert(c); - assert(msg); - assert(mime); - - snprintf(s, sizeof(s), - "HTTP/1.0 %i %s\n" - "Connection: close\n" - "Content-Type: %s\n" - "Cache-Control: no-cache\n" - "Expires: 0\n" - "Server: "PACKAGE_NAME"/"PACKAGE_VERSION"\n" - "\n", code, msg, mime); - - pa_ioline_puts(c->line, s); -} - -static void http_message(struct connection *c, int code, const char *msg, const char *text) { - char s[256]; - assert(c); - - http_response(c, code, msg, "text/html"); - - if (!text) - text = msg; - - snprintf(s, sizeof(s), - "<?xml version=\"1.0\"?>\n" - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" - "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head><title>%s</title></head>\n" - "<body>%s</body></html>\n", - text, text); - - pa_ioline_puts(c->line, s); - pa_ioline_defer_close(c->line); -} - - -static void connection_free(struct connection *c, int del) { - assert(c); - - if (c->url) - pa_xfree(c->url); - - if (del) - pa_idxset_remove_by_data(c->protocol->connections, c, NULL); - pa_ioline_unref(c->line); - pa_xfree(c); -} - -static void line_callback(pa_ioline *line, const char *s, void *userdata) { - struct connection *c = userdata; - assert(line); - assert(c); - - if (!s) { - /* EOF */ - connection_free(c, 1); - return; - } - - switch (c->state) { - case REQUEST_LINE: { - if (memcmp(s, "GET ", 4)) - goto fail; - - s +=4; - - c->url = pa_xstrndup(s, strcspn(s, " \r\n\t?")); - c->state = MIME_HEADER; - break; - - } - - case MIME_HEADER: { - - /* Ignore MIME headers */ - if (strcspn(s, " \r\n") != 0) - break; - - /* We're done */ - c->state = DATA; - - pa_log_info(__FILE__": request for %s", c->url); - - if (!strcmp(c->url, URL_ROOT)) { - char txt[256]; - http_response(c, 200, "OK", "text/html"); - - pa_ioline_puts(c->line, - "<?xml version=\"1.0\"?>\n" - "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n" - "<html xmlns=\"http://www.w3.org/1999/xhtml\"><title>"PACKAGE_NAME" "PACKAGE_VERSION"</title>\n" - "<link rel=\"stylesheet\" type=\"text/css\" href=\"style\"/></head><body>\n"); - - pa_ioline_puts(c->line, - "<h1>"PACKAGE_NAME" "PACKAGE_VERSION"</h1>\n" - "<table>"); - -#define PRINTF_FIELD(a,b) pa_ioline_printf(c->line, "<tr><td><b>%s</b></td><td>%s</td></tr>\n",(a),(b)) - - PRINTF_FIELD("User Name:", pa_get_user_name(txt, sizeof(txt))); - PRINTF_FIELD("Fully Qualified Domain Name:", pa_get_fqdn(txt, sizeof(txt))); - PRINTF_FIELD("Default Sample Specification:", pa_sample_spec_snprint(txt, sizeof(txt), &c->protocol->core->default_sample_spec)); - PRINTF_FIELD("Default Sink:", pa_namereg_get_default_sink_name(c->protocol->core)); - PRINTF_FIELD("Default Source:", pa_namereg_get_default_source_name(c->protocol->core)); - - pa_ioline_puts(c->line, "</table>"); - - pa_ioline_puts(c->line, "<p><a href=\"/status\">Click here</a> for an extensive server status report.</p>"); - - pa_ioline_puts(c->line, "</body></html>\n"); - - pa_ioline_defer_close(c->line); - } else if (!strcmp(c->url, URL_CSS)) { - http_response(c, 200, "OK", "text/css"); - - pa_ioline_puts(c->line, - "body { color: black; background-color: white; margin: 0.5cm; }\n" - "a:link, a:visited { color: #900000; }\n" - "p { margin-left: 0.5cm; margin-right: 0.5cm; }\n" - "h1 { color: #00009F; }\n" - "h2 { color: #00009F; }\n" - "ul { margin-left: .5cm; }\n" - "ol { margin-left: .5cm; }\n" - "pre { margin-left: .5cm; background-color: #f0f0f0; padding: 0.4cm;}\n" - ".grey { color: #afafaf; }\n" - "table { margin-left: 1cm; border:1px solid lightgrey; padding: 0.2cm; }\n" - "td { padding-left:10px; padding-right:10px; }\n"); - - pa_ioline_defer_close(c->line); - } else if (!strcmp(c->url, URL_STATUS)) { - char *r; - - http_response(c, 200, "OK", "text/plain"); - r = pa_full_status_string(c->protocol->core); - pa_ioline_puts(c->line, r); - pa_xfree(r); - - pa_ioline_defer_close(c->line); - } else - http_message(c, 404, "Not Found", NULL); - - break; - } - - default: - ; - } - - return; - -fail: - internal_server_error(c); -} - -static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) { - pa_protocol_http *p = userdata; - struct connection *c; - assert(s && io && p); - - if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { - pa_log_warn(__FILE__": Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); - pa_iochannel_free(io); - return; - } - - c = pa_xmalloc(sizeof(struct connection)); - c->protocol = p; - c->line = pa_ioline_new(io); - c->state = REQUEST_LINE; - c->url = NULL; - - pa_ioline_set_callback(c->line, line_callback, c); - pa_idxset_put(p->connections, c, NULL); -} - -pa_protocol_http* pa_protocol_http_new(pa_core *core, pa_socket_server *server, pa_module *m, PA_GCC_UNUSED pa_modargs *ma) { - pa_protocol_http* p; - assert(core && server); - - p = pa_xmalloc(sizeof(pa_protocol_http)); - p->module = m; - p->core = core; - p->server = server; - p->connections = pa_idxset_new(NULL, NULL); - - pa_socket_server_set_callback(p->server, on_connection, p); - - return p; -} - -static void free_connection(void *p, PA_GCC_UNUSED void *userdata) { - assert(p); - connection_free(p, 0); -} - -void pa_protocol_http_free(pa_protocol_http *p) { - assert(p); - - pa_idxset_free(p->connections, free_connection, NULL); - pa_socket_server_unref(p->server); - pa_xfree(p); -} diff --git a/src/polypcore/protocol-http.h b/src/polypcore/protocol-http.h deleted file mode 100644 index 10dd656b..00000000 --- a/src/polypcore/protocol-http.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef fooprotocolhttphfoo -#define fooprotocolhttphfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> -#include <polypcore/socket-server.h> -#include <polypcore/module.h> -#include <polypcore/modargs.h> - -typedef struct pa_protocol_http pa_protocol_http; - -pa_protocol_http* pa_protocol_http_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma); -void pa_protocol_http_free(pa_protocol_http *n); - -#endif diff --git a/src/polypcore/protocol-native.c b/src/polypcore/protocol-native.c deleted file mode 100644 index 221601a6..00000000 --- a/src/polypcore/protocol-native.c +++ /dev/null @@ -1,2398 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <unistd.h> - -#include <polyp/timeval.h> -#include <polyp/version.h> -#include <polyp/utf8.h> -#include <polyp/util.h> -#include <polyp/xmalloc.h> - -#include <polypcore/native-common.h> -#include <polypcore/packet.h> -#include <polypcore/client.h> -#include <polypcore/source-output.h> -#include <polypcore/sink-input.h> -#include <polypcore/pstream.h> -#include <polypcore/tagstruct.h> -#include <polypcore/pdispatch.h> -#include <polypcore/pstream-util.h> -#include <polypcore/authkey.h> -#include <polypcore/namereg.h> -#include <polypcore/core-scache.h> -#include <polypcore/core-subscribe.h> -#include <polypcore/log.h> -#include <polypcore/autoload.h> -#include <polypcore/authkey-prop.h> -#include <polypcore/strlist.h> -#include <polypcore/props.h> -#include <polypcore/sample-util.h> -#include <polypcore/llist.h> - -#include "protocol-native.h" - -/* Kick a client if it doesn't authenticate within this time */ -#define AUTH_TIMEOUT 60 - -/* Don't accept more connection than this */ -#define MAX_CONNECTIONS 10 - -#define MAX_MEMBLOCKQ_LENGTH (4*1024*1024) /* 4MB */ - -struct connection; -struct pa_protocol_native; - -struct record_stream { - struct connection *connection; - uint32_t index; - pa_source_output *source_output; - pa_memblockq *memblockq; - size_t fragment_size; -}; - -struct playback_stream { - int type; - struct connection *connection; - uint32_t index; - pa_sink_input *sink_input; - pa_memblockq *memblockq; - size_t requested_bytes; - int drain_request; - uint32_t drain_tag; - uint32_t syncid; - int underrun; - - /* Sync group members */ - PA_LLIST_FIELDS(struct playback_stream); -}; - -struct upload_stream { - int type; - struct connection *connection; - uint32_t index; - pa_memchunk memchunk; - size_t length; - char *name; - pa_sample_spec sample_spec; - pa_channel_map channel_map; -}; - -struct output_stream { - int type; -}; - -enum { - UPLOAD_STREAM, - PLAYBACK_STREAM -}; - -struct connection { - int authorized; - uint32_t version; - pa_protocol_native *protocol; - pa_client *client; - pa_pstream *pstream; - pa_pdispatch *pdispatch; - pa_idxset *record_streams, *output_streams; - uint32_t rrobin_index; - pa_subscription *subscription; - pa_time_event *auth_timeout_event; -}; - -struct pa_protocol_native { - pa_module *module; - int public; - pa_core *core; - pa_socket_server *server; - pa_idxset *connections; - uint8_t auth_cookie[PA_NATIVE_COOKIE_LENGTH]; - int auth_cookie_in_property; -#ifdef SCM_CREDENTIALS - char *auth_group; -#endif -}; - -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk); -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length); -static void sink_input_kill_cb(pa_sink_input *i); -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i); - -static void request_bytes(struct playback_stream*s); - -static void source_output_kill_cb(pa_source_output *o); -static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk); -static pa_usec_t source_output_get_latency_cb(pa_source_output *o); - -static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_create_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_drain_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_create_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_delete_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_auth(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_set_client_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_lookup(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_stat(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_get_playback_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_get_record_latency(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_create_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_finish_upload_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_play_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_remove_sample(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_get_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_get_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_get_server_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_subscribe(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_set_volume(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_set_mute(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_cork_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_flush_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_trigger_or_prebuf_playback_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_set_default_sink_or_source(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_set_stream_name(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_kill(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_load_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_unload_module(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_add_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_remove_autoload(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_get_autoload_info(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_get_autoload_info_list(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_cork_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); -static void command_flush_record_stream(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata); - -static const pa_pdispatch_cb_t command_table[PA_COMMAND_MAX] = { - [PA_COMMAND_ERROR] = NULL, - [PA_COMMAND_TIMEOUT] = NULL, - [PA_COMMAND_REPLY] = NULL, - [PA_COMMAND_CREATE_PLAYBACK_STREAM] = command_create_playback_stream, - [PA_COMMAND_DELETE_PLAYBACK_STREAM] = command_delete_stream, - [PA_COMMAND_DRAIN_PLAYBACK_STREAM] = command_drain_playback_stream, - [PA_COMMAND_CREATE_RECORD_STREAM] = command_create_record_stream, - [PA_COMMAND_DELETE_RECORD_STREAM] = command_delete_stream, - [PA_COMMAND_AUTH] = command_auth, - [PA_COMMAND_REQUEST] = NULL, - [PA_COMMAND_EXIT] = command_exit, - [PA_COMMAND_SET_CLIENT_NAME] = command_set_client_name, - [PA_COMMAND_LOOKUP_SINK] = command_lookup, - [PA_COMMAND_LOOKUP_SOURCE] = command_lookup, - [PA_COMMAND_STAT] = command_stat, - [PA_COMMAND_GET_PLAYBACK_LATENCY] = command_get_playback_latency, - [PA_COMMAND_GET_RECORD_LATENCY] = command_get_record_latency, - [PA_COMMAND_CREATE_UPLOAD_STREAM] = command_create_upload_stream, - [PA_COMMAND_DELETE_UPLOAD_STREAM] = command_delete_stream, - [PA_COMMAND_FINISH_UPLOAD_STREAM] = command_finish_upload_stream, - [PA_COMMAND_PLAY_SAMPLE] = command_play_sample, - [PA_COMMAND_REMOVE_SAMPLE] = command_remove_sample, - [PA_COMMAND_GET_SINK_INFO] = command_get_info, - [PA_COMMAND_GET_SOURCE_INFO] = command_get_info, - [PA_COMMAND_GET_CLIENT_INFO] = command_get_info, - [PA_COMMAND_GET_MODULE_INFO] = command_get_info, - [PA_COMMAND_GET_SINK_INPUT_INFO] = command_get_info, - [PA_COMMAND_GET_SOURCE_OUTPUT_INFO] = command_get_info, - [PA_COMMAND_GET_SAMPLE_INFO] = command_get_info, - [PA_COMMAND_GET_SINK_INFO_LIST] = command_get_info_list, - [PA_COMMAND_GET_SOURCE_INFO_LIST] = command_get_info_list, - [PA_COMMAND_GET_MODULE_INFO_LIST] = command_get_info_list, - [PA_COMMAND_GET_CLIENT_INFO_LIST] = command_get_info_list, - [PA_COMMAND_GET_SINK_INPUT_INFO_LIST] = command_get_info_list, - [PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST] = command_get_info_list, - [PA_COMMAND_GET_SAMPLE_INFO_LIST] = command_get_info_list, - [PA_COMMAND_GET_SERVER_INFO] = command_get_server_info, - [PA_COMMAND_SUBSCRIBE] = command_subscribe, - - [PA_COMMAND_SET_SINK_VOLUME] = command_set_volume, - [PA_COMMAND_SET_SINK_INPUT_VOLUME] = command_set_volume, - [PA_COMMAND_SET_SOURCE_VOLUME] = command_set_volume, - - [PA_COMMAND_SET_SINK_MUTE] = command_set_mute, - [PA_COMMAND_SET_SOURCE_MUTE] = command_set_mute, - - [PA_COMMAND_CORK_PLAYBACK_STREAM] = command_cork_playback_stream, - [PA_COMMAND_FLUSH_PLAYBACK_STREAM] = command_flush_playback_stream, - [PA_COMMAND_TRIGGER_PLAYBACK_STREAM] = command_trigger_or_prebuf_playback_stream, - [PA_COMMAND_PREBUF_PLAYBACK_STREAM] = command_trigger_or_prebuf_playback_stream, - - [PA_COMMAND_CORK_RECORD_STREAM] = command_cork_record_stream, - [PA_COMMAND_FLUSH_RECORD_STREAM] = command_flush_record_stream, - - [PA_COMMAND_SET_DEFAULT_SINK] = command_set_default_sink_or_source, - [PA_COMMAND_SET_DEFAULT_SOURCE] = command_set_default_sink_or_source, - [PA_COMMAND_SET_PLAYBACK_STREAM_NAME] = command_set_stream_name, - [PA_COMMAND_SET_RECORD_STREAM_NAME] = command_set_stream_name, - [PA_COMMAND_KILL_CLIENT] = command_kill, - [PA_COMMAND_KILL_SINK_INPUT] = command_kill, - [PA_COMMAND_KILL_SOURCE_OUTPUT] = command_kill, - [PA_COMMAND_LOAD_MODULE] = command_load_module, - [PA_COMMAND_UNLOAD_MODULE] = command_unload_module, - [PA_COMMAND_GET_AUTOLOAD_INFO] = command_get_autoload_info, - [PA_COMMAND_GET_AUTOLOAD_INFO_LIST] = command_get_autoload_info_list, - [PA_COMMAND_ADD_AUTOLOAD] = command_add_autoload, - [PA_COMMAND_REMOVE_AUTOLOAD] = command_remove_autoload -}; - -/* structure management */ - -static struct upload_stream* upload_stream_new( - struct connection *c, - const pa_sample_spec *ss, - const pa_channel_map *map, - const char *name, size_t length) { - - struct upload_stream *s; - assert(c && ss && name && length); - - s = pa_xnew(struct upload_stream, 1); - s->type = UPLOAD_STREAM; - s->connection = c; - s->sample_spec = *ss; - s->channel_map = *map; - s->name = pa_xstrdup(name); - - s->memchunk.memblock = NULL; - s->memchunk.index = 0; - s->memchunk.length = 0; - - s->length = length; - - pa_idxset_put(c->output_streams, s, &s->index); - return s; -} - -static void upload_stream_free(struct upload_stream *o) { - assert(o && o->connection); - - pa_idxset_remove_by_data(o->connection->output_streams, o, NULL); - - pa_xfree(o->name); - - if (o->memchunk.memblock) - pa_memblock_unref(o->memchunk.memblock); - - pa_xfree(o); -} - -static struct record_stream* record_stream_new( - struct connection *c, - pa_source *source, - const pa_sample_spec *ss, - const pa_channel_map *map, - const char *name, - size_t maxlength, - size_t fragment_size) { - - struct record_stream *s; - pa_source_output *source_output; - size_t base; - assert(c && source && ss && name && maxlength); - - if (!(source_output = pa_source_output_new(source, __FILE__, name, ss, map, -1))) - return NULL; - - s = pa_xnew(struct record_stream, 1); - s->connection = c; - s->source_output = source_output; - s->source_output->push = source_output_push_cb; - s->source_output->kill = source_output_kill_cb; - s->source_output->get_latency = source_output_get_latency_cb; - s->source_output->userdata = s; - s->source_output->owner = c->protocol->module; - s->source_output->client = c->client; - - s->memblockq = pa_memblockq_new( - 0, - maxlength, - 0, - base = pa_frame_size(ss), - 1, - 0, - NULL, - c->protocol->core->memblock_stat); - assert(s->memblockq); - - s->fragment_size = (fragment_size/base)*base; - if (!s->fragment_size) - s->fragment_size = base; - - pa_idxset_put(c->record_streams, s, &s->index); - return s; -} - -static void record_stream_free(struct record_stream* r) { - assert(r && r->connection); - - pa_idxset_remove_by_data(r->connection->record_streams, r, NULL); - pa_source_output_disconnect(r->source_output); - pa_source_output_unref(r->source_output); - pa_memblockq_free(r->memblockq); - pa_xfree(r); -} - -static struct playback_stream* playback_stream_new( - struct connection *c, - pa_sink *sink, - const pa_sample_spec *ss, - const pa_channel_map *map, - const char *name, - size_t maxlength, - size_t tlength, - size_t prebuf, - size_t minreq, - pa_cvolume *volume, - uint32_t syncid) { - - struct playback_stream *s, *ssync; - pa_sink_input *sink_input; - pa_memblock *silence; - uint32_t idx; - int64_t start_index; - - assert(c && sink && ss && name && maxlength); - - /* Find syncid group */ - for (ssync = pa_idxset_first(c->output_streams, &idx); ssync; ssync = pa_idxset_next(c->output_streams, &idx)) { - - if (ssync->type != PLAYBACK_STREAM) - continue; - - if (ssync->syncid == syncid) - break; - } - - /* Synced streams must connect to the same sink */ - if (ssync && ssync->sink_input->sink != sink) - return NULL; - - if (!(sink_input = pa_sink_input_new(sink, __FILE__, name, ss, map, volume, 0, -1))) - return NULL; - - s = pa_xnew(struct playback_stream, 1); - s->type = PLAYBACK_STREAM; - s->connection = c; - s->syncid = syncid; - s->sink_input = sink_input; - s->underrun = 1; - - s->sink_input->peek = sink_input_peek_cb; - s->sink_input->drop = sink_input_drop_cb; - s->sink_input->kill = sink_input_kill_cb; - s->sink_input->get_latency = sink_input_get_latency_cb; - s->sink_input->userdata = s; - s->sink_input->owner = c->protocol->module; - s->sink_input->client = c->client; - - if (ssync) { - /* Sync id found, now find head of list */ - PA_LLIST_FIND_HEAD(struct playback_stream, ssync, &ssync); - - /* Prepend ourselves */ - PA_LLIST_PREPEND(struct playback_stream, ssync, s); - - /* Set our start index to the current read index of the other grozp member(s) */ - assert(ssync->next); - start_index = pa_memblockq_get_read_index(ssync->next->memblockq); - } else { - /* This ia a new sync group */ - PA_LLIST_INIT(struct playback_stream, s); - start_index = 0; - } - - silence = pa_silence_memblock_new(ss, 0, c->protocol->core->memblock_stat); - - s->memblockq = pa_memblockq_new( - start_index, - maxlength, - tlength, - pa_frame_size(ss), - prebuf, - minreq, - silence, - c->protocol->core->memblock_stat); - - pa_memblock_unref(silence); - - s->requested_bytes = 0; - s->drain_request = 0; - - pa_idxset_put(c->output_streams, s, &s->index); - - return s; -} - -static void playback_stream_free(struct playback_stream* p) { - struct playback_stream *head; - assert(p && p->connection); - - if (p->drain_request) - pa_pstream_send_error(p->connection->pstream, p->drain_tag, PA_ERR_NOENTITY); - - PA_LLIST_FIND_HEAD(struct playback_stream, p, &head); - PA_LLIST_REMOVE(struct playback_stream, head, p); - - pa_idxset_remove_by_data(p->connection->output_streams, p, NULL); - pa_sink_input_disconnect(p->sink_input); - pa_sink_input_unref(p->sink_input); - pa_memblockq_free(p->memblockq); - pa_xfree(p); -} - -static void connection_free(struct connection *c) { - struct record_stream *r; - struct output_stream *o; - assert(c && c->protocol); - - pa_idxset_remove_by_data(c->protocol->connections, c, NULL); - while ((r = pa_idxset_first(c->record_streams, NULL))) - record_stream_free(r); - pa_idxset_free(c->record_streams, NULL, NULL); - - while ((o = pa_idxset_first(c->output_streams, NULL))) - if (o->type == PLAYBACK_STREAM) - playback_stream_free((struct playback_stream*) o); - else - upload_stream_free((struct upload_stream*) o); - pa_idxset_free(c->output_streams, NULL, NULL); - - pa_pdispatch_unref(c->pdispatch); - pa_pstream_close(c->pstream); - pa_pstream_unref(c->pstream); - pa_client_free(c->client); - - if (c->subscription) - pa_subscription_free(c->subscription); - - if (c->auth_timeout_event) - c->protocol->core->mainloop->time_free(c->auth_timeout_event); - - pa_xfree(c); -} - -static void request_bytes(struct playback_stream *s) { - pa_tagstruct *t; - size_t l; - assert(s); - - if (!(l = pa_memblockq_missing(s->memblockq))) - return; - - if (l <= s->requested_bytes) - return; - - l -= s->requested_bytes; - - if (l < pa_memblockq_get_minreq(s->memblockq)) - return; - - s->requested_bytes += l; - - t = pa_tagstruct_new(NULL, 0); - assert(t); - pa_tagstruct_putu32(t, PA_COMMAND_REQUEST); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, s->index); - pa_tagstruct_putu32(t, l); - pa_pstream_send_tagstruct(s->connection->pstream, t); - -/* pa_log(__FILE__": Requesting %u bytes", l); */ -} - -static void send_memblock(struct connection *c) { - uint32_t start; - struct record_stream *r; - - start = PA_IDXSET_INVALID; - for (;;) { - pa_memchunk chunk; - - if (!(r = pa_idxset_rrobin(c->record_streams, &c->rrobin_index))) - return; - - if (start == PA_IDXSET_INVALID) - start = c->rrobin_index; - else if (start == c->rrobin_index) - return; - - if (pa_memblockq_peek(r->memblockq, &chunk) >= 0) { - pa_memchunk schunk = chunk; - - if (schunk.length > r->fragment_size) - schunk.length = r->fragment_size; - - pa_pstream_send_memblock(c->pstream, r->index, 0, PA_SEEK_RELATIVE, &schunk); - pa_memblockq_drop(r->memblockq, &chunk, schunk.length); - pa_memblock_unref(schunk.memblock); - - return; - } - } -} - -static void send_playback_stream_killed(struct playback_stream *p) { - pa_tagstruct *t; - assert(p); - - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_PLAYBACK_STREAM_KILLED); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, p->index); - pa_pstream_send_tagstruct(p->connection->pstream, t); -} - -static void send_record_stream_killed(struct record_stream *r) { - pa_tagstruct *t; - assert(r); - - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_RECORD_STREAM_KILLED); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, r->index); - pa_pstream_send_tagstruct(r->connection->pstream, t); -} - -/*** sinkinput callbacks ***/ - -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - struct playback_stream *s; - assert(i && i->userdata && chunk); - s = i->userdata; - - if (pa_memblockq_get_length(s->memblockq) <= 0 && !s->underrun) { - pa_tagstruct *t; - - /* Report that we're empty */ - - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_UNDERFLOW); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, s->index); - pa_pstream_send_tagstruct(s->connection->pstream, t); - - s->underrun = 1; - } - - if (pa_memblockq_peek(s->memblockq, chunk) < 0) { -/* pa_log(__FILE__": peek: failure"); */ - return -1; - } - -/* pa_log(__FILE__": peek: %u", chunk->length); */ - - return 0; -} - -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - struct playback_stream *s; - assert(i && i->userdata && length); - s = i->userdata; - - pa_memblockq_drop(s->memblockq, chunk, length); - - request_bytes(s); - - if (s->drain_request && !pa_memblockq_is_readable(s->memblockq)) { - pa_pstream_send_simple_ack(s->connection->pstream, s->drain_tag); - s->drain_request = 0; - } - -/* pa_log(__FILE__": after_drop: %u %u", pa_memblockq_get_length(s->memblockq), pa_memblockq_is_readable(s->memblockq)); */ -} - -static void sink_input_kill_cb(pa_sink_input *i) { - assert(i && i->userdata); - send_playback_stream_killed((struct playback_stream *) i->userdata); - playback_stream_free((struct playback_stream *) i->userdata); -} - -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i) { - struct playback_stream *s; - assert(i && i->userdata); - s = i->userdata; - - /*pa_log(__FILE__": get_latency: %u", pa_memblockq_get_length(s->memblockq));*/ - - return pa_bytes_to_usec(pa_memblockq_get_length(s->memblockq), &s->sink_input->sample_spec); -} - -/*** source_output callbacks ***/ - -static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { - struct record_stream *s; - assert(o && o->userdata && chunk); - s = o->userdata; - - if (pa_memblockq_push_align(s->memblockq, chunk) < 0) { - pa_log_warn(__FILE__": Failed to push data into output queue."); - return; - } - - if (!pa_pstream_is_pending(s->connection->pstream)) - send_memblock(s->connection); -} - -static void source_output_kill_cb(pa_source_output *o) { - assert(o && o->userdata); - send_record_stream_killed((struct record_stream *) o->userdata); - record_stream_free((struct record_stream *) o->userdata); -} - -static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { - struct record_stream *s; - assert(o && o->userdata); - s = o->userdata; - - /*pa_log(__FILE__": get_latency: %u", pa_memblockq_get_length(s->memblockq));*/ - - return pa_bytes_to_usec(pa_memblockq_get_length(s->memblockq), &o->sample_spec); -} - -/*** pdispatch callbacks ***/ - -static void protocol_error(struct connection *c) { - pa_log(__FILE__": protocol error, kicking client"); - connection_free(c); -} - -#define CHECK_VALIDITY(pstream, expression, tag, error) do { \ -if (!(expression)) { \ - pa_pstream_send_error((pstream), (tag), (error)); \ - return; \ -} \ -} while(0); - -static pa_tagstruct *reply_new(uint32_t tag) { - pa_tagstruct *reply; - - reply = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(reply, PA_COMMAND_REPLY); - pa_tagstruct_putu32(reply, tag); - return reply; -} - -static void command_create_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - struct playback_stream *s; - uint32_t maxlength, tlength, prebuf, minreq, sink_index, syncid; - const char *name, *sink_name; - pa_sample_spec ss; - pa_channel_map map; - pa_tagstruct *reply; - pa_sink *sink; - pa_cvolume volume; - int corked; - - assert(c && t && c->protocol && c->protocol->core); - - if (pa_tagstruct_get( - t, - PA_TAG_STRING, &name, - PA_TAG_SAMPLE_SPEC, &ss, - PA_TAG_CHANNEL_MAP, &map, - PA_TAG_U32, &sink_index, - PA_TAG_STRING, &sink_name, - PA_TAG_U32, &maxlength, - PA_TAG_BOOLEAN, &corked, - PA_TAG_U32, &tlength, - PA_TAG_U32, &prebuf, - PA_TAG_U32, &minreq, - PA_TAG_U32, &syncid, - PA_TAG_CVOLUME, &volume, - PA_TAG_INVALID) < 0 || - !pa_tagstruct_eof(t) || - !name) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, map.channels == ss.channels && volume.channels == ss.channels, tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, maxlength > 0 && maxlength <= MAX_MEMBLOCKQ_LENGTH, tag, PA_ERR_INVALID); - - if (sink_index != PA_INVALID_INDEX) - sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index); - else - sink = pa_namereg_get(c->protocol->core, sink_name, PA_NAMEREG_SINK, 1); - - CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY); - - s = playback_stream_new(c, sink, &ss, &map, name, maxlength, tlength, prebuf, minreq, &volume, syncid); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID); - - pa_sink_input_cork(s->sink_input, corked); - - reply = reply_new(tag); - pa_tagstruct_putu32(reply, s->index); - assert(s->sink_input); - pa_tagstruct_putu32(reply, s->sink_input->index); - pa_tagstruct_putu32(reply, s->requested_bytes = pa_memblockq_missing(s->memblockq)); - - if (c->version >= 9) { - /* Since 0.9 we support sending the buffer metrics back to the client */ - - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_maxlength(s->memblockq)); - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_tlength(s->memblockq)); - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_prebuf(s->memblockq)); - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_minreq(s->memblockq)); - } - - pa_pstream_send_tagstruct(c->pstream, reply); - request_bytes(s); -} - -static void command_delete_stream(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t channel; - assert(c && t); - - if (pa_tagstruct_getu32(t, &channel) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - - if (command == PA_COMMAND_DELETE_PLAYBACK_STREAM) { - struct playback_stream *s; - if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || (s->type != PLAYBACK_STREAM)) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); - return; - } - - playback_stream_free(s); - } else if (command == PA_COMMAND_DELETE_RECORD_STREAM) { - struct record_stream *s; - if (!(s = pa_idxset_get_by_index(c->record_streams, channel))) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); - return; - } - - record_stream_free(s); - } else { - struct upload_stream *s; - assert(command == PA_COMMAND_DELETE_UPLOAD_STREAM); - if (!(s = pa_idxset_get_by_index(c->output_streams, channel)) || (s->type != UPLOAD_STREAM)) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); - return; - } - - upload_stream_free(s); - } - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_create_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - struct record_stream *s; - uint32_t maxlength, fragment_size; - uint32_t source_index; - const char *name, *source_name; - pa_sample_spec ss; - pa_channel_map map; - pa_tagstruct *reply; - pa_source *source; - int corked; - assert(c && t && c->protocol && c->protocol->core); - - if (pa_tagstruct_gets(t, &name) < 0 || - pa_tagstruct_get_sample_spec(t, &ss) < 0 || - pa_tagstruct_get_channel_map(t, &map) < 0 || - pa_tagstruct_getu32(t, &source_index) < 0 || - pa_tagstruct_gets(t, &source_name) < 0 || - pa_tagstruct_getu32(t, &maxlength) < 0 || - pa_tagstruct_get_boolean(t, &corked) < 0 || - pa_tagstruct_getu32(t, &fragment_size) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, source_index != PA_INVALID_INDEX || !source_name || (*source_name && pa_utf8_valid(source_name)), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, maxlength <= MAX_MEMBLOCKQ_LENGTH, tag, PA_ERR_INVALID); - - if (source_index != PA_INVALID_INDEX) - source = pa_idxset_get_by_index(c->protocol->core->sources, source_index); - else - source = pa_namereg_get(c->protocol->core, source_name, PA_NAMEREG_SOURCE, 1); - - CHECK_VALIDITY(c->pstream, source, tag, PA_ERR_NOENTITY); - - s = record_stream_new(c, source, &ss, &map, name, maxlength, fragment_size); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID); - - pa_source_output_cork(s->source_output, corked); - - reply = reply_new(tag); - pa_tagstruct_putu32(reply, s->index); - assert(s->source_output); - pa_tagstruct_putu32(reply, s->source_output->index); - - if (c->version >= 9) { - /* Since 0.9 we support sending the buffer metrics back to the client */ - - pa_tagstruct_putu32(reply, (uint32_t) pa_memblockq_get_maxlength(s->memblockq)); - pa_tagstruct_putu32(reply, (uint32_t) s->fragment_size); - } - - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_exit(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - assert(c && t); - - if (!pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop); - c->protocol->core->mainloop->quit(c->protocol->core->mainloop, 0); - pa_pstream_send_simple_ack(c->pstream, tag); /* nonsense */ -} - -static void command_auth(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - const void*cookie; - pa_tagstruct *reply; - assert(c && t); - - if (pa_tagstruct_getu32(t, &c->version) < 0 || - pa_tagstruct_get_arbitrary(t, &cookie, PA_NATIVE_COOKIE_LENGTH) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - /* Minimum supported version */ - if (c->version < 8) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_VERSION); - return; - } - - if (!c->authorized) { - int success = 0; - -#ifdef SCM_CREDENTIALS - const struct ucred *ucred = pa_pdispatch_creds(pd); - - if (ucred) { - if (ucred->uid == getuid()) - success = 1; - else if (c->protocol->auth_group) { - int r; - - if ((r = pa_uid_in_group(ucred->uid, c->protocol->auth_group)) < 0) - pa_log_warn(__FILE__": failed to check group membership."); - else if (r > 0) - success = 1; - } - - pa_log_info(__FILE__": Got credentials: pid=%lu uid=%lu gid=%lu auth=%i", - (unsigned long) ucred->pid, - (unsigned long) ucred->uid, - (unsigned long) ucred->gid, - success); - } -#endif - - if (memcmp(c->protocol->auth_cookie, cookie, PA_NATIVE_COOKIE_LENGTH) == 0) - success = 1; - - if (!success) { - pa_log_warn(__FILE__": Denied access to client with invalid authorization data."); - pa_pstream_send_error(c->pstream, tag, PA_ERR_ACCESS); - return; - } - - c->authorized = 1; - if (c->auth_timeout_event) { - c->protocol->core->mainloop->time_free(c->auth_timeout_event); - c->auth_timeout_event = NULL; - } - } - - reply = reply_new(tag); - pa_tagstruct_putu32(reply, PA_PROTOCOL_VERSION); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_set_client_name(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - const char *name; - assert(c && t); - - if (pa_tagstruct_gets(t, &name) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - - pa_client_set_name(c->client, name); - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_lookup(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - const char *name; - uint32_t idx = PA_IDXSET_INVALID; - assert(c && t); - - if (pa_tagstruct_gets(t, &name) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - - if (command == PA_COMMAND_LOOKUP_SINK) { - pa_sink *sink; - if ((sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1))) - idx = sink->index; - } else { - pa_source *source; - assert(command == PA_COMMAND_LOOKUP_SOURCE); - if ((source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1))) - idx = source->index; - } - - if (idx == PA_IDXSET_INVALID) - pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); - else { - pa_tagstruct *reply; - reply = reply_new(tag); - pa_tagstruct_putu32(reply, idx); - pa_pstream_send_tagstruct(c->pstream, reply); - } -} - -static void command_drain_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - struct playback_stream *s; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - s = pa_idxset_get_by_index(c->output_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); - - s->drain_request = 0; - - pa_memblockq_prebuf_disable(s->memblockq); - - if (!pa_memblockq_is_readable(s->memblockq)) { -/* pa_log("immediate drain: %u", pa_memblockq_get_length(s->memblockq)); */ - pa_pstream_send_simple_ack(c->pstream, tag); - } else { -/* pa_log("slow drain triggered"); */ - s->drain_request = 1; - s->drain_tag = tag; - - pa_sink_notify(s->sink_input->sink); - } -} - -static void command_stat(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - pa_tagstruct *reply; - assert(c && t); - - if (!pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - - reply = reply_new(tag); - pa_tagstruct_putu32(reply, c->protocol->core->memblock_stat->total); - pa_tagstruct_putu32(reply, c->protocol->core->memblock_stat->total_size); - pa_tagstruct_putu32(reply, c->protocol->core->memblock_stat->allocated); - pa_tagstruct_putu32(reply, c->protocol->core->memblock_stat->allocated_size); - pa_tagstruct_putu32(reply, pa_scache_total_size(c->protocol->core)); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_get_playback_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - pa_tagstruct *reply; - struct playback_stream *s; - struct timeval tv, now; - uint32_t idx; - pa_usec_t latency; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - pa_tagstruct_get_timeval(t, &tv) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - s = pa_idxset_get_by_index(c->output_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); - - reply = reply_new(tag); - - latency = pa_sink_get_latency(s->sink_input->sink); - if (s->sink_input->resampled_chunk.memblock) - latency += pa_bytes_to_usec(s->sink_input->resampled_chunk.length, &s->sink_input->sample_spec); - pa_tagstruct_put_usec(reply, latency); - - pa_tagstruct_put_usec(reply, 0); - pa_tagstruct_put_boolean(reply, pa_memblockq_is_readable(s->memblockq)); - pa_tagstruct_put_timeval(reply, &tv); - pa_tagstruct_put_timeval(reply, pa_gettimeofday(&now)); - pa_tagstruct_puts64(reply, pa_memblockq_get_write_index(s->memblockq)); - pa_tagstruct_puts64(reply, pa_memblockq_get_read_index(s->memblockq)); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_get_record_latency(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - pa_tagstruct *reply; - struct record_stream *s; - struct timeval tv, now; - uint32_t idx; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - pa_tagstruct_get_timeval(t, &tv) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - s = pa_idxset_get_by_index(c->record_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - - reply = reply_new(tag); - pa_tagstruct_put_usec(reply, s->source_output->source->monitor_of ? pa_sink_get_latency(s->source_output->source->monitor_of) : 0); - pa_tagstruct_put_usec(reply, pa_source_get_latency(s->source_output->source)); - pa_tagstruct_put_boolean(reply, 0); - pa_tagstruct_put_timeval(reply, &tv); - pa_tagstruct_put_timeval(reply, pa_gettimeofday(&now)); - pa_tagstruct_puts64(reply, pa_memblockq_get_write_index(s->memblockq)); - pa_tagstruct_puts64(reply, pa_memblockq_get_read_index(s->memblockq)); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_create_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - struct upload_stream *s; - uint32_t length; - const char *name; - pa_sample_spec ss; - pa_channel_map map; - pa_tagstruct *reply; - assert(c && t && c->protocol && c->protocol->core); - - if (pa_tagstruct_gets(t, &name) < 0 || - pa_tagstruct_get_sample_spec(t, &ss) < 0 || - pa_tagstruct_get_channel_map(t, &map) < 0 || - pa_tagstruct_getu32(t, &length) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, pa_sample_spec_valid(&ss), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, pa_channel_map_valid(&map), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, map.channels == ss.channels, tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, (length % pa_frame_size(&ss)) == 0 && length > 0, tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, length <= PA_SCACHE_ENTRY_SIZE_MAX, tag, PA_ERR_TOOLARGE); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - - s = upload_stream_new(c, &ss, &map, name, length); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_INVALID); - - reply = reply_new(tag); - pa_tagstruct_putu32(reply, s->index); - pa_tagstruct_putu32(reply, length); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_finish_upload_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t channel; - struct upload_stream *s; - uint32_t idx; - assert(c && t); - - if (pa_tagstruct_getu32(t, &channel) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - - s = pa_idxset_get_by_index(c->output_streams, channel); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == UPLOAD_STREAM, tag, PA_ERR_NOENTITY); - - if (pa_scache_add_item(c->protocol->core, s->name, &s->sample_spec, &s->channel_map, &s->memchunk, &idx) < 0) - pa_pstream_send_error(c->pstream, tag, PA_ERR_INTERNAL); - else - pa_pstream_send_simple_ack(c->pstream, tag); - - upload_stream_free(s); -} - -static void command_play_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t sink_index; - pa_volume_t volume; - pa_sink *sink; - const char *name, *sink_name; - assert(c && t); - - if (pa_tagstruct_getu32(t, &sink_index) < 0 || - pa_tagstruct_gets(t, &sink_name) < 0 || - pa_tagstruct_getu32(t, &volume) < 0 || - pa_tagstruct_gets(t, &name) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, sink_index != PA_INVALID_INDEX || !sink_name || (*sink_name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - - if (sink_index != PA_INVALID_INDEX) - sink = pa_idxset_get_by_index(c->protocol->core->sinks, sink_index); - else - sink = pa_namereg_get(c->protocol->core, sink_name, PA_NAMEREG_SINK, 1); - - CHECK_VALIDITY(c->pstream, sink, tag, PA_ERR_NOENTITY); - - if (pa_scache_play_item(c->protocol->core, name, sink, volume) < 0) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); - return; - } - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_remove_sample(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - const char *name; - assert(c && t); - - if (pa_tagstruct_gets(t, &name) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - - if (pa_scache_remove_item(c->protocol->core, name) < 0) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); - return; - } - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void sink_fill_tagstruct(pa_tagstruct *t, pa_sink *sink) { - assert(t && sink); - pa_tagstruct_put( - t, - PA_TAG_U32, sink->index, - PA_TAG_STRING, sink->name, - PA_TAG_STRING, sink->description, - PA_TAG_SAMPLE_SPEC, &sink->sample_spec, - PA_TAG_CHANNEL_MAP, &sink->channel_map, - PA_TAG_U32, sink->owner ? sink->owner->index : PA_INVALID_INDEX, - PA_TAG_CVOLUME, pa_sink_get_volume(sink, PA_MIXER_HARDWARE), - PA_TAG_BOOLEAN, pa_sink_get_mute(sink, PA_MIXER_HARDWARE), - PA_TAG_U32, sink->monitor_source->index, - PA_TAG_STRING, sink->monitor_source->name, - PA_TAG_USEC, pa_sink_get_latency(sink), - PA_TAG_STRING, sink->driver, - PA_TAG_U32, (sink->get_hw_volume ? PA_SINK_HW_VOLUME_CTRL : 0) | (sink->get_latency ? PA_SINK_LATENCY : 0), - PA_TAG_INVALID); -} - -static void source_fill_tagstruct(pa_tagstruct *t, pa_source *source) { - assert(t && source); - pa_tagstruct_put( - t, - PA_TAG_U32, source->index, - PA_TAG_STRING, source->name, - PA_TAG_STRING, source->description, - PA_TAG_SAMPLE_SPEC, &source->sample_spec, - PA_TAG_CHANNEL_MAP, &source->channel_map, - PA_TAG_U32, source->owner ? source->owner->index : PA_INVALID_INDEX, - PA_TAG_CVOLUME, pa_source_get_volume(source, PA_MIXER_HARDWARE), - PA_TAG_BOOLEAN, pa_source_get_mute(source, PA_MIXER_HARDWARE), - PA_TAG_U32, source->monitor_of ? source->monitor_of->index : PA_INVALID_INDEX, - PA_TAG_STRING, source->monitor_of ? source->monitor_of->name : NULL, - PA_TAG_USEC, pa_source_get_latency(source), - PA_TAG_STRING, source->driver, - PA_TAG_U32, (source->get_hw_volume ? PA_SOURCE_HW_VOLUME_CTRL : 0) | (source->get_latency ? PA_SOURCE_LATENCY : 0), - PA_TAG_INVALID); -} - -static void client_fill_tagstruct(pa_tagstruct *t, pa_client *client) { - assert(t && client); - pa_tagstruct_putu32(t, client->index); - pa_tagstruct_puts(t, client->name); - pa_tagstruct_putu32(t, client->owner ? client->owner->index : PA_INVALID_INDEX); - pa_tagstruct_puts(t, client->driver); -} - -static void module_fill_tagstruct(pa_tagstruct *t, pa_module *module) { - assert(t && module); - pa_tagstruct_putu32(t, module->index); - pa_tagstruct_puts(t, module->name); - pa_tagstruct_puts(t, module->argument); - pa_tagstruct_putu32(t, module->n_used); - pa_tagstruct_put_boolean(t, module->auto_unload); -} - -static void sink_input_fill_tagstruct(pa_tagstruct *t, pa_sink_input *s) { - assert(t && s); - pa_tagstruct_putu32(t, s->index); - pa_tagstruct_puts(t, s->name); - pa_tagstruct_putu32(t, s->owner ? s->owner->index : PA_INVALID_INDEX); - pa_tagstruct_putu32(t, s->client ? s->client->index : PA_INVALID_INDEX); - pa_tagstruct_putu32(t, s->sink->index); - pa_tagstruct_put_sample_spec(t, &s->sample_spec); - pa_tagstruct_put_channel_map(t, &s->channel_map); - pa_tagstruct_put_cvolume(t, &s->volume); - pa_tagstruct_put_usec(t, pa_sink_input_get_latency(s)); - pa_tagstruct_put_usec(t, pa_sink_get_latency(s->sink)); - pa_tagstruct_puts(t, pa_resample_method_to_string(pa_sink_input_get_resample_method(s))); - pa_tagstruct_puts(t, s->driver); -} - -static void source_output_fill_tagstruct(pa_tagstruct *t, pa_source_output *s) { - assert(t && s); - pa_tagstruct_putu32(t, s->index); - pa_tagstruct_puts(t, s->name); - pa_tagstruct_putu32(t, s->owner ? s->owner->index : PA_INVALID_INDEX); - pa_tagstruct_putu32(t, s->client ? s->client->index : PA_INVALID_INDEX); - pa_tagstruct_putu32(t, s->source->index); - pa_tagstruct_put_sample_spec(t, &s->sample_spec); - pa_tagstruct_put_channel_map(t, &s->channel_map); - pa_tagstruct_put_usec(t, pa_source_output_get_latency(s)); - pa_tagstruct_put_usec(t, pa_source_get_latency(s->source)); - pa_tagstruct_puts(t, pa_resample_method_to_string(pa_source_output_get_resample_method(s))); - pa_tagstruct_puts(t, s->driver); -} - -static void scache_fill_tagstruct(pa_tagstruct *t, pa_scache_entry *e) { - assert(t && e); - pa_tagstruct_putu32(t, e->index); - pa_tagstruct_puts(t, e->name); - pa_tagstruct_put_cvolume(t, &e->volume); - pa_tagstruct_put_usec(t, pa_bytes_to_usec(e->memchunk.length, &e->sample_spec)); - pa_tagstruct_put_sample_spec(t, &e->sample_spec); - pa_tagstruct_put_channel_map(t, &e->channel_map); - pa_tagstruct_putu32(t, e->memchunk.length); - pa_tagstruct_put_boolean(t, e->lazy); - pa_tagstruct_puts(t, e->filename); -} - -static void command_get_info(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - pa_sink *sink = NULL; - pa_source *source = NULL; - pa_client *client = NULL; - pa_module *module = NULL; - pa_sink_input *si = NULL; - pa_source_output *so = NULL; - pa_scache_entry *sce = NULL; - const char *name; - pa_tagstruct *reply; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - (command != PA_COMMAND_GET_CLIENT_INFO && - command != PA_COMMAND_GET_MODULE_INFO && - command != PA_COMMAND_GET_SINK_INPUT_INFO && - command != PA_COMMAND_GET_SOURCE_OUTPUT_INFO && - pa_tagstruct_gets(t, &name) < 0) || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); - - if (command == PA_COMMAND_GET_SINK_INFO) { - if (idx != PA_INVALID_INDEX) - sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); - } else if (command == PA_COMMAND_GET_SOURCE_INFO) { - if (idx != PA_INVALID_INDEX) - source = pa_idxset_get_by_index(c->protocol->core->sources, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); - } else if (command == PA_COMMAND_GET_CLIENT_INFO) - client = pa_idxset_get_by_index(c->protocol->core->clients, idx); - else if (command == PA_COMMAND_GET_MODULE_INFO) - module = pa_idxset_get_by_index(c->protocol->core->modules, idx); - else if (command == PA_COMMAND_GET_SINK_INPUT_INFO) - si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); - else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO) - so = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); - else { - assert(command == PA_COMMAND_GET_SAMPLE_INFO); - if (idx != PA_INVALID_INDEX) - sce = pa_idxset_get_by_index(c->protocol->core->scache, idx); - else - sce = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SAMPLE, 0); - } - - if (!sink && !source && !client && !module && !si && !so && !sce) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_NOENTITY); - return; - } - - reply = reply_new(tag); - if (sink) - sink_fill_tagstruct(reply, sink); - else if (source) - source_fill_tagstruct(reply, source); - else if (client) - client_fill_tagstruct(reply, client); - else if (module) - module_fill_tagstruct(reply, module); - else if (si) - sink_input_fill_tagstruct(reply, si); - else if (so) - source_output_fill_tagstruct(reply, so); - else - scache_fill_tagstruct(reply, sce); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_get_info_list(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - pa_idxset *i; - uint32_t idx; - void *p; - pa_tagstruct *reply; - assert(c && t); - - if (!pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - - reply = reply_new(tag); - - if (command == PA_COMMAND_GET_SINK_INFO_LIST) - i = c->protocol->core->sinks; - else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST) - i = c->protocol->core->sources; - else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST) - i = c->protocol->core->clients; - else if (command == PA_COMMAND_GET_MODULE_INFO_LIST) - i = c->protocol->core->modules; - else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST) - i = c->protocol->core->sink_inputs; - else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST) - i = c->protocol->core->source_outputs; - else { - assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST); - i = c->protocol->core->scache; - } - - if (i) { - for (p = pa_idxset_first(i, &idx); p; p = pa_idxset_next(i, &idx)) { - if (command == PA_COMMAND_GET_SINK_INFO_LIST) - sink_fill_tagstruct(reply, p); - else if (command == PA_COMMAND_GET_SOURCE_INFO_LIST) - source_fill_tagstruct(reply, p); - else if (command == PA_COMMAND_GET_CLIENT_INFO_LIST) - client_fill_tagstruct(reply, p); - else if (command == PA_COMMAND_GET_MODULE_INFO_LIST) - module_fill_tagstruct(reply, p); - else if (command == PA_COMMAND_GET_SINK_INPUT_INFO_LIST) - sink_input_fill_tagstruct(reply, p); - else if (command == PA_COMMAND_GET_SOURCE_OUTPUT_INFO_LIST) - source_output_fill_tagstruct(reply, p); - else { - assert(command == PA_COMMAND_GET_SAMPLE_INFO_LIST); - scache_fill_tagstruct(reply, p); - } - } - } - - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_get_server_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - pa_tagstruct *reply; - char txt[256]; - const char *n; - assert(c && t); - - if (!pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - - reply = reply_new(tag); - pa_tagstruct_puts(reply, PACKAGE_NAME); - pa_tagstruct_puts(reply, PACKAGE_VERSION); - pa_tagstruct_puts(reply, pa_get_user_name(txt, sizeof(txt))); - pa_tagstruct_puts(reply, pa_get_fqdn(txt, sizeof(txt))); - pa_tagstruct_put_sample_spec(reply, &c->protocol->core->default_sample_spec); - - n = pa_namereg_get_default_sink_name(c->protocol->core); - pa_tagstruct_puts(reply, n); - n = pa_namereg_get_default_source_name(c->protocol->core); - pa_tagstruct_puts(reply, n); - - pa_tagstruct_putu32(reply, c->protocol->core->cookie); - - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void subscription_cb(pa_core *core, pa_subscription_event_type_t e, uint32_t idx, void *userdata) { - pa_tagstruct *t; - struct connection *c = userdata; - assert(c && core); - - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_SUBSCRIBE_EVENT); - pa_tagstruct_putu32(t, (uint32_t) -1); - pa_tagstruct_putu32(t, e); - pa_tagstruct_putu32(t, idx); - pa_pstream_send_tagstruct(c->pstream, t); -} - -static void command_subscribe(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - pa_subscription_mask_t m; - assert(c && t); - - if (pa_tagstruct_getu32(t, &m) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, (m & ~PA_SUBSCRIPTION_MASK_ALL) == 0, tag, PA_ERR_INVALID); - - if (c->subscription) - pa_subscription_free(c->subscription); - - if (m != 0) { - c->subscription = pa_subscription_new(c->protocol->core, m, subscription_cb, c); - assert(c->subscription); - } else - c->subscription = NULL; - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_set_volume( - PA_GCC_UNUSED pa_pdispatch *pd, - uint32_t command, - uint32_t tag, - pa_tagstruct *t, - void *userdata) { - - struct connection *c = userdata; - uint32_t idx; - pa_cvolume volume; - pa_sink *sink = NULL; - pa_source *source = NULL; - pa_sink_input *si = NULL; - const char *name = NULL; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - (command == PA_COMMAND_SET_SINK_VOLUME && pa_tagstruct_gets(t, &name) < 0) || - (command == PA_COMMAND_SET_SOURCE_VOLUME && pa_tagstruct_gets(t, &name) < 0) || - pa_tagstruct_get_cvolume(t, &volume) || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, pa_cvolume_valid(&volume), tag, PA_ERR_INVALID); - - if (command == PA_COMMAND_SET_SINK_VOLUME) { - if (idx != PA_INVALID_INDEX) - sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); - } else if (command == PA_COMMAND_SET_SOURCE_VOLUME) { - if (idx != (uint32_t) -1) - source = pa_idxset_get_by_index(c->protocol->core->sources, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); - } else { - assert(command == PA_COMMAND_SET_SINK_INPUT_VOLUME); - si = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); - } - - CHECK_VALIDITY(c->pstream, si || sink || source, tag, PA_ERR_NOENTITY); - - if (sink) - pa_sink_set_volume(sink, PA_MIXER_HARDWARE, &volume); - else if (source) - pa_source_set_volume(source, PA_MIXER_HARDWARE, &volume); - else if (si) - pa_sink_input_set_volume(si, &volume); - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_set_mute( - PA_GCC_UNUSED pa_pdispatch *pd, - uint32_t command, - uint32_t tag, - pa_tagstruct *t, - void *userdata) { - - struct connection *c = userdata; - uint32_t idx; - int mute; - pa_sink *sink = NULL; - pa_source *source = NULL; - const char *name = NULL; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - pa_tagstruct_gets(t, &name) < 0 || - pa_tagstruct_get_boolean(t, &mute) || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX || !name || (*name && pa_utf8_valid(name)), tag, PA_ERR_INVALID); - - if (command == PA_COMMAND_SET_SINK_MUTE) { - if (idx != PA_INVALID_INDEX) - sink = pa_idxset_get_by_index(c->protocol->core->sinks, idx); - else - sink = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SINK, 1); - } else { - assert(command == PA_COMMAND_SET_SOURCE_MUTE); - if (idx != (uint32_t) -1) - source = pa_idxset_get_by_index(c->protocol->core->sources, idx); - else - source = pa_namereg_get(c->protocol->core, name, PA_NAMEREG_SOURCE, 1); - } - - CHECK_VALIDITY(c->pstream, sink || source, tag, PA_ERR_NOENTITY); - - if (sink) - pa_sink_set_mute(sink, PA_MIXER_HARDWARE, mute); - else if (source) - pa_source_set_mute(source, PA_MIXER_HARDWARE, mute); - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_cork_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - int b; - struct playback_stream *s, *ssync; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - pa_tagstruct_get_boolean(t, &b) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); - s = pa_idxset_get_by_index(c->output_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); - - pa_sink_input_cork(s->sink_input, b); - pa_memblockq_prebuf_force(s->memblockq); - - /* Do the same for all other members in the sync group */ - for (ssync = s->prev; ssync; ssync = ssync->prev) { - pa_sink_input_cork(ssync->sink_input, b); - pa_memblockq_prebuf_force(ssync->memblockq); - } - - for (ssync = s->next; ssync; ssync = ssync->next) { - pa_sink_input_cork(ssync->sink_input, b); - pa_memblockq_prebuf_force(ssync->memblockq); - } - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_flush_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - struct playback_stream *s, *ssync; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); - s = pa_idxset_get_by_index(c->output_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); - - pa_memblockq_flush(s->memblockq); - s->underrun = 0; - - /* Do the same for all other members in the sync group */ - for (ssync = s->prev; ssync; ssync = ssync->prev) { - pa_memblockq_flush(ssync->memblockq); - ssync->underrun = 0; - } - - for (ssync = s->next; ssync; ssync = ssync->next) { - pa_memblockq_flush(ssync->memblockq); - ssync->underrun = 0; - } - - pa_pstream_send_simple_ack(c->pstream, tag); - pa_sink_notify(s->sink_input->sink); - request_bytes(s); - - for (ssync = s->prev; ssync; ssync = ssync->prev) - request_bytes(ssync); - - for (ssync = s->next; ssync; ssync = ssync->next) - request_bytes(ssync); -} - -static void command_trigger_or_prebuf_playback_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - struct playback_stream *s; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, idx != PA_INVALID_INDEX, tag, PA_ERR_INVALID); - s = pa_idxset_get_by_index(c->output_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); - - switch (command) { - case PA_COMMAND_PREBUF_PLAYBACK_STREAM: - pa_memblockq_prebuf_force(s->memblockq); - break; - - case PA_COMMAND_TRIGGER_PLAYBACK_STREAM: - pa_memblockq_prebuf_disable(s->memblockq); - break; - - default: - abort(); - } - - pa_sink_notify(s->sink_input->sink); - pa_pstream_send_simple_ack(c->pstream, tag); - request_bytes(s); -} - -static void command_cork_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - struct record_stream *s; - int b; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - pa_tagstruct_get_boolean(t, &b) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - s = pa_idxset_get_by_index(c->record_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - - pa_source_output_cork(s->source_output, b); - pa_memblockq_prebuf_force(s->memblockq); - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_flush_record_stream(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - struct record_stream *s; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - s = pa_idxset_get_by_index(c->record_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - - pa_memblockq_flush(s->memblockq); - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_set_default_sink_or_source(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - const char *s; - assert(c && t); - - if (pa_tagstruct_gets(t, &s) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, !s || (*s && pa_utf8_valid(s)), tag, PA_ERR_INVALID); - - pa_namereg_set_default(c->protocol->core, s, command == PA_COMMAND_SET_DEFAULT_SOURCE ? PA_NAMEREG_SOURCE : PA_NAMEREG_SINK); - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_set_stream_name(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - const char *name; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - pa_tagstruct_gets(t, &name) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - - if (command == PA_COMMAND_SET_PLAYBACK_STREAM_NAME) { - struct playback_stream *s; - - s = pa_idxset_get_by_index(c->output_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - CHECK_VALIDITY(c->pstream, s->type == PLAYBACK_STREAM, tag, PA_ERR_NOENTITY); - - pa_sink_input_set_name(s->sink_input, name); - - } else { - struct record_stream *s; - - s = pa_idxset_get_by_index(c->record_streams, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - - pa_source_output_set_name(s->source_output, name); - } - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_kill(PA_GCC_UNUSED pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - - if (command == PA_COMMAND_KILL_CLIENT) { - pa_client *client; - - client = pa_idxset_get_by_index(c->protocol->core->clients, idx); - CHECK_VALIDITY(c->pstream, client, tag, PA_ERR_NOENTITY); - pa_client_kill(client); - - } else if (command == PA_COMMAND_KILL_SINK_INPUT) { - pa_sink_input *s; - - s = pa_idxset_get_by_index(c->protocol->core->sink_inputs, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - - pa_sink_input_kill(s); - } else { - pa_source_output *s; - - assert(command == PA_COMMAND_KILL_SOURCE_OUTPUT); - - s = pa_idxset_get_by_index(c->protocol->core->source_outputs, idx); - CHECK_VALIDITY(c->pstream, s, tag, PA_ERR_NOENTITY); - - pa_source_output_kill(s); - } - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_load_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - pa_module *m; - const char *name, *argument; - pa_tagstruct *reply; - assert(c && t); - - if (pa_tagstruct_gets(t, &name) < 0 || - pa_tagstruct_gets(t, &argument) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name) && !strchr(name, '/'), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, !argument || pa_utf8_valid(argument), tag, PA_ERR_INVALID); - - if (!(m = pa_module_load(c->protocol->core, name, argument))) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_MODINITFAILED); - return; - } - - reply = reply_new(tag); - pa_tagstruct_putu32(reply, m->index); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_unload_module(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - uint32_t idx; - pa_module *m; - assert(c && t); - - if (pa_tagstruct_getu32(t, &idx) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - m = pa_idxset_get_by_index(c->protocol->core->modules, idx); - CHECK_VALIDITY(c->pstream, m, tag, PA_ERR_NOENTITY); - - pa_module_unload_request(m); - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void command_add_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - const char *name, *module, *argument; - uint32_t type; - uint32_t idx; - pa_tagstruct *reply; - assert(c && t); - - if (pa_tagstruct_gets(t, &name) < 0 || - pa_tagstruct_getu32(t, &type) < 0 || - pa_tagstruct_gets(t, &module) < 0 || - pa_tagstruct_gets(t, &argument) < 0 || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name && *name && pa_utf8_valid(name), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, type == 0 || type == 1, tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, module && *module && pa_utf8_valid(module), tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, !argument || pa_utf8_valid(argument), tag, PA_ERR_INVALID); - - if (pa_autoload_add(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE, module, argument, &idx) < 0) { - pa_pstream_send_error(c->pstream, tag, PA_ERR_EXIST); - return; - } - - reply = reply_new(tag); - pa_tagstruct_putu32(reply, idx); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_remove_autoload(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - const char *name = NULL; - uint32_t type, idx = PA_IDXSET_INVALID; - int r; - assert(c && t); - - if ((pa_tagstruct_getu32(t, &idx) < 0 && - (pa_tagstruct_gets(t, &name) < 0 || - pa_tagstruct_getu32(t, &type) < 0)) || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name || idx != PA_IDXSET_INVALID, tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, !name || (*name && pa_utf8_valid(name) && (type == 0 || type == 1)), tag, PA_ERR_INVALID); - - if (name) - r = pa_autoload_remove_by_name(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE); - else - r = pa_autoload_remove_by_index(c->protocol->core, idx); - - CHECK_VALIDITY(c->pstream, r >= 0, tag, PA_ERR_NOENTITY); - - pa_pstream_send_simple_ack(c->pstream, tag); -} - -static void autoload_fill_tagstruct(pa_tagstruct *t, const pa_autoload_entry *e) { - assert(t && e); - - pa_tagstruct_putu32(t, e->index); - pa_tagstruct_puts(t, e->name); - pa_tagstruct_putu32(t, e->type == PA_NAMEREG_SINK ? 0 : 1); - pa_tagstruct_puts(t, e->module); - pa_tagstruct_puts(t, e->argument); -} - -static void command_get_autoload_info(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - const pa_autoload_entry *a = NULL; - uint32_t type, idx; - const char *name; - pa_tagstruct *reply; - assert(c && t); - - if ((pa_tagstruct_getu32(t, &idx) < 0 && - (pa_tagstruct_gets(t, &name) < 0 || - pa_tagstruct_getu32(t, &type) < 0)) || - !pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - CHECK_VALIDITY(c->pstream, name || idx != PA_IDXSET_INVALID, tag, PA_ERR_INVALID); - CHECK_VALIDITY(c->pstream, !name || (*name && (type == 0 || type == 1) && pa_utf8_valid(name)), tag, PA_ERR_INVALID); - - if (name) - a = pa_autoload_get_by_name(c->protocol->core, name, type == 0 ? PA_NAMEREG_SINK : PA_NAMEREG_SOURCE); - else - a = pa_autoload_get_by_index(c->protocol->core, idx); - - CHECK_VALIDITY(c->pstream, a, tag, PA_ERR_NOENTITY); - - reply = reply_new(tag); - autoload_fill_tagstruct(reply, a); - pa_pstream_send_tagstruct(c->pstream, reply); -} - -static void command_get_autoload_info_list(PA_GCC_UNUSED pa_pdispatch *pd, PA_GCC_UNUSED uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) { - struct connection *c = userdata; - pa_tagstruct *reply; - assert(c && t); - - if (!pa_tagstruct_eof(t)) { - protocol_error(c); - return; - } - - CHECK_VALIDITY(c->pstream, c->authorized, tag, PA_ERR_ACCESS); - - reply = reply_new(tag); - - if (c->protocol->core->autoload_hashmap) { - pa_autoload_entry *a; - void *state = NULL; - - while ((a = pa_hashmap_iterate(c->protocol->core->autoload_hashmap, &state, NULL))) - autoload_fill_tagstruct(reply, a); - } - - pa_pstream_send_tagstruct(c->pstream, reply); -} - -/*** pstream callbacks ***/ - -static void pstream_packet_callback(pa_pstream *p, pa_packet *packet, const void *creds, void *userdata) { - struct connection *c = userdata; - assert(p && packet && packet->data && c); - - if (pa_pdispatch_run(c->pdispatch, packet, creds, c) < 0) { - pa_log(__FILE__": invalid packet."); - connection_free(c); - } -} - -static void pstream_memblock_callback(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata) { - struct connection *c = userdata; - struct output_stream *stream; - assert(p && chunk && userdata); - - if (!(stream = pa_idxset_get_by_index(c->output_streams, channel))) { - pa_log(__FILE__": client sent block for invalid stream."); - connection_free(c); - return; - } - - if (stream->type == PLAYBACK_STREAM) { - struct playback_stream *ps = (struct playback_stream*) stream; - if (chunk->length >= ps->requested_bytes) - ps->requested_bytes = 0; - else - ps->requested_bytes -= chunk->length; - - pa_memblockq_seek(ps->memblockq, offset, seek); - - if (pa_memblockq_push_align(ps->memblockq, chunk) < 0) { - pa_tagstruct *t; - - pa_log_warn(__FILE__": failed to push data into queue"); - - /* Pushing this block into the queue failed, so we simulate - * it by skipping ahead */ - - pa_memblockq_seek(ps->memblockq, chunk->length, PA_SEEK_RELATIVE); - - /* Notify the user */ - t = pa_tagstruct_new(NULL, 0); - pa_tagstruct_putu32(t, PA_COMMAND_OVERFLOW); - pa_tagstruct_putu32(t, (uint32_t) -1); /* tag */ - pa_tagstruct_putu32(t, ps->index); - pa_pstream_send_tagstruct(p, t); - } - - ps->underrun = 0; - - pa_sink_notify(ps->sink_input->sink); - - } else { - struct upload_stream *u = (struct upload_stream*) stream; - size_t l; - assert(u->type == UPLOAD_STREAM); - - if (!u->memchunk.memblock) { - if (u->length == chunk->length) { - u->memchunk = *chunk; - pa_memblock_ref(u->memchunk.memblock); - u->length = 0; - } else { - u->memchunk.memblock = pa_memblock_new(u->length, c->protocol->core->memblock_stat); - u->memchunk.index = u->memchunk.length = 0; - } - } - - assert(u->memchunk.memblock); - - l = u->length; - if (l > chunk->length) - l = chunk->length; - - if (l > 0) { - memcpy((uint8_t*) u->memchunk.memblock->data + u->memchunk.index + u->memchunk.length, - (uint8_t*) chunk->memblock->data+chunk->index, l); - u->memchunk.length += l; - u->length -= l; - } - } -} - -static void pstream_die_callback(pa_pstream *p, void *userdata) { - struct connection *c = userdata; - assert(p && c); - connection_free(c); - -/* pa_log(__FILE__": connection died.");*/ -} - - -static void pstream_drain_callback(pa_pstream *p, void *userdata) { - struct connection *c = userdata; - assert(p && c); - - send_memblock(c); -} - -/*** client callbacks ***/ - -static void client_kill_cb(pa_client *c) { - assert(c && c->userdata); - connection_free(c->userdata); -} - -/*** socket server callbacks ***/ - -static void auth_timeout(pa_mainloop_api*m, pa_time_event *e, const struct timeval *tv, void *userdata) { - struct connection *c = userdata; - assert(m && tv && c && c->auth_timeout_event == e); - - if (!c->authorized) - connection_free(c); -} - -static void on_connection(PA_GCC_UNUSED pa_socket_server*s, pa_iochannel *io, void *userdata) { - pa_protocol_native *p = userdata; - struct connection *c; - char cname[256], pname[128]; - assert(io && p); - - if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { - pa_log_warn(__FILE__": Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); - pa_iochannel_free(io); - return; - } - - c = pa_xmalloc(sizeof(struct connection)); - - c->authorized =!! p->public; - - if (!c->authorized) { - struct timeval tv; - pa_gettimeofday(&tv); - tv.tv_sec += AUTH_TIMEOUT; - c->auth_timeout_event = p->core->mainloop->time_new(p->core->mainloop, &tv, auth_timeout, c); - } else - c->auth_timeout_event = NULL; - - c->version = 8; - c->protocol = p; - pa_iochannel_socket_peer_to_string(io, pname, sizeof(pname)); - snprintf(cname, sizeof(cname), "Native client (%s)", pname); - assert(p->core); - c->client = pa_client_new(p->core, __FILE__, cname); - assert(c->client); - c->client->kill = client_kill_cb; - c->client->userdata = c; - c->client->owner = p->module; - - c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->memblock_stat); - assert(c->pstream); - - pa_pstream_set_recieve_packet_callback(c->pstream, pstream_packet_callback, c); - pa_pstream_set_recieve_memblock_callback(c->pstream, pstream_memblock_callback, c); - pa_pstream_set_die_callback(c->pstream, pstream_die_callback, c); - pa_pstream_set_drain_callback(c->pstream, pstream_drain_callback, c); - - c->pdispatch = pa_pdispatch_new(p->core->mainloop, command_table, PA_COMMAND_MAX); - assert(c->pdispatch); - - c->record_streams = pa_idxset_new(NULL, NULL); - c->output_streams = pa_idxset_new(NULL, NULL); - assert(c->record_streams && c->output_streams); - - c->rrobin_index = PA_IDXSET_INVALID; - c->subscription = NULL; - - pa_idxset_put(p->connections, c, NULL); - - -#ifdef SCM_CREDENTIALS - if (pa_iochannel_creds_supported(io)) - pa_iochannel_creds_enable(io); - -#endif -} - -/*** module entry points ***/ - -static int load_key(pa_protocol_native*p, const char*fn) { - assert(p); - - p->auth_cookie_in_property = 0; - - if (!fn && pa_authkey_prop_get(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME, p->auth_cookie, sizeof(p->auth_cookie)) >= 0) { - pa_log_info(__FILE__": using already loaded auth cookie."); - pa_authkey_prop_ref(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME); - p->auth_cookie_in_property = 1; - return 0; - } - - if (!fn) - fn = PA_NATIVE_COOKIE_FILE; - - if (pa_authkey_load_auto(fn, p->auth_cookie, sizeof(p->auth_cookie)) < 0) - return -1; - - pa_log_info(__FILE__": loading cookie from disk."); - - if (pa_authkey_prop_put(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME, p->auth_cookie, sizeof(p->auth_cookie)) >= 0) - p->auth_cookie_in_property = 1; - - return 0; -} - -static pa_protocol_native* protocol_new_internal(pa_core *c, pa_module *m, pa_modargs *ma) { - pa_protocol_native *p; - int public = 0; - assert(c && ma); - - if (pa_modargs_get_value_boolean(ma, "auth-anonymous", &public) < 0) { - pa_log(__FILE__": auth-anonymous= expects a boolean argument."); - return NULL; - } - - p = pa_xnew(pa_protocol_native, 1); - p->core = c; - p->module = m; - p->public = public; - p->server = NULL; - -#ifdef SCM_CREDENTIALS - p->auth_group = pa_xstrdup(pa_modargs_get_value(ma, "auth-group", NULL)); -#endif - - if (load_key(p, pa_modargs_get_value(ma, "cookie", NULL)) < 0) { - pa_xfree(p); - return NULL; - } - - p->connections = pa_idxset_new(NULL, NULL); - assert(p->connections); - - return p; -} - -pa_protocol_native* pa_protocol_native_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma) { - char t[256]; - pa_protocol_native *p; - - if (!(p = protocol_new_internal(core, m, ma))) - return NULL; - - p->server = server; - pa_socket_server_set_callback(p->server, on_connection, p); - - if (pa_socket_server_get_address(p->server, t, sizeof(t))) { - pa_strlist *l; - l = pa_property_get(core, PA_NATIVE_SERVER_PROPERTY_NAME); - l = pa_strlist_prepend(l, t); - pa_property_replace(core, PA_NATIVE_SERVER_PROPERTY_NAME, l); - } - - return p; -} - -void pa_protocol_native_free(pa_protocol_native *p) { - struct connection *c; - assert(p); - - while ((c = pa_idxset_first(p->connections, NULL))) - connection_free(c); - pa_idxset_free(p->connections, NULL, NULL); - - if (p->server) { - char t[256]; - - if (pa_socket_server_get_address(p->server, t, sizeof(t))) { - pa_strlist *l; - l = pa_property_get(p->core, PA_NATIVE_SERVER_PROPERTY_NAME); - l = pa_strlist_remove(l, t); - - if (l) - pa_property_replace(p->core, PA_NATIVE_SERVER_PROPERTY_NAME, l); - else - pa_property_remove(p->core, PA_NATIVE_SERVER_PROPERTY_NAME); - } - - pa_socket_server_unref(p->server); - } - - if (p->auth_cookie_in_property) - pa_authkey_prop_unref(p->core, PA_NATIVE_COOKIE_PROPERTY_NAME); - -#ifdef SCM_CREDENTIALS - pa_xfree(p->auth_group); -#endif - pa_xfree(p); -} - -pa_protocol_native* pa_protocol_native_new_iochannel(pa_core*core, pa_iochannel *io, pa_module *m, pa_modargs *ma) { - pa_protocol_native *p; - - if (!(p = protocol_new_internal(core, m, ma))) - return NULL; - - on_connection(NULL, io, p); - - return p; -} diff --git a/src/polypcore/protocol-native.h b/src/polypcore/protocol-native.h deleted file mode 100644 index 88aa8494..00000000 --- a/src/polypcore/protocol-native.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef fooprotocolnativehfoo -#define fooprotocolnativehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/core.h> -#include <polypcore/socket-server.h> -#include <polypcore/module.h> -#include <polypcore/modargs.h> - -typedef struct pa_protocol_native pa_protocol_native; - -pa_protocol_native* pa_protocol_native_new(pa_core*core, pa_socket_server *server, pa_module *m, pa_modargs *ma); -void pa_protocol_native_free(pa_protocol_native *n); - -pa_protocol_native* pa_protocol_native_new_iochannel(pa_core*core, pa_iochannel *io, pa_module *m, pa_modargs *ma); - -#endif diff --git a/src/polypcore/protocol-simple.c b/src/polypcore/protocol-simple.c deleted file mode 100644 index 8b319d70..00000000 --- a/src/polypcore/protocol-simple.c +++ /dev/null @@ -1,494 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> -#include <limits.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/sink-input.h> -#include <polypcore/source-output.h> -#include <polypcore/client.h> -#include <polypcore/sample-util.h> -#include <polypcore/namereg.h> -#include <polypcore/log.h> -#include <polypcore/core-error.h> - -#include "protocol-simple.h" - -/* Don't allow more than this many concurrent connections */ -#define MAX_CONNECTIONS 10 - -struct connection { - pa_protocol_simple *protocol; - pa_iochannel *io; - pa_sink_input *sink_input; - pa_source_output *source_output; - pa_client *client; - pa_memblockq *input_memblockq, *output_memblockq; - pa_defer_event *defer_event; - - int dead; - - struct { - pa_memblock *current_memblock; - size_t memblock_index, fragment_size; - } playback; -}; - -struct pa_protocol_simple { - pa_module *module; - pa_core *core; - pa_socket_server*server; - pa_idxset *connections; - enum { - RECORD = 1, - PLAYBACK = 2, - DUPLEX = 3 - } mode; - pa_sample_spec sample_spec; - char *source_name, *sink_name; -}; - -#define PLAYBACK_BUFFER_SECONDS (.5) -#define PLAYBACK_BUFFER_FRAGMENTS (10) -#define RECORD_BUFFER_SECONDS (5) -#define RECORD_BUFFER_FRAGMENTS (100) - -static void connection_free(struct connection *c) { - assert(c); - - pa_idxset_remove_by_data(c->protocol->connections, c, NULL); - - if (c->playback.current_memblock) - pa_memblock_unref(c->playback.current_memblock); - if (c->sink_input) { - pa_sink_input_disconnect(c->sink_input); - pa_sink_input_unref(c->sink_input); - } - if (c->source_output) { - pa_source_output_disconnect(c->source_output); - pa_source_output_unref(c->source_output); - } - if (c->client) - pa_client_free(c->client); - if (c->io) - pa_iochannel_free(c->io); - if (c->input_memblockq) - pa_memblockq_free(c->input_memblockq); - if (c->output_memblockq) - pa_memblockq_free(c->output_memblockq); - if (c->defer_event) - c->protocol->core->mainloop->defer_free(c->defer_event); - pa_xfree(c); -} - -static int do_read(struct connection *c) { - pa_memchunk chunk; - ssize_t r; - size_t l; - - if (!c->sink_input || !(l = pa_memblockq_missing(c->input_memblockq))) - return 0; - - if (l > c->playback.fragment_size) - l = c->playback.fragment_size; - - if (c->playback.current_memblock) - if (c->playback.current_memblock->length - c->playback.memblock_index < l) { - pa_memblock_unref(c->playback.current_memblock); - c->playback.current_memblock = NULL; - c->playback.memblock_index = 0; - } - - if (!c->playback.current_memblock) { - c->playback.current_memblock = pa_memblock_new(c->playback.fragment_size*2, c->protocol->core->memblock_stat); - assert(c->playback.current_memblock && c->playback.current_memblock->length >= l); - c->playback.memblock_index = 0; - } - - if ((r = pa_iochannel_read(c->io, (uint8_t*) c->playback.current_memblock->data+c->playback.memblock_index, l)) <= 0) { - pa_log_debug(__FILE__": read(): %s", r == 0 ? "EOF" : pa_cstrerror(errno)); - return -1; - } - - chunk.memblock = c->playback.current_memblock; - chunk.index = c->playback.memblock_index; - chunk.length = r; - assert(chunk.memblock); - - c->playback.memblock_index += r; - - assert(c->input_memblockq); - pa_memblockq_push_align(c->input_memblockq, &chunk); - assert(c->sink_input); - pa_sink_notify(c->sink_input->sink); - - return 0; -} - -static int do_write(struct connection *c) { - pa_memchunk chunk; - ssize_t r; - - if (!c->source_output) - return 0; - - assert(c->output_memblockq); - if (pa_memblockq_peek(c->output_memblockq, &chunk) < 0) - return 0; - - assert(chunk.memblock && chunk.length); - - if ((r = pa_iochannel_write(c->io, (uint8_t*) chunk.memblock->data+chunk.index, chunk.length)) < 0) { - pa_memblock_unref(chunk.memblock); - pa_log(__FILE__": write(): %s", pa_cstrerror(errno)); - return -1; - } - - pa_memblockq_drop(c->output_memblockq, &chunk, r); - pa_memblock_unref(chunk.memblock); - - pa_source_notify(c->source_output->source); - - return 0; -} - -static void do_work(struct connection *c) { - assert(c); - - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); - c->protocol->core->mainloop->defer_enable(c->defer_event, 0); - - if (c->dead) - return; - - if (pa_iochannel_is_readable(c->io)) { - if (do_read(c) < 0) - goto fail; - } else if (pa_iochannel_is_hungup(c->io)) - goto fail; - - if (pa_iochannel_is_writable(c->io)) { - if (do_write(c) < 0) - goto fail; - } - - return; - -fail: - - if (c->sink_input) { - c->dead = 1; - - pa_iochannel_free(c->io); - c->io = NULL; - - pa_memblockq_prebuf_disable(c->input_memblockq); - pa_sink_notify(c->sink_input->sink); - } else - connection_free(c); -} - -/*** sink_input callbacks ***/ - -static int sink_input_peek_cb(pa_sink_input *i, pa_memchunk *chunk) { - struct connection*c; - assert(i && i->userdata && chunk); - c = i->userdata; - - if (pa_memblockq_peek(c->input_memblockq, chunk) < 0) { - - if (c->dead) - connection_free(c); - - return -1; - } - - return 0; -} - -static void sink_input_drop_cb(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - struct connection*c = i->userdata; - assert(i && c && length); - - pa_memblockq_drop(c->input_memblockq, chunk, length); - - /* do something */ - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); - c->protocol->core->mainloop->defer_enable(c->defer_event, 1); -} - -static void sink_input_kill_cb(pa_sink_input *i) { - assert(i && i->userdata); - connection_free((struct connection *) i->userdata); -} - - -static pa_usec_t sink_input_get_latency_cb(pa_sink_input *i) { - struct connection*c = i->userdata; - assert(i && c); - return pa_bytes_to_usec(pa_memblockq_get_length(c->input_memblockq), &c->sink_input->sample_spec); -} - -/*** source_output callbacks ***/ - -static void source_output_push_cb(pa_source_output *o, const pa_memchunk *chunk) { - struct connection *c = o->userdata; - assert(o && c && chunk); - - pa_memblockq_push(c->output_memblockq, chunk); - - /* do something */ - assert(c->protocol && c->protocol->core && c->protocol->core->mainloop && c->protocol->core->mainloop->defer_enable); - c->protocol->core->mainloop->defer_enable(c->defer_event, 1); -} - -static void source_output_kill_cb(pa_source_output *o) { - assert(o && o->userdata); - connection_free((struct connection *) o->userdata); -} - -static pa_usec_t source_output_get_latency_cb(pa_source_output *o) { - struct connection*c = o->userdata; - assert(o && c); - return pa_bytes_to_usec(pa_memblockq_get_length(c->output_memblockq), &c->source_output->sample_spec); -} - -/*** client callbacks ***/ - -static void client_kill_cb(pa_client *c) { - assert(c && c->userdata); - connection_free((struct connection *) c->userdata); -} - -/*** pa_iochannel callbacks ***/ - -static void io_callback(pa_iochannel*io, void *userdata) { - struct connection *c = userdata; - assert(io && c && c->io == io); - - do_work(c); -} - -/*** fixed callback ***/ - -static void defer_callback(pa_mainloop_api*a, pa_defer_event *e, void *userdata) { - struct connection *c = userdata; - assert(a && c && c->defer_event == e); - - do_work(c); -} - -/*** socket_server callbacks ***/ - -static void on_connection(pa_socket_server*s, pa_iochannel *io, void *userdata) { - pa_protocol_simple *p = userdata; - struct connection *c = NULL; - char cname[256]; - assert(s && io && p); - - if (pa_idxset_size(p->connections)+1 > MAX_CONNECTIONS) { - pa_log(__FILE__": Warning! Too many connections (%u), dropping incoming connection.", MAX_CONNECTIONS); - pa_iochannel_free(io); - return; - } - - c = pa_xmalloc(sizeof(struct connection)); - c->io = io; - c->sink_input = NULL; - c->source_output = NULL; - c->defer_event = NULL; - c->input_memblockq = c->output_memblockq = NULL; - c->protocol = p; - c->playback.current_memblock = NULL; - c->playback.memblock_index = 0; - c->playback.fragment_size = 0; - c->dead = 0; - - pa_iochannel_socket_peer_to_string(io, cname, sizeof(cname)); - c->client = pa_client_new(p->core, __FILE__, cname); - assert(c->client); - c->client->owner = p->module; - c->client->kill = client_kill_cb; - c->client->userdata = c; - - if (p->mode & PLAYBACK) { - pa_sink *sink; - size_t l; - - if (!(sink = pa_namereg_get(p->core, p->sink_name, PA_NAMEREG_SINK, 1))) { - pa_log(__FILE__": Failed to get sink."); - goto fail; - } - - if (!(c->sink_input = pa_sink_input_new(sink, __FILE__, c->client->name, &p->sample_spec, NULL, NULL, 0, -1))) { - pa_log(__FILE__": Failed to create sink input."); - goto fail; - } - - c->sink_input->owner = p->module; - c->sink_input->client = c->client; - - c->sink_input->peek = sink_input_peek_cb; - c->sink_input->drop = sink_input_drop_cb; - c->sink_input->kill = sink_input_kill_cb; - c->sink_input->get_latency = sink_input_get_latency_cb; - c->sink_input->userdata = c; - - l = (size_t) (pa_bytes_per_second(&p->sample_spec)*PLAYBACK_BUFFER_SECONDS); - c->input_memblockq = pa_memblockq_new( - 0, - l, - 0, - pa_frame_size(&p->sample_spec), - (size_t) -1, - l/PLAYBACK_BUFFER_FRAGMENTS, - NULL, - p->core->memblock_stat); - assert(c->input_memblockq); - pa_iochannel_socket_set_rcvbuf(io, l/PLAYBACK_BUFFER_FRAGMENTS*5); - c->playback.fragment_size = l/10; - } - - if (p->mode & RECORD) { - pa_source *source; - size_t l; - - if (!(source = pa_namereg_get(p->core, p->source_name, PA_NAMEREG_SOURCE, 1))) { - pa_log(__FILE__": Failed to get source."); - goto fail; - } - - c->source_output = pa_source_output_new(source, __FILE__, c->client->name, &p->sample_spec, NULL, -1); - if (!c->source_output) { - pa_log(__FILE__": Failed to create source output."); - goto fail; - } - c->source_output->owner = p->module; - c->source_output->client = c->client; - - c->source_output->push = source_output_push_cb; - c->source_output->kill = source_output_kill_cb; - c->source_output->get_latency = source_output_get_latency_cb; - c->source_output->userdata = c; - - l = (size_t) (pa_bytes_per_second(&p->sample_spec)*RECORD_BUFFER_SECONDS); - c->output_memblockq = pa_memblockq_new( - 0, - l, - 0, - pa_frame_size(&p->sample_spec), - 1, - 0, - NULL, - p->core->memblock_stat); - pa_iochannel_socket_set_sndbuf(io, l/RECORD_BUFFER_FRAGMENTS*2); - } - - pa_iochannel_set_callback(c->io, io_callback, c); - pa_idxset_put(p->connections, c, NULL); - - c->defer_event = p->core->mainloop->defer_new(p->core->mainloop, defer_callback, c); - assert(c->defer_event); - p->core->mainloop->defer_enable(c->defer_event, 0); - - return; - -fail: - if (c) - connection_free(c); -} - -pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma) { - pa_protocol_simple* p = NULL; - int enable; - assert(core && server && ma); - - p = pa_xmalloc0(sizeof(pa_protocol_simple)); - p->module = m; - p->core = core; - p->server = server; - p->connections = pa_idxset_new(NULL, NULL); - - p->sample_spec = core->default_sample_spec; - if (pa_modargs_get_sample_spec(ma, &p->sample_spec) < 0) { - pa_log(__FILE__": Failed to parse sample type specification."); - goto fail; - } - - p->source_name = pa_xstrdup(pa_modargs_get_value(ma, "source", NULL)); - p->sink_name = pa_xstrdup(pa_modargs_get_value(ma, "sink", NULL)); - - enable = 0; - if (pa_modargs_get_value_boolean(ma, "record", &enable) < 0) { - pa_log(__FILE__": record= expects a numeric argument."); - goto fail; - } - p->mode = enable ? RECORD : 0; - - enable = 1; - if (pa_modargs_get_value_boolean(ma, "playback", &enable) < 0) { - pa_log(__FILE__": playback= expects a numeric argument."); - goto fail; - } - p->mode |= enable ? PLAYBACK : 0; - - if ((p->mode & (RECORD|PLAYBACK)) == 0) { - pa_log(__FILE__": neither playback nor recording enabled for protocol."); - goto fail; - } - - pa_socket_server_set_callback(p->server, on_connection, p); - - return p; - -fail: - if (p) - pa_protocol_simple_free(p); - return NULL; -} - - -void pa_protocol_simple_free(pa_protocol_simple *p) { - struct connection *c; - assert(p); - - if (p->connections) { - while((c = pa_idxset_first(p->connections, NULL))) - connection_free(c); - - pa_idxset_free(p->connections, NULL, NULL); - } - - if (p->server) - pa_socket_server_unref(p->server); - pa_xfree(p); -} - diff --git a/src/polypcore/protocol-simple.h b/src/polypcore/protocol-simple.h deleted file mode 100644 index f11c7759..00000000 --- a/src/polypcore/protocol-simple.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef fooprotocolsimplehfoo -#define fooprotocolsimplehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/socket-server.h> -#include <polypcore/module.h> -#include <polypcore/core.h> -#include <polypcore/modargs.h> - -typedef struct pa_protocol_simple pa_protocol_simple; - -pa_protocol_simple* pa_protocol_simple_new(pa_core *core, pa_socket_server *server, pa_module *m, pa_modargs *ma); -void pa_protocol_simple_free(pa_protocol_simple *n); - -#endif diff --git a/src/polypcore/pstream-util.c b/src/polypcore/pstream-util.c deleted file mode 100644 index bd1d1a87..00000000 --- a/src/polypcore/pstream-util.c +++ /dev/null @@ -1,62 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> - -#include <polypcore/native-common.h> - -#include "pstream-util.h" - -void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, int creds) { - size_t length; - uint8_t *data; - pa_packet *packet; - assert(p); - assert(t); - - data = pa_tagstruct_free_data(t, &length); - assert(data && length); - packet = pa_packet_new_dynamic(data, length); - assert(packet); - pa_pstream_send_packet(p, packet, creds); - pa_packet_unref(packet); -} - -void pa_pstream_send_error(pa_pstream *p, uint32_t tag, uint32_t error) { - pa_tagstruct *t = pa_tagstruct_new(NULL, 0); - assert(t); - pa_tagstruct_putu32(t, PA_COMMAND_ERROR); - pa_tagstruct_putu32(t, tag); - pa_tagstruct_putu32(t, error); - pa_pstream_send_tagstruct(p, t); -} - -void pa_pstream_send_simple_ack(pa_pstream *p, uint32_t tag) { - pa_tagstruct *t = pa_tagstruct_new(NULL, 0); - assert(t); - pa_tagstruct_putu32(t, PA_COMMAND_REPLY); - pa_tagstruct_putu32(t, tag); - pa_pstream_send_tagstruct(p, t); -} diff --git a/src/polypcore/pstream-util.h b/src/polypcore/pstream-util.h deleted file mode 100644 index f2677a44..00000000 --- a/src/polypcore/pstream-util.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef foopstreamutilhfoo -#define foopstreamutilhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> -#include <polypcore/pstream.h> -#include <polypcore/tagstruct.h> - -/* The tagstruct is freed!*/ -void pa_pstream_send_tagstruct_with_creds(pa_pstream *p, pa_tagstruct *t, int creds); - -#define pa_pstream_send_tagstruct(p, t) pa_pstream_send_tagstruct_with_creds((p), (t), 0) - -void pa_pstream_send_error(pa_pstream *p, uint32_t tag, uint32_t error); -void pa_pstream_send_simple_ack(pa_pstream *p, uint32_t tag); - -#endif diff --git a/src/polypcore/pstream.c b/src/polypcore/pstream.c deleted file mode 100644 index 074cab91..00000000 --- a/src/polypcore/pstream.c +++ /dev/null @@ -1,589 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> -#include <unistd.h> - -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif - -#include "winsock.h" - -#include <polyp/xmalloc.h> - -#include <polypcore/queue.h> -#include <polypcore/log.h> -#include <polypcore/core-scache.h> - -#include "pstream.h" - -enum { - PA_PSTREAM_DESCRIPTOR_LENGTH, - PA_PSTREAM_DESCRIPTOR_CHANNEL, - PA_PSTREAM_DESCRIPTOR_OFFSET_HI, - PA_PSTREAM_DESCRIPTOR_OFFSET_LO, - PA_PSTREAM_DESCRIPTOR_SEEK, - PA_PSTREAM_DESCRIPTOR_MAX -}; - -typedef uint32_t pa_pstream_descriptor[PA_PSTREAM_DESCRIPTOR_MAX]; - -#define PA_PSTREAM_DESCRIPTOR_SIZE (PA_PSTREAM_DESCRIPTOR_MAX*sizeof(uint32_t)) -#define FRAME_SIZE_MAX PA_SCACHE_ENTRY_SIZE_MAX /* allow uploading a single sample in one frame at max */ - -struct item_info { - enum { PA_PSTREAM_ITEM_PACKET, PA_PSTREAM_ITEM_MEMBLOCK } type; - - /* memblock info */ - pa_memchunk chunk; - uint32_t channel; - int64_t offset; - pa_seek_mode_t seek_mode; - - /* packet info */ - pa_packet *packet; -#ifdef SCM_CREDENTIALS - int with_creds; -#endif -}; - -struct pa_pstream { - int ref; - - pa_mainloop_api *mainloop; - pa_defer_event *defer_event; - pa_iochannel *io; - pa_queue *send_queue; - - int dead; - - struct { - struct item_info* current; - pa_pstream_descriptor descriptor; - void *data; - size_t index; - } write; - - struct { - pa_memblock *memblock; - pa_packet *packet; - pa_pstream_descriptor descriptor; - void *data; - size_t index; - } read; - - pa_pstream_packet_cb_t recieve_packet_callback; - void *recieve_packet_callback_userdata; - - pa_pstream_memblock_cb_t recieve_memblock_callback; - void *recieve_memblock_callback_userdata; - - pa_pstream_notify_cb_t drain_callback; - void *drain_callback_userdata; - - pa_pstream_notify_cb_t die_callback; - void *die_callback_userdata; - - pa_memblock_stat *memblock_stat; - -#ifdef SCM_CREDENTIALS - int send_creds_now; - struct ucred ucred; - int creds_valid; -#endif -}; - -static int do_write(pa_pstream *p); -static int do_read(pa_pstream *p); - -static void do_something(pa_pstream *p) { - assert(p); - - p->mainloop->defer_enable(p->defer_event, 0); - - pa_pstream_ref(p); - - if (!p->dead && pa_iochannel_is_readable(p->io)) { - if (do_read(p) < 0) - goto fail; - } else if (!p->dead && pa_iochannel_is_hungup(p->io)) - goto fail; - - if (!p->dead && pa_iochannel_is_writable(p->io)) { - if (do_write(p) < 0) - goto fail; - } - - pa_pstream_unref(p); - return; - -fail: - - p->dead = 1; - - if (p->die_callback) - p->die_callback(p, p->die_callback_userdata); - - pa_pstream_unref(p); -} - -static void io_callback(pa_iochannel*io, void *userdata) { - pa_pstream *p = userdata; - - assert(p); - assert(p->io == io); - - do_something(p); -} - -static void defer_callback(pa_mainloop_api *m, pa_defer_event *e, void*userdata) { - pa_pstream *p = userdata; - - assert(p); - assert(p->defer_event == e); - assert(p->mainloop == m); - - do_something(p); -} - -pa_pstream *pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_memblock_stat *s) { - pa_pstream *p; - assert(io); - - p = pa_xnew(pa_pstream, 1); - - p->ref = 1; - p->io = io; - pa_iochannel_set_callback(io, io_callback, p); - - p->dead = 0; - - p->mainloop = m; - p->defer_event = m->defer_new(m, defer_callback, p); - m->defer_enable(p->defer_event, 0); - - p->send_queue = pa_queue_new(); - assert(p->send_queue); - - p->write.current = NULL; - p->write.index = 0; - - p->read.memblock = NULL; - p->read.packet = NULL; - p->read.index = 0; - - p->recieve_packet_callback = NULL; - p->recieve_packet_callback_userdata = NULL; - - p->recieve_memblock_callback = NULL; - p->recieve_memblock_callback_userdata = NULL; - - p->drain_callback = NULL; - p->drain_callback_userdata = NULL; - - p->die_callback = NULL; - p->die_callback_userdata = NULL; - - p->memblock_stat = s; - - pa_iochannel_socket_set_rcvbuf(io, 1024*8); - pa_iochannel_socket_set_sndbuf(io, 1024*8); - -#ifdef SCM_CREDENTIALS - p->send_creds_now = 0; - p->creds_valid = 0; -#endif - return p; -} - -static void item_free(void *item, PA_GCC_UNUSED void *p) { - struct item_info *i = item; - assert(i); - - if (i->type == PA_PSTREAM_ITEM_MEMBLOCK) { - assert(i->chunk.memblock); - pa_memblock_unref(i->chunk.memblock); - } else { - assert(i->type == PA_PSTREAM_ITEM_PACKET); - assert(i->packet); - pa_packet_unref(i->packet); - } - - pa_xfree(i); -} - -static void pstream_free(pa_pstream *p) { - assert(p); - - pa_pstream_close(p); - - pa_queue_free(p->send_queue, item_free, NULL); - - if (p->write.current) - item_free(p->write.current, NULL); - - if (p->read.memblock) - pa_memblock_unref(p->read.memblock); - - if (p->read.packet) - pa_packet_unref(p->read.packet); - - pa_xfree(p); -} - -void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, int with_creds) { - struct item_info *i; - assert(p && packet && p->ref >= 1); - - if (p->dead) - return; - -/* pa_log(__FILE__": push-packet %p", packet); */ - - i = pa_xnew(struct item_info, 1); - i->type = PA_PSTREAM_ITEM_PACKET; - i->packet = pa_packet_ref(packet); -#ifdef SCM_CREDENTIALS - i->with_creds = with_creds; -#endif - - pa_queue_push(p->send_queue, i); - p->mainloop->defer_enable(p->defer_event, 1); -} - -void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek_mode, const pa_memchunk *chunk) { - struct item_info *i; - assert(p && channel != (uint32_t) -1 && chunk && p->ref >= 1); - - if (p->dead) - return; - -/* pa_log(__FILE__": push-memblock %p", chunk); */ - - i = pa_xnew(struct item_info, 1); - i->type = PA_PSTREAM_ITEM_MEMBLOCK; - i->chunk = *chunk; - i->channel = channel; - i->offset = offset; - i->seek_mode = seek_mode; - - pa_memblock_ref(i->chunk.memblock); - - pa_queue_push(p->send_queue, i); - p->mainloop->defer_enable(p->defer_event, 1); -} - -static void prepare_next_write_item(pa_pstream *p) { - assert(p); - - if (!(p->write.current = pa_queue_pop(p->send_queue))) - return; - - p->write.index = 0; - - if (p->write.current->type == PA_PSTREAM_ITEM_PACKET) { - /*pa_log(__FILE__": pop-packet %p", p->write.current->packet);*/ - - assert(p->write.current->packet); - p->write.data = p->write.current->packet->data; - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->packet->length); - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL] = htonl((uint32_t) -1); - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = 0; - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = 0; - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_SEEK] = 0; - -#ifdef SCM_CREDENTIALS - p->send_creds_now = 1; -#endif - - } else { - assert(p->write.current->type == PA_PSTREAM_ITEM_MEMBLOCK && p->write.current->chunk.memblock); - p->write.data = (uint8_t*) p->write.current->chunk.memblock->data + p->write.current->chunk.index; - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH] = htonl(p->write.current->chunk.length); - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL] = htonl(p->write.current->channel); - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = htonl((uint32_t) (((uint64_t) p->write.current->offset) >> 32)); - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = htonl((uint32_t) ((uint64_t) p->write.current->offset)); - p->write.descriptor[PA_PSTREAM_DESCRIPTOR_SEEK] = htonl(p->write.current->seek_mode); - -#ifdef SCM_CREDENTIALS - p->send_creds_now = 1; -#endif - } -} - -static int do_write(pa_pstream *p) { - void *d; - size_t l; - ssize_t r; - assert(p); - - if (!p->write.current) - prepare_next_write_item(p); - - if (!p->write.current) - return 0; - - assert(p->write.data); - - if (p->write.index < PA_PSTREAM_DESCRIPTOR_SIZE) { - d = (uint8_t*) p->write.descriptor + p->write.index; - l = PA_PSTREAM_DESCRIPTOR_SIZE - p->write.index; - } else { - d = (uint8_t*) p->write.data + p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE; - l = ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->write.index - PA_PSTREAM_DESCRIPTOR_SIZE); - } - -#ifdef SCM_CREDENTIALS - if (p->send_creds_now) { - - if ((r = pa_iochannel_write_with_creds(p->io, d, l)) < 0) - return -1; - - p->send_creds_now = 0; - } else -#endif - - if ((r = pa_iochannel_write(p->io, d, l)) < 0) - return -1; - - p->write.index += r; - - if (p->write.index >= PA_PSTREAM_DESCRIPTOR_SIZE+ntohl(p->write.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH])) { - assert(p->write.current); - item_free(p->write.current, (void *) 1); - p->write.current = NULL; - - if (p->drain_callback && !pa_pstream_is_pending(p)) - p->drain_callback(p, p->drain_callback_userdata); - } - - return 0; -} - -static int do_read(pa_pstream *p) { - void *d; - size_t l; - ssize_t r; - assert(p); - - if (p->read.index < PA_PSTREAM_DESCRIPTOR_SIZE) { - d = (uint8_t*) p->read.descriptor + p->read.index; - l = PA_PSTREAM_DESCRIPTOR_SIZE - p->read.index; - } else { - assert(p->read.data); - d = (uint8_t*) p->read.data + p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE; - l = ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) - (p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE); - } - -#ifdef SCM_CREDENTIALS - { - int b; - - if ((r = pa_iochannel_read_with_creds(p->io, d, l, &p->ucred, &b)) <= 0) - return -1; - - p->creds_valid = p->creds_valid || b; - } -#else - if ((r = pa_iochannel_read(p->io, d, l)) <= 0) - return -1; -#endif - - p->read.index += r; - - if (p->read.index == PA_PSTREAM_DESCRIPTOR_SIZE) { - /* Reading of frame descriptor complete */ - - /* Frame size too large */ - if (ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) > FRAME_SIZE_MAX) { - pa_log_warn(__FILE__": Frame size too large: %lu > %lu", (unsigned long) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]), (unsigned long) FRAME_SIZE_MAX); - return -1; - } - - assert(!p->read.packet && !p->read.memblock); - - if (ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]) == (uint32_t) -1) { - /* Frame is a packet frame */ - p->read.packet = pa_packet_new(ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH])); - p->read.data = p->read.packet->data; - } else { - /* Frame is a memblock frame */ - p->read.memblock = pa_memblock_new(ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]), p->memblock_stat); - p->read.data = p->read.memblock->data; - - if (ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_SEEK]) > PA_SEEK_RELATIVE_END) { - pa_log_warn(__FILE__": Invalid seek mode"); - return -1; - } - } - - } else if (p->read.index > PA_PSTREAM_DESCRIPTOR_SIZE) { - /* Frame payload available */ - - if (p->read.memblock && p->recieve_memblock_callback) { /* Is this memblock data? Than pass it to the user */ - l = (p->read.index - r) < PA_PSTREAM_DESCRIPTOR_SIZE ? p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE : (size_t) r; - - if (l > 0) { - pa_memchunk chunk; - - chunk.memblock = p->read.memblock; - chunk.index = p->read.index - PA_PSTREAM_DESCRIPTOR_SIZE - l; - chunk.length = l; - - if (p->recieve_memblock_callback) { - int64_t offset; - - offset = (int64_t) ( - (((uint64_t) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI])) << 32) | - (((uint64_t) ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO])))); - - p->recieve_memblock_callback( - p, - ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_CHANNEL]), - offset, - ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_SEEK]), - &chunk, - p->recieve_memblock_callback_userdata); - } - - /* Drop seek info for following callbacks */ - p->read.descriptor[PA_PSTREAM_DESCRIPTOR_SEEK] = - p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_HI] = - p->read.descriptor[PA_PSTREAM_DESCRIPTOR_OFFSET_LO] = 0; - } - } - - /* Frame complete */ - if (p->read.index >= ntohl(p->read.descriptor[PA_PSTREAM_DESCRIPTOR_LENGTH]) + PA_PSTREAM_DESCRIPTOR_SIZE) { - if (p->read.memblock) { - assert(!p->read.packet); - - pa_memblock_unref(p->read.memblock); - p->read.memblock = NULL; - } else { - assert(p->read.packet); - - if (p->recieve_packet_callback) -#ifdef SCM_CREDENTIALS - p->recieve_packet_callback(p, p->read.packet, p->creds_valid ? &p->ucred : NULL, p->recieve_packet_callback_userdata); -#else - p->recieve_packet_callback(p, p->read.packet, NULL, p->recieve_packet_callback_userdata); -#endif - - pa_packet_unref(p->read.packet); - p->read.packet = NULL; - } - - p->read.index = 0; -#ifdef SCM_CREDENTIALS - p->creds_valid = 0; -#endif - } - } - - return 0; -} - -void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) { - assert(p); - assert(p->ref >= 1); - - p->die_callback = cb; - p->die_callback_userdata = userdata; -} - - -void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata) { - assert(p); - assert(p->ref >= 1); - - p->drain_callback = cb; - p->drain_callback_userdata = userdata; -} - -void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata) { - assert(p); - assert(p->ref >= 1); - - p->recieve_packet_callback = cb; - p->recieve_packet_callback_userdata = userdata; -} - -void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata) { - assert(p); - assert(p->ref >= 1); - - p->recieve_memblock_callback = cb; - p->recieve_memblock_callback_userdata = userdata; -} - -int pa_pstream_is_pending(pa_pstream *p) { - assert(p); - - if (p->dead) - return 0; - - return p->write.current || !pa_queue_is_empty(p->send_queue); -} - -void pa_pstream_unref(pa_pstream*p) { - assert(p); - assert(p->ref >= 1); - - if (--p->ref == 0) - pstream_free(p); -} - -pa_pstream* pa_pstream_ref(pa_pstream*p) { - assert(p); - assert(p->ref >= 1); - - p->ref++; - return p; -} - -void pa_pstream_close(pa_pstream *p) { - assert(p); - - p->dead = 1; - - if (p->io) { - pa_iochannel_free(p->io); - p->io = NULL; - } - - if (p->defer_event) { - p->mainloop->defer_free(p->defer_event); - p->defer_event = NULL; - } - - p->die_callback = NULL; - p->drain_callback = NULL; - p->recieve_packet_callback = NULL; - p->recieve_memblock_callback = NULL; -} diff --git a/src/polypcore/pstream.h b/src/polypcore/pstream.h deleted file mode 100644 index feb1b151..00000000 --- a/src/polypcore/pstream.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef foopstreamhfoo -#define foopstreamhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> - -#include <polyp/mainloop-api.h> -#include <polyp/def.h> -#include <polypcore/packet.h> -#include <polypcore/memblock.h> -#include <polypcore/iochannel.h> -#include <polypcore/memchunk.h> - -typedef struct pa_pstream pa_pstream; - -typedef void (*pa_pstream_packet_cb_t)(pa_pstream *p, pa_packet *packet, const void *creds, void *userdata); -typedef void (*pa_pstream_memblock_cb_t)(pa_pstream *p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk, void *userdata); -typedef void (*pa_pstream_notify_cb_t)(pa_pstream *p, void *userdata); - -pa_pstream* pa_pstream_new(pa_mainloop_api *m, pa_iochannel *io, pa_memblock_stat *s); -void pa_pstream_unref(pa_pstream*p); -pa_pstream* pa_pstream_ref(pa_pstream*p); - -void pa_pstream_send_packet(pa_pstream*p, pa_packet *packet, int with_creds); -void pa_pstream_send_memblock(pa_pstream*p, uint32_t channel, int64_t offset, pa_seek_mode_t seek, const pa_memchunk *chunk); - -void pa_pstream_set_recieve_packet_callback(pa_pstream *p, pa_pstream_packet_cb_t cb, void *userdata); -void pa_pstream_set_recieve_memblock_callback(pa_pstream *p, pa_pstream_memblock_cb_t cb, void *userdata); -void pa_pstream_set_drain_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata); - -void pa_pstream_set_die_callback(pa_pstream *p, pa_pstream_notify_cb_t cb, void *userdata); - -int pa_pstream_is_pending(pa_pstream *p); - -void pa_pstream_close(pa_pstream *p); - -#endif diff --git a/src/polypcore/queue.c b/src/polypcore/queue.c deleted file mode 100644 index 01f957d9..00000000 --- a/src/polypcore/queue.c +++ /dev/null @@ -1,109 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <stdlib.h> - -#include <polyp/xmalloc.h> - -#include "queue.h" - -struct queue_entry { - struct queue_entry *next; - void *data; -}; - -struct pa_queue { - struct queue_entry *front, *back; - unsigned length; -}; - -pa_queue* pa_queue_new(void) { - pa_queue *q = pa_xnew(pa_queue, 1); - q->front = q->back = NULL; - q->length = 0; - return q; -} - -void pa_queue_free(pa_queue* q, void (*destroy)(void *p, void *userdata), void *userdata) { - struct queue_entry *e; - assert(q); - - e = q->front; - while (e) { - struct queue_entry *n = e->next; - - if (destroy) - destroy(e->data, userdata); - - pa_xfree(e); - e = n; - } - - pa_xfree(q); -} - -void pa_queue_push(pa_queue *q, void *p) { - struct queue_entry *e; - - e = pa_xnew(struct queue_entry, 1); - e->data = p; - e->next = NULL; - - if (q->back) - q->back->next = e; - else { - assert(!q->front); - q->front = e; - } - - q->back = e; - q->length++; -} - -void* pa_queue_pop(pa_queue *q) { - void *p; - struct queue_entry *e; - assert(q); - - if (!(e = q->front)) - return NULL; - - q->front = e->next; - if (q->back == e) - q->back = NULL; - - p = e->data; - pa_xfree(e); - - q->length--; - - return p; -} - -int pa_queue_is_empty(pa_queue *q) { - assert(q); - return q->length == 0; -} diff --git a/src/polypcore/queue.h b/src/polypcore/queue.h deleted file mode 100644 index 3edcfb63..00000000 --- a/src/polypcore/queue.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef fooqueuehfoo -#define fooqueuehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef struct pa_queue pa_queue; - -/* A simple implementation of the abstract data type queue. Stores - * pointers as members. The memory has to be managed by the caller. */ - -pa_queue* pa_queue_new(void); - -/* Free the queue and run the specified callback function for every remaining entry. The callback function may be NULL. */ -void pa_queue_free(pa_queue* q, void (*destroy)(void *p, void *userdata), void *userdata); - -void pa_queue_push(pa_queue *q, void *p); -void* pa_queue_pop(pa_queue *q); - -int pa_queue_is_empty(pa_queue *q); - -#endif diff --git a/src/polypcore/random.c b/src/polypcore/random.c deleted file mode 100644 index d7a37b0b..00000000 --- a/src/polypcore/random.c +++ /dev/null @@ -1,108 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <fcntl.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> -#include <stdlib.h> -#include <assert.h> -#include <time.h> - -#include <polypcore/core-util.h> -#include <polypcore/log.h> - -#include "random.h" - -static int has_whined = 0; - -static const char *devices[] = { "/dev/urandom", "/dev/random", NULL }; - -static int random_proper(void *ret_data, size_t length) { -#ifdef OS_IS_WIN32 - assert(ret_data && length); - - return -1; - -#else /* OS_IS_WIN32 */ - - int fd, ret = -1; - ssize_t r = 0; - const char **device; - - assert(ret_data && length); - - device = devices; - - while (*device) { - ret = 0; - - if ((fd = open(*device, O_RDONLY)) >= 0) { - - if ((r = pa_loop_read(fd, ret_data, length)) < 0 || (size_t) r != length) - ret = -1; - - close(fd); - } else - ret = -1; - - if (ret == 0) - break; - } - - return ret; -#endif /* OS_IS_WIN32 */ -} - -void pa_random_seed(void) { - unsigned int seed; - - if (random_proper(&seed, sizeof(unsigned int)) < 0) { - if (!has_whined) - pa_log_warn(__FILE__": failed to get proper entropy. Falling back to seeding with current time."); - has_whined = 1; - - seed = (unsigned int) time(NULL); - } - - srand(seed); -} - -void pa_random(void *ret_data, size_t length) { - uint8_t *p; - size_t l; - - assert(ret_data && length); - - if (random_proper(ret_data, length) >= 0) - return; - - if (!has_whined) - pa_log_warn(__FILE__": failed to get proper entropy. Falling back to unsecure pseudo RNG."); - has_whined = 1; - - for (p = ret_data, l = length; l > 0; p++, l--) - *p = (uint8_t) rand(); -} diff --git a/src/polypcore/random.h b/src/polypcore/random.h deleted file mode 100644 index 1f152dc7..00000000 --- a/src/polypcore/random.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef foorandomhfoo -#define foorandomhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -void pa_random_seed(void); -void pa_random(void *ret_data, size_t length); - -#endif diff --git a/src/polypcore/resampler.c b/src/polypcore/resampler.c deleted file mode 100644 index 33e8c295..00000000 --- a/src/polypcore/resampler.c +++ /dev/null @@ -1,618 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <string.h> - -#include <samplerate.h> -#include <liboil/liboilfuncs.h> -#include <liboil/liboil.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/sconv.h> -#include <polypcore/log.h> - -#include "resampler.h" - -struct pa_resampler { - pa_resample_method_t resample_method; - pa_sample_spec i_ss, o_ss; - pa_channel_map i_cm, o_cm; - size_t i_fz, o_fz; - pa_memblock_stat *memblock_stat; - - void (*impl_free)(pa_resampler *r); - void (*impl_update_input_rate)(pa_resampler *r, uint32_t rate); - void (*impl_run)(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out); - void *impl_data; -}; - -struct impl_libsamplerate { - float* buf1, *buf2, *buf3, *buf4; - unsigned buf1_samples, buf2_samples, buf3_samples, buf4_samples; - - pa_convert_to_float32ne_func_t to_float32ne_func; - pa_convert_from_float32ne_func_t from_float32ne_func; - SRC_STATE *src_state; - - int map_table[PA_CHANNELS_MAX][PA_CHANNELS_MAX]; - int map_required; -}; - -struct impl_trivial { - unsigned o_counter; - unsigned i_counter; -}; - -static int libsamplerate_init(pa_resampler*r); -static int trivial_init(pa_resampler*r); - -pa_resampler* pa_resampler_new( - const pa_sample_spec *a, - const pa_channel_map *am, - const pa_sample_spec *b, - const pa_channel_map *bm, - pa_memblock_stat *s, - pa_resample_method_t resample_method) { - - pa_resampler *r = NULL; - - assert(a); - assert(b); - assert(pa_sample_spec_valid(a)); - assert(pa_sample_spec_valid(b)); - assert(resample_method != PA_RESAMPLER_INVALID); - - r = pa_xnew(pa_resampler, 1); - r->impl_data = NULL; - r->memblock_stat = s; - r->resample_method = resample_method; - - r->impl_free = NULL; - r->impl_update_input_rate = NULL; - r->impl_run = NULL; - - /* Fill sample specs */ - r->i_ss = *a; - r->o_ss = *b; - - if (am) - r->i_cm = *am; - else - pa_channel_map_init_auto(&r->i_cm, r->i_ss.channels, PA_CHANNEL_MAP_DEFAULT); - - if (bm) - r->o_cm = *bm; - else - pa_channel_map_init_auto(&r->o_cm, r->o_ss.channels, PA_CHANNEL_MAP_DEFAULT); - - r->i_fz = pa_frame_size(a); - r->o_fz = pa_frame_size(b); - - /* Choose implementation */ - if (a->channels != b->channels || - a->format != b->format || - !pa_channel_map_equal(&r->i_cm, &r->o_cm) || - resample_method != PA_RESAMPLER_TRIVIAL) { - - /* Use the libsamplerate based resampler for the complicated cases */ - if (resample_method == PA_RESAMPLER_TRIVIAL) - r->resample_method = PA_RESAMPLER_SRC_ZERO_ORDER_HOLD; - - if (libsamplerate_init(r) < 0) - goto fail; - - } else { - /* Use our own simple non-fp resampler for the trivial cases and when the user selects it */ - if (trivial_init(r) < 0) - goto fail; - } - - return r; - -fail: - if (r) - pa_xfree(r); - - return NULL; -} - -void pa_resampler_free(pa_resampler *r) { - assert(r); - - if (r->impl_free) - r->impl_free(r); - - pa_xfree(r); -} - -void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate) { - assert(r); - assert(rate > 0); - - if (r->i_ss.rate == rate) - return; - - r->i_ss.rate = rate; - - if (r->impl_update_input_rate) - r->impl_update_input_rate(r, rate); -} - -void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { - assert(r && in && out && r->impl_run); - - r->impl_run(r, in, out); -} - -size_t pa_resampler_request(pa_resampler *r, size_t out_length) { - assert(r); - - return (((out_length / r->o_fz)*r->i_ss.rate)/r->o_ss.rate) * r->i_fz; -} - -pa_resample_method_t pa_resampler_get_method(pa_resampler *r) { - assert(r); - return r->resample_method; -} - -static const char * const resample_methods[] = { - "src-sinc-best-quality", - "src-sinc-medium-quality", - "src-sinc-fastest", - "src-zero-order-hold", - "src-linear", - "trivial" -}; - -const char *pa_resample_method_to_string(pa_resample_method_t m) { - - if (m < 0 || m >= PA_RESAMPLER_MAX) - return NULL; - - return resample_methods[m]; -} - -pa_resample_method_t pa_parse_resample_method(const char *string) { - pa_resample_method_t m; - - assert(string); - - for (m = 0; m < PA_RESAMPLER_MAX; m++) - if (!strcmp(string, resample_methods[m])) - return m; - - return PA_RESAMPLER_INVALID; -} - - -/*** libsamplerate based implementation ***/ - -static void libsamplerate_free(pa_resampler *r) { - struct impl_libsamplerate *u; - - assert(r); - assert(r->impl_data); - - u = r->impl_data; - - if (u->src_state) - src_delete(u->src_state); - - pa_xfree(u->buf1); - pa_xfree(u->buf2); - pa_xfree(u->buf3); - pa_xfree(u->buf4); - pa_xfree(u); -} - -static void calc_map_table(pa_resampler *r) { - struct impl_libsamplerate *u; - unsigned oc; - assert(r); - assert(r->impl_data); - - u = r->impl_data; - - if (!(u->map_required = (!pa_channel_map_equal(&r->i_cm, &r->o_cm) || r->i_ss.channels != r->o_ss.channels))) - return; - - for (oc = 0; oc < r->o_ss.channels; oc++) { - unsigned ic, i = 0; - - for (ic = 0; ic < r->i_ss.channels; ic++) { - pa_channel_position_t a, b; - - a = r->i_cm.map[ic]; - b = r->o_cm.map[oc]; - - if (a == b || - (a == PA_CHANNEL_POSITION_MONO && b == PA_CHANNEL_POSITION_LEFT) || - (a == PA_CHANNEL_POSITION_MONO && b == PA_CHANNEL_POSITION_RIGHT) || - (a == PA_CHANNEL_POSITION_LEFT && b == PA_CHANNEL_POSITION_MONO) || - (a == PA_CHANNEL_POSITION_RIGHT && b == PA_CHANNEL_POSITION_MONO)) - - u->map_table[oc][i++] = ic; - } - - /* Add an end marker */ - if (i < PA_CHANNELS_MAX) - u->map_table[oc][i] = -1; - } -} - -static float * convert_to_float(pa_resampler *r, void *input, unsigned n_frames) { - struct impl_libsamplerate *u; - unsigned n_samples; - - assert(r); - assert(input); - assert(r->impl_data); - u = r->impl_data; - - /* Convert the incoming sample into floats and place them in buf1 */ - - if (!u->to_float32ne_func) - return input; - - n_samples = n_frames * r->i_ss.channels; - - if (u->buf1_samples < n_samples) - u->buf1 = pa_xrealloc(u->buf1, sizeof(float) * (u->buf1_samples = n_samples)); - - u->to_float32ne_func(n_samples, input, u->buf1); - - return u->buf1; -} - -static float *remap_channels(pa_resampler *r, float *input, unsigned n_frames) { - struct impl_libsamplerate *u; - unsigned n_samples; - int i_skip, o_skip; - unsigned oc; - - assert(r); - assert(input); - assert(r->impl_data); - u = r->impl_data; - - /* Remap channels and place the result int buf2 */ - - if (!u->map_required) - return input; - - n_samples = n_frames * r->o_ss.channels; - - if (u->buf2_samples < n_samples) - u->buf2 = pa_xrealloc(u->buf2, sizeof(float) * (u->buf2_samples = n_samples)); - - memset(u->buf2, 0, n_samples * sizeof(float)); - - o_skip = sizeof(float) * r->o_ss.channels; - i_skip = sizeof(float) * r->i_ss.channels; - - for (oc = 0; oc < r->o_ss.channels; oc++) { - unsigned i; - static const float one = 1.0; - - for (i = 0; i < PA_CHANNELS_MAX && u->map_table[oc][i] >= 0; i++) - oil_vectoradd_f32( - u->buf2 + oc, o_skip, - u->buf2 + oc, o_skip, - input + u->map_table[oc][i], i_skip, - n_frames, - &one, &one); - } - - return u->buf2; -} - -static float *resample(pa_resampler *r, float *input, unsigned *n_frames) { - struct impl_libsamplerate *u; - SRC_DATA data; - unsigned out_n_frames, out_n_samples; - int ret; - - assert(r); - assert(input); - assert(n_frames); - assert(r->impl_data); - u = r->impl_data; - - /* Resample the data and place the result in buf3 */ - - if (!u->src_state) - return input; - - out_n_frames = (*n_frames*r->o_ss.rate/r->i_ss.rate)+1024; - out_n_samples = out_n_frames * r->o_ss.channels; - - if (u->buf3_samples < out_n_samples) - u->buf3 = pa_xrealloc(u->buf3, sizeof(float) * (u->buf3_samples = out_n_samples)); - - data.data_in = input; - data.input_frames = *n_frames; - - data.data_out = u->buf3; - data.output_frames = out_n_frames; - - data.src_ratio = (double) r->o_ss.rate / r->i_ss.rate; - data.end_of_input = 0; - - ret = src_process(u->src_state, &data); - assert(ret == 0); - assert((unsigned) data.input_frames_used == *n_frames); - - *n_frames = data.output_frames_gen; - - return u->buf3; -} - -static void *convert_from_float(pa_resampler *r, float *input, unsigned n_frames) { - struct impl_libsamplerate *u; - unsigned n_samples; - - assert(r); - assert(input); - assert(r->impl_data); - u = r->impl_data; - - /* Convert the data into the correct sample type and place the result in buf4 */ - - if (!u->from_float32ne_func) - return input; - - n_samples = n_frames * r->o_ss.channels; - - if (u->buf4_samples < n_samples) - u->buf4 = pa_xrealloc(u->buf4, sizeof(float) * (u->buf4_samples = n_samples)); - - u->from_float32ne_func(n_samples, input, u->buf4); - - return u->buf4; -} - -static void libsamplerate_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { - struct impl_libsamplerate *u; - float *buf; - void *input, *output; - unsigned n_frames; - - assert(r); - assert(in); - assert(out); - assert(in->length); - assert(in->memblock); - assert(in->length % r->i_fz == 0); - assert(r->impl_data); - - u = r->impl_data; - - input = ((uint8_t*) in->memblock->data + in->index); - n_frames = in->length / r->i_fz; - assert(n_frames > 0); - - buf = convert_to_float(r, input, n_frames); - buf = remap_channels(r, buf, n_frames); - buf = resample(r, buf, &n_frames); - - if (n_frames) { - output = convert_from_float(r, buf, n_frames); - - if (output == input) { - /* Mm, no adjustment has been necessary, so let's return the original block */ - out->memblock = pa_memblock_ref(in->memblock); - out->index = in->index; - out->length = in->length; - } else { - float **p = NULL; - - out->length = n_frames * r->o_fz; - out->index = 0; - - if (output == u->buf1) { - p = &u->buf1; - u->buf1_samples = 0; - } else if (output == u->buf2) { - p = &u->buf2; - u->buf2_samples = 0; - } else if (output == u->buf3) { - p = &u->buf3; - u->buf3_samples = 0; - } else if (output == u->buf4) { - p = &u->buf4; - u->buf4_samples = 0; - } - - assert(p); - - /* Take the existing buffer and make it a memblock */ - out->memblock = pa_memblock_new_dynamic(*p, out->length, r->memblock_stat); - *p = NULL; - } - } else { - out->memblock = NULL; - out->index = out->length = 0; - } -} - -static void libsamplerate_update_input_rate(pa_resampler *r, uint32_t rate) { - struct impl_libsamplerate *u; - - assert(r); - assert(rate > 0); - assert(r->impl_data); - u = r->impl_data; - - if (!u->src_state) { - int err; - u->src_state = src_new(r->resample_method, r->o_ss.channels, &err); - assert(u->src_state); - } else { - int ret = src_set_ratio(u->src_state, (double) r->o_ss.rate / rate); - assert(ret == 0); - } -} - -static int libsamplerate_init(pa_resampler *r) { - struct impl_libsamplerate *u = NULL; - int err; - - r->impl_data = u = pa_xnew(struct impl_libsamplerate, 1); - - u->buf1 = u->buf2 = u->buf3 = u->buf4 = NULL; - u->buf1_samples = u->buf2_samples = u->buf3_samples = u->buf4_samples = 0; - - if (r->i_ss.format == PA_SAMPLE_FLOAT32NE) - u->to_float32ne_func = NULL; - else if (!(u->to_float32ne_func = pa_get_convert_to_float32ne_function(r->i_ss.format))) - goto fail; - - if (r->o_ss.format == PA_SAMPLE_FLOAT32NE) - u->from_float32ne_func = NULL; - else if (!(u->from_float32ne_func = pa_get_convert_from_float32ne_function(r->o_ss.format))) - goto fail; - - if (r->o_ss.rate == r->i_ss.rate) - u->src_state = NULL; - else if (!(u->src_state = src_new(r->resample_method, r->o_ss.channels, &err))) - goto fail; - - r->impl_free = libsamplerate_free; - r->impl_update_input_rate = libsamplerate_update_input_rate; - r->impl_run = libsamplerate_run; - - calc_map_table(r); - - return 0; - -fail: - pa_xfree(u); - return -1; -} - -/* Trivial implementation */ - -static void trivial_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out) { - size_t fz; - unsigned n_frames; - struct impl_trivial *u; - - assert(r); - assert(in); - assert(out); - assert(r->impl_data); - - u = r->impl_data; - - fz = r->i_fz; - assert(fz == r->o_fz); - - n_frames = in->length/fz; - - if (r->i_ss.rate == r->o_ss.rate) { - - /* In case there's no diefference in sample types, do nothing */ - *out = *in; - pa_memblock_ref(out->memblock); - - u->o_counter += n_frames; - } else { - /* Do real resampling */ - size_t l; - unsigned o_index; - - /* The length of the new memory block rounded up */ - l = ((((n_frames+1) * r->o_ss.rate) / r->i_ss.rate) + 1) * fz; - - out->index = 0; - out->memblock = pa_memblock_new(l, r->memblock_stat); - - for (o_index = 0;; o_index++, u->o_counter++) { - unsigned j; - - j = (u->o_counter * r->i_ss.rate / r->o_ss.rate); - j = j > u->i_counter ? j - u->i_counter : 0; - - if (j >= n_frames) - break; - - assert(o_index*fz < out->memblock->length); - - memcpy((uint8_t*) out->memblock->data + fz*o_index, - (uint8_t*) in->memblock->data + in->index + fz*j, fz); - - } - - out->length = o_index*fz; - } - - u->i_counter += n_frames; - - /* Normalize counters */ - while (u->i_counter >= r->i_ss.rate) { - u->i_counter -= r->i_ss.rate; - assert(u->o_counter >= r->o_ss.rate); - u->o_counter -= r->o_ss.rate; - } -} - -static void trivial_free(pa_resampler *r) { - assert(r); - - pa_xfree(r->impl_data); -} - -static void trivial_update_input_rate(pa_resampler *r, uint32_t rate) { - struct impl_trivial *u; - - assert(r); - assert(rate > 0); - assert(r->impl_data); - - u = r->impl_data; - u->i_counter = 0; - u->o_counter = 0; -} - -static int trivial_init(pa_resampler*r) { - struct impl_trivial *u; - - assert(r); - assert(r->i_ss.format == r->o_ss.format); - assert(r->i_ss.channels == r->o_ss.channels); - - r->impl_data = u = pa_xnew(struct impl_trivial, 1); - u->o_counter = u->i_counter = 0; - - r->impl_run = trivial_run; - r->impl_free = trivial_free; - r->impl_update_input_rate = trivial_update_input_rate; - - return 0; -} - - diff --git a/src/polypcore/resampler.h b/src/polypcore/resampler.h deleted file mode 100644 index 2f4d3cbe..00000000 --- a/src/polypcore/resampler.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef fooresamplerhfoo -#define fooresamplerhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <samplerate.h> - -#include <polyp/sample.h> -#include <polyp/channelmap.h> -#include <polypcore/memblock.h> -#include <polypcore/memchunk.h> - -typedef struct pa_resampler pa_resampler; - -typedef enum pa_resample_method { - PA_RESAMPLER_INVALID = -1, - PA_RESAMPLER_SRC_SINC_BEST_QUALITY = SRC_SINC_BEST_QUALITY, - PA_RESAMPLER_SRC_SINC_MEDIUM_QUALITY = SRC_SINC_MEDIUM_QUALITY, - PA_RESAMPLER_SRC_SINC_FASTEST = SRC_SINC_FASTEST, - PA_RESAMPLER_SRC_ZERO_ORDER_HOLD = SRC_ZERO_ORDER_HOLD, - PA_RESAMPLER_SRC_LINEAR = SRC_LINEAR, - PA_RESAMPLER_TRIVIAL, - PA_RESAMPLER_MAX -} pa_resample_method_t; - -pa_resampler* pa_resampler_new( - const pa_sample_spec *a, - const pa_channel_map *am, - const pa_sample_spec *b, - const pa_channel_map *bm, - pa_memblock_stat *s, - pa_resample_method_t resample_method); - -void pa_resampler_free(pa_resampler *r); - -/* Returns the size of an input memory block which is required to return the specified amount of output data */ -size_t pa_resampler_request(pa_resampler *r, size_t out_length); - -/* Pass the specified memory chunk to the resampler and return the newly resampled data */ -void pa_resampler_run(pa_resampler *r, const pa_memchunk *in, pa_memchunk *out); - -/* Change the input rate of the resampler object */ -void pa_resampler_set_input_rate(pa_resampler *r, uint32_t rate); - -/* Return the resampling method of the resampler object */ -pa_resample_method_t pa_resampler_get_method(pa_resampler *r); - -/* Try to parse the resampler method */ -pa_resample_method_t pa_parse_resample_method(const char *string); - -/* return a human readable string for the specified resampling method. Inverse of pa_parse_resample_method() */ -const char *pa_resample_method_to_string(pa_resample_method_t m); - -#endif diff --git a/src/polypcore/sample-util.c b/src/polypcore/sample-util.c deleted file mode 100644 index 7a75ce1c..00000000 --- a/src/polypcore/sample-util.c +++ /dev/null @@ -1,405 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <string.h> -#include <assert.h> -#include <stdlib.h> - -#include <liboil/liboilfuncs.h> - -#include <polypcore/log.h> - -#include "sample-util.h" -#include "endianmacros.h" - -pa_memblock *pa_silence_memblock_new(const pa_sample_spec *spec, size_t length, pa_memblock_stat*s) { - assert(spec); - - if (length == 0) - length = pa_bytes_per_second(spec)/10; /* 100 ms */ - - return pa_silence_memblock(pa_memblock_new(length, s), spec); -} - -pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec) { - assert(b && b->data && spec); - pa_silence_memory(b->data, b->length, spec); - return b; -} - -void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec) { - assert(c && c->memblock && c->memblock->data && spec && c->length); - - pa_silence_memory((uint8_t*) c->memblock->data+c->index, c->length, spec); -} - -void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec) { - uint8_t c = 0; - assert(p && length && spec); - - switch (spec->format) { - case PA_SAMPLE_U8: - c = 0x80; - break; - case PA_SAMPLE_S16LE: - case PA_SAMPLE_S16BE: - case PA_SAMPLE_FLOAT32: - c = 0; - break; - case PA_SAMPLE_ALAW: - case PA_SAMPLE_ULAW: - c = 80; - break; - default: - assert(0); - } - - memset(p, c, length); -} - -size_t pa_mix( - const pa_mix_info streams[], - unsigned nstreams, - void *data, - size_t length, - const pa_sample_spec *spec, - const pa_cvolume *volume, - int mute) { - - assert(streams && data && length && spec); - - switch (spec->format) { - case PA_SAMPLE_S16NE:{ - size_t d; - unsigned channel = 0; - - for (d = 0;; d += sizeof(int16_t)) { - int32_t sum = 0; - - if (d >= length) - return d; - - if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { - unsigned i; - - for (i = 0; i < nstreams; i++) { - int32_t v; - pa_volume_t cvolume = streams[i].volume.values[channel]; - - if (d >= streams[i].chunk.length) - return d; - - if (cvolume == PA_VOLUME_MUTED) - v = 0; - else { - v = *((int16_t*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d)); - - if (cvolume != PA_VOLUME_NORM) - v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); - } - - sum += v; - } - - if (volume->values[channel] != PA_VOLUME_NORM) - sum = (int32_t) (sum * pa_sw_volume_to_linear(volume->values[channel])); - - if (sum < -0x8000) sum = -0x8000; - if (sum > 0x7FFF) sum = 0x7FFF; - - } - - *((int16_t*) data) = sum; - data = (uint8_t*) data + sizeof(int16_t); - - if (++channel >= spec->channels) - channel = 0; - } - } - - case PA_SAMPLE_S16RE:{ - size_t d; - unsigned channel = 0; - - for (d = 0;; d += sizeof(int16_t)) { - int32_t sum = 0; - - if (d >= length) - return d; - - if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { - unsigned i; - - for (i = 0; i < nstreams; i++) { - int32_t v; - pa_volume_t cvolume = streams[i].volume.values[channel]; - - if (d >= streams[i].chunk.length) - return d; - - if (cvolume == PA_VOLUME_MUTED) - v = 0; - else { - v = INT16_SWAP(*((int16_t*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d))); - - if (cvolume != PA_VOLUME_NORM) - v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); - } - - sum += v; - } - - if (volume->values[channel] != PA_VOLUME_NORM) - sum = (int32_t) (sum * pa_sw_volume_to_linear(volume->values[channel])); - - if (sum < -0x8000) sum = -0x8000; - if (sum > 0x7FFF) sum = 0x7FFF; - - } - - *((int16_t*) data) = INT16_SWAP(sum); - data = (uint8_t*) data + sizeof(int16_t); - - if (++channel >= spec->channels) - channel = 0; - } - } - - case PA_SAMPLE_U8: { - size_t d; - unsigned channel = 0; - - for (d = 0;; d ++) { - int32_t sum = 0; - - if (d >= length) - return d; - - if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { - unsigned i; - - for (i = 0; i < nstreams; i++) { - int32_t v; - pa_volume_t cvolume = streams[i].volume.values[channel]; - - if (d >= streams[i].chunk.length) - return d; - - if (cvolume == PA_VOLUME_MUTED) - v = 0; - else { - v = (int32_t) *((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d) - 0x80; - - if (cvolume != PA_VOLUME_NORM) - v = (int32_t) (v * pa_sw_volume_to_linear(cvolume)); - } - - sum += v; - } - - if (volume->values[channel] != PA_VOLUME_NORM) - sum = (int32_t) (sum * pa_sw_volume_to_linear(volume->values[channel])); - - if (sum < -0x80) sum = -0x80; - if (sum > 0x7F) sum = 0x7F; - - } - - *((uint8_t*) data) = (uint8_t) (sum + 0x80); - data = (uint8_t*) data + 1; - - if (++channel >= spec->channels) - channel = 0; - } - } - - case PA_SAMPLE_FLOAT32NE: { - size_t d; - unsigned channel = 0; - - for (d = 0;; d += sizeof(float)) { - float sum = 0; - - if (d >= length) - return d; - - if (!mute && volume->values[channel] != PA_VOLUME_MUTED) { - unsigned i; - - for (i = 0; i < nstreams; i++) { - float v; - pa_volume_t cvolume = streams[i].volume.values[channel]; - - if (d >= streams[i].chunk.length) - return d; - - if (cvolume == PA_VOLUME_MUTED) - v = 0; - else { - v = *((float*) ((uint8_t*) streams[i].chunk.memblock->data + streams[i].chunk.index + d)); - - if (cvolume != PA_VOLUME_NORM) - v *= pa_sw_volume_to_linear(cvolume); - } - - sum += v; - } - - if (volume->values[channel] != PA_VOLUME_NORM) - sum *= pa_sw_volume_to_linear(volume->values[channel]); - } - - *((float*) data) = sum; - data = (uint8_t*) data + sizeof(float); - - if (++channel >= spec->channels) - channel = 0; - } - } - - default: - pa_log_error(__FILE__": ERROR: Unable to mix audio data of format %s.", pa_sample_format_to_string(spec->format)); - abort(); - } -} - - -void pa_volume_memchunk(pa_memchunk*c, const pa_sample_spec *spec, const pa_cvolume *volume) { - assert(c && spec && (c->length % pa_frame_size(spec) == 0)); - assert(volume); - - if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_NORM)) - return; - - if (pa_cvolume_channels_equal_to(volume, PA_VOLUME_MUTED)) { - pa_silence_memchunk(c, spec); - return; - } - - switch (spec->format) { - case PA_SAMPLE_S16NE: { - int16_t *d; - size_t n; - unsigned channel; - double linear[PA_CHANNELS_MAX]; - - for (channel = 0; channel < spec->channels; channel++) - linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); - - for (channel = 0, d = (int16_t*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { - int32_t t = (int32_t)(*d); - - t = (int32_t) (t * linear[channel]); - - if (t < -0x8000) t = -0x8000; - if (t > 0x7FFF) t = 0x7FFF; - - *d = (int16_t) t; - - if (++channel >= spec->channels) - channel = 0; - } - break; - } - - case PA_SAMPLE_S16RE: { - int16_t *d; - size_t n; - unsigned channel; - double linear[PA_CHANNELS_MAX]; - - for (channel = 0; channel < spec->channels; channel++) - linear[channel] = pa_sw_volume_to_linear(volume->values[channel]); - - for (channel = 0, d = (int16_t*) ((uint8_t*) c->memblock->data+c->index), n = c->length/sizeof(int16_t); n > 0; d++, n--) { - int32_t t = (int32_t)(INT16_SWAP(*d)); - - t = (int32_t) (t * linear[channel]); - - if (t < -0x8000) t = -0x8000; - if (t > 0x7FFF) t = 0x7FFF; - - *d = INT16_SWAP((int16_t) t); - - if (++channel >= spec->channels) - channel = 0; - } - - break; - } - - case PA_SAMPLE_U8: { - uint8_t *d; - size_t n; - unsigned channel = 0; - - for (d = (uint8_t*) c->memblock->data + c->index, n = c->length; n > 0; d++, n--) { - int32_t t = (int32_t) *d - 0x80; - - t = (int32_t) (t * pa_sw_volume_to_linear(volume->values[channel])); - - if (t < -0x80) t = -0x80; - if (t > 0x7F) t = 0x7F; - - *d = (uint8_t) (t + 0x80); - - if (++channel >= spec->channels) - channel = 0; - } - break; - } - - case PA_SAMPLE_FLOAT32NE: { - float *d; - int skip; - unsigned n; - unsigned channel; - - d = (float*) ((uint8_t*) c->memblock->data + c->index); - skip = spec->channels * sizeof(float); - n = c->length/sizeof(float)/spec->channels; - - for (channel = 0; channel < spec->channels ; channel ++) { - float v, *t; - - if (volume->values[channel] == PA_VOLUME_NORM) - continue; - - v = (float) pa_sw_volume_to_linear(volume->values[channel]); - - t = d + channel; - oil_scalarmult_f32(t, skip, t, skip, &v, n); - } - break; - } - - default: - pa_log_error(__FILE__": ERROR: Unable to change volume of format %s.", - pa_sample_format_to_string(spec->format)); - abort(); - } -} - diff --git a/src/polypcore/sample-util.h b/src/polypcore/sample-util.h deleted file mode 100644 index da7f56e1..00000000 --- a/src/polypcore/sample-util.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef foosampleutilhfoo -#define foosampleutilhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polyp/sample.h> -#include <polyp/volume.h> -#include <polypcore/memblock.h> -#include <polypcore/memchunk.h> - -pa_memblock *pa_silence_memblock(pa_memblock* b, const pa_sample_spec *spec); -pa_memblock *pa_silence_memblock_new(const pa_sample_spec *spec, size_t length, pa_memblock_stat*s); -void pa_silence_memchunk(pa_memchunk *c, const pa_sample_spec *spec); -void pa_silence_memory(void *p, size_t length, const pa_sample_spec *spec); - -typedef struct pa_mix_info { - pa_memchunk chunk; - pa_cvolume volume; - void *userdata; -} pa_mix_info; - -size_t pa_mix( - const pa_mix_info channels[], - unsigned nchannels, - void *data, - size_t length, - const pa_sample_spec *spec, - const pa_cvolume *volume, - int mute); - -void pa_volume_memchunk( - pa_memchunk*c, - const pa_sample_spec *spec, - const pa_cvolume *volume); - -#endif diff --git a/src/polypcore/sconv-s16be.c b/src/polypcore/sconv-s16be.c deleted file mode 100644 index 8b076f06..00000000 --- a/src/polypcore/sconv-s16be.c +++ /dev/null @@ -1,41 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include "endianmacros.h" - -#define INT16_FROM INT16_FROM_BE -#define INT16_TO INT16_TO_BE - -#define pa_sconv_s16le_to_float32ne pa_sconv_s16be_to_float32ne -#define pa_sconv_s16le_from_float32ne pa_sconv_s16be_from_float32ne - -#ifdef WORDS_BIGENDIAN -#define SWAP_WORDS 0 -#else -#define SWAP_WORDS 1 -#endif - -#include "sconv-s16le.h" -#include "sconv-s16le.c" diff --git a/src/polypcore/sconv-s16be.h b/src/polypcore/sconv-s16be.h deleted file mode 100644 index b2b6a8c7..00000000 --- a/src/polypcore/sconv-s16be.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef foosconv_s16befoo -#define foosconv_s16befoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -void pa_sconv_s16be_to_float32ne(unsigned n, const void *a, float *b); -void pa_sconv_s16be_from_float32ne(unsigned n, const float *a, void *b); - -#endif diff --git a/src/polypcore/sconv-s16le.c b/src/polypcore/sconv-s16le.c deleted file mode 100644 index 0814c35b..00000000 --- a/src/polypcore/sconv-s16le.c +++ /dev/null @@ -1,103 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> -#include <inttypes.h> - -#include <liboil/liboilfuncs.h> - -#include <polypcore/sconv.h> -#include <polypcore/log.h> - -#include "endianmacros.h" - -#include "sconv-s16le.h" - -#ifndef INT16_FROM -#define INT16_FROM INT16_FROM_LE -#endif - -#ifndef INT16_TO -#define INT16_TO INT16_TO_LE -#endif - -#ifndef SWAP_WORDS -#ifdef WORDS_BIGENDIAN -#define SWAP_WORDS 1 -#else -#define SWAP_WORDS 0 -#endif -#endif - -void pa_sconv_s16le_to_float32ne(unsigned n, const void *a, float *b) { - const int16_t *ca = a; - - assert(a); - assert(b); - -#if SWAP_WORDS == 1 - - for (; n > 0; n--) { - int16_t s = *(ca++); - *(b++) = ((float) INT16_FROM(s))/0x7FFF; - } - -#else -{ - static const double add = 0, factor = 1.0/0x7FFF; - oil_scaleconv_f32_s16(b, ca, n, &add, &factor); -} -#endif -} - -void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, void *b) { - int16_t *cb = b; - - assert(a); - assert(b); - -#if SWAP_WORDS == 1 - - for (; n > 0; n--) { - int16_t s; - float v = *(a++); - - if (v > 1) - v = 1; - - if (v < -1) - v = -1; - - s = (int16_t) (v * 0x7FFF); - *(cb++) = INT16_TO(s); - } - -#else -{ - static const double add = 0, factor = 0x7FFF; - oil_scaleconv_s16_f32(cb, a, n, &add, &factor); -} -#endif -} diff --git a/src/polypcore/sconv-s16le.h b/src/polypcore/sconv-s16le.h deleted file mode 100644 index ef5e31e8..00000000 --- a/src/polypcore/sconv-s16le.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef foosconv_s16lefoo -#define foosconv_s16lefoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -void pa_sconv_s16le_to_float32ne(unsigned n, const void *a, float *b); -void pa_sconv_s16le_from_float32ne(unsigned n, const float *a, void *b); - -#endif diff --git a/src/polypcore/sconv.c b/src/polypcore/sconv.c deleted file mode 100644 index c557be67..00000000 --- a/src/polypcore/sconv.c +++ /dev/null @@ -1,169 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <assert.h> - -#include <liboil/liboilfuncs.h> -#include <liboil/liboil.h> - -#include <polypcore/g711.h> - -#include "endianmacros.h" -#include "sconv-s16le.h" -#include "sconv-s16be.h" - -#include "sconv.h" - -static void u8_to_float32ne(unsigned n, const void *a, float *b) { - const uint8_t *ca = a; - static const double add = -128.0/127.0, factor = 1.0/127.0; - - assert(a); - assert(b); - - oil_scaleconv_f32_u8(b, ca, n, &add, &factor); -} - -static void u8_from_float32ne(unsigned n, const float *a, void *b) { - uint8_t *cb = b; - static const double add = 128.0, factor = 127.0; - - assert(a); - assert(b); - - oil_scaleconv_u8_f32(cb, a, n, &add, &factor); -} - -static void float32ne_to_float32ne(unsigned n, const void *a, float *b) { - assert(a); - assert(b); - - oil_memcpy(b, a, sizeof(float) * n); -} - -static void float32ne_from_float32ne(unsigned n, const float *a, void *b) { - assert(a); - assert(b); - - oil_memcpy(b, a, sizeof(float) * n); -} - -static void ulaw_to_float32ne(unsigned n, const void *a, float *b) { - const uint8_t *ca = a; - - assert(a); - assert(b); - - for (; n > 0; n--) - *(b++) = st_ulaw2linear16(*(ca++)) * 1.0F / 0x7FFF; -} - -static void ulaw_from_float32ne(unsigned n, const float *a, void *b) { - uint8_t *cb = b; - - assert(a); - assert(b); - - for (; n > 0; n--) { - float v = *(a++); - - if (v > 1) - v = 1; - - if (v < -1) - v = -1; - - *(cb++) = st_14linear2ulaw((int16_t) (v * 0x1FFF)); - } -} - -static void alaw_to_float32ne(unsigned n, const void *a, float *b) { - const uint8_t *ca = a; - - assert(a); - assert(b); - - for (; n > 0; n--) - *(b++) = st_alaw2linear16(*(ca++)) * 1.0F / 0x7FFF; -} - -static void alaw_from_float32ne(unsigned n, const float *a, void *b) { - uint8_t *cb = b; - - assert(a); - assert(b); - - for (; n > 0; n--) { - float v = *(a++); - - if (v > 1) - v = 1; - - if (v < -1) - v = -1; - - *(cb++) = st_13linear2alaw((int16_t) (v * 0xFFF)); - } -} - -pa_convert_to_float32ne_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f) { - switch(f) { - case PA_SAMPLE_U8: - return u8_to_float32ne; - case PA_SAMPLE_S16LE: - return pa_sconv_s16le_to_float32ne; - case PA_SAMPLE_S16BE: - return pa_sconv_s16be_to_float32ne; - case PA_SAMPLE_FLOAT32NE: - return float32ne_to_float32ne; - case PA_SAMPLE_ALAW: - return alaw_to_float32ne; - case PA_SAMPLE_ULAW: - return ulaw_to_float32ne; - default: - return NULL; - } -} - -pa_convert_from_float32ne_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f) { - switch(f) { - case PA_SAMPLE_U8: - return u8_from_float32ne; - case PA_SAMPLE_S16LE: - return pa_sconv_s16le_from_float32ne; - case PA_SAMPLE_S16BE: - return pa_sconv_s16be_from_float32ne; - case PA_SAMPLE_FLOAT32NE: - return float32ne_from_float32ne; - case PA_SAMPLE_ALAW: - return alaw_from_float32ne; - case PA_SAMPLE_ULAW: - return ulaw_from_float32ne; - default: - return NULL; - } -} diff --git a/src/polypcore/sconv.h b/src/polypcore/sconv.h deleted file mode 100644 index a0c15c24..00000000 --- a/src/polypcore/sconv.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef foosconvhfoo -#define foosconvhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polyp/sample.h> - -typedef void (*pa_convert_to_float32ne_func_t)(unsigned n, const void *a, float *b); -typedef void (*pa_convert_from_float32ne_func_t)(unsigned n, const float *a, void *b); - -pa_convert_to_float32ne_func_t pa_get_convert_to_float32ne_function(pa_sample_format_t f); -pa_convert_from_float32ne_func_t pa_get_convert_from_float32ne_function(pa_sample_format_t f); - -#endif diff --git a/src/polypcore/sink-input.c b/src/polypcore/sink-input.c deleted file mode 100644 index bd2a1dcd..00000000 --- a/src/polypcore/sink-input.c +++ /dev/null @@ -1,386 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/utf8.h> -#include <polyp/xmalloc.h> - -#include <polypcore/sample-util.h> -#include <polypcore/core-subscribe.h> -#include <polypcore/log.h> - -#include "sink-input.h" - -#define CONVERT_BUFFER_LENGTH 4096 - -#define CHECK_VALIDITY_RETURN_NULL(condition) \ -do {\ -if (!(condition)) \ - return NULL; \ -} while (0) - -pa_sink_input* pa_sink_input_new( - pa_sink *s, - const char *driver, - const char *name, - const pa_sample_spec *spec, - const pa_channel_map *map, - const pa_cvolume *volume, - int variable_rate, - int resample_method) { - - pa_sink_input *i; - pa_resampler *resampler = NULL; - int r; - char st[256]; - pa_channel_map tmap; - pa_cvolume tvol; - - assert(s); - assert(spec); - assert(s->state == PA_SINK_RUNNING); - - CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec)); - - if (!map) - map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT); - if (!volume) - volume = pa_cvolume_reset(&tvol, spec->channels); - - CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map)); - CHECK_VALIDITY_RETURN_NULL(volume && pa_cvolume_valid(volume)); - CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels); - CHECK_VALIDITY_RETURN_NULL(volume->channels == spec->channels); - CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver)); - CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name)); - - if (pa_idxset_size(s->inputs) >= PA_MAX_INPUTS_PER_SINK) { - pa_log_warn(__FILE__": Failed to create sink input: too many inputs per sink."); - return NULL; - } - - if (resample_method == PA_RESAMPLER_INVALID) - resample_method = s->core->resample_method; - - if (variable_rate || !pa_sample_spec_equal(spec, &s->sample_spec) || !pa_channel_map_equal(map, &s->channel_map)) - if (!(resampler = pa_resampler_new(spec, map, &s->sample_spec, &s->channel_map, s->core->memblock_stat, resample_method))) - return NULL; - - i = pa_xnew(pa_sink_input, 1); - i->ref = 1; - i->state = PA_SINK_INPUT_RUNNING; - i->name = pa_xstrdup(name); - i->driver = pa_xstrdup(driver); - i->owner = NULL; - i->sink = s; - i->client = NULL; - - i->sample_spec = *spec; - i->channel_map = *map; - i->volume = *volume; - - i->peek = NULL; - i->drop = NULL; - i->kill = NULL; - i->get_latency = NULL; - i->underrun = NULL; - i->userdata = NULL; - - i->playing = 0; - - pa_memchunk_reset(&i->resampled_chunk); - i->resampler = resampler; - - assert(s->core); - r = pa_idxset_put(s->core->sink_inputs, i, &i->index); - assert(r == 0 && i->index != PA_IDXSET_INVALID); - r = pa_idxset_put(s->inputs, i, NULL); - assert(r == 0); - - pa_sample_spec_snprint(st, sizeof(st), spec); - pa_log_info(__FILE__": created %u \"%s\" on %u with sample spec \"%s\"", i->index, i->name, s->index, st); - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_NEW, i->index); - - return i; -} - -void pa_sink_input_disconnect(pa_sink_input *i) { - assert(i); - assert(i->state != PA_SINK_INPUT_DISCONNECTED); - assert(i->sink); - assert(i->sink->core); - - pa_idxset_remove_by_data(i->sink->core->sink_inputs, i, NULL); - pa_idxset_remove_by_data(i->sink->inputs, i, NULL); - - pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_REMOVE, i->index); - i->sink = NULL; - - i->peek = NULL; - i->drop = NULL; - i->kill = NULL; - i->get_latency = NULL; - i->underrun = NULL; - - i->playing = 0; - i->state = PA_SINK_INPUT_DISCONNECTED; -} - -static void sink_input_free(pa_sink_input* i) { - assert(i); - - if (i->state != PA_SINK_INPUT_DISCONNECTED) - pa_sink_input_disconnect(i); - - pa_log_info(__FILE__": freed %u \"%s\"", i->index, i->name); - - if (i->resampled_chunk.memblock) - pa_memblock_unref(i->resampled_chunk.memblock); - - if (i->resampler) - pa_resampler_free(i->resampler); - - pa_xfree(i->name); - pa_xfree(i->driver); - pa_xfree(i); -} - -void pa_sink_input_unref(pa_sink_input *i) { - assert(i); - assert(i->ref >= 1); - - if (!(--i->ref)) - sink_input_free(i); -} - -pa_sink_input* pa_sink_input_ref(pa_sink_input *i) { - assert(i); - assert(i->ref >= 1); - - i->ref++; - return i; -} - -void pa_sink_input_kill(pa_sink_input*i) { - assert(i); - assert(i->ref >= 1); - - if (i->kill) - i->kill(i); -} - -pa_usec_t pa_sink_input_get_latency(pa_sink_input *i) { - pa_usec_t r = 0; - - assert(i); - assert(i->ref >= 1); - - if (i->get_latency) - r += i->get_latency(i); - - if (i->resampled_chunk.memblock) - r += pa_bytes_to_usec(i->resampled_chunk.length, &i->sample_spec); - - return r; -} - -int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume) { - int ret = -1; - int do_volume_adj_here; - - assert(i); - assert(i->ref >= 1); - assert(chunk); - assert(volume); - - pa_sink_input_ref(i); - - if (!i->peek || !i->drop || i->state == PA_SINK_INPUT_CORKED) - goto finish; - - if (!i->resampler) { - do_volume_adj_here = 0; - ret = i->peek(i, chunk); - goto finish; - } - - do_volume_adj_here = !pa_channel_map_equal(&i->channel_map, &i->sink->channel_map); - - while (!i->resampled_chunk.memblock) { - pa_memchunk tchunk; - size_t l; - - if ((ret = i->peek(i, &tchunk)) < 0) - goto finish; - - assert(tchunk.length); - - l = pa_resampler_request(i->resampler, CONVERT_BUFFER_LENGTH); - - if (l > tchunk.length) - l = tchunk.length; - - i->drop(i, &tchunk, l); - tchunk.length = l; - - /* It might be necessary to adjust the volume here */ - if (do_volume_adj_here) { - pa_memchunk_make_writable(&tchunk, i->sink->core->memblock_stat, 0); - pa_volume_memchunk(&tchunk, &i->sample_spec, &i->volume); - } - - pa_resampler_run(i->resampler, &tchunk, &i->resampled_chunk); - pa_memblock_unref(tchunk.memblock); - } - - assert(i->resampled_chunk.memblock); - assert(i->resampled_chunk.length); - - *chunk = i->resampled_chunk; - pa_memblock_ref(i->resampled_chunk.memblock); - - ret = 0; - -finish: - - if (ret < 0 && i->playing && i->underrun) - i->underrun(i); - - i->playing = ret >= 0; - - if (ret >= 0) { - /* Let's see if we had to apply the volume adjustment - * ourselves, or if this can be done by the sink for us */ - - if (do_volume_adj_here) - /* We had different channel maps, so we already did the adjustment */ - pa_cvolume_reset(volume, i->sink->sample_spec.channels); - else - /* We've both the same channel map, so let's have the sink do the adjustment for us*/ - *volume = i->volume; - } - - pa_sink_input_unref(i); - - return ret; -} - -void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length) { - assert(i); - assert(i->ref >= 1); - assert(length > 0); - - if (!i->resampler) { - if (i->drop) - i->drop(i, chunk, length); - return; - } - - assert(i->resampled_chunk.memblock); - assert(i->resampled_chunk.length >= length); - - i->resampled_chunk.index += length; - i->resampled_chunk.length -= length; - - if (i->resampled_chunk.length <= 0) { - pa_memblock_unref(i->resampled_chunk.memblock); - i->resampled_chunk.memblock = NULL; - i->resampled_chunk.index = i->resampled_chunk.length = 0; - } -} - -void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume) { - assert(i); - assert(i->ref >= 1); - assert(i->sink); - assert(i->sink->core); - - if (pa_cvolume_equal(&i->volume, volume)) - return; - - i->volume = *volume; - pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); -} - -const pa_cvolume * pa_sink_input_get_volume(pa_sink_input *i) { - assert(i); - assert(i->ref >= 1); - - return &i->volume; -} - -void pa_sink_input_cork(pa_sink_input *i, int b) { - int n; - - assert(i); - assert(i->ref >= 1); - - if (i->state == PA_SINK_INPUT_DISCONNECTED) - return; - - n = i->state == PA_SINK_INPUT_CORKED && !b; - - i->state = b ? PA_SINK_INPUT_CORKED : PA_SINK_INPUT_RUNNING; - - if (n) - pa_sink_notify(i->sink); -} - -void pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate) { - assert(i); - assert(i->resampler); - assert(i->ref >= 1); - - if (i->sample_spec.rate == rate) - return; - - i->sample_spec.rate = rate; - pa_resampler_set_input_rate(i->resampler, rate); -} - -void pa_sink_input_set_name(pa_sink_input *i, const char *name) { - assert(i); - assert(i->ref >= 1); - - pa_xfree(i->name); - i->name = pa_xstrdup(name); - - pa_subscription_post(i->sink->core, PA_SUBSCRIPTION_EVENT_SINK_INPUT|PA_SUBSCRIPTION_EVENT_CHANGE, i->index); -} - -pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i) { - assert(i); - assert(i->ref >= 1); - - if (!i->resampler) - return PA_RESAMPLER_INVALID; - - return pa_resampler_get_method(i->resampler); -} diff --git a/src/polypcore/sink-input.h b/src/polypcore/sink-input.h deleted file mode 100644 index 4cf4460a..00000000 --- a/src/polypcore/sink-input.h +++ /dev/null @@ -1,107 +0,0 @@ -#ifndef foosinkinputhfoo -#define foosinkinputhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> - -typedef struct pa_sink_input pa_sink_input; - -#include <polyp/sample.h> -#include <polypcore/sink.h> -#include <polypcore/memblockq.h> -#include <polypcore/resampler.h> -#include <polypcore/module.h> -#include <polypcore/client.h> - -typedef enum pa_sink_input_state { - PA_SINK_INPUT_RUNNING, - PA_SINK_INPUT_CORKED, - PA_SINK_INPUT_DISCONNECTED -} pa_sink_input_state_t; - -struct pa_sink_input { - int ref; - uint32_t index; - pa_sink_input_state_t state; - - char *name, *driver; - pa_module *owner; - - pa_sink *sink; - pa_client *client; - - pa_sample_spec sample_spec; - pa_channel_map channel_map; - - pa_cvolume volume; - - int (*peek) (pa_sink_input *i, pa_memchunk *chunk); - void (*drop) (pa_sink_input *i, const pa_memchunk *chunk, size_t length); - void (*kill) (pa_sink_input *i); - pa_usec_t (*get_latency) (pa_sink_input *i); - void (*underrun) (pa_sink_input *i); - - void *userdata; - - int playing; - - pa_memchunk resampled_chunk; - pa_resampler *resampler; -}; - -pa_sink_input* pa_sink_input_new( - pa_sink *s, - const char *driver, - const char *name, - const pa_sample_spec *spec, - const pa_channel_map *map, - const pa_cvolume *volume, - int variable_rate, - int resample_method); - -void pa_sink_input_unref(pa_sink_input* i); -pa_sink_input* pa_sink_input_ref(pa_sink_input* i); - -/* To be called by the implementing module only */ -void pa_sink_input_disconnect(pa_sink_input* i); - -/* External code may request disconnection with this funcion */ -void pa_sink_input_kill(pa_sink_input*i); - -pa_usec_t pa_sink_input_get_latency(pa_sink_input *i); - -int pa_sink_input_peek(pa_sink_input *i, pa_memchunk *chunk, pa_cvolume *volume); -void pa_sink_input_drop(pa_sink_input *i, const pa_memchunk *chunk, size_t length); - -void pa_sink_input_set_volume(pa_sink_input *i, const pa_cvolume *volume); -const pa_cvolume * pa_sink_input_get_volume(pa_sink_input *i); - -void pa_sink_input_cork(pa_sink_input *i, int b); - -void pa_sink_input_set_rate(pa_sink_input *i, uint32_t rate); - -void pa_sink_input_set_name(pa_sink_input *i, const char *name); - -pa_resample_method_t pa_sink_input_get_resample_method(pa_sink_input *i); - -#endif diff --git a/src/polypcore/sink.c b/src/polypcore/sink.c deleted file mode 100644 index dc27ca2e..00000000 --- a/src/polypcore/sink.c +++ /dev/null @@ -1,513 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <assert.h> -#include <string.h> -#include <stdio.h> - -#include <polyp/introspect.h> -#include <polyp/utf8.h> -#include <polyp/xmalloc.h> - -#include <polypcore/sink-input.h> -#include <polypcore/namereg.h> -#include <polypcore/core-util.h> -#include <polypcore/sample-util.h> -#include <polypcore/core-subscribe.h> -#include <polypcore/log.h> - -#include "sink.h" - -#define MAX_MIX_CHANNELS 32 - -#define CHECK_VALIDITY_RETURN_NULL(condition) \ -do {\ -if (!(condition)) \ - return NULL; \ -} while (0) - -pa_sink* pa_sink_new( - pa_core *core, - const char *driver, - const char *name, - int fail, - const pa_sample_spec *spec, - const pa_channel_map *map) { - - pa_sink *s; - char *n = NULL; - char st[256]; - int r; - pa_channel_map tmap; - - assert(core); - assert(name); - assert(spec); - - CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec)); - - if (!map) - map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT); - - CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map)); - CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels); - CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver)); - CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name) && *name); - - s = pa_xnew(pa_sink, 1); - - if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SINK, s, fail))) { - pa_xfree(s); - return NULL; - } - - s->ref = 1; - s->core = core; - s->state = PA_SINK_RUNNING; - s->name = pa_xstrdup(name); - s->description = NULL; - s->driver = pa_xstrdup(driver); - s->owner = NULL; - - s->sample_spec = *spec; - s->channel_map = *map; - - s->inputs = pa_idxset_new(NULL, NULL); - - pa_cvolume_reset(&s->sw_volume, spec->channels); - pa_cvolume_reset(&s->hw_volume, spec->channels); - s->sw_muted = 0; - s->hw_muted = 0; - - s->get_latency = NULL; - s->notify = NULL; - s->set_hw_volume = NULL; - s->get_hw_volume = NULL; - s->set_hw_mute = NULL; - s->get_hw_mute = NULL; - s->userdata = NULL; - - r = pa_idxset_put(core->sinks, s, &s->index); - assert(s->index != PA_IDXSET_INVALID && r >= 0); - - pa_sample_spec_snprint(st, sizeof(st), spec); - pa_log_info(__FILE__": created %u \"%s\" with sample spec \"%s\"", s->index, s->name, st); - - n = pa_sprintf_malloc("%s_monitor", name); - s->monitor_source = pa_source_new(core, driver, n, 0, spec, map); - assert(s->monitor_source); - pa_xfree(n); - s->monitor_source->monitor_of = s; - s->monitor_source->description = pa_sprintf_malloc("Monitor source of sink '%s'", s->name); - - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_NEW, s->index); - - return s; -} - -void pa_sink_disconnect(pa_sink* s) { - pa_sink_input *i, *j = NULL; - - assert(s); - assert(s->state == PA_SINK_RUNNING); - - pa_namereg_unregister(s->core, s->name); - - while ((i = pa_idxset_first(s->inputs, NULL))) { - assert(i != j); - pa_sink_input_kill(i); - j = i; - } - - pa_source_disconnect(s->monitor_source); - - pa_idxset_remove_by_data(s->core->sinks, s, NULL); - - s->get_latency = NULL; - s->notify = NULL; - s->get_hw_volume = NULL; - s->set_hw_volume = NULL; - s->set_hw_mute = NULL; - s->get_hw_mute = NULL; - - s->state = PA_SINK_DISCONNECTED; - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); -} - -static void sink_free(pa_sink *s) { - assert(s); - assert(!s->ref); - - if (s->state != PA_SINK_DISCONNECTED) - pa_sink_disconnect(s); - - pa_log_info(__FILE__": freed %u \"%s\"", s->index, s->name); - - pa_source_unref(s->monitor_source); - s->monitor_source = NULL; - - pa_idxset_free(s->inputs, NULL, NULL); - - pa_xfree(s->name); - pa_xfree(s->description); - pa_xfree(s->driver); - pa_xfree(s); -} - -void pa_sink_unref(pa_sink*s) { - assert(s); - assert(s->ref >= 1); - - if (!(--s->ref)) - sink_free(s); -} - -pa_sink* pa_sink_ref(pa_sink *s) { - assert(s); - assert(s->ref >= 1); - - s->ref++; - return s; -} - -void pa_sink_notify(pa_sink*s) { - assert(s); - assert(s->ref >= 1); - - if (s->notify) - s->notify(s); -} - -static unsigned fill_mix_info(pa_sink *s, pa_mix_info *info, unsigned maxinfo) { - uint32_t idx = PA_IDXSET_INVALID; - pa_sink_input *i; - unsigned n = 0; - - assert(s); - assert(s->ref >= 1); - assert(info); - - for (i = pa_idxset_first(s->inputs, &idx); maxinfo > 0 && i; i = pa_idxset_next(s->inputs, &idx)) { - /* Increase ref counter, to make sure that this input doesn't - * vanish while we still need it */ - pa_sink_input_ref(i); - - if (pa_sink_input_peek(i, &info->chunk, &info->volume) < 0) { - pa_sink_input_unref(i); - continue; - } - - info->userdata = i; - - assert(info->chunk.memblock); - assert(info->chunk.memblock->data); - assert(info->chunk.length); - - info++; - maxinfo--; - n++; - } - - return n; -} - -static void inputs_drop(pa_sink *s, pa_mix_info *info, unsigned maxinfo, size_t length) { - assert(s); - assert(s->ref >= 1); - assert(info); - - for (; maxinfo > 0; maxinfo--, info++) { - pa_sink_input *i = info->userdata; - - assert(i); - assert(info->chunk.memblock); - - /* Drop read data */ - pa_sink_input_drop(i, &info->chunk, length); - pa_memblock_unref(info->chunk.memblock); - - /* Decrease ref counter */ - pa_sink_input_unref(i); - info->userdata = NULL; - } -} - -int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result) { - pa_mix_info info[MAX_MIX_CHANNELS]; - unsigned n; - int r = -1; - - assert(s); - assert(s->ref >= 1); - assert(length); - assert(result); - - pa_sink_ref(s); - - n = fill_mix_info(s, info, MAX_MIX_CHANNELS); - - if (n <= 0) - goto finish; - - if (n == 1) { - pa_cvolume volume; - - *result = info[0].chunk; - pa_memblock_ref(result->memblock); - - if (result->length > length) - result->length = length; - - pa_sw_cvolume_multiply(&volume, &s->sw_volume, &info[0].volume); - - if (s->sw_muted || !pa_cvolume_is_norm(&volume)) { - pa_memchunk_make_writable(result, s->core->memblock_stat, 0); - if (s->sw_muted) - pa_silence_memchunk(result, &s->sample_spec); - else - pa_volume_memchunk(result, &s->sample_spec, &volume); - } - } else { - result->memblock = pa_memblock_new(length, s->core->memblock_stat); - assert(result->memblock); - -/* pa_log("mixing %i", n); */ - - result->length = pa_mix(info, n, result->memblock->data, length, - &s->sample_spec, &s->sw_volume, s->sw_muted); - result->index = 0; - } - - inputs_drop(s, info, n, result->length); - pa_source_post(s->monitor_source, result); - - r = 0; - -finish: - pa_sink_unref(s); - - return r; -} - -int pa_sink_render_into(pa_sink*s, pa_memchunk *target) { - pa_mix_info info[MAX_MIX_CHANNELS]; - unsigned n; - int r = -1; - - assert(s); - assert(s->ref >= 1); - assert(target); - assert(target->memblock); - assert(target->length); - assert(target->memblock->data); - - pa_sink_ref(s); - - n = fill_mix_info(s, info, MAX_MIX_CHANNELS); - - if (n <= 0) - goto finish; - - if (n == 1) { - pa_cvolume volume; - - if (target->length > info[0].chunk.length) - target->length = info[0].chunk.length; - - memcpy((uint8_t*) target->memblock->data + target->index, - (uint8_t*) info[0].chunk.memblock->data + info[0].chunk.index, - target->length); - - pa_sw_cvolume_multiply(&volume, &s->sw_volume, &info[0].volume); - - if (s->sw_muted) - pa_silence_memchunk(target, &s->sample_spec); - else if (!pa_cvolume_is_norm(&volume)) - pa_volume_memchunk(target, &s->sample_spec, &volume); - } else - target->length = pa_mix(info, n, - (uint8_t*) target->memblock->data + target->index, - target->length, - &s->sample_spec, - &s->sw_volume, - s->sw_muted); - - inputs_drop(s, info, n, target->length); - pa_source_post(s->monitor_source, target); - - r = 0; - -finish: - pa_sink_unref(s); - - return r; -} - -void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target) { - pa_memchunk chunk; - size_t l, d; - - assert(s); - assert(s->ref >= 1); - assert(target); - assert(target->memblock); - assert(target->length); - assert(target->memblock->data); - - pa_sink_ref(s); - - l = target->length; - d = 0; - while (l > 0) { - chunk = *target; - chunk.index += d; - chunk.length -= d; - - if (pa_sink_render_into(s, &chunk) < 0) - break; - - d += chunk.length; - l -= chunk.length; - } - - if (l > 0) { - chunk = *target; - chunk.index += d; - chunk.length -= d; - pa_silence_memchunk(&chunk, &s->sample_spec); - } - - pa_sink_unref(s); -} - -void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result) { - assert(s); - assert(s->ref >= 1); - assert(length); - assert(result); - - /*** This needs optimization ***/ - - result->memblock = pa_memblock_new(result->length = length, s->core->memblock_stat); - result->index = 0; - - pa_sink_render_into_full(s, result); -} - -pa_usec_t pa_sink_get_latency(pa_sink *s) { - assert(s); - assert(s->ref >= 1); - - if (!s->get_latency) - return 0; - - return s->get_latency(s); -} - -void pa_sink_set_owner(pa_sink *s, pa_module *m) { - assert(s); - assert(s->ref >= 1); - - s->owner = m; - - if (s->monitor_source) - pa_source_set_owner(s->monitor_source, m); -} - -void pa_sink_set_volume(pa_sink *s, pa_mixer_t m, const pa_cvolume *volume) { - pa_cvolume *v; - - assert(s); - assert(s->ref >= 1); - assert(volume); - - if (m == PA_MIXER_HARDWARE && s->set_hw_volume) - v = &s->hw_volume; - else - v = &s->sw_volume; - - if (pa_cvolume_equal(v, volume)) - return; - - *v = *volume; - - if (v == &s->hw_volume) - if (s->set_hw_volume(s) < 0) - s->sw_volume = *volume; - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); -} - -const pa_cvolume *pa_sink_get_volume(pa_sink *s, pa_mixer_t m) { - assert(s); - assert(s->ref >= 1); - - if (m == PA_MIXER_HARDWARE && s->set_hw_volume) { - - if (s->get_hw_volume) - s->get_hw_volume(s); - - return &s->hw_volume; - } else - return &s->sw_volume; -} - -void pa_sink_set_mute(pa_sink *s, pa_mixer_t m, int mute) { - int *t; - - assert(s); - assert(s->ref >= 1); - - if (m == PA_MIXER_HARDWARE && s->set_hw_mute) - t = &s->hw_muted; - else - t = &s->sw_muted; - - if (!!*t == !!mute) - return; - - *t = !!mute; - - if (t == &s->hw_muted) - if (s->set_hw_mute(s) < 0) - s->sw_muted = !!mute; - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SINK|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); -} - -int pa_sink_get_mute(pa_sink *s, pa_mixer_t m) { - assert(s); - assert(s->ref >= 1); - - if (m == PA_MIXER_HARDWARE && s->set_hw_mute) { - - if (s->get_hw_mute) - s->get_hw_mute(s); - - return s->hw_muted; - } else - return s->sw_muted; -} diff --git a/src/polypcore/sink.h b/src/polypcore/sink.h deleted file mode 100644 index 59d45597..00000000 --- a/src/polypcore/sink.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef foosinkhfoo -#define foosinkhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> - -typedef struct pa_sink pa_sink; - -#include <polyp/sample.h> -#include <polyp/channelmap.h> -#include <polyp/volume.h> -#include <polypcore/core-def.h> -#include <polypcore/core.h> -#include <polypcore/idxset.h> -#include <polypcore/source.h> -#include <polypcore/module.h> - -#define PA_MAX_INPUTS_PER_SINK 32 - -typedef enum pa_sink_state { - PA_SINK_RUNNING, - PA_SINK_DISCONNECTED -} pa_sink_state_t; - -struct pa_sink { - int ref; - uint32_t index; - pa_core *core; - pa_sink_state_t state; - - char *name, *description, *driver; - pa_module *owner; - - pa_sample_spec sample_spec; - pa_channel_map channel_map; - - pa_idxset *inputs; - pa_source *monitor_source; - - pa_cvolume hw_volume, sw_volume; - int hw_muted, sw_muted; - - void (*notify)(pa_sink*sink); - pa_usec_t (*get_latency)(pa_sink *s); - int (*set_hw_volume)(pa_sink *s); - int (*get_hw_volume)(pa_sink *s); - int (*set_hw_mute)(pa_sink *s); - int (*get_hw_mute)(pa_sink *s); - - void *userdata; -}; - -pa_sink* pa_sink_new( - pa_core *core, - const char *driver, - const char *name, - int namereg_fail, - const pa_sample_spec *spec, - const pa_channel_map *map); - -void pa_sink_disconnect(pa_sink* s); -void pa_sink_unref(pa_sink*s); -pa_sink* pa_sink_ref(pa_sink *s); - -int pa_sink_render(pa_sink*s, size_t length, pa_memchunk *result); -void pa_sink_render_full(pa_sink *s, size_t length, pa_memchunk *result); -int pa_sink_render_into(pa_sink*s, pa_memchunk *target); -void pa_sink_render_into_full(pa_sink *s, pa_memchunk *target); - -pa_usec_t pa_sink_get_latency(pa_sink *s); - -void pa_sink_notify(pa_sink*s); - -void pa_sink_set_owner(pa_sink *sink, pa_module *m); - -void pa_sink_set_volume(pa_sink *sink, pa_mixer_t m, const pa_cvolume *volume); -const pa_cvolume *pa_sink_get_volume(pa_sink *sink, pa_mixer_t m); -void pa_sink_set_mute(pa_sink *sink, pa_mixer_t m, int mute); -int pa_sink_get_mute(pa_sink *sink, pa_mixer_t m); - -#endif diff --git a/src/polypcore/sioman.c b/src/polypcore/sioman.c deleted file mode 100644 index b389ecee..00000000 --- a/src/polypcore/sioman.c +++ /dev/null @@ -1,43 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <assert.h> - -#include "sioman.h" - -static int stdio_inuse = 0; - -int pa_stdio_acquire(void) { - if (stdio_inuse) - return -1; - - stdio_inuse = 1; - return 0; -} - -void pa_stdio_release(void) { - assert(stdio_inuse); - stdio_inuse = 0; -} diff --git a/src/polypcore/sioman.h b/src/polypcore/sioman.h deleted file mode 100644 index 840d93f2..00000000 --- a/src/polypcore/sioman.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef foosiomanhfoo -#define foosiomanhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -int pa_stdio_acquire(void); -void pa_stdio_release(void); - -#endif diff --git a/src/polypcore/socket-client.c b/src/polypcore/socket-client.c deleted file mode 100644 index efb6de9a..00000000 --- a/src/polypcore/socket-client.c +++ /dev/null @@ -1,526 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -/* #undef HAVE_LIBASYNCNS */ - -#include <unistd.h> -#include <stdio.h> -#include <errno.h> -#include <string.h> -#include <assert.h> -#include <stdlib.h> - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_SYS_UN_H -#include <sys/un.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif - -#ifdef HAVE_LIBASYNCNS -#include <asyncns.h> -#endif - -#include "winsock.h" - -#include <polyp/timeval.h> -#include <polyp/xmalloc.h> - -#include <polypcore/core-error.h> -#include <polypcore/socket-util.h> -#include <polypcore/core-util.h> -#include <polypcore/log.h> -#include <polypcore/parseaddr.h> - -#include "socket-client.h" - -#define CONNECT_TIMEOUT 5 - -struct pa_socket_client { - int ref; - pa_mainloop_api *mainloop; - int fd; - pa_io_event *io_event; - pa_time_event *timeout_event; - pa_defer_event *defer_event; - void (*callback)(pa_socket_client*c, pa_iochannel *io, void *userdata); - void *userdata; - int local; -#ifdef HAVE_LIBASYNCNS - asyncns_t *asyncns; - asyncns_query_t * asyncns_query; - pa_io_event *asyncns_io_event; -#endif -}; - -static pa_socket_client*pa_socket_client_new(pa_mainloop_api *m) { - pa_socket_client *c; - assert(m); - - c = pa_xmalloc(sizeof(pa_socket_client)); - c->ref = 1; - c->mainloop = m; - c->fd = -1; - c->io_event = NULL; - c->defer_event = NULL; - c->timeout_event = NULL; - c->callback = NULL; - c->userdata = NULL; - c->local = 0; - -#ifdef HAVE_LIBASYNCNS - c->asyncns = NULL; - c->asyncns_io_event = NULL; - c->asyncns_query = NULL; -#endif - - return c; -} - -static void free_events(pa_socket_client *c) { - assert(c); - - if (c->io_event) { - c->mainloop->io_free(c->io_event); - c->io_event = NULL; - } - - if (c->defer_event) { - c->mainloop->defer_free(c->defer_event); - c->defer_event = NULL; - } - - if (c->timeout_event) { - c->mainloop->time_free(c->timeout_event); - c->timeout_event = NULL; - } -} - -static void do_call(pa_socket_client *c) { - pa_iochannel *io = NULL; - int error; - socklen_t lerror; - assert(c && c->callback); - - pa_socket_client_ref(c); - - if (c->fd < 0) - goto finish; - - lerror = sizeof(error); - if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void*)&error, &lerror) < 0) { - pa_log(__FILE__": getsockopt(): %s", pa_cstrerror(errno)); - goto finish; - } - - if (lerror != sizeof(error)) { - pa_log(__FILE__": getsockopt() returned invalid size."); - goto finish; - } - - if (error != 0) { - pa_log_debug(__FILE__": connect(): %s", pa_cstrerror(errno)); - errno = error; - goto finish; - } - - io = pa_iochannel_new(c->mainloop, c->fd, c->fd); - assert(io); - -finish: - if (!io && c->fd >= 0) - close(c->fd); - c->fd = -1; - - free_events(c); - - assert(c->callback); - c->callback(c, io, c->userdata); - - pa_socket_client_unref(c); -} - -static void connect_fixed_cb(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { - pa_socket_client *c = userdata; - assert(m && c && c->defer_event == e); - do_call(c); -} - -static void connect_io_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { - pa_socket_client *c = userdata; - assert(m && c && c->io_event == e && fd >= 0); - do_call(c); -} - -static int do_connect(pa_socket_client *c, const struct sockaddr *sa, socklen_t len) { - int r; - assert(c && sa && len); - - pa_make_nonblock_fd(c->fd); - - if ((r = connect(c->fd, sa, len)) < 0) { -#ifdef OS_IS_WIN32 - if (WSAGetLastError() != EWOULDBLOCK) { - pa_log_debug(__FILE__": connect(): %d", WSAGetLastError()); -#else - if (errno != EINPROGRESS) { - pa_log_debug(__FILE__": connect(): %s (%d)", pa_cstrerror(errno), errno); -#endif - return -1; - } - - c->io_event = c->mainloop->io_new(c->mainloop, c->fd, PA_IO_EVENT_OUTPUT, connect_io_cb, c); - assert(c->io_event); - } else { - c->defer_event = c->mainloop->defer_new(c->mainloop, connect_fixed_cb, c); - assert(c->defer_event); - } - - return 0; -} - -pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port) { - struct sockaddr_in sa; - assert(m && port > 0); - - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_port = htons(port); - sa.sin_addr.s_addr = htonl(address); - - return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa)); -} - -#ifdef HAVE_SYS_UN_H - -pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) { - struct sockaddr_un sa; - assert(m && filename); - - memset(&sa, 0, sizeof(sa)); - sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1); - sa.sun_path[sizeof(sa.sun_path) - 1] = 0; - - return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa)); -} - -#else /* HAVE_SYS_UN_H */ - -pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename) { - return NULL; -} - -#endif /* HAVE_SYS_UN_H */ - -static int sockaddr_prepare(pa_socket_client *c, const struct sockaddr *sa, size_t salen) { - assert(c); - assert(sa); - assert(salen); - - switch (sa->sa_family) { - case AF_UNIX: - c->local = 1; - break; - - case AF_INET: - c->local = ((const struct sockaddr_in*) sa)->sin_addr.s_addr == INADDR_LOOPBACK; - break; - - case AF_INET6: - c->local = memcmp(&((const struct sockaddr_in6*) sa)->sin6_addr, &in6addr_loopback, sizeof(struct in6_addr)) == 0; - break; - - default: - c->local = 0; - } - - if ((c->fd = socket(sa->sa_family, SOCK_STREAM, 0)) < 0) { - pa_log(__FILE__": socket(): %s", pa_cstrerror(errno)); - return -1; - } - - pa_fd_set_cloexec(c->fd, 1); - if (sa->sa_family == AF_INET || sa->sa_family == AF_INET6) - pa_socket_tcp_low_delay(c->fd); - else - pa_socket_low_delay(c->fd); - - if (do_connect(c, sa, salen) < 0) - return -1; - - return 0; -} - -pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct sockaddr *sa, size_t salen) { - pa_socket_client *c; - assert(m && sa); - c = pa_socket_client_new(m); - assert(c); - - if (sockaddr_prepare(c, sa, salen) < 0) - goto fail; - - return c; - -fail: - pa_socket_client_unref(c); - return NULL; - -} - -static void socket_client_free(pa_socket_client *c) { - assert(c && c->mainloop); - - - free_events(c); - - if (c->fd >= 0) - close(c->fd); - -#ifdef HAVE_LIBASYNCNS - if (c->asyncns_query) - asyncns_cancel(c->asyncns, c->asyncns_query); - if (c->asyncns) - asyncns_free(c->asyncns); - if (c->asyncns_io_event) - c->mainloop->io_free(c->asyncns_io_event); -#endif - - pa_xfree(c); -} - -void pa_socket_client_unref(pa_socket_client *c) { - assert(c && c->ref >= 1); - - if (!(--(c->ref))) - socket_client_free(c); -} - -pa_socket_client* pa_socket_client_ref(pa_socket_client *c) { - assert(c && c->ref >= 1); - c->ref++; - return c; -} - -void pa_socket_client_set_callback(pa_socket_client *c, void (*on_connection)(pa_socket_client *c, pa_iochannel*io, void *userdata), void *userdata) { - assert(c); - c->callback = on_connection; - c->userdata = userdata; -} - -pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[16], uint16_t port) { - struct sockaddr_in6 sa; - - memset(&sa, 0, sizeof(sa)); - sa.sin6_family = AF_INET6; - sa.sin6_port = htons(port); - memcpy(&sa.sin6_addr, address, sizeof(sa.sin6_addr)); - - return pa_socket_client_new_sockaddr(m, (struct sockaddr*) &sa, sizeof(sa)); -} - -#ifdef HAVE_LIBASYNCNS - -static void asyncns_cb(pa_mainloop_api*m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { - pa_socket_client *c = userdata; - struct addrinfo *res = NULL; - int ret; - assert(m && c && c->asyncns_io_event == e && fd >= 0); - - if (asyncns_wait(c->asyncns, 0) < 0) - goto fail; - - if (!asyncns_isdone(c->asyncns, c->asyncns_query)) - return; - - ret = asyncns_getaddrinfo_done(c->asyncns, c->asyncns_query, &res); - c->asyncns_query = NULL; - - if (ret != 0 || !res) - goto fail; - - if (res->ai_addr) - sockaddr_prepare(c, res->ai_addr, res->ai_addrlen); - - asyncns_freeaddrinfo(res); - - m->io_free(c->asyncns_io_event); - c->asyncns_io_event = NULL; - return; - -fail: - m->io_free(c->asyncns_io_event); - c->asyncns_io_event = NULL; - - errno = EHOSTUNREACH; - do_call(c); - return; - -} - -#endif - -static void timeout_cb(pa_mainloop_api *m, pa_time_event *e, const struct timeval *tv, void *userdata) { - pa_socket_client *c = userdata; - assert(m); - assert(e); - assert(tv); - assert(c); - - if (c->fd >= 0) { - close(c->fd); - c->fd = -1; - } - - errno = ETIMEDOUT; - do_call(c); -} - -static void start_timeout(pa_socket_client *c) { - struct timeval tv; - assert(c); - assert(!c->timeout_event); - - pa_gettimeofday(&tv); - pa_timeval_add(&tv, CONNECT_TIMEOUT * 1000000); - c->timeout_event = c->mainloop->time_new(c->mainloop, &tv, timeout_cb, c); -} - -pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char*name, uint16_t default_port) { - pa_socket_client *c = NULL; - pa_parsed_address a; - assert(m && name); - - if (pa_parse_address(name, &a) < 0) - return NULL; - - if (!a.port) - a.port = default_port; - - switch (a.type) { - case PA_PARSED_ADDRESS_UNIX: - if ((c = pa_socket_client_new_unix(m, a.path_or_host))) - start_timeout(c); - break; - - case PA_PARSED_ADDRESS_TCP4: /* Fallthrough */ - case PA_PARSED_ADDRESS_TCP6: /* Fallthrough */ - case PA_PARSED_ADDRESS_TCP_AUTO:{ - - struct addrinfo hints; - char port[12]; - - snprintf(port, sizeof(port), "%u", (unsigned) a.port); - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = a.type == PA_PARSED_ADDRESS_TCP4 ? PF_INET : (a.type == PA_PARSED_ADDRESS_TCP6 ? PF_INET6 : PF_UNSPEC); - hints.ai_socktype = SOCK_STREAM; - -#ifdef HAVE_LIBASYNCNS - { - asyncns_t *asyncns; - - if (!(asyncns = asyncns_new(1))) - goto finish; - - c = pa_socket_client_new(m); - c->asyncns = asyncns; - c->asyncns_io_event = m->io_new(m, asyncns_fd(c->asyncns), PA_IO_EVENT_INPUT, asyncns_cb, c); - c->asyncns_query = asyncns_getaddrinfo(c->asyncns, a.path_or_host, port, &hints); - assert(c->asyncns_query); - start_timeout(c); - } -#else /* HAVE_LIBASYNCNS */ - { -#ifdef HAVE_GETADDRINFO - int ret; - struct addrinfo *res = NULL; - - ret = getaddrinfo(a.path_or_host, port, &hints, &res); - - if (ret < 0 || !res) - goto finish; - - if (res->ai_addr) { - if ((c = pa_socket_client_new_sockaddr(m, res->ai_addr, res->ai_addrlen))) - start_timeout(c); - } - - freeaddrinfo(res); -#else /* HAVE_GETADDRINFO */ - struct hostent *host = NULL; - struct sockaddr_in s; - - /* FIXME: PF_INET6 support */ - if (hints.ai_family == PF_INET6) { - pa_log_error(__FILE__": IPv6 is not supported on Windows"); - goto finish; - } - - host = gethostbyname(a.path_or_host); - if (!host) { - unsigned int addr = inet_addr(a.path_or_host); - if (addr != INADDR_NONE) - host = gethostbyaddr((char*)&addr, 4, AF_INET); - } - - if (!host) - goto finish; - - s.sin_family = AF_INET; - memcpy(&s.sin_addr, host->h_addr, sizeof(struct in_addr)); - s.sin_port = htons(a.port); - - if ((c = pa_socket_client_new_sockaddr(m, (struct sockaddr*)&s, sizeof(s)))) - start_timeout(c); -#endif /* HAVE_GETADDRINFO */ - } -#endif /* HAVE_LIBASYNCNS */ - } - } - -finish: - pa_xfree(a.path_or_host); - return c; - -} - -/* Return non-zero when the target sockaddr is considered - local. "local" means UNIX socket or TCP socket on localhost. Other - local IP addresses are not considered local. */ -int pa_socket_client_is_local(pa_socket_client *c) { - assert(c); - return c->local; -} diff --git a/src/polypcore/socket-client.h b/src/polypcore/socket-client.h deleted file mode 100644 index d0005331..00000000 --- a/src/polypcore/socket-client.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef foosocketclienthfoo -#define foosocketclienthfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> - -#include <polyp/mainloop-api.h> -#include <polypcore/iochannel.h> - -struct sockaddr; - -typedef struct pa_socket_client pa_socket_client; - -pa_socket_client* pa_socket_client_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port); -pa_socket_client* pa_socket_client_new_ipv6(pa_mainloop_api *m, uint8_t address[16], uint16_t port); -pa_socket_client* pa_socket_client_new_unix(pa_mainloop_api *m, const char *filename); -pa_socket_client* pa_socket_client_new_sockaddr(pa_mainloop_api *m, const struct sockaddr *sa, size_t salen); -pa_socket_client* pa_socket_client_new_string(pa_mainloop_api *m, const char *a, uint16_t default_port); - -void pa_socket_client_unref(pa_socket_client *c); -pa_socket_client* pa_socket_client_ref(pa_socket_client *c); - -void pa_socket_client_set_callback(pa_socket_client *c, void (*on_connection)(pa_socket_client *c, pa_iochannel*io, void *userdata), void *userdata); - -int pa_socket_client_is_local(pa_socket_client *c); - -#endif diff --git a/src/polypcore/socket-server.c b/src/polypcore/socket-server.c deleted file mode 100644 index 17071ec2..00000000 --- a/src/polypcore/socket-server.c +++ /dev/null @@ -1,505 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <assert.h> -#include <errno.h> -#include <string.h> -#include <sys/types.h> -#include <stdio.h> -#include <unistd.h> - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_SYS_UN_H -#include <sys/un.h> -#ifndef SUN_LEN -#define SUN_LEN(ptr) \ - ((size_t)(((struct sockaddr_un *) 0)->sun_path) + strlen((ptr)->sun_path)) -#endif -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif - -#ifdef HAVE_LIBWRAP -#include <tcpd.h> -#endif - -#ifndef HAVE_INET_NTOP -#include "inet_ntop.h" -#endif - -#ifndef HAVE_INET_PTON -#include "inet_pton.h" -#endif - -#include "winsock.h" - -#include <polyp/xmalloc.h> -#include <polyp/util.h> - -#include <polypcore/socket-util.h> -#include <polypcore/core-util.h> -#include <polypcore/log.h> -#include <polypcore/core-error.h> - -#include "socket-server.h" - -struct pa_socket_server { - int ref; - int fd; - char *filename; - char *tcpwrap_service; - - void (*on_connection)(pa_socket_server*s, pa_iochannel *io, void *userdata); - void *userdata; - - pa_io_event *io_event; - pa_mainloop_api *mainloop; - enum { SOCKET_SERVER_GENERIC, SOCKET_SERVER_IPV4, SOCKET_SERVER_UNIX, SOCKET_SERVER_IPV6 } type; -}; - -static void callback(pa_mainloop_api *mainloop, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { - pa_socket_server *s = userdata; - pa_iochannel *io; - int nfd; - assert(s && s->mainloop == mainloop && s->io_event == e && e && fd >= 0 && fd == s->fd); - - pa_socket_server_ref(s); - - if ((nfd = accept(fd, NULL, NULL)) < 0) { - pa_log(__FILE__": accept(): %s", pa_cstrerror(errno)); - goto finish; - } - - pa_fd_set_cloexec(nfd, 1); - - if (!s->on_connection) { - close(nfd); - goto finish; - } - -#ifdef HAVE_LIBWRAP - - if (s->tcpwrap_service) { - struct request_info req; - - request_init(&req, RQ_DAEMON, s->tcpwrap_service, RQ_FILE, nfd, NULL); - fromhost(&req); - if (!hosts_access(&req)) { - pa_log_warn(__FILE__": TCP connection refused by tcpwrap."); - close(nfd); - goto finish; - } - - pa_log_info(__FILE__": TCP connection accepted by tcpwrap."); - } -#endif - - /* There should be a check for socket type here */ - if (s->type == SOCKET_SERVER_IPV4) - pa_socket_tcp_low_delay(fd); - else - pa_socket_low_delay(fd); - - io = pa_iochannel_new(s->mainloop, nfd, nfd); - assert(io); - s->on_connection(s, io, s->userdata); - -finish: - pa_socket_server_unref(s); -} - -pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd) { - pa_socket_server *s; - assert(m && fd >= 0); - - s = pa_xmalloc(sizeof(pa_socket_server)); - s->ref = 1; - s->fd = fd; - s->filename = NULL; - s->on_connection = NULL; - s->userdata = NULL; - s->tcpwrap_service = NULL; - - s->mainloop = m; - s->io_event = m->io_new(m, fd, PA_IO_EVENT_INPUT, callback, s); - assert(s->io_event); - - s->type = SOCKET_SERVER_GENERIC; - - return s; -} - -pa_socket_server* pa_socket_server_ref(pa_socket_server *s) { - assert(s && s->ref >= 1); - s->ref++; - return s; -} - -#ifdef HAVE_SYS_UN_H - -pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *filename) { - int fd = -1; - struct sockaddr_un sa; - pa_socket_server *s; - - assert(m && filename); - - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { - pa_log(__FILE__": socket(): %s", pa_cstrerror(errno)); - goto fail; - } - - pa_fd_set_cloexec(fd, 1); - - sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, filename, sizeof(sa.sun_path)-1); - sa.sun_path[sizeof(sa.sun_path) - 1] = 0; - - pa_socket_low_delay(fd); - - if (bind(fd, (struct sockaddr*) &sa, SUN_LEN(&sa)) < 0) { - pa_log(__FILE__": bind(): %s", pa_cstrerror(errno)); - goto fail; - } - - if (listen(fd, 5) < 0) { - pa_log(__FILE__": listen(): %s", pa_cstrerror(errno)); - goto fail; - } - - s = pa_socket_server_new(m, fd); - assert(s); - - s->filename = pa_xstrdup(filename); - s->type = SOCKET_SERVER_UNIX; - - return s; - -fail: - if (fd >= 0) - close(fd); - - return NULL; -} - -#else /* HAVE_SYS_UN_H */ - -pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *filename) { - return NULL; -} - -#endif /* HAVE_SYS_UN_H */ - -pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, const char *tcpwrap_service) { - pa_socket_server *ss; - int fd = -1; - struct sockaddr_in sa; - int on = 1; - - assert(m && port); - - if ((fd = socket(PF_INET, SOCK_STREAM, 0)) < 0) { - pa_log(__FILE__": socket(PF_INET): %s", pa_cstrerror(errno)); - goto fail; - } - - pa_fd_set_cloexec(fd, 1); - -#ifdef SO_REUSEADDR - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) - pa_log(__FILE__": setsockopt(): %s", pa_cstrerror(errno)); -#endif - - pa_socket_tcp_low_delay(fd); - - memset(&sa, 0, sizeof(sa)); - sa.sin_family = AF_INET; - sa.sin_port = htons(port); - sa.sin_addr.s_addr = htonl(address); - - if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - pa_log(__FILE__": bind(): %s", pa_cstrerror(errno)); - goto fail; - } - - if (listen(fd, 5) < 0) { - pa_log(__FILE__": listen(): %s", pa_cstrerror(errno)); - goto fail; - } - - if ((ss = pa_socket_server_new(m, fd))) { - ss->type = SOCKET_SERVER_IPV4; - ss->tcpwrap_service = pa_xstrdup(tcpwrap_service); - } - - return ss; - -fail: - if (fd >= 0) - close(fd); - - return NULL; -} - -pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, const char *tcpwrap_service) { - pa_socket_server *ss; - int fd = -1; - struct sockaddr_in6 sa; - int on = 1; - - assert(m && port); - - if ((fd = socket(PF_INET6, SOCK_STREAM, 0)) < 0) { - pa_log(__FILE__": socket(PF_INET6): %s", pa_cstrerror(errno)); - goto fail; - } - - pa_fd_set_cloexec(fd, 1); - -#ifdef IPV6_V6ONLY - if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) - pa_log(__FILE__": setsockopt(IPPROTO_IPV6, IPV6_V6ONLY): %s", pa_cstrerror(errno)); -#endif - -#ifdef SO_REUSEADDR - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) - pa_log(__FILE__": setsockopt(SOL_SOCKET, SO_REUSEADDR, 1): %s", pa_cstrerror(errno)); -#endif - - pa_socket_tcp_low_delay(fd); - - memset(&sa, 0, sizeof(sa)); - sa.sin6_family = AF_INET6; - sa.sin6_port = htons(port); - memcpy(sa.sin6_addr.s6_addr, address, 16); - - if (bind(fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - pa_log(__FILE__": bind(): %s", pa_cstrerror(errno)); - goto fail; - } - - if (listen(fd, 5) < 0) { - pa_log(__FILE__": listen(): %s", pa_cstrerror(errno)); - goto fail; - } - - if ((ss = pa_socket_server_new(m, fd))) { - ss->type = SOCKET_SERVER_IPV6; - ss->tcpwrap_service = pa_xstrdup(tcpwrap_service); - } - - return ss; - -fail: - if (fd >= 0) - close(fd); - - return NULL; -} - -pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) { - assert(m); - assert(port > 0); - - return pa_socket_server_new_ipv4(m, INADDR_LOOPBACK, port, tcpwrap_service); -} - -pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) { - assert(m); - assert(port > 0); - - return pa_socket_server_new_ipv6(m, in6addr_loopback.s6_addr, port, tcpwrap_service); -} - -pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) { - assert(m); - assert(port > 0); - - return pa_socket_server_new_ipv4(m, INADDR_ANY, port, tcpwrap_service); -} - -pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service) { - assert(m); - assert(port > 0); - - return pa_socket_server_new_ipv6(m, in6addr_any.s6_addr, port, tcpwrap_service); -} - -pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) { - struct in_addr ipv4; - - assert(m); - assert(name); - assert(port > 0); - - if (inet_pton(AF_INET, name, &ipv4) > 0) - return pa_socket_server_new_ipv4(m, ntohl(ipv4.s_addr), port, tcpwrap_service); - - return NULL; -} - -pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service) { - struct in6_addr ipv6; - - assert(m); - assert(name); - assert(port > 0); - - if (inet_pton(AF_INET6, name, &ipv6) > 0) - return pa_socket_server_new_ipv6(m, ipv6.s6_addr, port, tcpwrap_service); - - return NULL; -} - -static void socket_server_free(pa_socket_server*s) { - assert(s); - - if (s->filename) { - unlink(s->filename); - pa_xfree(s->filename); - } - - close(s->fd); - - pa_xfree(s->tcpwrap_service); - - s->mainloop->io_free(s->io_event); - pa_xfree(s); -} - -void pa_socket_server_unref(pa_socket_server *s) { - assert(s && s->ref >= 1); - - if (!(--(s->ref))) - socket_server_free(s); -} - -void pa_socket_server_set_callback(pa_socket_server*s, void (*on_connection)(pa_socket_server*s, pa_iochannel *io, void *userdata), void *userdata) { - assert(s && s->ref >= 1); - - s->on_connection = on_connection; - s->userdata = userdata; -} - -char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l) { - assert(s && c && l > 0); - - switch (s->type) { - case SOCKET_SERVER_IPV6: { - struct sockaddr_in6 sa; - socklen_t sa_len = sizeof(sa); - - if (getsockname(s->fd, (struct sockaddr*) &sa, &sa_len) < 0) { - pa_log(__FILE__": getsockname(): %s", pa_cstrerror(errno)); - return NULL; - } - - if (memcmp(&in6addr_any, &sa.sin6_addr, sizeof(in6addr_any)) == 0) { - char fqdn[256]; - if (!pa_get_fqdn(fqdn, sizeof(fqdn))) - return NULL; - - snprintf(c, l, "tcp6:%s:%u", fqdn, (unsigned) ntohs(sa.sin6_port)); - - } else if (memcmp(&in6addr_loopback, &sa.sin6_addr, sizeof(in6addr_loopback)) == 0) { - char hn[256]; - if (!pa_get_host_name(hn, sizeof(hn))) - return NULL; - - snprintf(c, l, "{%s}tcp6:localhost:%u", hn, (unsigned) ntohs(sa.sin6_port)); - } else { - char ip[INET6_ADDRSTRLEN]; - - if (!inet_ntop(AF_INET6, &sa.sin6_addr, ip, sizeof(ip))) { - pa_log(__FILE__": inet_ntop(): %s", pa_cstrerror(errno)); - return NULL; - } - - snprintf(c, l, "tcp6:[%s]:%u", ip, (unsigned) ntohs(sa.sin6_port)); - } - - return c; - } - - case SOCKET_SERVER_IPV4: { - struct sockaddr_in sa; - socklen_t sa_len = sizeof(sa); - - if (getsockname(s->fd, (struct sockaddr*) &sa, &sa_len) < 0) { - pa_log(__FILE__": getsockname(): %s", pa_cstrerror(errno)); - return NULL; - } - - if (sa.sin_addr.s_addr == INADDR_ANY) { - char fqdn[256]; - if (!pa_get_fqdn(fqdn, sizeof(fqdn))) - return NULL; - - snprintf(c, l, "tcp:%s:%u", fqdn, (unsigned) ntohs(sa.sin_port)); - } else if (sa.sin_addr.s_addr == INADDR_LOOPBACK) { - char hn[256]; - if (!pa_get_host_name(hn, sizeof(hn))) - return NULL; - - snprintf(c, l, "{%s}tcp:localhost:%u", hn, (unsigned) ntohs(sa.sin_port)); - } else { - char ip[INET_ADDRSTRLEN]; - - if (!inet_ntop(AF_INET, &sa.sin_addr, ip, sizeof(ip))) { - pa_log(__FILE__": inet_ntop(): %s", pa_cstrerror(errno)); - return NULL; - } - - snprintf(c, l, "tcp:[%s]:%u", ip, (unsigned) ntohs(sa.sin_port)); - - } - - return c; - } - - case SOCKET_SERVER_UNIX: { - char hn[256]; - - if (!s->filename) - return NULL; - - if (!pa_get_host_name(hn, sizeof(hn))) - return NULL; - - snprintf(c, l, "{%s}unix:%s", hn, s->filename); - return c; - } - - default: - return NULL; - } -} diff --git a/src/polypcore/socket-server.h b/src/polypcore/socket-server.h deleted file mode 100644 index cd3276ad..00000000 --- a/src/polypcore/socket-server.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef foosocketserverhfoo -#define foosocketserverhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> -#include <polyp/mainloop-api.h> -#include <polypcore/iochannel.h> - -/* It is safe to destroy the calling socket_server object from the callback */ - -typedef struct pa_socket_server pa_socket_server; - -pa_socket_server* pa_socket_server_new(pa_mainloop_api *m, int fd); -pa_socket_server* pa_socket_server_new_unix(pa_mainloop_api *m, const char *filename); -pa_socket_server* pa_socket_server_new_ipv4(pa_mainloop_api *m, uint32_t address, uint16_t port, const char *tcpwrap_service); -pa_socket_server* pa_socket_server_new_ipv6(pa_mainloop_api *m, const uint8_t address[16], uint16_t port, const char *tcpwrap_service); -pa_socket_server* pa_socket_server_new_ipv4_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service); -pa_socket_server* pa_socket_server_new_ipv6_loopback(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service); -pa_socket_server* pa_socket_server_new_ipv4_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service); -pa_socket_server* pa_socket_server_new_ipv6_any(pa_mainloop_api *m, uint16_t port, const char *tcpwrap_service); -pa_socket_server* pa_socket_server_new_ipv4_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service); -pa_socket_server* pa_socket_server_new_ipv6_string(pa_mainloop_api *m, const char *name, uint16_t port, const char *tcpwrap_service); - -void pa_socket_server_unref(pa_socket_server*s); -pa_socket_server* pa_socket_server_ref(pa_socket_server *s); - -void pa_socket_server_set_callback(pa_socket_server*s, void (*on_connection)(pa_socket_server*s, pa_iochannel *io, void *userdata), void *userdata); - -char *pa_socket_server_get_address(pa_socket_server *s, char *c, size_t l); - -#endif diff --git a/src/polypcore/socket-util.c b/src/polypcore/socket-util.c deleted file mode 100644 index 3cd205db..00000000 --- a/src/polypcore/socket-util.c +++ /dev/null @@ -1,266 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdarg.h> -#include <stdlib.h> -#include <signal.h> -#include <errno.h> -#include <assert.h> -#include <string.h> -#include <stdio.h> -#include <sys/types.h> -#include <fcntl.h> -#include <unistd.h> -#include <sys/stat.h> - -#ifdef HAVE_SYS_SOCKET_H -#include <sys/socket.h> -#endif -#ifdef HAVE_SYS_UN_H -#include <sys/un.h> -#endif -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif -#ifdef HAVE_NETINET_IN_SYSTM_H -#include <netinet/in_systm.h> -#endif -#ifdef HAVE_NETINET_IP_H -#include <netinet/ip.h> -#endif -#ifdef HAVE_NETINET_TCP_H -#include <netinet/tcp.h> -#endif -#ifdef HAVE_NETDB_H -#include <netdb.h> -#endif -#ifdef HAVE_ARPA_INET_H -#include <arpa/inet.h> -#endif - -#ifndef HAVE_INET_NTOP -#include "inet_ntop.h" -#endif - -#include "winsock.h" - -#include <polyp/xmalloc.h> - -#include <polypcore/core-error.h> -#include <polypcore/core-util.h> -#include <polypcore/log.h> - -#include "socket-util.h" - -void pa_socket_peer_to_string(int fd, char *c, size_t l) { - struct stat st; - - assert(c && l && fd >= 0); - -#ifndef OS_IS_WIN32 - if (fstat(fd, &st) < 0) { - snprintf(c, l, "Invalid client fd"); - return; - } -#endif - -#ifndef OS_IS_WIN32 - if (S_ISSOCK(st.st_mode)) { -#endif - union { - struct sockaddr sa; - struct sockaddr_in in; - struct sockaddr_in6 in6; -#ifdef HAVE_SYS_UN_H - struct sockaddr_un un; -#endif - } sa; - socklen_t sa_len = sizeof(sa); - - if (getpeername(fd, &sa.sa, &sa_len) >= 0) { - - if (sa.sa.sa_family == AF_INET) { - uint32_t ip = ntohl(sa.in.sin_addr.s_addr); - - snprintf(c, l, "TCP/IP client from %i.%i.%i.%i:%u", - ip >> 24, - (ip >> 16) & 0xFF, - (ip >> 8) & 0xFF, - ip & 0xFF, - ntohs(sa.in.sin_port)); - return; - } else if (sa.sa.sa_family == AF_INET6) { - char buf[INET6_ADDRSTRLEN]; - const char *res; - - res = inet_ntop(AF_INET6, &sa.in6.sin6_addr, buf, sizeof(buf)); - if (res) { - snprintf(c, l, "TCP/IP client from [%s]:%u", buf, ntohs(sa.in6.sin6_port)); - return; - } -#ifdef HAVE_SYS_UN_H - } else if (sa.sa.sa_family == AF_UNIX) { - snprintf(c, l, "UNIX socket client"); - return; -#endif - } - - } -#ifndef OS_IS_WIN32 - snprintf(c, l, "Unknown network client"); - return; - } else if (S_ISCHR(st.st_mode) && (fd == 0 || fd == 1)) { - snprintf(c, l, "STDIN/STDOUT client"); - return; - } -#endif /* OS_IS_WIN32 */ - - snprintf(c, l, "Unknown client"); -} - -int pa_socket_low_delay(int fd) { -#ifdef SO_PRIORITY - int priority; - assert(fd >= 0); - - priority = 7; - if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, (void*)&priority, sizeof(priority)) < 0) - return -1; -#endif - - return 0; -} - -int pa_socket_tcp_low_delay(int fd) { - int ret, tos, on; - - assert(fd >= 0); - - ret = pa_socket_low_delay(fd); - - on = 1; - tos = 0; - -#if defined(SOL_TCP) || defined(IPPROTO_TCP) -#if defined(SOL_TCP) - if (setsockopt(fd, SOL_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) -#else - if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (void*)&on, sizeof(on)) < 0) -#endif - ret = -1; -#endif - -#if defined(IPTOS_LOWDELAY) && defined(IP_TOS) && (defined(SOL_IP) || \ - defined(IPPROTO_IP)) - tos = IPTOS_LOWDELAY; -#ifdef SOL_IP - if (setsockopt(fd, SOL_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) -#else - if (setsockopt(fd, IPPROTO_IP, IP_TOS, (void*)&tos, sizeof(tos)) < 0) -#endif - ret = -1; -#endif - - return ret; - -} - -int pa_socket_set_rcvbuf(int fd, size_t l) { - assert(fd >= 0); - -/* if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (void*)&l, sizeof(l)) < 0) { */ -/* pa_log(__FILE__": SO_RCVBUF: %s", strerror(errno)); */ -/* return -1; */ -/* } */ - - return 0; -} - -int pa_socket_set_sndbuf(int fd, size_t l) { - assert(fd >= 0); - -/* if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void*)&l, sizeof(l)) < 0) { */ -/* pa_log(__FILE__": SO_SNDBUF: %s", strerror(errno)); */ -/* return -1; */ -/* } */ - - return 0; -} - -#ifdef HAVE_SYS_UN_H - -int pa_unix_socket_is_stale(const char *fn) { - struct sockaddr_un sa; - int fd = -1, ret = -1; - - if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) { - pa_log(__FILE__": socket(): %s", pa_cstrerror(errno)); - goto finish; - } - - sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, fn, sizeof(sa.sun_path)-1); - sa.sun_path[sizeof(sa.sun_path) - 1] = 0; - - if (connect(fd, (struct sockaddr*) &sa, sizeof(sa)) < 0) { - if (errno == ECONNREFUSED) - ret = 1; - } else - ret = 0; - -finish: - if (fd >= 0) - close(fd); - - return ret; -} - -int pa_unix_socket_remove_stale(const char *fn) { - int r; - - if ((r = pa_unix_socket_is_stale(fn)) < 0) - return errno != ENOENT ? -1 : 0; - - if (!r) - return 0; - - /* Yes, here is a race condition. But who cares? */ - if (unlink(fn) < 0) - return -1; - - return 0; -} - -#else /* HAVE_SYS_UN_H */ - -int pa_unix_socket_is_stale(const char *fn) { - return -1; -} - -int pa_unix_socket_remove_stale(const char *fn) { - return -1; -} - -#endif /* HAVE_SYS_UN_H */ diff --git a/src/polypcore/socket-util.h b/src/polypcore/socket-util.h deleted file mode 100644 index ae16fb16..00000000 --- a/src/polypcore/socket-util.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef foosocketutilhfoo -#define foosocketutilhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <sys/types.h> - -void pa_socket_peer_to_string(int fd, char *c, size_t l); - -int pa_socket_low_delay(int fd); -int pa_socket_tcp_low_delay(int fd); - -int pa_socket_set_sndbuf(int fd, size_t l); -int pa_socket_set_rcvbuf(int fd, size_t l); - -int pa_unix_socket_is_stale(const char *fn); -int pa_unix_socket_remove_stale(const char *fn); - -#endif diff --git a/src/polypcore/sound-file-stream.c b/src/polypcore/sound-file-stream.c deleted file mode 100644 index 68fd8a89..00000000 --- a/src/polypcore/sound-file-stream.c +++ /dev/null @@ -1,192 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <assert.h> -#include <stdio.h> -#include <string.h> - -#include <sndfile.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/sink-input.h> -#include <polypcore/log.h> - -#include "sound-file-stream.h" - -#define BUF_SIZE (1024*10) - -struct userdata { - SNDFILE *sndfile; - pa_sink_input *sink_input; - pa_memchunk memchunk; - sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames); -}; - -static void free_userdata(struct userdata *u) { - assert(u); - if (u->sink_input) { - pa_sink_input_disconnect(u->sink_input); - pa_sink_input_unref(u->sink_input); - } - - if (u->memchunk.memblock) - pa_memblock_unref(u->memchunk.memblock); - if (u->sndfile) - sf_close(u->sndfile); - - pa_xfree(u); -} - -static void sink_input_kill(pa_sink_input *i) { - assert(i && i->userdata); - free_userdata(i->userdata); -} - -static int sink_input_peek(pa_sink_input *i, pa_memchunk *chunk) { - struct userdata *u; - assert(i && chunk && i->userdata); - u = i->userdata; - - if (!u->memchunk.memblock) { - uint32_t fs = pa_frame_size(&i->sample_spec); - sf_count_t n; - - u->memchunk.memblock = pa_memblock_new(BUF_SIZE, i->sink->core->memblock_stat); - u->memchunk.index = 0; - - if (u->readf_function) { - if ((n = u->readf_function(u->sndfile, u->memchunk.memblock->data, BUF_SIZE/fs)) <= 0) - n = 0; - - u->memchunk.length = n * fs; - } else { - if ((n = sf_read_raw(u->sndfile, u->memchunk.memblock->data, BUF_SIZE)) <= 0) - n = 0; - - u->memchunk.length = n; - } - - if (!u->memchunk.length) { - free_userdata(u); - return -1; - } - } - - *chunk = u->memchunk; - pa_memblock_ref(chunk->memblock); - assert(chunk->length); - return 0; -} - -static void sink_input_drop(pa_sink_input *i, const pa_memchunk*chunk, size_t length) { - struct userdata *u; - assert(i && chunk && length && i->userdata); - u = i->userdata; - - assert(!memcmp(chunk, &u->memchunk, sizeof(chunk))); - assert(length <= u->memchunk.length); - - u->memchunk.index += length; - u->memchunk.length -= length; - - if (u->memchunk.length <= 0) { - pa_memblock_unref(u->memchunk.memblock); - u->memchunk.memblock = NULL; - u->memchunk.index = u->memchunk.length = 0; - } -} - -int pa_play_file(pa_sink *sink, const char *fname, const pa_cvolume *volume) { - struct userdata *u = NULL; - SF_INFO sfinfo; - pa_sample_spec ss; - assert(sink && fname); - - u = pa_xmalloc(sizeof(struct userdata)); - u->sink_input = NULL; - u->memchunk.memblock = NULL; - u->memchunk.index = u->memchunk.length = 0; - u->sndfile = NULL; - - memset(&sfinfo, 0, sizeof(sfinfo)); - - if (!(u->sndfile = sf_open(fname, SFM_READ, &sfinfo))) { - pa_log(__FILE__": Failed to open file %s", fname); - goto fail; - } - - u->readf_function = NULL; - - switch (sfinfo.format & 0xFF) { - case SF_FORMAT_PCM_16: - case SF_FORMAT_PCM_U8: - case SF_FORMAT_PCM_S8: - ss.format = PA_SAMPLE_S16NE; - u->readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_short; - break; - - case SF_FORMAT_ULAW: - ss.format = PA_SAMPLE_ULAW; - break; - - case SF_FORMAT_ALAW: - ss.format = PA_SAMPLE_ALAW; - break; - - case SF_FORMAT_FLOAT: - default: - ss.format = PA_SAMPLE_FLOAT32NE; - u->readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_float; - break; - } - - ss.rate = sfinfo.samplerate; - ss.channels = sfinfo.channels; - - if (!pa_sample_spec_valid(&ss)) { - pa_log(__FILE__": Unsupported sample format in file %s", fname); - goto fail; - } - - if (!(u->sink_input = pa_sink_input_new(sink, __FILE__, fname, &ss, NULL, volume, 0, -1))) - goto fail; - - u->sink_input->peek = sink_input_peek; - u->sink_input->drop = sink_input_drop; - u->sink_input->kill = sink_input_kill; - u->sink_input->userdata = u; - - pa_sink_notify(sink); - - return 0; - -fail: - if (u) - free_userdata(u); - - return -1; -} diff --git a/src/polypcore/sound-file-stream.h b/src/polypcore/sound-file-stream.h deleted file mode 100644 index 5effc7f0..00000000 --- a/src/polypcore/sound-file-stream.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef foosoundfilestreamhfoo -#define foosoundfilestreamhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/sink.h> - -int pa_play_file(pa_sink *sink, const char *fname, const pa_cvolume *volume); - -#endif diff --git a/src/polypcore/sound-file.c b/src/polypcore/sound-file.c deleted file mode 100644 index bd0cf596..00000000 --- a/src/polypcore/sound-file.c +++ /dev/null @@ -1,163 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <assert.h> - -#include <sndfile.h> - -#include <polyp/sample.h> -#include <polypcore/log.h> - -#include "sound-file.h" -#include "core-scache.h" - -int pa_sound_file_load(const char *fname, pa_sample_spec *ss, pa_channel_map *map, pa_memchunk *chunk, pa_memblock_stat *s) { - SNDFILE*sf = NULL; - SF_INFO sfinfo; - int ret = -1; - size_t l; - sf_count_t (*readf_function)(SNDFILE *sndfile, void *ptr, sf_count_t frames) = NULL; - assert(fname && ss && chunk); - - chunk->memblock = NULL; - chunk->index = chunk->length = 0; - - memset(&sfinfo, 0, sizeof(sfinfo)); - - if (!(sf = sf_open(fname, SFM_READ, &sfinfo))) { - pa_log(__FILE__": Failed to open file %s", fname); - goto finish; - } - - switch (sfinfo.format & SF_FORMAT_SUBMASK) { - case SF_FORMAT_PCM_16: - case SF_FORMAT_PCM_U8: - case SF_FORMAT_PCM_S8: - ss->format = PA_SAMPLE_S16NE; - readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_short; - break; - - case SF_FORMAT_ULAW: - ss->format = PA_SAMPLE_ULAW; - break; - - case SF_FORMAT_ALAW: - ss->format = PA_SAMPLE_ALAW; - break; - - case SF_FORMAT_FLOAT: - case SF_FORMAT_DOUBLE: - default: - ss->format = PA_SAMPLE_FLOAT32NE; - readf_function = (sf_count_t (*)(SNDFILE *sndfile, void *ptr, sf_count_t frames)) sf_readf_float; - break; - } - - ss->rate = sfinfo.samplerate; - ss->channels = sfinfo.channels; - - if (!pa_sample_spec_valid(ss)) { - pa_log(__FILE__": Unsupported sample format in file %s", fname); - goto finish; - } - - if (map) - pa_channel_map_init_auto(map, ss->channels, PA_CHANNEL_MAP_DEFAULT); - - if ((l = pa_frame_size(ss)*sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { - pa_log(__FILE__": File too large"); - goto finish; - } - - chunk->memblock = pa_memblock_new(l, s); - assert(chunk->memblock); - chunk->index = 0; - chunk->length = l; - - if ((readf_function && readf_function(sf, chunk->memblock->data, sfinfo.frames) != sfinfo.frames) || - (!readf_function && sf_read_raw(sf, chunk->memblock->data, l) != l)) { - pa_log(__FILE__": Premature file end"); - goto finish; - } - - ret = 0; - -finish: - - if (sf) - sf_close(sf); - - if (ret != 0 && chunk->memblock) - pa_memblock_unref(chunk->memblock); - - return ret; - -} - -int pa_sound_file_too_big_to_cache(const char *fname) { - SNDFILE*sf = NULL; - SF_INFO sfinfo; - pa_sample_spec ss; - - if (!(sf = sf_open(fname, SFM_READ, &sfinfo))) { - pa_log(__FILE__": Failed to open file %s", fname); - return 0; - } - - sf_close(sf); - - switch (sfinfo.format & SF_FORMAT_SUBMASK) { - case SF_FORMAT_PCM_16: - case SF_FORMAT_PCM_U8: - case SF_FORMAT_PCM_S8: - ss.format = PA_SAMPLE_S16NE; - break; - - case SF_FORMAT_ULAW: - ss.format = PA_SAMPLE_ULAW; - break; - - case SF_FORMAT_ALAW: - ss.format = PA_SAMPLE_ALAW; - break; - - case SF_FORMAT_DOUBLE: - case SF_FORMAT_FLOAT: - default: - ss.format = PA_SAMPLE_FLOAT32NE; - break; - } - - ss.rate = sfinfo.samplerate; - ss.channels = sfinfo.channels; - - if ((pa_frame_size(&ss) * sfinfo.frames) > PA_SCACHE_ENTRY_SIZE_MAX) { - pa_log(__FILE__": File too large %s", fname); - return 1; - } - - return 0; -} diff --git a/src/polypcore/sound-file.h b/src/polypcore/sound-file.h deleted file mode 100644 index 9d687f90..00000000 --- a/src/polypcore/sound-file.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef soundfilehfoo -#define soundfilehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polyp/sample.h> -#include <polyp/channelmap.h> -#include <polypcore/memchunk.h> - -int pa_sound_file_load(const char *fname, pa_sample_spec *ss, pa_channel_map *map, pa_memchunk *chunk, pa_memblock_stat *s); - -int pa_sound_file_too_big_to_cache(const char *fname); - -#endif diff --git a/src/polypcore/source-output.c b/src/polypcore/source-output.c deleted file mode 100644 index 8ac3a33d..00000000 --- a/src/polypcore/source-output.c +++ /dev/null @@ -1,241 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/utf8.h> -#include <polyp/xmalloc.h> - -#include <polypcore/core-subscribe.h> -#include <polypcore/log.h> - -#include "source-output.h" - -#define CHECK_VALIDITY_RETURN_NULL(condition) \ -do {\ -if (!(condition)) \ - return NULL; \ -} while (0) - -pa_source_output* pa_source_output_new( - pa_source *s, - const char *driver, - const char *name, - const pa_sample_spec *spec, - const pa_channel_map *map, - int resample_method) { - - pa_source_output *o; - pa_resampler *resampler = NULL; - int r; - char st[256]; - pa_channel_map tmap; - - assert(s); - assert(spec); - assert(s->state == PA_SOURCE_RUNNING); - - CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec)); - - if (!map) - map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT); - - CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map)); - CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels); - CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver)); - CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name)); - - if (pa_idxset_size(s->outputs) >= PA_MAX_OUTPUTS_PER_SOURCE) { - pa_log(__FILE__": Failed to create source output: too many outputs per source."); - return NULL; - } - - if (resample_method == PA_RESAMPLER_INVALID) - resample_method = s->core->resample_method; - - if (!pa_sample_spec_equal(&s->sample_spec, spec) || !pa_channel_map_equal(&s->channel_map, map)) - if (!(resampler = pa_resampler_new(&s->sample_spec, &s->channel_map, spec, map, s->core->memblock_stat, resample_method))) - return NULL; - - o = pa_xnew(pa_source_output, 1); - o->ref = 1; - o->state = PA_SOURCE_OUTPUT_RUNNING; - o->name = pa_xstrdup(name); - o->driver = pa_xstrdup(driver); - o->owner = NULL; - o->source = s; - o->client = NULL; - - o->sample_spec = *spec; - o->channel_map = *map; - - o->push = NULL; - o->kill = NULL; - o->get_latency = NULL; - o->userdata = NULL; - - o->resampler = resampler; - - assert(s->core); - r = pa_idxset_put(s->core->source_outputs, o, &o->index); - assert(r == 0 && o->index != PA_IDXSET_INVALID); - r = pa_idxset_put(s->outputs, o, NULL); - assert(r == 0); - - pa_sample_spec_snprint(st, sizeof(st), spec); - pa_log_info(__FILE__": created %u \"%s\" on %u with sample spec \"%s\"", o->index, o->name, s->index, st); - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_NEW, o->index); - - return o; -} - -void pa_source_output_disconnect(pa_source_output*o) { - assert(o); - assert(o->state != PA_SOURCE_OUTPUT_DISCONNECTED); - assert(o->source); - assert(o->source->core); - - pa_idxset_remove_by_data(o->source->core->source_outputs, o, NULL); - pa_idxset_remove_by_data(o->source->outputs, o, NULL); - - pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_REMOVE, o->index); - o->source = NULL; - - o->push = NULL; - o->kill = NULL; - o->get_latency = NULL; - - o->state = PA_SOURCE_OUTPUT_DISCONNECTED; -} - -static void source_output_free(pa_source_output* o) { - assert(o); - - if (o->state != PA_SOURCE_OUTPUT_DISCONNECTED) - pa_source_output_disconnect(o); - - pa_log_info(__FILE__": freed %u \"%s\"", o->index, o->name); - - if (o->resampler) - pa_resampler_free(o->resampler); - - pa_xfree(o->name); - pa_xfree(o->driver); - pa_xfree(o); -} - -void pa_source_output_unref(pa_source_output* o) { - assert(o); - assert(o->ref >= 1); - - if (!(--o->ref)) - source_output_free(o); -} - -pa_source_output* pa_source_output_ref(pa_source_output *o) { - assert(o); - assert(o->ref >= 1); - - o->ref++; - return o; -} - - -void pa_source_output_kill(pa_source_output*o) { - assert(o); - assert(o->ref >= 1); - - if (o->kill) - o->kill(o); -} - -void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk) { - pa_memchunk rchunk; - - assert(o); - assert(chunk); - assert(chunk->length); - assert(o->push); - - if (o->state == PA_SOURCE_OUTPUT_CORKED) - return; - - if (!o->resampler) { - o->push(o, chunk); - return; - } - - pa_resampler_run(o->resampler, chunk, &rchunk); - if (!rchunk.length) - return; - - assert(rchunk.memblock); - o->push(o, &rchunk); - pa_memblock_unref(rchunk.memblock); -} - -void pa_source_output_set_name(pa_source_output *o, const char *name) { - assert(o); - assert(o->ref >= 1); - - pa_xfree(o->name); - o->name = pa_xstrdup(name); - - pa_subscription_post(o->source->core, PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT|PA_SUBSCRIPTION_EVENT_CHANGE, o->index); -} - -pa_usec_t pa_source_output_get_latency(pa_source_output *o) { - assert(o); - assert(o->ref >= 1); - - if (o->get_latency) - return o->get_latency(o); - - return 0; -} - -void pa_source_output_cork(pa_source_output *o, int b) { - assert(o); - assert(o->ref >= 1); - - if (o->state == PA_SOURCE_OUTPUT_DISCONNECTED) - return; - - o->state = b ? PA_SOURCE_OUTPUT_CORKED : PA_SOURCE_OUTPUT_RUNNING; -} - -pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o) { - assert(o); - assert(o->ref >= 1); - - if (!o->resampler) - return PA_RESAMPLER_INVALID; - - return pa_resampler_get_method(o->resampler); -} diff --git a/src/polypcore/source-output.h b/src/polypcore/source-output.h deleted file mode 100644 index 1c612052..00000000 --- a/src/polypcore/source-output.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef foosourceoutputhfoo -#define foosourceoutputhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> - -typedef struct pa_source_output pa_source_output; - -#include <polyp/sample.h> -#include <polypcore/source.h> -#include <polypcore/memblockq.h> -#include <polypcore/resampler.h> -#include <polypcore/module.h> -#include <polypcore/client.h> - -typedef enum { - PA_SOURCE_OUTPUT_RUNNING, - PA_SOURCE_OUTPUT_CORKED, - PA_SOURCE_OUTPUT_DISCONNECTED -} pa_source_output_state_t; - -struct pa_source_output { - int ref; - uint32_t index; - pa_source_output_state_t state; - - char *name, *driver; - pa_module *owner; - - pa_source *source; - pa_client *client; - - pa_sample_spec sample_spec; - pa_channel_map channel_map; - - void (*push)(pa_source_output *o, const pa_memchunk *chunk); - void (*kill)(pa_source_output* o); - pa_usec_t (*get_latency) (pa_source_output *o); - - pa_resampler* resampler; - - void *userdata; -}; - -pa_source_output* pa_source_output_new( - pa_source *s, - const char *driver, - const char *name, - const pa_sample_spec *spec, - const pa_channel_map *map, - int resample_method); - -void pa_source_output_unref(pa_source_output* o); -pa_source_output* pa_source_output_ref(pa_source_output *o); - -/* To be called by the implementing module only */ -void pa_source_output_disconnect(pa_source_output*o); - -/* External code may request disconnection with this funcion */ -void pa_source_output_kill(pa_source_output*o); - -void pa_source_output_push(pa_source_output *o, const pa_memchunk *chunk); - -void pa_source_output_set_name(pa_source_output *i, const char *name); - -pa_usec_t pa_source_output_get_latency(pa_source_output *i); - -void pa_source_output_cork(pa_source_output *i, int b); - -pa_resample_method_t pa_source_output_get_resample_method(pa_source_output *o); - -#endif diff --git a/src/polypcore/source.c b/src/polypcore/source.c deleted file mode 100644 index c53bf079..00000000 --- a/src/polypcore/source.c +++ /dev/null @@ -1,313 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdio.h> -#include <assert.h> -#include <stdlib.h> -#include <string.h> - -#include <polyp/utf8.h> -#include <polyp/xmalloc.h> - -#include <polypcore/source-output.h> -#include <polypcore/namereg.h> -#include <polypcore/core-subscribe.h> -#include <polypcore/log.h> -#include <polypcore/sample-util.h> - -#include "source.h" - -#define CHECK_VALIDITY_RETURN_NULL(condition) \ -do {\ -if (!(condition)) \ - return NULL; \ -} while (0) - -pa_source* pa_source_new( - pa_core *core, - const char *driver, - const char *name, - int fail, - const pa_sample_spec *spec, - const pa_channel_map *map) { - - pa_source *s; - char st[256]; - int r; - pa_channel_map tmap; - - assert(core); - assert(name); - assert(spec); - - CHECK_VALIDITY_RETURN_NULL(pa_sample_spec_valid(spec)); - - if (!map) - map = pa_channel_map_init_auto(&tmap, spec->channels, PA_CHANNEL_MAP_DEFAULT); - - CHECK_VALIDITY_RETURN_NULL(map && pa_channel_map_valid(map)); - CHECK_VALIDITY_RETURN_NULL(map->channels == spec->channels); - CHECK_VALIDITY_RETURN_NULL(!driver || pa_utf8_valid(driver)); - CHECK_VALIDITY_RETURN_NULL(pa_utf8_valid(name) && *name); - - s = pa_xnew(pa_source, 1); - - if (!(name = pa_namereg_register(core, name, PA_NAMEREG_SOURCE, s, fail))) { - pa_xfree(s); - return NULL; - } - - s->ref = 1; - s->core = core; - s->state = PA_SOURCE_RUNNING; - s->name = pa_xstrdup(name); - s->description = NULL; - s->driver = pa_xstrdup(driver); - s->owner = NULL; - - s->sample_spec = *spec; - s->channel_map = *map; - - s->outputs = pa_idxset_new(NULL, NULL); - s->monitor_of = NULL; - - pa_cvolume_reset(&s->sw_volume, spec->channels); - pa_cvolume_reset(&s->hw_volume, spec->channels); - s->sw_muted = 0; - s->hw_muted = 0; - - s->get_latency = NULL; - s->notify = NULL; - s->set_hw_volume = NULL; - s->get_hw_volume = NULL; - s->set_hw_mute = NULL; - s->get_hw_mute = NULL; - s->userdata = NULL; - - r = pa_idxset_put(core->sources, s, &s->index); - assert(s->index != PA_IDXSET_INVALID && r >= 0); - - pa_sample_spec_snprint(st, sizeof(st), spec); - pa_log_info(__FILE__": created %u \"%s\" with sample spec \"%s\"", s->index, s->name, st); - - pa_subscription_post(core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_NEW, s->index); - - return s; -} - -void pa_source_disconnect(pa_source *s) { - pa_source_output *o, *j = NULL; - - assert(s); - assert(s->state == PA_SOURCE_RUNNING); - - pa_namereg_unregister(s->core, s->name); - - while ((o = pa_idxset_first(s->outputs, NULL))) { - assert(o != j); - pa_source_output_kill(o); - j = o; - } - - pa_idxset_remove_by_data(s->core->sources, s, NULL); - - s->get_latency = NULL; - s->notify = NULL; - s->get_hw_volume = NULL; - s->set_hw_volume = NULL; - s->set_hw_mute = NULL; - s->get_hw_mute = NULL; - - s->state = PA_SOURCE_DISCONNECTED; - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE | PA_SUBSCRIPTION_EVENT_REMOVE, s->index); -} - -static void source_free(pa_source *s) { - assert(s); - assert(!s->ref); - - if (s->state != PA_SOURCE_DISCONNECTED) - pa_source_disconnect(s); - - pa_log_info(__FILE__": freed %u \"%s\"", s->index, s->name); - - pa_idxset_free(s->outputs, NULL, NULL); - - pa_xfree(s->name); - pa_xfree(s->description); - pa_xfree(s->driver); - pa_xfree(s); -} - -void pa_source_unref(pa_source *s) { - assert(s); - assert(s->ref >= 1); - - if (!(--s->ref)) - source_free(s); -} - -pa_source* pa_source_ref(pa_source *s) { - assert(s); - assert(s->ref >= 1); - - s->ref++; - return s; -} - -void pa_source_notify(pa_source*s) { - assert(s); - assert(s->ref >= 1); - - if (s->notify) - s->notify(s); -} - -static int do_post(void *p, PA_GCC_UNUSED uint32_t idx, PA_GCC_UNUSED int *del, void*userdata) { - pa_source_output *o = p; - const pa_memchunk *chunk = userdata; - - assert(o); - assert(chunk); - - pa_source_output_push(o, chunk); - return 0; -} - -void pa_source_post(pa_source*s, const pa_memchunk *chunk) { - assert(s); - assert(s->ref >= 1); - assert(chunk); - - pa_source_ref(s); - - if (s->sw_muted || !pa_cvolume_is_norm(&s->sw_volume)) { - pa_memchunk vchunk = *chunk; - - pa_memblock_ref(vchunk.memblock); - pa_memchunk_make_writable(&vchunk, s->core->memblock_stat, 0); - if (s->sw_muted) - pa_silence_memchunk(&vchunk, &s->sample_spec); - else - pa_volume_memchunk(&vchunk, &s->sample_spec, &s->sw_volume); - pa_idxset_foreach(s->outputs, do_post, &vchunk); - pa_memblock_unref(vchunk.memblock); - } else - pa_idxset_foreach(s->outputs, do_post, (void*) chunk); - - pa_source_unref(s); -} - -void pa_source_set_owner(pa_source *s, pa_module *m) { - assert(s); - assert(s->ref >= 1); - - s->owner = m; -} - -pa_usec_t pa_source_get_latency(pa_source *s) { - assert(s); - assert(s->ref >= 1); - - if (!s->get_latency) - return 0; - - return s->get_latency(s); -} - -void pa_source_set_volume(pa_source *s, pa_mixer_t m, const pa_cvolume *volume) { - pa_cvolume *v; - - assert(s); - assert(s->ref >= 1); - assert(volume); - - if (m == PA_MIXER_HARDWARE && s->set_hw_volume) - v = &s->hw_volume; - else - v = &s->sw_volume; - - if (pa_cvolume_equal(v, volume)) - return; - - *v = *volume; - - if (v == &s->hw_volume) - if (s->set_hw_volume(s) < 0) - s->sw_volume = *volume; - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); -} - -const pa_cvolume *pa_source_get_volume(pa_source *s, pa_mixer_t m) { - assert(s); - assert(s->ref >= 1); - - if (m == PA_MIXER_HARDWARE && s->set_hw_volume) { - - if (s->get_hw_volume) - s->get_hw_volume(s); - - return &s->hw_volume; - } else - return &s->sw_volume; -} - -void pa_source_set_mute(pa_source *s, pa_mixer_t m, int mute) { - int *t; - - assert(s); - assert(s->ref >= 1); - - if (m == PA_MIXER_HARDWARE && s->set_hw_mute) - t = &s->hw_muted; - else - t = &s->sw_muted; - - if (!!*t == !!mute) - return; - - *t = !!mute; - - if (t == &s->hw_muted) - if (s->set_hw_mute(s) < 0) - s->sw_muted = !!mute; - - pa_subscription_post(s->core, PA_SUBSCRIPTION_EVENT_SOURCE|PA_SUBSCRIPTION_EVENT_CHANGE, s->index); -} - -int pa_source_get_mute(pa_source *s, pa_mixer_t m) { - assert(s); - assert(s->ref >= 1); - - if (m == PA_MIXER_HARDWARE && s->set_hw_mute) { - - if (s->get_hw_mute) - s->get_hw_mute(s); - - return s->hw_muted; - } else - return s->sw_muted; -} diff --git a/src/polypcore/source.h b/src/polypcore/source.h deleted file mode 100644 index 63b77624..00000000 --- a/src/polypcore/source.h +++ /dev/null @@ -1,101 +0,0 @@ -#ifndef foosourcehfoo -#define foosourcehfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef struct pa_source pa_source; - -#include <inttypes.h> - -#include <polyp/sample.h> -#include <polyp/channelmap.h> -#include <polyp/volume.h> -#include <polypcore/core-def.h> -#include <polypcore/core.h> -#include <polypcore/idxset.h> -#include <polypcore/memblock.h> -#include <polypcore/memchunk.h> -#include <polypcore/sink.h> -#include <polypcore/module.h> - -#define PA_MAX_OUTPUTS_PER_SOURCE 16 - -typedef enum pa_source_state { - PA_SOURCE_RUNNING, - PA_SOURCE_DISCONNECTED -} pa_source_state_t; - -struct pa_source { - int ref; - uint32_t index; - pa_core *core; - pa_source_state_t state; - - char *name, *description, *driver; - pa_module *owner; - - pa_sample_spec sample_spec; - pa_channel_map channel_map; - - pa_idxset *outputs; - pa_sink *monitor_of; - - pa_cvolume hw_volume, sw_volume; - int hw_muted, sw_muted; - - void (*notify)(pa_source*source); - pa_usec_t (*get_latency)(pa_source *s); - int (*set_hw_volume)(pa_source *s); - int (*get_hw_volume)(pa_source *s); - int (*set_hw_mute)(pa_source *s); - int (*get_hw_mute)(pa_source *s); - - void *userdata; -}; - -pa_source* pa_source_new( - pa_core *core, - const char *driver, - const char *name, - int namereg_fail, - const pa_sample_spec *spec, - const pa_channel_map *map); - -void pa_source_disconnect(pa_source *s); -void pa_source_unref(pa_source *s); -pa_source* pa_source_ref(pa_source *c); - -/* Pass a new memory block to all output streams */ -void pa_source_post(pa_source*s, const pa_memchunk *b); - -void pa_source_notify(pa_source *s); - -void pa_source_set_owner(pa_source *s, pa_module *m); - -pa_usec_t pa_source_get_latency(pa_source *s); - -void pa_source_set_volume(pa_source *source, pa_mixer_t m, const pa_cvolume *volume); -const pa_cvolume *pa_source_get_volume(pa_source *source, pa_mixer_t m); -void pa_source_set_mute(pa_source *source, pa_mixer_t m, int mute); -int pa_source_get_mute(pa_source *source, pa_mixer_t m); - -#endif diff --git a/src/polypcore/strbuf.c b/src/polypcore/strbuf.c deleted file mode 100644 index d1517a11..00000000 --- a/src/polypcore/strbuf.c +++ /dev/null @@ -1,167 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <sys/types.h> -#include <stdlib.h> -#include <assert.h> -#include <string.h> -#include <stdarg.h> -#include <stdio.h> - -#include <polyp/xmalloc.h> - -#include "strbuf.h" - -/* A chunk of the linked list that makes up the string */ -struct chunk { - struct chunk *next; - size_t length; -}; - -#define CHUNK_TO_TEXT(c) ((char*) (c) + sizeof(struct chunk)) - -struct pa_strbuf { - size_t length; - struct chunk *head, *tail; -}; - -pa_strbuf *pa_strbuf_new(void) { - pa_strbuf *sb = pa_xmalloc(sizeof(pa_strbuf)); - sb->length = 0; - sb->head = sb->tail = NULL; - return sb; -} - -void pa_strbuf_free(pa_strbuf *sb) { - assert(sb); - while (sb->head) { - struct chunk *c = sb->head; - sb->head = sb->head->next; - pa_xfree(c); - } - - pa_xfree(sb); -} - -/* Make a C string from the string buffer. The caller has to free - * string with pa_xfree(). */ -char *pa_strbuf_tostring(pa_strbuf *sb) { - char *t, *e; - struct chunk *c; - assert(sb); - - e = t = pa_xmalloc(sb->length+1); - - for (c = sb->head; c; c = c->next) { - assert((size_t) (e-t) <= sb->length); - memcpy(e, CHUNK_TO_TEXT(c), c->length); - e += c->length; - } - - /* Trailing NUL */ - *e = 0; - - assert(e == t+sb->length); - - return t; -} - -/* Combination of pa_strbuf_free() and pa_strbuf_tostring() */ -char *pa_strbuf_tostring_free(pa_strbuf *sb) { - char *t; - assert(sb); - t = pa_strbuf_tostring(sb); - pa_strbuf_free(sb); - return t; -} - -/* Append a string to the string buffer */ -void pa_strbuf_puts(pa_strbuf *sb, const char *t) { - assert(sb && t); - pa_strbuf_putsn(sb, t, strlen(t)); -} - -/* Append a new chunk to the linked list */ -static void append(pa_strbuf *sb, struct chunk *c) { - assert(sb && c); - - if (sb->tail) { - assert(sb->head); - sb->tail->next = c; - } else { - assert(!sb->head); - sb->head = c; - } - - sb->tail = c; - sb->length += c->length; - c->next = NULL; -} - -/* Append up to l bytes of a string to the string buffer */ -void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t l) { - struct chunk *c; - assert(sb && t); - - if (!l) - return; - - c = pa_xmalloc(sizeof(struct chunk)+l); - c->length = l; - memcpy(CHUNK_TO_TEXT(c), t, l); - - append(sb, c); -} - -/* Append a printf() style formatted string to the string buffer. */ -/* The following is based on an example from the GNU libc documentation */ -int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) { - int size = 100; - struct chunk *c = NULL; - - assert(sb); - - for(;;) { - va_list ap; - int r; - - c = pa_xrealloc(c, sizeof(struct chunk)+size); - - va_start(ap, format); - r = vsnprintf(CHUNK_TO_TEXT(c), size, format, ap); - va_end(ap); - - if (r > -1 && r < size) { - c->length = r; - append(sb, c); - return r; - } - - if (r > -1) /* glibc 2.1 */ - size = r+1; - else /* glibc 2.0 */ - size *= 2; - } -} diff --git a/src/polypcore/strbuf.h b/src/polypcore/strbuf.h deleted file mode 100644 index 4b06a7e6..00000000 --- a/src/polypcore/strbuf.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef foostrbufhfoo -#define foostrbufhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <polypcore/gccmacro.h> - -typedef struct pa_strbuf pa_strbuf; - -pa_strbuf *pa_strbuf_new(void); -void pa_strbuf_free(pa_strbuf *sb); -char *pa_strbuf_tostring(pa_strbuf *sb); -char *pa_strbuf_tostring_free(pa_strbuf *sb); - -int pa_strbuf_printf(pa_strbuf *sb, const char *format, ...) PA_GCC_PRINTF_ATTR(2,3); -void pa_strbuf_puts(pa_strbuf *sb, const char *t); -void pa_strbuf_putsn(pa_strbuf *sb, const char *t, size_t m); - -#endif diff --git a/src/polypcore/strlist.c b/src/polypcore/strlist.c deleted file mode 100644 index b9420749..00000000 --- a/src/polypcore/strlist.c +++ /dev/null @@ -1,139 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <assert.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/strbuf.h> -#include <polypcore/core-util.h> - -#include "strlist.h" - -struct pa_strlist { - pa_strlist *next; - char *str; -}; - -pa_strlist* pa_strlist_prepend(pa_strlist *l, const char *s) { - pa_strlist *n; - assert(s); - n = pa_xmalloc(sizeof(pa_strlist)); - n->str = pa_xstrdup(s); - n->next = l; - return n; -} - -char *pa_strlist_tostring(pa_strlist *l) { - int first = 1; - pa_strbuf *b; - - b = pa_strbuf_new(); - for (; l; l = l->next) { - if (!first) - pa_strbuf_puts(b, " "); - first = 0; - pa_strbuf_puts(b, l->str); - } - - return pa_strbuf_tostring_free(b); -} - -pa_strlist* pa_strlist_remove(pa_strlist *l, const char *s) { - pa_strlist *ret = l, *prev = NULL; - assert(l && s); - - while (l) { - if (!strcmp(l->str, s)) { - pa_strlist *n = l->next; - - if (!prev) { - assert(ret == l); - ret = n; - } else - prev->next = n; - - pa_xfree(l->str); - pa_xfree(l); - - l = n; - - } else { - prev = l; - l = l->next; - } - } - - return ret; -} - -void pa_strlist_free(pa_strlist *l) { - while (l) { - pa_strlist *c = l; - l = l->next; - - pa_xfree(c->str); - pa_xfree(c); - } -} - -pa_strlist* pa_strlist_pop(pa_strlist *l, char **s) { - pa_strlist *r; - assert(s); - - if (!l) { - *s = NULL; - return NULL; - } - - *s = l->str; - r = l->next; - pa_xfree(l); - return r; -} - -pa_strlist* pa_strlist_parse(const char *s) { - pa_strlist *head = NULL, *p = NULL; - const char *state = NULL; - char *r; - - while ((r = pa_split_spaces(s, &state))) { - pa_strlist *n; - - n = pa_xmalloc(sizeof(pa_strlist)); - n->str = r; - n->next = NULL; - - if (p) - p->next = n; - else - head = n; - - p = n; - } - - return head; -} diff --git a/src/polypcore/strlist.h b/src/polypcore/strlist.h deleted file mode 100644 index 2c54dc74..00000000 --- a/src/polypcore/strlist.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef foostrlisthfoo -#define foostrlisthfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef struct pa_strlist pa_strlist; - -/* Add the specified server string to the list, return the new linked list head */ -pa_strlist* pa_strlist_prepend(pa_strlist *l, const char *s); - -/* Remove the specified string from the list, return the new linked list head */ -pa_strlist* pa_strlist_remove(pa_strlist *l, const char *s); - -/* Make a whitespace separated string of all server stringes. Returned memory has to be freed with pa_xfree() */ -char *pa_strlist_tostring(pa_strlist *l); - -/* Free the entire list */ -void pa_strlist_free(pa_strlist *l); - -/* Return the next entry in the list in *string and remove it from - * the list. Returns the new list head. The memory *string points to - * has to be freed with pa_xfree() */ -pa_strlist* pa_strlist_pop(pa_strlist *l, char **s); - -/* Parse a whitespace separated server list */ -pa_strlist* pa_strlist_parse(const char *s); - -#endif diff --git a/src/polypcore/tagstruct.c b/src/polypcore/tagstruct.c deleted file mode 100644 index 27582cae..00000000 --- a/src/polypcore/tagstruct.c +++ /dev/null @@ -1,630 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <sys/time.h> -#include <assert.h> -#include <stdarg.h> - -#ifdef HAVE_NETINET_IN_H -#include <netinet/in.h> -#endif - -#include "winsock.h" - -#include <polyp/xmalloc.h> - -#include "tagstruct.h" - - -struct pa_tagstruct { - uint8_t *data; - size_t length, allocated; - size_t rindex; - - int dynamic; -}; - -pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length) { - pa_tagstruct*t; - - assert(!data || (data && length)); - - t = pa_xmalloc(sizeof(pa_tagstruct)); - t->data = (uint8_t*) data; - t->allocated = t->length = data ? length : 0; - t->rindex = 0; - t->dynamic = !data; - return t; -} - -void pa_tagstruct_free(pa_tagstruct*t) { - assert(t); - if (t->dynamic) - pa_xfree(t->data); - pa_xfree(t); -} - -uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l) { - uint8_t *p; - assert(t && t->dynamic && l); - p = t->data; - *l = t->length; - pa_xfree(t); - return p; -} - -static void extend(pa_tagstruct*t, size_t l) { - assert(t && t->dynamic); - - if (t->length+l <= t->allocated) - return; - - t->data = pa_xrealloc(t->data, t->allocated = t->length+l+100); -} - - -void pa_tagstruct_puts(pa_tagstruct*t, const char *s) { - size_t l; - assert(t); - if (s) { - l = strlen(s)+2; - extend(t, l); - t->data[t->length] = PA_TAG_STRING; - strcpy((char*) (t->data+t->length+1), s); - t->length += l; - } else { - extend(t, 1); - t->data[t->length] = PA_TAG_STRING_NULL; - t->length += 1; - } -} - -void pa_tagstruct_putu32(pa_tagstruct*t, uint32_t i) { - assert(t); - extend(t, 5); - t->data[t->length] = PA_TAG_U32; - i = htonl(i); - memcpy(t->data+t->length+1, &i, 4); - t->length += 5; -} - -void pa_tagstruct_putu8(pa_tagstruct*t, uint8_t c) { - assert(t); - extend(t, 2); - t->data[t->length] = PA_TAG_U8; - *(t->data+t->length+1) = c; - t->length += 2; -} - -void pa_tagstruct_put_sample_spec(pa_tagstruct *t, const pa_sample_spec *ss) { - uint32_t rate; - assert(t && ss); - extend(t, 7); - t->data[t->length] = PA_TAG_SAMPLE_SPEC; - t->data[t->length+1] = (uint8_t) ss->format; - t->data[t->length+2] = ss->channels; - rate = htonl(ss->rate); - memcpy(t->data+t->length+3, &rate, 4); - t->length += 7; -} - -void pa_tagstruct_put_arbitrary(pa_tagstruct *t, const void *p, size_t length) { - uint32_t tmp; - assert(t && p); - - extend(t, 5+length); - t->data[t->length] = PA_TAG_ARBITRARY; - tmp = htonl(length); - memcpy(t->data+t->length+1, &tmp, 4); - if (length) - memcpy(t->data+t->length+5, p, length); - t->length += 5+length; -} - -void pa_tagstruct_put_boolean(pa_tagstruct*t, int b) { - assert(t); - extend(t, 1); - t->data[t->length] = b ? PA_TAG_BOOLEAN_TRUE : PA_TAG_BOOLEAN_FALSE; - t->length += 1; -} - -void pa_tagstruct_put_timeval(pa_tagstruct*t, const struct timeval *tv) { - uint32_t tmp; - assert(t); - extend(t, 9); - t->data[t->length] = PA_TAG_TIMEVAL; - tmp = htonl(tv->tv_sec); - memcpy(t->data+t->length+1, &tmp, 4); - tmp = htonl(tv->tv_usec); - memcpy(t->data+t->length+5, &tmp, 4); - t->length += 9; -} - -void pa_tagstruct_put_usec(pa_tagstruct*t, pa_usec_t u) { - uint32_t tmp; - assert(t); - extend(t, 9); - t->data[t->length] = PA_TAG_USEC; - tmp = htonl((uint32_t) (u >> 32)); - memcpy(t->data+t->length+1, &tmp, 4); - tmp = htonl((uint32_t) u); - memcpy(t->data+t->length+5, &tmp, 4); - t->length += 9; -} - -void pa_tagstruct_putu64(pa_tagstruct*t, uint64_t u) { - uint32_t tmp; - assert(t); - extend(t, 9); - t->data[t->length] = PA_TAG_U64; - tmp = htonl((uint32_t) (u >> 32)); - memcpy(t->data+t->length+1, &tmp, 4); - tmp = htonl((uint32_t) u); - memcpy(t->data+t->length+5, &tmp, 4); - t->length += 9; -} - -void pa_tagstruct_puts64(pa_tagstruct*t, int64_t u) { - uint32_t tmp; - assert(t); - extend(t, 9); - t->data[t->length] = PA_TAG_S64; - tmp = htonl((uint32_t) ((uint64_t) u >> 32)); - memcpy(t->data+t->length+1, &tmp, 4); - tmp = htonl((uint32_t) ((uint64_t) u)); - memcpy(t->data+t->length+5, &tmp, 4); - t->length += 9; -} - -void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map) { - unsigned i; - - assert(t); - extend(t, 2 + map->channels); - - t->data[t->length++] = PA_TAG_CHANNEL_MAP; - t->data[t->length++] = map->channels; - - for (i = 0; i < map->channels; i ++) - t->data[t->length++] = (uint8_t) map->map[i]; -} - -void pa_tagstruct_put_cvolume(pa_tagstruct *t, const pa_cvolume *cvolume) { - unsigned i; - pa_volume_t vol; - - assert(t); - extend(t, 2 + cvolume->channels * sizeof(pa_volume_t)); - - t->data[t->length++] = PA_TAG_CVOLUME; - t->data[t->length++] = cvolume->channels; - - for (i = 0; i < cvolume->channels; i ++) { - vol = htonl(cvolume->values[i]); - memcpy(t->data + t->length, &vol, sizeof(pa_volume_t)); - t->length += sizeof(pa_volume_t); - } -} - -int pa_tagstruct_gets(pa_tagstruct*t, const char **s) { - int error = 0; - size_t n; - char *c; - assert(t && s); - - if (t->rindex+1 > t->length) - return -1; - - if (t->data[t->rindex] == PA_TAG_STRING_NULL) { - t->rindex++; - *s = NULL; - return 0; - } - - if (t->rindex+2 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_STRING) - return -1; - - error = 1; - for (n = 0, c = (char*) (t->data+t->rindex+1); t->rindex+1+n < t->length; n++, c++) - if (!*c) { - error = 0; - break; - } - - if (error) - return -1; - - *s = (char*) (t->data+t->rindex+1); - - t->rindex += n+2; - return 0; -} - -int pa_tagstruct_getu32(pa_tagstruct*t, uint32_t *i) { - assert(t && i); - - if (t->rindex+5 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_U32) - return -1; - - memcpy(i, t->data+t->rindex+1, 4); - *i = ntohl(*i); - t->rindex += 5; - return 0; -} - -int pa_tagstruct_getu8(pa_tagstruct*t, uint8_t *c) { - assert(t && c); - - if (t->rindex+2 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_U8) - return -1; - - *c = t->data[t->rindex+1]; - t->rindex +=2; - return 0; -} - -int pa_tagstruct_get_sample_spec(pa_tagstruct *t, pa_sample_spec *ss) { - assert(t && ss); - - if (t->rindex+7 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_SAMPLE_SPEC) - return -1; - - ss->format = t->data[t->rindex+1]; - ss->channels = t->data[t->rindex+2]; - memcpy(&ss->rate, t->data+t->rindex+3, 4); - ss->rate = ntohl(ss->rate); - - t->rindex += 7; - return 0; -} - -int pa_tagstruct_get_arbitrary(pa_tagstruct *t, const void **p, size_t length) { - uint32_t len; - assert(t && p); - - if (t->rindex+5+length > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_ARBITRARY) - return -1; - - memcpy(&len, t->data+t->rindex+1, 4); - if (ntohl(len) != length) - return -1; - - *p = t->data+t->rindex+5; - t->rindex += 5+length; - return 0; -} - -int pa_tagstruct_eof(pa_tagstruct*t) { - assert(t); - return t->rindex >= t->length; -} - -const uint8_t* pa_tagstruct_data(pa_tagstruct*t, size_t *l) { - assert(t && t->dynamic && l); - *l = t->length; - return t->data; -} - -int pa_tagstruct_get_boolean(pa_tagstruct*t, int *b) { - assert(t && b); - - if (t->rindex+1 > t->length) - return -1; - - if (t->data[t->rindex] == PA_TAG_BOOLEAN_TRUE) - *b = 1; - else if (t->data[t->rindex] == PA_TAG_BOOLEAN_FALSE) - *b = 0; - else - return -1; - - t->rindex +=1; - return 0; -} - -int pa_tagstruct_get_timeval(pa_tagstruct*t, struct timeval *tv) { - - if (t->rindex+9 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_TIMEVAL) - return -1; - - memcpy(&tv->tv_sec, t->data+t->rindex+1, 4); - tv->tv_sec = ntohl(tv->tv_sec); - memcpy(&tv->tv_usec, t->data+t->rindex+5, 4); - tv->tv_usec = ntohl(tv->tv_usec); - t->rindex += 9; - return 0; -} - -int pa_tagstruct_get_usec(pa_tagstruct*t, pa_usec_t *u) { - uint32_t tmp; - assert(t && u); - - if (t->rindex+9 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_USEC) - return -1; - - memcpy(&tmp, t->data+t->rindex+1, 4); - *u = (pa_usec_t) ntohl(tmp) << 32; - memcpy(&tmp, t->data+t->rindex+5, 4); - *u |= (pa_usec_t) ntohl(tmp); - t->rindex +=9; - return 0; -} - -int pa_tagstruct_getu64(pa_tagstruct*t, uint64_t *u) { - uint32_t tmp; - assert(t && u); - - if (t->rindex+9 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_U64) - return -1; - - memcpy(&tmp, t->data+t->rindex+1, 4); - *u = (uint64_t) ntohl(tmp) << 32; - memcpy(&tmp, t->data+t->rindex+5, 4); - *u |= (uint64_t) ntohl(tmp); - t->rindex +=9; - return 0; -} - -int pa_tagstruct_gets64(pa_tagstruct*t, int64_t *u) { - uint32_t tmp; - assert(t && u); - - if (t->rindex+9 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_S64) - return -1; - - memcpy(&tmp, t->data+t->rindex+1, 4); - *u = (int64_t) ((uint64_t) ntohl(tmp) << 32); - memcpy(&tmp, t->data+t->rindex+5, 4); - *u |= (int64_t) ntohl(tmp); - t->rindex +=9; - return 0; -} - -int pa_tagstruct_get_channel_map(pa_tagstruct *t, pa_channel_map *map) { - unsigned i; - - assert(t); - assert(map); - - if (t->rindex+2 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_CHANNEL_MAP) - return -1; - - if ((map->channels = t->data[t->rindex+1]) > PA_CHANNELS_MAX) - return -1; - - if (t->rindex+2+map->channels > t->length) - return -1; - - for (i = 0; i < map->channels; i ++) - map->map[i] = (int8_t) t->data[t->rindex + 2 + i]; - - t->rindex += 2 + map->channels; - return 0; -} - -int pa_tagstruct_get_cvolume(pa_tagstruct *t, pa_cvolume *cvolume) { - unsigned i; - pa_volume_t vol; - - assert(t); - assert(cvolume); - - if (t->rindex+2 > t->length) - return -1; - - if (t->data[t->rindex] != PA_TAG_CVOLUME) - return -1; - - if ((cvolume->channels = t->data[t->rindex+1]) > PA_CHANNELS_MAX) - return -1; - - if (t->rindex+2+cvolume->channels*sizeof(pa_volume_t) > t->length) - return -1; - - for (i = 0; i < cvolume->channels; i ++) { - memcpy(&vol, t->data + t->rindex + 2 + i * sizeof(pa_volume_t), sizeof(pa_volume_t)); - cvolume->values[i] = (pa_volume_t) ntohl(vol); - } - - t->rindex += 2 + cvolume->channels * sizeof(pa_volume_t); - return 0; -} - -void pa_tagstruct_put(pa_tagstruct *t, ...) { - va_list va; - assert(t); - - va_start(va, t); - - for (;;) { - int tag = va_arg(va, int); - - if (tag == PA_TAG_INVALID) - break; - - switch (tag) { - case PA_TAG_STRING: - case PA_TAG_STRING_NULL: - pa_tagstruct_puts(t, va_arg(va, char*)); - break; - - case PA_TAG_U32: - pa_tagstruct_putu32(t, va_arg(va, uint32_t)); - break; - - case PA_TAG_U8: - pa_tagstruct_putu8(t, (uint8_t) va_arg(va, int)); - break; - - case PA_TAG_U64: - pa_tagstruct_putu64(t, va_arg(va, uint64_t)); - break; - - case PA_TAG_SAMPLE_SPEC: - pa_tagstruct_put_sample_spec(t, va_arg(va, pa_sample_spec*)); - break; - - case PA_TAG_ARBITRARY: { - void *p = va_arg(va, void*); - size_t size = va_arg(va, size_t); - pa_tagstruct_put_arbitrary(t, p, size); - break; - } - - case PA_TAG_BOOLEAN_TRUE: - case PA_TAG_BOOLEAN_FALSE: - pa_tagstruct_put_boolean(t, va_arg(va, int)); - break; - - case PA_TAG_TIMEVAL: - pa_tagstruct_put_timeval(t, va_arg(va, struct timeval*)); - break; - - case PA_TAG_USEC: - pa_tagstruct_put_usec(t, va_arg(va, pa_usec_t)); - break; - - case PA_TAG_CHANNEL_MAP: - pa_tagstruct_put_channel_map(t, va_arg(va, pa_channel_map *)); - break; - - case PA_TAG_CVOLUME: - pa_tagstruct_put_cvolume(t, va_arg(va, pa_cvolume *)); - break; - - default: - abort(); - } - } - - va_end(va); -} - -int pa_tagstruct_get(pa_tagstruct *t, ...) { - va_list va; - int ret = 0; - - assert(t); - - va_start(va, t); - while (ret == 0) { - int tag = va_arg(va, int); - - if (tag == PA_TAG_INVALID) - break; - - switch (tag) { - case PA_TAG_STRING: - case PA_TAG_STRING_NULL: - ret = pa_tagstruct_gets(t, va_arg(va, const char**)); - break; - - case PA_TAG_U32: - ret = pa_tagstruct_getu32(t, va_arg(va, uint32_t*)); - break; - - case PA_TAG_U8: - ret = pa_tagstruct_getu8(t, va_arg(va, uint8_t*)); - break; - - case PA_TAG_U64: - ret = pa_tagstruct_getu64(t, va_arg(va, uint64_t*)); - break; - - case PA_TAG_SAMPLE_SPEC: - ret = pa_tagstruct_get_sample_spec(t, va_arg(va, pa_sample_spec*)); - break; - - case PA_TAG_ARBITRARY: { - const void **p = va_arg(va, const void**); - size_t size = va_arg(va, size_t); - ret = pa_tagstruct_get_arbitrary(t, p, size); - break; - } - - case PA_TAG_BOOLEAN_TRUE: - case PA_TAG_BOOLEAN_FALSE: - ret = pa_tagstruct_get_boolean(t, va_arg(va, int*)); - break; - - case PA_TAG_TIMEVAL: - ret = pa_tagstruct_get_timeval(t, va_arg(va, struct timeval*)); - break; - - case PA_TAG_USEC: - ret = pa_tagstruct_get_usec(t, va_arg(va, pa_usec_t*)); - break; - - case PA_TAG_CHANNEL_MAP: - ret = pa_tagstruct_get_channel_map(t, va_arg(va, pa_channel_map *)); - break; - - case PA_TAG_CVOLUME: - ret = pa_tagstruct_get_cvolume(t, va_arg(va, pa_cvolume *)); - break; - - - default: - abort(); - } - - } - - va_end(va); - return ret; -} diff --git a/src/polypcore/tagstruct.h b/src/polypcore/tagstruct.h deleted file mode 100644 index d5e6050b..00000000 --- a/src/polypcore/tagstruct.h +++ /dev/null @@ -1,93 +0,0 @@ -#ifndef footagstructhfoo -#define footagstructhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2.1 of the - License, or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <inttypes.h> -#include <sys/types.h> -#include <sys/time.h> -#include <time.h> - -#include <polyp/sample.h> -#include <polyp/channelmap.h> -#include <polyp/volume.h> - -typedef struct pa_tagstruct pa_tagstruct; - -enum { - PA_TAG_INVALID = 0, - PA_TAG_STRING = 't', - PA_TAG_STRING_NULL = 'N', - PA_TAG_U32 = 'L', - PA_TAG_U8 = 'B', - PA_TAG_U64 = 'R', - PA_TAG_S64 = 'r', - PA_TAG_SAMPLE_SPEC = 'a', - PA_TAG_ARBITRARY = 'x', - PA_TAG_BOOLEAN_TRUE = '1', - PA_TAG_BOOLEAN_FALSE = '0', - PA_TAG_BOOLEAN = PA_TAG_BOOLEAN_TRUE, - PA_TAG_TIMEVAL = 'T', - PA_TAG_USEC = 'U' /* 64bit unsigned */, - PA_TAG_CHANNEL_MAP = 'm', - PA_TAG_CVOLUME = 'v' -}; - -pa_tagstruct *pa_tagstruct_new(const uint8_t* data, size_t length); -void pa_tagstruct_free(pa_tagstruct*t); -uint8_t* pa_tagstruct_free_data(pa_tagstruct*t, size_t *l); - -int pa_tagstruct_eof(pa_tagstruct*t); -const uint8_t* pa_tagstruct_data(pa_tagstruct*t, size_t *l); - -void pa_tagstruct_put(pa_tagstruct *t, ...); - -void pa_tagstruct_puts(pa_tagstruct*t, const char *s); -void pa_tagstruct_putu8(pa_tagstruct*t, uint8_t c); -void pa_tagstruct_putu32(pa_tagstruct*t, uint32_t i); -void pa_tagstruct_putu64(pa_tagstruct*t, uint64_t i); -void pa_tagstruct_puts64(pa_tagstruct*t, int64_t i); -void pa_tagstruct_put_sample_spec(pa_tagstruct *t, const pa_sample_spec *ss); -void pa_tagstruct_put_arbitrary(pa_tagstruct*t, const void *p, size_t length); -void pa_tagstruct_put_boolean(pa_tagstruct*t, int b); -void pa_tagstruct_put_timeval(pa_tagstruct*t, const struct timeval *tv); -void pa_tagstruct_put_usec(pa_tagstruct*t, pa_usec_t u); -void pa_tagstruct_put_channel_map(pa_tagstruct *t, const pa_channel_map *map); -void pa_tagstruct_put_cvolume(pa_tagstruct *t, const pa_cvolume *cvolume); - -int pa_tagstruct_get(pa_tagstruct *t, ...); - -int pa_tagstruct_gets(pa_tagstruct*t, const char **s); -int pa_tagstruct_getu8(pa_tagstruct*t, uint8_t *c); -int pa_tagstruct_getu32(pa_tagstruct*t, uint32_t *i); -int pa_tagstruct_getu64(pa_tagstruct*t, uint64_t *i); -int pa_tagstruct_gets64(pa_tagstruct*t, int64_t *i); -int pa_tagstruct_get_sample_spec(pa_tagstruct *t, pa_sample_spec *ss); -int pa_tagstruct_get_arbitrary(pa_tagstruct *t, const void **p, size_t length); -int pa_tagstruct_get_boolean(pa_tagstruct *t, int *b); -int pa_tagstruct_get_timeval(pa_tagstruct*t, struct timeval *tv); -int pa_tagstruct_get_usec(pa_tagstruct*t, pa_usec_t *u); -int pa_tagstruct_get_channel_map(pa_tagstruct *t, pa_channel_map *map); -int pa_tagstruct_get_cvolume(pa_tagstruct *t, pa_cvolume *v); - - -#endif diff --git a/src/polypcore/tokenizer.c b/src/polypcore/tokenizer.c deleted file mode 100644 index 667643fe..00000000 --- a/src/polypcore/tokenizer.c +++ /dev/null @@ -1,90 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> -#include <assert.h> -#include <stdlib.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/dynarray.h> -#include <polypcore/gccmacro.h> - -#include "tokenizer.h" - -struct pa_tokenizer { - pa_dynarray *dynarray; -}; - -static void token_free(void *p, PA_GCC_UNUSED void *userdata) { - pa_xfree(p); -} - -static void parse(pa_dynarray*a, const char *s, unsigned args) { - int infty = 0; - const char delimiter[] = " \t\n\r"; - const char *p; - assert(a && s); - - if (args == 0) - infty = 1; - - p = s+strspn(s, delimiter); - while (*p && (infty || args >= 2)) { - size_t l = strcspn(p, delimiter); - char *n = pa_xstrndup(p, l); - pa_dynarray_append(a, n); - p += l; - p += strspn(p, delimiter); - args--; - } - - if (args && *p) { - char *n = pa_xstrdup(p); - pa_dynarray_append(a, n); - } -} - -pa_tokenizer* pa_tokenizer_new(const char *s, unsigned args) { - pa_tokenizer *t; - - t = pa_xmalloc(sizeof(pa_tokenizer)); - t->dynarray = pa_dynarray_new(); - assert(t->dynarray); - - parse(t->dynarray, s, args); - return t; -} - -void pa_tokenizer_free(pa_tokenizer *t) { - assert(t); - pa_dynarray_free(t->dynarray, token_free, NULL); - pa_xfree(t); -} - -const char *pa_tokenizer_get(pa_tokenizer *t, unsigned i) { - assert(t); - return pa_dynarray_get(t->dynarray, i); -} diff --git a/src/polypcore/tokenizer.h b/src/polypcore/tokenizer.h deleted file mode 100644 index bedacb8a..00000000 --- a/src/polypcore/tokenizer.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef footokenizerhfoo -#define footokenizerhfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -typedef struct pa_tokenizer pa_tokenizer; - -pa_tokenizer* pa_tokenizer_new(const char *s, unsigned args); -void pa_tokenizer_free(pa_tokenizer *t); - -const char *pa_tokenizer_get(pa_tokenizer *t, unsigned i); - -#endif diff --git a/src/polypcore/winsock.h b/src/polypcore/winsock.h deleted file mode 100644 index ae868b38..00000000 --- a/src/polypcore/winsock.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef foowinsockhfoo -#define foowinsockhfoo - -#ifdef HAVE_WINSOCK2_H -#include <winsock2.h> - -#define ESHUTDOWN WSAESHUTDOWN -#define ECONNRESET WSAECONNRESET -#define ECONNABORTED WSAECONNABORTED -#define ENETRESET WSAENETRESET -#define EINPROGRESS WSAEINPROGRESS -#define EAFNOSUPPORT WSAEAFNOSUPPORT -#define ETIMEDOUT WSAETIMEDOUT -#define ECONNREFUSED WSAECONNREFUSED -#define EHOSTUNREACH WSAEHOSTUNREACH -#define EWOULDBLOCK WSAEWOULDBLOCK - -#endif - -#ifdef HAVE_WS2TCPIP_H -#include <ws2tcpip.h> -#endif - -#endif diff --git a/src/polypcore/x11prop.c b/src/polypcore/x11prop.c deleted file mode 100644 index e57fc136..00000000 --- a/src/polypcore/x11prop.c +++ /dev/null @@ -1,70 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <string.h> - -#include <X11/Xlib.h> -#include <X11/Xatom.h> - -#include "x11prop.h" - - -void pa_x11_set_prop(Display *d, const char *name, const char *data) { - Atom a = XInternAtom(d, name, False); - XChangeProperty(d, RootWindow(d, 0), a, XA_STRING, 8, PropModeReplace, (const unsigned char*) data, strlen(data)+1); -} - -void pa_x11_del_prop(Display *d, const char *name) { - Atom a = XInternAtom(d, name, False); - XDeleteProperty(d, RootWindow(d, 0), a); -} - -char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l) { - Atom actual_type; - int actual_format; - unsigned long nitems; - unsigned long nbytes_after; - unsigned char *prop = NULL; - char *ret = NULL; - - Atom a = XInternAtom(d, name, False); - if (XGetWindowProperty(d, RootWindow(d, 0), a, 0, (l+2)/4, False, XA_STRING, &actual_type, &actual_format, &nitems, &nbytes_after, &prop) != Success) - goto finish; - - if (actual_type != XA_STRING) - goto finish; - - memcpy(p, prop, nitems); - p[nitems] = 0; - - ret = p; - -finish: - - if (prop) - XFree(prop); - - return ret; -} diff --git a/src/polypcore/x11prop.h b/src/polypcore/x11prop.h deleted file mode 100644 index 5531c640..00000000 --- a/src/polypcore/x11prop.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef foox11prophfoo -#define foox11prophfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <sys/types.h> - -#include <X11/Xlib.h> - -void pa_x11_set_prop(Display *d, const char *name, const char *data); -void pa_x11_del_prop(Display *d, const char *name); -char* pa_x11_get_prop(Display *d, const char *name, char *p, size_t l); - -#endif diff --git a/src/polypcore/x11wrap.c b/src/polypcore/x11wrap.c deleted file mode 100644 index b53a43b6..00000000 --- a/src/polypcore/x11wrap.c +++ /dev/null @@ -1,247 +0,0 @@ -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <assert.h> -#include <stdio.h> - -#include <polyp/xmalloc.h> - -#include <polypcore/llist.h> -#include <polypcore/log.h> -#include <polypcore/props.h> - -#include "x11wrap.h" - -typedef struct pa_x11_internal pa_x11_internal; - -struct pa_x11_internal { - PA_LLIST_FIELDS(pa_x11_internal); - pa_x11_wrapper *wrapper; - pa_io_event* io_event; - int fd; -}; - -struct pa_x11_wrapper { - pa_core *core; - int ref; - - char *property_name; - Display *display; - - pa_defer_event* defer_event; - pa_io_event* io_event; - - PA_LLIST_HEAD(pa_x11_client, clients); - PA_LLIST_HEAD(pa_x11_internal, internals); -}; - -struct pa_x11_client { - PA_LLIST_FIELDS(pa_x11_client); - pa_x11_wrapper *wrapper; - int (*callback)(pa_x11_wrapper *w, XEvent *e, void *userdata); - void *userdata; -}; - -/* Dispatch all pending X11 events */ -static void work(pa_x11_wrapper *w) { - assert(w && w->ref >= 1); - - while (XPending(w->display)) { - pa_x11_client *c; - XEvent e; - XNextEvent(w->display, &e); - - for (c = w->clients; c; c = c->next) { - assert(c->callback); - if (c->callback(w, &e, c->userdata) != 0) - break; - } - } -} - -/* IO notification event for the X11 display connection */ -static void display_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { - pa_x11_wrapper *w = userdata; - assert(m && e && fd >= 0 && w && w->ref >= 1); - work(w); -} - -/* Deferred notification event. Called once each main loop iteration */ -static void defer_event(pa_mainloop_api *m, pa_defer_event *e, void *userdata) { - pa_x11_wrapper *w = userdata; - assert(m && e && w && w->ref >= 1); - - m->defer_enable(e, 0); - - work(w); -} - -/* IO notification event for X11 internal connections */ -static void internal_io_event(pa_mainloop_api *m, pa_io_event *e, int fd, PA_GCC_UNUSED pa_io_event_flags_t f, void *userdata) { - pa_x11_wrapper *w = userdata; - assert(m && e && fd >= 0 && w && w->ref >= 1); - - XProcessInternalConnection(w->display, fd); - - work(w); -} - -/* Add a new IO source for the specified X11 internal connection */ -static pa_x11_internal* x11_internal_add(pa_x11_wrapper *w, int fd) { - pa_x11_internal *i; - assert(fd >= 0); - - i = pa_xmalloc(sizeof(pa_x11_internal)); - assert(i); - i->wrapper = w; - i->io_event = w->core->mainloop->io_new(w->core->mainloop, fd, PA_IO_EVENT_INPUT, internal_io_event, w); - i->fd = fd; - - PA_LLIST_PREPEND(pa_x11_internal, w->internals, i); - return i; -} - -/* Remove an IO source for an X11 internal connection */ -static void x11_internal_remove(pa_x11_wrapper *w, pa_x11_internal *i) { - assert(i); - - PA_LLIST_REMOVE(pa_x11_internal, w->internals, i); - w->core->mainloop->io_free(i->io_event); - pa_xfree(i); -} - -/* Implementation of XConnectionWatchProc */ -static void x11_watch(Display *display, XPointer userdata, int fd, Bool opening, XPointer *watch_data) { - pa_x11_wrapper *w = (pa_x11_wrapper*) userdata; - assert(display && w && fd >= 0); - - if (opening) - *watch_data = (XPointer) x11_internal_add(w, fd); - else - x11_internal_remove(w, (pa_x11_internal*) *watch_data); -} - -static pa_x11_wrapper* x11_wrapper_new(pa_core *c, const char *name, const char *t) { - pa_x11_wrapper*w; - Display *d; - int r; - - if (!(d = XOpenDisplay(name))) { - pa_log(__FILE__": XOpenDisplay() failed"); - return NULL; - } - - w = pa_xmalloc(sizeof(pa_x11_wrapper)); - w->core = c; - w->ref = 1; - w->property_name = pa_xstrdup(t); - w->display = d; - - PA_LLIST_HEAD_INIT(pa_x11_client, w->clients); - PA_LLIST_HEAD_INIT(pa_x11_internal, w->internals); - - w->defer_event = c->mainloop->defer_new(c->mainloop, defer_event, w); - w->io_event = c->mainloop->io_new(c->mainloop, ConnectionNumber(d), PA_IO_EVENT_INPUT, display_io_event, w); - - XAddConnectionWatch(d, x11_watch, (XPointer) w); - - r = pa_property_set(c, w->property_name, w); - assert(r >= 0); - - return w; -} - -static void x11_wrapper_free(pa_x11_wrapper*w) { - int r; - assert(w); - - r = pa_property_remove(w->core, w->property_name); - assert(r >= 0); - - assert(!w->clients); - - XRemoveConnectionWatch(w->display, x11_watch, (XPointer) w); - XCloseDisplay(w->display); - - w->core->mainloop->io_free(w->io_event); - w->core->mainloop->defer_free(w->defer_event); - - while (w->internals) - x11_internal_remove(w, w->internals); - - pa_xfree(w->property_name); - pa_xfree(w); -} - -pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name) { - char t[256]; - pa_x11_wrapper *w; - assert(c); - - snprintf(t, sizeof(t), "x11-wrapper%s%s", name ? "-" : "", name ? name : ""); - if ((w = pa_property_get(c, t))) - return pa_x11_wrapper_ref(w); - - return x11_wrapper_new(c, name, t); -} - -pa_x11_wrapper* pa_x11_wrapper_ref(pa_x11_wrapper *w) { - assert(w && w->ref >= 1); - w->ref++; - return w; -} - -void pa_x11_wrapper_unref(pa_x11_wrapper* w) { - assert(w && w->ref >= 1); - - if (!(--w->ref)) - x11_wrapper_free(w); -} - -Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w) { - assert(w && w->ref >= 1); - - /* Somebody is using us, schedule a output buffer flush */ - w->core->mainloop->defer_enable(w->defer_event, 1); - - return w->display; -} - -pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, int (*cb)(pa_x11_wrapper *w, XEvent *e, void *userdata), void *userdata) { - pa_x11_client *c; - assert(w && w->ref >= 1); - - c = pa_xmalloc(sizeof(pa_x11_client)); - c->wrapper = w; - c->callback = cb; - c->userdata = userdata; - - PA_LLIST_PREPEND(pa_x11_client, w->clients, c); - - return c; -} - -void pa_x11_client_free(pa_x11_client *c) { - assert(c && c->wrapper && c->wrapper->ref >= 1); - - PA_LLIST_REMOVE(pa_x11_client, c->wrapper->clients, c); - pa_xfree(c); -} diff --git a/src/polypcore/x11wrap.h b/src/polypcore/x11wrap.h deleted file mode 100644 index 15969869..00000000 --- a/src/polypcore/x11wrap.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef foox11wraphfoo -#define foox11wraphfoo - -/* $Id$ */ - -/*** - This file is part of polypaudio. - - polypaudio is free software; you can redistribute it and/or modify - it under the terms of the GNU Lesser General Public License as published - by the Free Software Foundation; either version 2 of the License, - or (at your option) any later version. - - polypaudio is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with polypaudio; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 - USA. -***/ - -#include <X11/Xlib.h> - -#include <polypcore/core.h> - -typedef struct pa_x11_wrapper pa_x11_wrapper; - -/* Return the X11 wrapper for this core. In case no wrapper was - existant before, allocate a new one */ -pa_x11_wrapper* pa_x11_wrapper_get(pa_core *c, const char *name); - -/* Increase the wrapper's reference count by one */ -pa_x11_wrapper* pa_x11_wrapper_ref(pa_x11_wrapper *w); - -/* Decrease the reference counter of an X11 wrapper object */ -void pa_x11_wrapper_unref(pa_x11_wrapper* w); - -/* Return the X11 display object for this connection */ -Display *pa_x11_wrapper_get_display(pa_x11_wrapper *w); - -typedef struct pa_x11_client pa_x11_client; - -/* Register an X11 client, that is called for each X11 event */ -pa_x11_client* pa_x11_client_new(pa_x11_wrapper *w, int (*cb)(pa_x11_wrapper *w, XEvent *e, void *userdata), void *userdata); - -/* Free an X11 client object */ -void pa_x11_client_free(pa_x11_client *c); - -#endif |