From e591ce9ba8cb66b39d20291c7cdd71b075bcd49f Mon Sep 17 00:00:00 2001 From: Hanspeter Portner Date: Sun, 3 Dec 2023 17:32:48 +0100 Subject: [PATCH] Remove old osc.lv2 subdir --- osc.lv2/.gitlab-ci.yml | 2 - osc.lv2/COPYING | 201 ----- osc.lv2/README.md | 33 - osc.lv2/VERSION | 1 - osc.lv2/gitlab-ci/generic.yml | 106 --- osc.lv2/lv2-osc.doap.ttl | 40 - osc.lv2/manifest.ttl | 23 - osc.lv2/meson.build | 36 - osc.lv2/osc.lv2/endian.h | 120 --- osc.lv2/osc.lv2/forge.h | 474 ----------- osc.lv2/osc.lv2/osc.h | 192 ----- osc.lv2/osc.lv2/reader.h | 629 --------------- osc.lv2/osc.lv2/stream.h | 1433 --------------------------------- osc.lv2/osc.lv2/util.h | 631 --------------- osc.lv2/osc.lv2/writer.h | 579 ------------- osc.lv2/osc.ttl | 42 - osc.lv2/test/osc_test.c | 1373 ------------------------------- 17 files changed, 5915 deletions(-) delete mode 100644 osc.lv2/.gitlab-ci.yml delete mode 100644 osc.lv2/COPYING delete mode 100644 osc.lv2/README.md delete mode 100644 osc.lv2/VERSION delete mode 100644 osc.lv2/gitlab-ci/generic.yml delete mode 100644 osc.lv2/lv2-osc.doap.ttl delete mode 100644 osc.lv2/manifest.ttl delete mode 100644 osc.lv2/meson.build delete mode 100644 osc.lv2/osc.lv2/endian.h delete mode 100644 osc.lv2/osc.lv2/forge.h delete mode 100644 osc.lv2/osc.lv2/osc.h delete mode 100644 osc.lv2/osc.lv2/reader.h delete mode 100644 osc.lv2/osc.lv2/stream.h delete mode 100644 osc.lv2/osc.lv2/util.h delete mode 100644 osc.lv2/osc.lv2/writer.h delete mode 100644 osc.lv2/osc.ttl delete mode 100644 osc.lv2/test/osc_test.c diff --git a/osc.lv2/.gitlab-ci.yml b/osc.lv2/.gitlab-ci.yml deleted file mode 100644 index 979769c..0000000 --- a/osc.lv2/.gitlab-ci.yml +++ /dev/null @@ -1,2 +0,0 @@ -include: - - local: 'gitlab-ci/generic.yml' diff --git a/osc.lv2/COPYING b/osc.lv2/COPYING deleted file mode 100644 index ddb9a46..0000000 --- a/osc.lv2/COPYING +++ /dev/null @@ -1,201 +0,0 @@ - The Artistic License 2.0 - - Copyright (c) 2000-2006, The Perl Foundation. - - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -Preamble - -This license establishes the terms under which a given free software -Package may be copied, modified, distributed, and/or redistributed. -The intent is that the Copyright Holder maintains some artistic -control over the development of that Package while still keeping the -Package available as open source and free software. - -You are always permitted to make arrangements wholly outside of this -license directly with the Copyright Holder of a given Package. If the -terms of this license do not permit the full use that you propose to -make of the Package, you should contact the Copyright Holder and seek -a different licensing arrangement. - -Definitions - - "Copyright Holder" means the individual(s) or organization(s) - named in the copyright notice for the entire Package. - - "Contributor" means any party that has contributed code or other - material to the Package, in accordance with the Copyright Holder's - procedures. - - "You" and "your" means any person who would like to copy, - distribute, or modify the Package. - - "Package" means the collection of files distributed by the - Copyright Holder, and derivatives of that collection and/or of - those files. A given Package may consist of either the Standard - Version, or a Modified Version. - - "Distribute" means providing a copy of the Package or making it - accessible to anyone else, or in the case of a company or - organization, to others outside of your company or organization. - - "Distributor Fee" means any fee that you charge for Distributing - this Package or providing support for this Package to another - party. It does not mean licensing fees. - - "Standard Version" refers to the Package if it has not been - modified, or has been modified only in ways explicitly requested - by the Copyright Holder. - - "Modified Version" means the Package, if it has been changed, and - such changes were not explicitly requested by the Copyright - Holder. - - "Original License" means this Artistic License as Distributed with - the Standard Version of the Package, in its current version or as - it may be modified by The Perl Foundation in the future. - - "Source" form means the source code, documentation source, and - configuration files for the Package. - - "Compiled" form means the compiled bytecode, object code, binary, - or any other form resulting from mechanical transformation or - translation of the Source form. - - -Permission for Use and Modification Without Distribution - -(1) You are permitted to use the Standard Version and create and use -Modified Versions for any purpose without restriction, provided that -you do not Distribute the Modified Version. - - -Permissions for Redistribution of the Standard Version - -(2) You may Distribute verbatim copies of the Source form of the -Standard Version of this Package in any medium without restriction, -either gratis or for a Distributor Fee, provided that you duplicate -all of the original copyright notices and associated disclaimers. At -your discretion, such verbatim copies may or may not include a -Compiled form of the Package. - -(3) You may apply any bug fixes, portability changes, and other -modifications made available from the Copyright Holder. The resulting -Package will still be considered the Standard Version, and as such -will be subject to the Original License. - - -Distribution of Modified Versions of the Package as Source - -(4) You may Distribute your Modified Version as Source (either gratis -or for a Distributor Fee, and with or without a Compiled form of the -Modified Version) provided that you clearly document how it differs -from the Standard Version, including, but not limited to, documenting -any non-standard features, executables, or modules, and provided that -you do at least ONE of the following: - - (a) make the Modified Version available to the Copyright Holder - of the Standard Version, under the Original License, so that the - Copyright Holder may include your modifications in the Standard - Version. - - (b) ensure that installation of your Modified Version does not - prevent the user installing or running the Standard Version. In - addition, the Modified Version must bear a name that is different - from the name of the Standard Version. - - (c) allow anyone who receives a copy of the Modified Version to - make the Source form of the Modified Version available to others - under - - (i) the Original License or - - (ii) a license that permits the licensee to freely copy, - modify and redistribute the Modified Version using the same - licensing terms that apply to the copy that the licensee - received, and requires that the Source form of the Modified - Version, and of any works derived from it, be made freely - available in that license fees are prohibited but Distributor - Fees are allowed. - - -Distribution of Compiled Forms of the Standard Version -or Modified Versions without the Source - -(5) You may Distribute Compiled forms of the Standard Version without -the Source, provided that you include complete instructions on how to -get the Source of the Standard Version. Such instructions must be -valid at the time of your distribution. If these instructions, at any -time while you are carrying out such distribution, become invalid, you -must provide new instructions on demand or cease further distribution. -If you provide valid instructions or cease distribution within thirty -days after you become aware that the instructions are invalid, then -you do not forfeit any of your rights under this license. - -(6) You may Distribute a Modified Version in Compiled form without -the Source, provided that you comply with Section 4 with respect to -the Source of the Modified Version. - - -Aggregating or Linking the Package - -(7) You may aggregate the Package (either the Standard Version or -Modified Version) with other packages and Distribute the resulting -aggregation provided that you do not charge a licensing fee for the -Package. Distributor Fees are permitted, and licensing fees for other -components in the aggregation are permitted. The terms of this license -apply to the use and Distribution of the Standard or Modified Versions -as included in the aggregation. - -(8) You are permitted to link Modified and Standard Versions with -other works, to embed the Package in a larger work of your own, or to -build stand-alone binary or bytecode versions of applications that -include the Package, and Distribute the result without restriction, -provided the result does not expose a direct interface to the Package. - - -Items That are Not Considered Part of a Modified Version - -(9) Works (including, but not limited to, modules and scripts) that -merely extend or make use of the Package, do not, by themselves, cause -the Package to be a Modified Version. In addition, such works are not -considered parts of the Package itself, and are not subject to the -terms of this license. - - -General Provisions - -(10) Any use, modification, and distribution of the Standard or -Modified Versions is governed by this Artistic License. By using, -modifying or distributing the Package, you accept this license. Do not -use, modify, or distribute the Package, if you do not accept this -license. - -(11) If your Modified Version has been derived from a Modified -Version made by someone other than you, you are nevertheless required -to ensure that your Modified Version complies with the requirements of -this license. - -(12) This license does not grant you the right to use any trademark, -service mark, tradename, or logo of the Copyright Holder. - -(13) This license includes the non-exclusive, worldwide, -free-of-charge patent license to make, have made, use, offer to sell, -sell, import and otherwise transfer the Package with respect to any -patent claims licensable by the Copyright Holder that are necessarily -infringed by the Package. If you institute patent litigation -(including a cross-claim or counterclaim) against any party alleging -that the Package constitutes direct or contributory patent -infringement, then this Artistic License to you shall terminate on the -date that such litigation is filed. - -(14) Disclaimer of Warranty: -THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS -IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED -WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR -NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL -LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL -BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/osc.lv2/README.md b/osc.lv2/README.md deleted file mode 100644 index 1a30571..0000000 --- a/osc.lv2/README.md +++ /dev/null @@ -1,33 +0,0 @@ -# osc.lv2 - -## Open Sound Control Extension for the LV2 Plugin Specification - -### Build Status - -[![build status](https://gitlab.com/OpenMusicKontrollers/osc.lv2/badges/master/build.svg)](https://gitlab.com/OpenMusicKontrollers/osc.lv2/commits/master) - -### Build / test - - git clone https://git.open-music-kontrollers.ch/lv2/osc.lv2 - cd osc.lv2 - meson build - cd build - ninja -j4 - ninja test - -### License - -Copyright (c) 2017 Hanspeter Portner (dev@open-music-kontrollers.ch) - -This is free software: you can redistribute it and/or modify -it under the terms of the Artistic License 2.0 as published by -The Perl Foundation. - -This source 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 -Artistic License 2.0 for more details. - -You should have received a copy of the Artistic License 2.0 -along the source as a COPYING file. If not, obtain it from -. diff --git a/osc.lv2/VERSION b/osc.lv2/VERSION deleted file mode 100644 index a63a9fe..0000000 --- a/osc.lv2/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.1.159 diff --git a/osc.lv2/gitlab-ci/generic.yml b/osc.lv2/gitlab-ci/generic.yml deleted file mode 100644 index 5cd2abc..0000000 --- a/osc.lv2/gitlab-ci/generic.yml +++ /dev/null @@ -1,106 +0,0 @@ -stages: - - build - - deploy - -variables: - PKG_CONFIG_PATH: "/opt/lv2/lib/pkgconfig:/opt/${CI_BUILD_NAME}/lib/pkgconfig:/usr/lib/${CI_BUILD_NAME}/pkgconfig" - BUILD_OPTS : "" - -.native_template: &native_definition - stage: build - script: - - meson --prefix="${CI_PROJECT_DIR}/${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" -Dlv2libdir="" --cross-file "${CI_BUILD_NAME}" ${BUILD_OPTS} build - - ninja -C build - - ninja -C build test - - ninja -C build install - - - scan-build --status-bugs meson --prefix="${CI_PROJECT_DIR}/${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" -Dlv2libdir="" --cross-file "${CI_BUILD_NAME}" ${BUILD_OPTS} scanbuild - - scan-build --status-bugs ninja -C scanbuild - - scan-build --status-bugs ninja -C scanbuild test - artifacts: - name: "${CI_PROJECT_NAME}-$(cat VERSION)-${CI_BUILD_NAME}" - paths: - - "${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}/" - -.cross_template: &cross_definition - stage: build - script: - - meson --prefix="${CI_PROJECT_DIR}/${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" -Dlv2libdir="" --cross-file "${CI_BUILD_NAME}" ${BUILD_OPTS} build - - ninja -C build - - ninja -C build test - - ninja -C build install - artifacts: - name: "${CI_PROJECT_NAME}-$(cat VERSION)-${CI_BUILD_NAME}" - paths: - - "${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}/" - -# build -.universal_linux_template_stretch: &universal_linux_definition_stretch - image: ventosus/universal-linux-gnu:stretch - <<: *cross_definition - -.universal_linux_template_buster: &universal_linux_definition_buster - image: ventosus/universal-linux-gnu:buster - <<: *native_definition - -.universal_linux_template_bullseye: &universal_linux_definition_bullseye - image: ventosus/universal-linux-gnu:bullseye - <<: *native_definition - -.arm_linux_template_stretch: &arm_linux_definition_stretch - image: ventosus/arm-linux-gnueabihf:stretch - <<: *cross_definition - -.arm_linux_template_buster: &arm_linux_definition_buster - image: ventosus/arm-linux-gnueabihf:buster - <<: *cross_definition - -.arm_linux_template_bullseye: &arm_linux_definition_bullseye - image: ventosus/arm-linux-gnueabihf:bullseye - <<: *cross_definition - -# build -x86_64-linux-gnu-stretch: - <<: *universal_linux_definition_stretch - -x86_64-linux-gnu-buster: - <<: *universal_linux_definition_buster - -x86_64-linux-gnu-bullseye: - <<: *universal_linux_definition_bullseye - -i686-linux-gnu-stretch: - <<: *universal_linux_definition_stretch - -i686-linux-gnu-buster: - <<: *universal_linux_definition_buster - -i686-linux-gnu-bullseye: - <<: *universal_linux_definition_bullseye - -arm-linux-gnueabihf-stretch: - <<: *arm_linux_definition_stretch - -arm-linux-gnueabihf-buster: - <<: *arm_linux_definition_buster - -arm-linux-gnueabihf-bullseye: - <<: *arm_linux_definition_bullseye - -aarch64-linux-gnu-stretch: - <<: *arm_linux_definition_stretch - -aarch64-linux-gnu-buster: - <<: *arm_linux_definition_buster - -aarch64-linux-gnu-bullseye: - <<: *arm_linux_definition_bullseye - -pack: - stage: deploy - script: - - echo 'packing up' - artifacts: - name: "${CI_PROJECT_NAME}-$(cat VERSION)" - paths: - - "${CI_PROJECT_NAME}-$(cat VERSION)/" diff --git a/osc.lv2/lv2-osc.doap.ttl b/osc.lv2/lv2-osc.doap.ttl deleted file mode 100644 index ef74f92..0000000 --- a/osc.lv2/lv2-osc.doap.ttl +++ /dev/null @@ -1,40 +0,0 @@ -# Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) -# -# This is free software: you can redistribute it and/or modify -# it under the terms of the Artistic License 2.0 as published by -# The Perl Foundation. -# -# This source 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 -# Artistic License 2.0 for more details. -# -# You should have received a copy of the Artistic License 2.0 -# along the source as a COPYING file. If not, obtain it from -# http://www.perlfoundation.org/artistic_license_2_0. - -@prefix dcs: . -@prefix doap: . -@prefix foaf: . -@prefix rdfs: . -@prefix lic: . -@prefix omk: . - - - a doap:Project ; - doap:license lic:Artistic-2.0 ; - doap:name "LV2 OSC" ; - doap:shortdesc "A definition of atomified OSC." ; - doap:maintainer omk:me ; - doap:created "2015-06-19" ; - doap:developer omk:me ; - doap:release [ - doap:revision "1.0" ; - doap:created "2015-06-19" ; - dcs:blame omk:me ; - dcs:changeset [ - dcs:item [ - rdfs:label "Initial release." - ] - ] - ] . diff --git a/osc.lv2/manifest.ttl b/osc.lv2/manifest.ttl deleted file mode 100644 index a2bbaf8..0000000 --- a/osc.lv2/manifest.ttl +++ /dev/null @@ -1,23 +0,0 @@ -# Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) -# -# This is free software: you can redistribute it and/or modify -# it under the terms of the Artistic License 2.0 as published by -# The Perl Foundation. -# -# This source 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 -# Artistic License 2.0 for more details. -# -# You should have received a copy of the Artistic License 2.0 -# along the source as a COPYING file. If not, obtain it from -# http://www.perlfoundation.org/artistic_license_2_0. - -@prefix lv2: . -@prefix rdfs: . - - - a lv2:Specification ; - lv2:minorVersion 1 ; - lv2:microVersion 0 ; - rdfs:seeAlso . diff --git a/osc.lv2/meson.build b/osc.lv2/meson.build deleted file mode 100644 index 750f0dc..0000000 --- a/osc.lv2/meson.build +++ /dev/null @@ -1,36 +0,0 @@ -project('osc.lv2', 'c', default_options : [ - 'buildtype=release', - 'warning_level=3', - 'werror=true', - 'b_lto=false', - 'c_std=c11']) - -version = run_command('cat', 'VERSION').stdout().strip() - -add_project_arguments('-D_GNU_SOURCE', language : 'c') - -conf_data = configuration_data() -cc = meson.get_compiler('c') - -lv2_dep = dependency('lv2') -thread_dep = dependency('threads') -deps = [lv2_dep, thread_dep] - -c_args = [] - -if host_machine.system() == 'windows' - deps += cc.find_library('ws2_32') - c_args += '-Wno-error=format' - c_args += '-Wno-error=format-extra-args' -endif - -osc_test = executable('osc_test', - join_paths('test', 'osc_test.c'), - c_args : c_args, - dependencies : deps, - install : false) - -# FIXME start virautl serial pair before test -# socat -d -d pty,raw,echo=0 pty,raw,echo=0 -test('Test', osc_test, - timeout : 240) diff --git a/osc.lv2/osc.lv2/endian.h b/osc.lv2/osc.lv2/endian.h deleted file mode 100644 index f310c51..0000000 --- a/osc.lv2/osc.lv2/endian.h +++ /dev/null @@ -1,120 +0,0 @@ -// "License": Public Domain -// I, Mathias Panzenböck, place this file hereby into the public domain. Use it at your own risk for whatever you like. -// In case there are jurisdictions that don't support putting things in the public domain you can also consider it to -// be "dual licensed" under the BSD, MIT and Apache licenses, if you want to. This code is trivial anyway. Consider it -// an example on how to get the endian conversion functions on different platforms. - -#ifndef PORTABLE_ENDIAN_H__ -#define PORTABLE_ENDIAN_H__ - -#if (defined(_WIN16) || defined(_WIN32) || defined(_WIN64)) && !defined(__WINDOWS__) - -# define __WINDOWS__ - -#endif - -#if defined(__linux__) || defined(__CYGWIN__) - -# include - -#elif defined(__APPLE__) - -# include - -# define htobe16(x) OSSwapHostToBigInt16(x) -# define htole16(x) OSSwapHostToLittleInt16(x) -# define be16toh(x) OSSwapBigToHostInt16(x) -# define le16toh(x) OSSwapLittleToHostInt16(x) - -# define htobe32(x) OSSwapHostToBigInt32(x) -# define htole32(x) OSSwapHostToLittleInt32(x) -# define be32toh(x) OSSwapBigToHostInt32(x) -# define le32toh(x) OSSwapLittleToHostInt32(x) - -# define htobe64(x) OSSwapHostToBigInt64(x) -# define htole64(x) OSSwapHostToLittleInt64(x) -# define be64toh(x) OSSwapBigToHostInt64(x) -# define le64toh(x) OSSwapLittleToHostInt64(x) - -# define __BYTE_ORDER BYTE_ORDER -# define __BIG_ENDIAN BIG_ENDIAN -# define __LITTLE_ENDIAN LITTLE_ENDIAN -# define __PDP_ENDIAN PDP_ENDIAN - -#elif defined(__OpenBSD__) - -# include - -#elif defined(__NetBSD__) || defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) - -# include - -#elif defined(__WINDOWS__) - -# include -# include - -# if BYTE_ORDER == LITTLE_ENDIAN - -# define htobe16(x) htons(x) -# define htole16(x) (x) -# define be16toh(x) ntohs(x) -# define le16toh(x) (x) - -# define htobe32(x) htonl(x) -# define htole32(x) (x) -# define be32toh(x) ntohl(x) -# define le32toh(x) (x) - -# ifndef htonll -static inline uint64_t htonll(uint64_t n) -{ - return (((uint64_t)htonl(n)) << 32) + htonl(n >> 32); -} -# endif - -# ifndef ntohll -# define ntohll htonll -# endif - -# define htobe64(x) htonll(x) -# define htole64(x) (x) -# define be64toh(x) ntohll(x) -# define le64toh(x) (x) - -# elif BYTE_ORDER == BIG_ENDIAN - - /* that would be xbox 360 */ -# define htobe16(x) (x) -# define htole16(x) __builtin_bswap16(x) -# define be16toh(x) (x) -# define le16toh(x) __builtin_bswap16(x) - -# define htobe32(x) (x) -# define htole32(x) __builtin_bswap32(x) -# define be32toh(x) (x) -# define le32toh(x) __builtin_bswap32(x) - -# define htobe64(x) (x) -# define htole64(x) __builtin_bswap64(x) -# define be64toh(x) (x) -# define le64toh(x) __builtin_bswap64(x) - -# else - -# error byte order not supported - -# endif - -# define __BYTE_ORDER BYTE_ORDER -# define __BIG_ENDIAN BIG_ENDIAN -# define __LITTLE_ENDIAN LITTLE_ENDIAN -# define __PDP_ENDIAN PDP_ENDIAN - -#else - -# error platform not supported - -#endif - -#endif diff --git a/osc.lv2/osc.lv2/forge.h b/osc.lv2/osc.lv2/forge.h deleted file mode 100644 index 6dc5fe7..0000000 --- a/osc.lv2/osc.lv2/forge.h +++ /dev/null @@ -1,474 +0,0 @@ -/* - * Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the Artistic License 2.0 as published by - * The Perl Foundation. - * - * This source 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 - * Artistic License 2.0 for more details. - * - * You should have received a copy of the Artistic License 2.0 - * along the source as a COPYING file. If not, obtain it from - * http://www.perlfoundation.org/artistic_license_2_0. - */ - -#ifndef LV2_OSC_FORGE_H -#define LV2_OSC_FORGE_H - -#include - -#include -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#define lv2_osc_forge_int(forge, osc_urid, val) \ - lv2_atom_forge_int((forge), (val)) - -#define lv2_osc_forge_float(forge, osc_urid, val) \ - lv2_atom_forge_float((forge), (val)) - -#define lv2_osc_forge_string(forge, osc_urid, val, len) \ - lv2_atom_forge_string((forge), (val), (len)) - -#define lv2_osc_forge_long(forge, osc_urid, val) \ - lv2_atom_forge_long((forge), (val)) - -#define lv2_osc_forge_double(forge, osc_urid, val) \ - lv2_atom_forge_double((forge), (val)) - -#define lv2_osc_forge_true(forge, osc_urid) \ - lv2_atom_forge_bool((forge), 1) - -#define lv2_osc_forge_false(forge, osc_urid) \ - lv2_atom_forge_bool((forge), 0) - -#define lv2_osc_forge_nil(forge, osc_urid) \ - lv2_atom_forge_literal((forge), "", 0, (osc_urid)->OSC_Nil, 0) - -#define lv2_osc_forge_impulse(forge, osc_urid) \ - lv2_atom_forge_literal((forge), "", 0, (osc_urid)->OSC_Impulse, 0) - -#define lv2_osc_forge_symbol(forge, osc_urid, val) \ - lv2_atom_forge_urid((forge), (val)) - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_chunk(LV2_Atom_Forge *forge, LV2_URID type, - const uint8_t *buf, uint32_t size) -{ - LV2_Atom_Forge_Ref ref; - - if( (ref = lv2_atom_forge_atom(forge, size, type)) - && (ref = lv2_atom_forge_raw(forge, buf, size)) ) - { - lv2_atom_forge_pad(forge, size); - return ref; - } - - return 0; -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_midi(LV2_Atom_Forge *forge, LV2_OSC_URID *osc_urid, - const uint8_t *buf, uint32_t size) -{ - assert(size <= 3); - return lv2_osc_forge_chunk(forge, osc_urid->MIDI_MidiEvent, buf, size); -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_blob(LV2_Atom_Forge* forge, LV2_OSC_URID *osc_urid, - const uint8_t *buf, uint32_t size) -{ - return lv2_osc_forge_chunk(forge, osc_urid->ATOM_Chunk, buf, size); -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_char(LV2_Atom_Forge* forge, LV2_OSC_URID *osc_urid, - char val) -{ - return lv2_atom_forge_literal(forge, &val, 1, osc_urid->OSC_Char, 0); -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_rgba(LV2_Atom_Forge* forge, LV2_OSC_URID *osc_urid, - uint8_t r, uint8_t g, uint8_t b, uint8_t a) -{ - char val [9]; - sprintf(val, "%02"PRIx8"%02"PRIx8"%02"PRIx8"%02"PRIx8, r, g, b, a); - return lv2_atom_forge_literal(forge, val, 8, osc_urid->OSC_RGBA, 0); -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_timetag(LV2_Atom_Forge *forge, LV2_OSC_URID *osc_urid, - const LV2_OSC_Timetag *timetag) -{ - LV2_Atom_Forge_Frame frame; - LV2_Atom_Forge_Ref ref; - - if( (ref = lv2_atom_forge_object(forge, &frame, 0, osc_urid->OSC_Timetag)) - && (ref = lv2_atom_forge_key(forge, osc_urid->OSC_timetagIntegral)) - && (ref = lv2_atom_forge_long(forge, timetag->integral)) - && (ref = lv2_atom_forge_key(forge, osc_urid->OSC_timetagFraction)) - && (ref = lv2_atom_forge_long(forge, timetag->fraction)) ) - { - lv2_atom_forge_pop(forge, &frame); - return ref; - } - - return 0; -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_bundle_head(LV2_Atom_Forge* forge, LV2_OSC_URID *osc_urid, - LV2_Atom_Forge_Frame frame [2], const LV2_OSC_Timetag *timetag) -{ - LV2_Atom_Forge_Ref ref; - - if( (ref = lv2_atom_forge_object(forge, &frame[0], 0, osc_urid->OSC_Bundle)) - && (ref = lv2_atom_forge_key(forge, osc_urid->OSC_bundleTimetag)) - && (ref = lv2_osc_forge_timetag(forge, osc_urid, timetag)) - && (ref = lv2_atom_forge_key(forge, osc_urid->OSC_bundleItems)) - && (ref = lv2_atom_forge_tuple(forge, &frame[1])) ) - { - return ref; - } - - return 0; -} - -/** - TODO -*/ -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_message_head(LV2_Atom_Forge *forge, LV2_OSC_URID *osc_urid, - LV2_Atom_Forge_Frame frame [2], const char *path) -{ - assert(path); - - LV2_Atom_Forge_Ref ref; - if( (ref = lv2_atom_forge_object(forge, &frame[0], 0, osc_urid->OSC_Message)) - && (ref = lv2_atom_forge_key(forge, osc_urid->OSC_messagePath)) - && (ref = lv2_atom_forge_string(forge, path, strlen(path))) - && (ref = lv2_atom_forge_key(forge, osc_urid->OSC_messageArguments)) - && (ref = lv2_atom_forge_tuple(forge, &frame[1])) ) - { - return ref; - } - - return 0; -} - -/** - TODO -*/ -static inline void -lv2_osc_forge_pop(LV2_Atom_Forge *forge, LV2_Atom_Forge_Frame frame [2]) -{ - lv2_atom_forge_pop(forge, &frame[1]); // a LV2_Atom_Tuple - lv2_atom_forge_pop(forge, &frame[0]); // a LV2_Atom_Object -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_message_varlist(LV2_Atom_Forge *forge, LV2_OSC_URID *osc_urid, - const char *path, const char *fmt, va_list args) -{ - LV2_Atom_Forge_Frame frame [2]; - LV2_Atom_Forge_Ref ref; - - if(!lv2_osc_check_path(path) || !lv2_osc_check_fmt(fmt, 0)) - return 0; - if(!(ref = lv2_osc_forge_message_head(forge, osc_urid, frame, path))) - return 0; - - for(const char *type = fmt; *type; type++) - { - switch( (LV2_OSC_Type)*type) - { - case LV2_OSC_INT32: - { - if(!(ref = lv2_osc_forge_int(forge, osc_urid, va_arg(args, int32_t)))) - return 0; - break; - } - case LV2_OSC_FLOAT: - { - if(!(ref = lv2_osc_forge_float(forge, osc_urid, (float)va_arg(args, double)))) - return 0; - break; - } - case LV2_OSC_STRING: - { - const char *s = va_arg(args, const char *); - if(!s || !(ref = lv2_osc_forge_string(forge, osc_urid, s, strlen(s)))) - return 0; - break; - } - case LV2_OSC_BLOB: - { - const int32_t size = va_arg(args, int32_t); - const uint8_t *b = va_arg(args, const uint8_t *); - if(!b || !(ref = lv2_osc_forge_blob(forge, osc_urid, b, size))) - return 0; - break; - } - - case LV2_OSC_INT64: - { - if(!(ref = lv2_osc_forge_long(forge, osc_urid, va_arg(args, int64_t)))) - return 0; - break; - } - case LV2_OSC_DOUBLE: - { - if(!(ref = lv2_osc_forge_double(forge, osc_urid, va_arg(args, double)))) - return 0; - break; - } - case LV2_OSC_TIMETAG: - { - const LV2_OSC_Timetag timetag = { - .integral = va_arg(args, uint32_t), - .fraction = va_arg(args, uint32_t) - }; - if(!(ref = lv2_osc_forge_timetag(forge, osc_urid, &timetag))) - return 0; - break; - } - - case LV2_OSC_TRUE: - { - if(!(ref = lv2_osc_forge_true(forge, osc_urid))) - return 0; - break; - } - case LV2_OSC_FALSE: - { - if(!(ref = lv2_osc_forge_false(forge, osc_urid))) - return 0; - break; - } - case LV2_OSC_NIL: - { - if(!(ref = lv2_osc_forge_nil(forge, osc_urid))) - return 0; - break; - } - case LV2_OSC_IMPULSE: - { - if(!(ref = lv2_osc_forge_impulse(forge, osc_urid))) - return 0; - break; - } - - case LV2_OSC_SYMBOL: - { - if(!(ref = lv2_osc_forge_symbol(forge, osc_urid, va_arg(args, uint32_t)))) - return 0; - break; - } - case LV2_OSC_MIDI: - { - const int32_t size = va_arg(args, int32_t); - const uint8_t *m = va_arg(args, const uint8_t *); - if(!m || !(ref = lv2_osc_forge_midi(forge, osc_urid, m, size))) - return 0; - break; - } - case LV2_OSC_CHAR: - { - if(!(ref = lv2_osc_forge_char(forge, osc_urid, (char)va_arg(args, int)))) - return 0; - break; - } - case LV2_OSC_RGBA: - { - if(!(ref = lv2_osc_forge_rgba(forge, osc_urid, - (uint8_t)va_arg(args, unsigned), - (uint8_t)va_arg(args, unsigned), - (uint8_t)va_arg(args, unsigned), - (uint8_t)va_arg(args, unsigned)))) - return 0; - break; - } - } - } - - lv2_osc_forge_pop(forge, frame); - - return ref; -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_message_vararg(LV2_Atom_Forge *forge, LV2_OSC_URID *osc_urid, - const char *path, const char *fmt, ...) -{ - LV2_Atom_Forge_Ref ref; - va_list args; - - va_start(args, fmt); - - ref = lv2_osc_forge_message_varlist(forge, osc_urid, path, fmt, args); - - va_end(args); - - return ref; -} - -static inline LV2_Atom_Forge_Ref -lv2_osc_forge_packet(LV2_Atom_Forge *forge, LV2_OSC_URID *osc_urid, - LV2_URID_Map *map, const uint8_t *buf, size_t size) -{ - LV2_OSC_Reader reader; - LV2_Atom_Forge_Frame frame [2]; - LV2_Atom_Forge_Ref ref; - - lv2_osc_reader_initialize(&reader, buf, size); - - if(lv2_osc_reader_is_bundle(&reader)) - { - LV2_OSC_Item *itm = OSC_READER_BUNDLE_BEGIN(&reader, size); - - if(itm && (ref = lv2_osc_forge_bundle_head(forge, osc_urid, frame, - LV2_OSC_TIMETAG_CREATE(itm->timetag)))) - { - OSC_READER_BUNDLE_ITERATE(&reader, itm) - { - if(!(ref = lv2_osc_forge_packet(forge, osc_urid, map, itm->body, itm->size))) - return 0; - } - - lv2_osc_forge_pop(forge, frame); - - return ref; - } - } - else if(lv2_osc_reader_is_message(&reader)) - { - LV2_OSC_Arg *arg = OSC_READER_MESSAGE_BEGIN(&reader, size); - - if(arg && (ref = lv2_osc_forge_message_head(forge, osc_urid, frame, arg->path))) - { - OSC_READER_MESSAGE_ITERATE(&reader, arg) - { - switch( (LV2_OSC_Type)*arg->type) - { - case LV2_OSC_INT32: - { - if(!(ref = lv2_osc_forge_int(forge, osc_urid, arg->i))) - return 0; - break; - } - case LV2_OSC_FLOAT: - { - if(!(ref = lv2_osc_forge_float(forge, osc_urid, arg->f))) - return 0; - break; - } - case LV2_OSC_STRING: - { - if(!(ref = lv2_osc_forge_string(forge, osc_urid, arg->s, arg->size - 1))) - return 0; - break; - } - case LV2_OSC_BLOB: - { - if(!(ref = lv2_osc_forge_blob(forge, osc_urid, arg->b, arg->size))) - return 0; - break; - } - - case LV2_OSC_INT64: - { - if(!(ref = lv2_osc_forge_long(forge, osc_urid, arg->h))) - return 0; - break; - } - case LV2_OSC_DOUBLE: - { - if(!(ref = lv2_osc_forge_double(forge, osc_urid, arg->d))) - return 0; - break; - } - case LV2_OSC_TIMETAG: - { - if(!(ref = lv2_osc_forge_timetag(forge, osc_urid, LV2_OSC_TIMETAG_CREATE(arg->t)))) - return 0; - break; - } - - case LV2_OSC_TRUE: - { - if(!(ref = lv2_osc_forge_true(forge, osc_urid))) - return 0; - break; - } - case LV2_OSC_FALSE: - { - if(!(ref = lv2_osc_forge_false(forge, osc_urid))) - return 0; - break; - } - case LV2_OSC_NIL: - { - if(!(ref = lv2_osc_forge_nil(forge, osc_urid))) - return 0; - break; - } - case LV2_OSC_IMPULSE: - { - if(!(ref = lv2_osc_forge_impulse(forge, osc_urid))) - return 0; - break; - } - - case LV2_OSC_SYMBOL: - { - if(!(ref = lv2_osc_forge_symbol(forge, osc_urid, - map->map(map->handle, arg->S)))) - return 0; - break; - } - case LV2_OSC_MIDI: - { - if(!(ref = lv2_osc_forge_midi(forge, osc_urid, &arg->b[1], arg->size - 1))) - return 0; - break; - } - case LV2_OSC_CHAR: - { - if(!(ref = lv2_osc_forge_char(forge, osc_urid, arg->c))) - return 0; - break; - } - case LV2_OSC_RGBA: - { - if(!(ref = lv2_osc_forge_rgba(forge, osc_urid, arg->R, arg->G, arg->B, arg->A))) - return 0; - break; - } - } - } - - lv2_osc_forge_pop(forge, frame); - - return ref; - } - } - - return 0; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // LV2_OSC_FORGE_H diff --git a/osc.lv2/osc.lv2/osc.h b/osc.lv2/osc.lv2/osc.h deleted file mode 100644 index 1ada68c..0000000 --- a/osc.lv2/osc.lv2/osc.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the Artistic License 2.0 as published by - * The Perl Foundation. - * - * This source 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 - * Artistic License 2.0 for more details. - * - * You should have received a copy of the Artistic License 2.0 - * along the source as a COPYING file. If not, obtain it from - * http://www.perlfoundation.org/artistic_license_2_0. - */ - -#ifndef LV2_OSC_H -#define LV2_OSC_H - -#include - -#include -#include -#include - -#define LV2_OSC_URI "http://open-music-kontrollers.ch/lv2/osc" -#define LV2_OSC_PREFIX LV2_OSC_URI "#" - -#define LV2_OSC__Event LV2_OSC_PREFIX "Event" // atom message type -#define LV2_OSC__schedule LV2_OSC_PREFIX "schedule" // feature - -#define LV2_OSC__Packet LV2_OSC_PREFIX "Packet" // atom object type - -#define LV2_OSC__Bundle LV2_OSC_PREFIX "Bundle" // atom object type -#define LV2_OSC__bundleTimetag LV2_OSC_PREFIX "bundleTimetag" // atom object property -#define LV2_OSC__bundleItems LV2_OSC_PREFIX "bundleItems" - -#define LV2_OSC__Message LV2_OSC_PREFIX "Message" // atom object type -#define LV2_OSC__messagePath LV2_OSC_PREFIX "messagePath" // atom object property -#define LV2_OSC__messageArguments LV2_OSC_PREFIX "messageArguments" // atom object property - -#define LV2_OSC__Timetag LV2_OSC_PREFIX "Timetag" // atom object type -#define LV2_OSC__timetagIntegral LV2_OSC_PREFIX "timetagIntegral" // atom object property -#define LV2_OSC__timetagFraction LV2_OSC_PREFIX "timetagFraction" // atom object property - -#define LV2_OSC__Nil LV2_OSC_PREFIX "Nil" // atom literal type -#define LV2_OSC__Impulse LV2_OSC_PREFIX "Impulse" // atom literal type -#define LV2_OSC__Char LV2_OSC_PREFIX "Char" // atom literal type -#define LV2_OSC__RGBA LV2_OSC_PREFIX "RGBA" // atom literal type - -#define LV2_OSC_PADDED_SIZE(size) ( ( (size_t)(size) + 3 ) & ( ~3 ) ) -#define LV2_OSC_IMMEDIATE 1ULL - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *LV2_OSC_Schedule_Handle; - -typedef double (*LV2_OSC_Schedule_OSC2Frames)( - LV2_OSC_Schedule_Handle handle, - uint64_t timetag); - -typedef uint64_t (*LV2_OSC_Schedule_Frames2OSC)( - LV2_OSC_Schedule_Handle handle, - double frames); - -typedef struct _LV2_OSC_Schedule { - LV2_OSC_Schedule_Handle handle; - LV2_OSC_Schedule_OSC2Frames osc2frames; - LV2_OSC_Schedule_Frames2OSC frames2osc; -} LV2_OSC_Schedule; - -typedef enum LV2_OSC_Type { - LV2_OSC_INT32 = 'i', - LV2_OSC_FLOAT = 'f', - LV2_OSC_STRING = 's', - LV2_OSC_BLOB = 'b', - - LV2_OSC_TRUE = 'T', - LV2_OSC_FALSE = 'F', - LV2_OSC_NIL = 'N', - LV2_OSC_IMPULSE = 'I', - - LV2_OSC_INT64 = 'h', - LV2_OSC_DOUBLE = 'd', - LV2_OSC_TIMETAG = 't', - - LV2_OSC_SYMBOL = 'S', - LV2_OSC_CHAR = 'c', - LV2_OSC_MIDI = 'm', - LV2_OSC_RGBA = 'r' -} LV2_OSC_Type; - -union swap32_t { - uint32_t u; - - int32_t i; - float f; -}; - -union swap64_t { - uint64_t u; - - int64_t h; - uint64_t t; - double d; -}; - -typedef struct _LV2_OSC_Timetag { - uint32_t integral; - uint32_t fraction; -} LV2_OSC_Timetag; - -typedef struct _LV2_OSC_URID { - LV2_URID OSC_Packet; - - LV2_URID OSC_Bundle; - LV2_URID OSC_bundleTimetag; - LV2_URID OSC_bundleItems; - - LV2_URID OSC_Message; - LV2_URID OSC_messagePath; - LV2_URID OSC_messageArguments; - - LV2_URID OSC_Timetag; - LV2_URID OSC_timetagIntegral; - LV2_URID OSC_timetagFraction; - - LV2_URID OSC_Nil; - LV2_URID OSC_Impulse; - LV2_URID OSC_Char; - LV2_URID OSC_RGBA; - - LV2_URID MIDI_MidiEvent; - - LV2_URID ATOM_Int; - LV2_URID ATOM_Long; - LV2_URID ATOM_String; - LV2_URID ATOM_Literal; - LV2_URID ATOM_Float; - LV2_URID ATOM_Double; - LV2_URID ATOM_URID; - LV2_URID ATOM_Bool; - LV2_URID ATOM_Tuple; - LV2_URID ATOM_Object; - LV2_URID ATOM_Chunk; -} LV2_OSC_URID; - -static inline void -lv2_osc_urid_init(LV2_OSC_URID *osc_urid, LV2_URID_Map *map) -{ - osc_urid->OSC_Packet = map->map(map->handle, LV2_OSC__Packet); - - osc_urid->OSC_Bundle = map->map(map->handle, LV2_OSC__Bundle); - osc_urid->OSC_bundleTimetag = map->map(map->handle, LV2_OSC__bundleTimetag); - osc_urid->OSC_bundleItems = map->map(map->handle, LV2_OSC__bundleItems); - - osc_urid->OSC_Message = map->map(map->handle, LV2_OSC__Message); - osc_urid->OSC_messagePath = map->map(map->handle, LV2_OSC__messagePath); - osc_urid->OSC_messageArguments = map->map(map->handle, LV2_OSC__messageArguments); - - osc_urid->OSC_Timetag = map->map(map->handle, LV2_OSC__Timetag); - osc_urid->OSC_timetagIntegral = map->map(map->handle, LV2_OSC__timetagIntegral); - osc_urid->OSC_timetagFraction = map->map(map->handle, LV2_OSC__timetagFraction); - - osc_urid->OSC_Nil = map->map(map->handle, LV2_OSC__Nil); - osc_urid->OSC_Impulse = map->map(map->handle, LV2_OSC__Impulse); - osc_urid->OSC_Char = map->map(map->handle, LV2_OSC__Char); - osc_urid->OSC_RGBA = map->map(map->handle, LV2_OSC__RGBA); - - osc_urid->MIDI_MidiEvent = map->map(map->handle, LV2_MIDI__MidiEvent); - - osc_urid->ATOM_Int = map->map(map->handle, LV2_ATOM__Int); - osc_urid->ATOM_Long = map->map(map->handle, LV2_ATOM__Long); - osc_urid->ATOM_String = map->map(map->handle, LV2_ATOM__String); - osc_urid->ATOM_Literal = map->map(map->handle, LV2_ATOM__Literal); - osc_urid->ATOM_Float = map->map(map->handle, LV2_ATOM__Float); - osc_urid->ATOM_Double = map->map(map->handle, LV2_ATOM__Double); - osc_urid->ATOM_URID = map->map(map->handle, LV2_ATOM__URID); - osc_urid->ATOM_Bool = map->map(map->handle, LV2_ATOM__Bool); - osc_urid->ATOM_Tuple = map->map(map->handle, LV2_ATOM__Tuple); - osc_urid->ATOM_Object = map->map(map->handle, LV2_ATOM__Object); - osc_urid->ATOM_Chunk = map->map(map->handle, LV2_ATOM__Chunk); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // LV2_OSC_H diff --git a/osc.lv2/osc.lv2/reader.h b/osc.lv2/osc.lv2/reader.h deleted file mode 100644 index ae46dfa..0000000 --- a/osc.lv2/osc.lv2/reader.h +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the Artistic License 2.0 as published by - * The Perl Foundation. - * - * This source 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 - * Artistic License 2.0 for more details. - * - * You should have received a copy of the Artistic License 2.0 - * along the source as a COPYING file. If not, obtain it from - * http://www.perlfoundation.org/artistic_license_2_0. - */ - -#ifndef LV2_OSC_READER_H -#define LV2_OSC_READER_H - -#include -#include -#include - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - - -typedef struct _LV2_OSC_Tree LV2_OSC_Tree; -typedef struct _LV2_OSC_Reader LV2_OSC_Reader; -typedef struct _LV2_OSC_Item LV2_OSC_Item; -typedef struct _LV2_OSC_Arg LV2_OSC_Arg; -typedef void (*LV2_OSC_Branch)(LV2_OSC_Reader *reader, LV2_OSC_Arg *arg, - const LV2_OSC_Tree *tree, void *data); - -struct _LV2_OSC_Tree { - const char *name; - const LV2_OSC_Tree *trees; - LV2_OSC_Branch branch; -}; - -struct _LV2_OSC_Reader { - const uint8_t *buf; - const uint8_t *ptr; - const uint8_t *end; -}; - -struct _LV2_OSC_Item { - int32_t size; - const uint8_t *body; - - uint64_t timetag; - const uint8_t *end; -}; - -struct _LV2_OSC_Arg { - const char *type; - int32_t size; - union { - int32_t i; - float f; - const char *s; - const uint8_t *b; - - int64_t h; - double d; - uint64_t t; - - const uint8_t *m; - const char *S; - char c; - struct { - uint8_t R; - uint8_t G; - uint8_t B; - uint8_t A; - }; // anonymous RGBA struct - }; - - const char *path; - const uint8_t *end; -}; - -static inline void -lv2_osc_reader_initialize(LV2_OSC_Reader *reader, const uint8_t *buf, size_t size) -{ - reader->buf = buf; - reader->ptr = buf; - reader->end = buf + size; -} - -static inline bool -lv2_osc_reader_overflow(LV2_OSC_Reader *reader, size_t size) -{ - return reader->ptr + size > reader->end; -} - -static inline bool -lv2_osc_reader_be32toh(LV2_OSC_Reader *reader, union swap32_t *s32) -{ - if(lv2_osc_reader_overflow(reader, 4)) - return false; - - s32->u = *(const uint32_t *)reader->ptr; - s32->u = be32toh(s32->u); - reader->ptr += 4; - - return true; -} - -static inline bool -lv2_osc_reader_be64toh(LV2_OSC_Reader *reader, union swap64_t *s64) -{ - if(lv2_osc_reader_overflow(reader, 8)) - return false; - - s64->u = *(const uint64_t *)reader->ptr; - s64->u = be64toh(s64->u); - reader->ptr += 8; - - return true; -} - -static inline bool -lv2_osc_reader_get_int32(LV2_OSC_Reader *reader, int32_t *i) -{ - union swap32_t s32; - if(!lv2_osc_reader_be32toh(reader, &s32)) - return false; - - *i = s32.i; - - return true; -} - -static inline bool -lv2_osc_reader_get_float(LV2_OSC_Reader *reader, float *f) -{ - union swap32_t s32; - if(!lv2_osc_reader_be32toh(reader, &s32)) - return false; - - *f = s32.f; - - return true; -} - -static inline bool -lv2_osc_reader_get_int64(LV2_OSC_Reader *reader, int64_t *h) -{ - union swap64_t s64; - if(!lv2_osc_reader_be64toh(reader, &s64)) - return false; - - *h = s64.h; - - return true; -} - -static inline bool -lv2_osc_reader_get_timetag(LV2_OSC_Reader *reader, uint64_t *t) -{ - union swap64_t s64; - if(!lv2_osc_reader_be64toh(reader, &s64)) - return false; - - *t = s64.u; - - return true; -} - -static inline bool -lv2_osc_reader_get_double(LV2_OSC_Reader *reader, double *d) -{ - union swap64_t s64; - if(!lv2_osc_reader_be64toh(reader, &s64)) - return false; - - *d = s64.d; - - return true; -} - -static inline bool -lv2_osc_reader_get_string(LV2_OSC_Reader *reader, const char **s) -{ - const char *str = (const char *)reader->ptr; - const size_t padded = LV2_OSC_PADDED_SIZE(strlen(str) + 1); - if(lv2_osc_reader_overflow(reader, padded )) - return false; - - *s = str; - reader->ptr += padded; - - return true; -} - -static inline bool -lv2_osc_reader_get_symbol(LV2_OSC_Reader *reader, const char **S) -{ - return lv2_osc_reader_get_string(reader, S); -} - -static inline bool -lv2_osc_reader_get_midi(LV2_OSC_Reader *reader, const uint8_t **m) -{ - if(lv2_osc_reader_overflow(reader, 4)) - return false; - - *m = reader->ptr; - reader->ptr += 4; - - return true; -} - -static inline bool -lv2_osc_reader_get_blob(LV2_OSC_Reader *reader, int32_t *len, const uint8_t **body) -{ - if(!lv2_osc_reader_get_int32(reader, len)) - return false; - - const size_t padded = LV2_OSC_PADDED_SIZE(*len); - if(lv2_osc_reader_overflow(reader, padded)) - return false; - - *body = reader->ptr; - reader->ptr += padded; - - return true; -} - -static inline bool -lv2_osc_reader_get_rgba(LV2_OSC_Reader *reader, uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *a) -{ - if(lv2_osc_reader_overflow(reader, 4)) - return false; - - *r = reader->ptr[0]; - *g = reader->ptr[1]; - *b = reader->ptr[2]; - *a = reader->ptr[3]; - reader->ptr += 4; - - return true; -} - -static inline bool -lv2_osc_reader_get_char(LV2_OSC_Reader *reader, char *c) -{ - int32_t i; - if(!lv2_osc_reader_get_int32(reader, &i)) - return false; - - *c = i; - - return true; -} - -static inline LV2_OSC_Item * -lv2_osc_reader_item_raw(LV2_OSC_Reader *reader, LV2_OSC_Item *itm) -{ - if(!lv2_osc_reader_get_int32(reader, &itm->size)) - return NULL; - - if(lv2_osc_reader_overflow(reader, itm->size)) - return NULL; - - itm->body = reader->ptr; - - return itm; -} - -static inline LV2_OSC_Item * -lv2_osc_reader_item_begin(LV2_OSC_Reader *reader, LV2_OSC_Item *itm, size_t len) -{ - if(lv2_osc_reader_overflow(reader, len)) - return NULL; - - itm->end = reader->ptr + len; - - if(lv2_osc_reader_overflow(reader, 16)) - return NULL; - - if(strncmp((const char *)reader->ptr, "#bundle", 8)) - return NULL; - reader->ptr += 8; - - if(!lv2_osc_reader_get_timetag(reader, &itm->timetag)) - return NULL; - - return lv2_osc_reader_item_raw(reader, itm); -} - -static inline bool -lv2_osc_reader_item_is_end(LV2_OSC_Reader *reader, LV2_OSC_Item *itm) -{ - return reader->ptr > itm->end; -} - -static inline LV2_OSC_Item * -lv2_osc_reader_item_next(LV2_OSC_Reader *reader, LV2_OSC_Item *itm) -{ - reader->ptr += itm->size; - - return lv2_osc_reader_item_raw(reader, itm); -} - -#define OSC_READER_BUNDLE_BEGIN(reader, len) \ - lv2_osc_reader_item_begin( \ - (reader), \ - &(LV2_OSC_Item){ .size = 0, .body = NULL, .timetag = 1ULL, .end = NULL }, \ - len) - -#define OSC_READER_BUNDLE_ITERATE(reader, itm) \ - for(itm = itm; \ - itm && !lv2_osc_reader_item_is_end((reader), (itm)); \ - itm = lv2_osc_reader_item_next((reader), (itm))) - -#define OSC_READER_BUNDLE_FOREACH(reader, itm, len) \ - for(LV2_OSC_Item *(itm) = OSC_READER_BUNDLE_BEGIN((reader), (len)); \ - itm && !lv2_osc_reader_item_is_end((reader), (itm)); \ - itm = lv2_osc_reader_item_next((reader), (itm))) - -static inline LV2_OSC_Arg * -lv2_osc_reader_arg_raw(LV2_OSC_Reader *reader, LV2_OSC_Arg *arg) -{ - switch( (LV2_OSC_Type)*arg->type) - { - case LV2_OSC_INT32: - { - if(!lv2_osc_reader_get_int32(reader, &arg->i)) - return NULL; - arg->size = 4; - - break; - } - case LV2_OSC_FLOAT: - { - if(!lv2_osc_reader_get_float(reader, &arg->f)) - return NULL; - arg->size = 4; - - break; - } - case LV2_OSC_STRING: - { - if(!lv2_osc_reader_get_string(reader, &arg->s)) - return NULL; - arg->size = strlen(arg->s) + 1; - - break; - } - case LV2_OSC_BLOB: - { - if(!lv2_osc_reader_get_blob(reader, &arg->size, &arg->b)) - return NULL; - //arg->size = arg->size; - - break; - } - - case LV2_OSC_TRUE: - case LV2_OSC_FALSE: - case LV2_OSC_NIL: - case LV2_OSC_IMPULSE: - break; - - case LV2_OSC_INT64: - { - if(!lv2_osc_reader_get_int64(reader, &arg->h)) - return NULL; - arg->size = 8; - - break; - } - case LV2_OSC_DOUBLE: - { - if(!lv2_osc_reader_get_double(reader, &arg->d)) - return NULL; - arg->size = 8; - - break; - } - case LV2_OSC_TIMETAG: - { - if(!lv2_osc_reader_get_timetag(reader, &arg->t)) - return NULL; - arg->size = 8; - - break; - } - - case LV2_OSC_MIDI: - { - if(!lv2_osc_reader_get_midi(reader, &arg->m)) - return NULL; - arg->size = 4; - - break; - } - case LV2_OSC_SYMBOL: - { - if(!lv2_osc_reader_get_symbol(reader, &arg->S)) - return NULL; - arg->size = strlen(arg->S) + 1; - - break; - } - case LV2_OSC_CHAR: - { - if(!lv2_osc_reader_get_char(reader, &arg->c)) - return NULL; - arg->size = 4; - - break; - } - case LV2_OSC_RGBA: - { - if(!lv2_osc_reader_get_rgba(reader, &arg->R, &arg->G, &arg->B, &arg->A)) - return NULL; - arg->size = 4; - - break; - } - } - - return arg; -} - -static inline LV2_OSC_Arg * -lv2_osc_reader_arg_begin(LV2_OSC_Reader *reader, LV2_OSC_Arg *arg, size_t len) -{ - if(lv2_osc_reader_overflow(reader, len)) - return NULL; - - arg->end = reader->ptr + len; - - if(!lv2_osc_reader_get_string(reader, &arg->path)) //TODO check for validity - return NULL; - - if(!lv2_osc_reader_get_string(reader, &arg->type)) //TODO check for validity - return NULL; - - if(*arg->type != ',') - return NULL; - - arg->type++; // skip ',' - - return lv2_osc_reader_arg_raw(reader, arg); -} - -static inline bool -lv2_osc_reader_arg_is_end(LV2_OSC_Reader *reader, LV2_OSC_Arg *arg) -{ - return (*arg->type == '\0') || (reader->ptr > arg->end); -} - -static inline LV2_OSC_Arg * -lv2_osc_reader_arg_next(LV2_OSC_Reader *reader, LV2_OSC_Arg *arg) -{ - arg->type++; - - return lv2_osc_reader_arg_raw(reader, arg); -} - -#define OSC_READER_MESSAGE_BEGIN(reader, len) \ - lv2_osc_reader_arg_begin( \ - (reader), \ - &(LV2_OSC_Arg){ .type = NULL, .size = 0, .path = NULL, .end = NULL }, \ - len) - -#define OSC_READER_MESSAGE_ITERATE(reader, arg) \ - for(arg = arg; \ - arg && !lv2_osc_reader_arg_is_end((reader), (arg)); \ - arg = lv2_osc_reader_arg_next((reader), (arg))) - -#define OSC_READER_MESSAGE_FOREACH(reader, arg, len) \ - for(LV2_OSC_Arg *(arg) = OSC_READER_MESSAGE_BEGIN((reader), (len)); \ - arg && !lv2_osc_reader_arg_is_end((reader), (arg)); \ - arg = lv2_osc_reader_arg_next((reader), (arg))) - -static inline bool -lv2_osc_reader_arg_varlist(LV2_OSC_Reader *reader, const char *fmt, va_list args) -{ - for(const char *type = fmt; *type; type++) - { - switch( (LV2_OSC_Type)*type) - { - case LV2_OSC_INT32: - if(!lv2_osc_reader_get_int32(reader, va_arg(args, int32_t *))) - return false; - break; - case LV2_OSC_FLOAT: - if(!lv2_osc_reader_get_float(reader, va_arg(args, float *))) - return false; - break; - case LV2_OSC_STRING: - if(!lv2_osc_reader_get_string(reader, va_arg(args, const char **))) - return false; - break; - case LV2_OSC_BLOB: - if(!lv2_osc_reader_get_blob(reader, va_arg(args, int32_t *), va_arg(args, const uint8_t **))) - return false; - break; - - case LV2_OSC_TRUE: - case LV2_OSC_FALSE: - case LV2_OSC_NIL: - case LV2_OSC_IMPULSE: - break; - - case LV2_OSC_INT64: - if(!lv2_osc_reader_get_int64(reader, va_arg(args, int64_t *))) - return false; - break; - case LV2_OSC_DOUBLE: - if(!lv2_osc_reader_get_double(reader, va_arg(args, double *))) - return false; - break; - case LV2_OSC_TIMETAG: - if(!lv2_osc_reader_get_timetag(reader, va_arg(args, uint64_t *))) - return false; - break; - - case LV2_OSC_MIDI: - if(!lv2_osc_reader_get_midi(reader, va_arg(args, const uint8_t **))) - return false; - break; - case LV2_OSC_SYMBOL: - if(!lv2_osc_reader_get_symbol(reader, va_arg(args, const char **))) - return false; - break; - case LV2_OSC_CHAR: - if(!lv2_osc_reader_get_char(reader, va_arg(args, char *))) - return false; - break; - case LV2_OSC_RGBA: - if(!lv2_osc_reader_get_rgba(reader, va_arg(args, uint8_t *), va_arg(args, uint8_t *), - va_arg(args, uint8_t *), va_arg(args, uint8_t *))) - return false; - break; - } - } - - return true; -} - -static inline bool -lv2_osc_reader_arg_vararg(LV2_OSC_Reader *reader, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - - const bool res = lv2_osc_reader_arg_varlist(reader, fmt, args); - - va_end(args); - - return res; -} - -static inline bool -lv2_osc_reader_is_bundle(LV2_OSC_Reader *reader) -{ - return strncmp((const char *)reader->ptr, "#bundle", 8) == 0; -} - -static inline bool -lv2_osc_reader_is_message(LV2_OSC_Reader *reader) -{ - return reader->ptr[0] == '/'; //FIXME check path -} - -static inline void -_lv2_osc_trees_internal(LV2_OSC_Reader *reader, const char *path, const char *from, - LV2_OSC_Arg *arg, const LV2_OSC_Tree *trees, void *data) -{ - const char *ptr = strchr(from, '/'); - const char *pattern = strpbrk(from, "*?[]{}/"); - const bool has_pattern = pattern && (pattern[0] != '/'); - (void)has_pattern; //FIXME - - const size_t len = ptr - ? (size_t)(ptr - from) - : strlen(from); - - for(const LV2_OSC_Tree *tree = trees; tree && tree->name; tree++) - { - if(lv2_osc_pattern_match(from, tree->name, len)) - { - if(tree->trees && ptr) - { - if(tree->branch) - { - LV2_OSC_Reader reader_clone = *reader; - tree->branch(&reader_clone, arg, tree, data); - } - - _lv2_osc_trees_internal(reader, path, &ptr[1], arg, tree->trees, data); - } - else if(tree->branch && !ptr) - { - LV2_OSC_Reader reader_clone = *reader; - tree->branch(&reader_clone, arg, tree, data); - } - } - } -} - -static inline void -lv2_osc_reader_match(LV2_OSC_Reader *reader, size_t len, - const LV2_OSC_Tree *trees, void *data) -{ - LV2_OSC_Arg *arg = OSC_READER_MESSAGE_BEGIN(reader, len); - const char *path = arg->path; - const char *from = &path[1]; - - _lv2_osc_trees_internal(reader, path, from, arg, trees, data); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // LV2_OSC_READER_H diff --git a/osc.lv2/osc.lv2/stream.h b/osc.lv2/osc.lv2/stream.h deleted file mode 100644 index 55c94d2..0000000 --- a/osc.lv2/osc.lv2/stream.h +++ /dev/null @@ -1,1433 +0,0 @@ -/* - * Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the Artistic License 2.0 as published by - * The Perl Foundation. - * - * This source 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 - * Artistic License 2.0 for more details. - * - * You should have received a copy of the Artistic License 2.0 - * along the source as a COPYING file. If not, obtain it from - * http://www.perlfoundation.org/artistic_license_2_0. - */ - -#ifndef LV2_OSC_STREAM_H -#define LV2_OSC_STREAM_H - -#include -#include -#include -#if !defined(_WIN32) -# include -# include -# include -# include -# include -# include -# include -# include -#endif -#include -#include -#include -#include -#include - -#include - -#if !defined(LV2_OSC_STREAM_SNDBUF) -# define LV2_OSC_STREAM_SNDBUF 0x100000 // 1 M -#endif - -#if !defined(LV2_OSC_STREAM_RCVBUF) -# define LV2_OSC_STREAM_RCVBUF 0x100000 // 1 M -#endif - -#if !defined(LV2_OSC_STREAM_REQBUF) -# define LV2_OSC_STREAM_REQBUF 1024 -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void * -(*LV2_OSC_Stream_Write_Request)(void *data, size_t minimum, size_t *maximum); - -typedef void -(*LV2_OSC_Stream_Write_Advance)(void *data, size_t written); - -typedef const void * -(*LV2_OSC_Stream_Read_Request)(void *data, size_t *toread); - -typedef void -(*LV2_OSC_Stream_Read_Advance)(void *data); - -typedef struct _LV2_OSC_Address LV2_OSC_Address; -typedef struct _LV2_OSC_Driver LV2_OSC_Driver; -typedef struct _LV2_OSC_Stream LV2_OSC_Stream; - -struct _LV2_OSC_Address { - socklen_t len; - union { - struct sockaddr_in in4; - struct sockaddr_in6 in6; - }; -}; - -struct _LV2_OSC_Driver { - LV2_OSC_Stream_Write_Request write_req; - LV2_OSC_Stream_Write_Advance write_adv; - LV2_OSC_Stream_Read_Request read_req; - LV2_OSC_Stream_Read_Advance read_adv; -}; - -struct _LV2_OSC_Stream { - int socket_family; - int socket_type; - int protocol; - bool server; - bool slip; - bool serial; - bool connected; - int sock; - int fd; - LV2_OSC_Address self; - LV2_OSC_Address peer; - const LV2_OSC_Driver *driv; - void *data; - uint8_t tx_buf [0x4000]; - uint8_t rx_buf [0x4000]; - size_t rx_off; - char url [PATH_MAX]; -}; - -typedef enum _LV2_OSC_Enum { - LV2_OSC_NONE = 0x000000, - - LV2_OSC_SEND = 0x800000, - LV2_OSC_RECV = 0x400000, - LV2_OSC_CONN = 0x200000, - - LV2_OSC_ERR = 0x00ffff -} LV2_OSC_Enum; - -static const char *udp_prefix = "osc.udp://"; -static const char *tcp_prefix = "osc.tcp://"; -static const char *tcp_slip_prefix = "osc.slip.tcp://"; -static const char *tcp_prefix_prefix = "osc.prefix.tcp://"; -static const char *ser_prefix = "osc.serial://"; -//FIXME serial - - -static inline int -_lv2_osc_stream_interface_attribs(int fd, int speed) -{ - struct termios tty; - - if(tcgetattr(fd, &tty) < 0) - { - return -1; - } - - cfsetospeed(&tty, (speed_t)speed); - cfsetispeed(&tty, (speed_t)speed); - - tty.c_cflag |= (CLOCAL | CREAD); /* ignore modem controls */ - tty.c_cflag &= ~CSIZE; - tty.c_cflag |= CS8; /* 8-bit characters */ - tty.c_cflag &= ~PARENB; /* no parity bit */ - tty.c_cflag &= ~CSTOPB; /* only need 1 stop bit */ - tty.c_cflag &= ~CRTSCTS; /* no hardware flowcontrol */ - - /* setup for non-canonical mode */ - tty.c_iflag &= ~(IGNCR | ONLCR | IXON); - tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); - tty.c_oflag &= ~OPOST; - - /* fetch bytes as they become available */ - tty.c_cc[VMIN] = 0; - tty.c_cc[VTIME] = 0; - - if(tcsetattr(fd, TCSANOW, &tty) != 0) - { - return -1; - } - - return 0; -} - -#define LV2_OSC_STREAM_ERRNO(EV, ERRNO) ( (EV & (~LV2_OSC_ERR)) | (ERRNO) ) - -static inline void -_close_socket(int *fd) -{ - if(fd) - { - if(*fd >= 0) - { - close(*fd); - } - - *fd = -1; - } -} - -static inline int -lv2_osc_stream_deinit(LV2_OSC_Stream *stream) -{ - _close_socket(&stream->fd); - _close_socket(&stream->sock); - - return 0; -} - -static inline int -_lv2_osc_stream_reinit(LV2_OSC_Stream *stream) -{ - LV2_OSC_Enum ev = LV2_OSC_NONE; - lv2_osc_stream_deinit(stream); - - char *dup = strdup(stream->url); - if(!dup) - { - ev = LV2_OSC_STREAM_ERRNO(ev, ENOMEM); - goto fail; - } - - char *ptr = dup; - char *tmp; - - if(strncmp(ptr, udp_prefix, strlen(udp_prefix)) == 0) - { - stream->slip = false; - stream->socket_family = AF_INET; - stream->socket_type = SOCK_DGRAM; - stream->protocol = IPPROTO_UDP; - ptr += strlen(udp_prefix); - } - else if(strncmp(ptr, tcp_prefix, strlen(tcp_prefix)) == 0) - { - stream->slip = true; - stream->socket_family = AF_INET; - stream->socket_type = SOCK_STREAM; - stream->protocol = IPPROTO_TCP; - ptr += strlen(tcp_prefix); - } - else if(strncmp(ptr, tcp_slip_prefix, strlen(tcp_slip_prefix)) == 0) - { - stream->slip = true; - stream->socket_family = AF_INET; - stream->socket_type = SOCK_STREAM; - stream->protocol = IPPROTO_TCP; - ptr += strlen(tcp_slip_prefix); - } - else if(strncmp(ptr, tcp_prefix_prefix, strlen(tcp_prefix_prefix)) == 0) - { - stream->slip = false; - stream->socket_family = AF_INET; - stream->socket_type = SOCK_STREAM; - stream->protocol = IPPROTO_TCP; - ptr += strlen(tcp_prefix_prefix); - } - else if(strncmp(ptr, ser_prefix, strlen(ser_prefix)) == 0) - { - stream->slip = true; - stream->serial = true; - ptr += strlen(ser_prefix); - } - else - { - ev = LV2_OSC_STREAM_ERRNO(ev, ENOPROTOOPT); - goto fail; - } - - if(ptr[0] == '\0') - { - ev = LV2_OSC_STREAM_ERRNO(ev, EDESTADDRREQ); - goto fail; - } - - if(stream->serial) - { - stream->sock = open(ptr, O_RDWR | O_NOCTTY | O_NDELAY); - if(stream->sock < 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(fcntl(stream->sock, F_SETFL, FNDELAY) == -1) //FIXME - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(_lv2_osc_stream_interface_attribs(stream->sock, B115200) == -1) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - stream->connected = true; - } - else // !stream->serial - { - const char *node = NULL; - const char *iface = NULL; - const char *service = NULL; - - // optional IPv6 - if(ptr[0] == '[') - { - stream->socket_family = AF_INET6; - ++ptr; - } - - node = ptr; - - // optional IPv6 - if( (tmp = strchr(ptr, '%')) ) - { - if(stream->socket_family != AF_INET6) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EPROTOTYPE); - goto fail; - } - - ptr = tmp; - ptr[0] = '\0'; - iface = ++ptr; - } - - // optional IPv6 - if( (tmp = strchr(ptr, ']')) ) - if(ptr) - { - if(stream->socket_family != AF_INET6) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EDESTADDRREQ); - goto fail; - } - - ptr = tmp; - ptr[0] = '\0'; - ++ptr; - } - - // mandatory IPv4/6 - ptr = strchr(ptr, ':'); - if(!ptr) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EDESTADDRREQ); - goto fail; - } - - ptr[0] = '\0'; - - service = ++ptr; - - if(strlen(node) == 0) - { - node = NULL; - stream->server = true; - } - - stream->sock = socket(stream->socket_family, stream->socket_type, - stream->protocol); - - if(stream->sock < 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(fcntl(stream->sock, F_SETFL, O_NONBLOCK) == -1) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - const int sendbuff = LV2_OSC_STREAM_SNDBUF; - const int recvbuff = LV2_OSC_STREAM_RCVBUF; - const int reuseaddr = 1; - - if(setsockopt(stream->sock, SOL_SOCKET, - SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == -1) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(setsockopt(stream->sock, SOL_SOCKET, - SO_RCVBUF, &recvbuff, sizeof(recvbuff)) == -1) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(setsockopt(stream->sock, SOL_SOCKET, - SO_REUSEADDR, &reuseaddr, sizeof(reuseaddr)) == -1) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(stream->socket_family == AF_INET) // IPv4 - { - if(stream->server) - { - // resolve self address - struct addrinfo hints; - memset(&hints, 0x0, sizeof(struct addrinfo)); - hints.ai_family = stream->socket_family; - hints.ai_socktype = stream->socket_type; - hints.ai_protocol = stream->protocol; - - struct addrinfo *res; - if(getaddrinfo(node, service, &hints, &res) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - if(res->ai_addrlen != sizeof(stream->peer.in4)) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EPROTOTYPE); - goto fail; - } - - stream->self.len = res->ai_addrlen; - memcpy(&stream->self.in4, res->ai_addr, res->ai_addrlen); - stream->self.in4.sin_addr.s_addr = htonl(INADDR_ANY); - - freeaddrinfo(res); - - if(bind(stream->sock, (struct sockaddr *)&stream->self.in4, - stream->self.len) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - } - else // client - { - stream->self.len = sizeof(stream->self.in4); - stream->self.in4.sin_family = stream->socket_family; - stream->self.in4.sin_port = htons(0); - stream->self.in4.sin_addr.s_addr = htonl(INADDR_ANY); - - if(bind(stream->sock, (struct sockaddr *)&stream->self.in4, - stream->self.len) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - // resolve peer address - struct addrinfo hints; - memset(&hints, 0x0, sizeof(struct addrinfo)); - hints.ai_family = stream->socket_family; - hints.ai_socktype = stream->socket_type; - hints.ai_protocol = stream->protocol; - - struct addrinfo *res; - if(getaddrinfo(node, service, &hints, &res) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - if(res->ai_addrlen != sizeof(stream->peer.in4)) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EPROTOTYPE); - goto fail; - } - - stream->peer.len = res->ai_addrlen; - memcpy(&stream->peer.in4, res->ai_addr, res->ai_addrlen); - - freeaddrinfo(res); - } - - if(stream->socket_type == SOCK_DGRAM) - { - const int broadcast = 1; - - if(setsockopt(stream->sock, SOL_SOCKET, SO_BROADCAST, - &broadcast, sizeof(broadcast)) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - //FIXME handle multicast - } - else if(stream->socket_type == SOCK_STREAM) - { - const int flag = 1; - - if(setsockopt(stream->sock, stream->protocol, - TCP_NODELAY, &flag, sizeof(flag)) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(setsockopt(stream->sock, SOL_SOCKET, - SO_KEEPALIVE, &flag, sizeof(flag)) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(stream->server) - { - if(listen(stream->sock, 1) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - } - else // client - { - if(connect(stream->sock, (struct sockaddr *)&stream->peer.in4, - stream->peer.len) == 0) - { - stream->connected = true; - } - } - } - else - { - ev = LV2_OSC_STREAM_ERRNO(ev, EPROTOTYPE); - goto fail; - } - } - else if(stream->socket_family == AF_INET6) // IPv6 - { - if(stream->server) - { - // resolve self address - struct addrinfo hints; - memset(&hints, 0x0, sizeof(struct addrinfo)); - hints.ai_family = stream->socket_family; - hints.ai_socktype = stream->socket_type; - hints.ai_protocol = stream->protocol; - - struct addrinfo *res; - if(getaddrinfo(node, service, &hints, &res) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - if(res->ai_addrlen != sizeof(stream->peer.in6)) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EPROTOTYPE); - goto fail; - } - - stream->self.len = res->ai_addrlen; - memcpy(&stream->self.in6, res->ai_addr, res->ai_addrlen); - stream->self.in6.sin6_addr = in6addr_any; - if(iface) - { - stream->self.in6.sin6_scope_id = if_nametoindex(iface); - } - - freeaddrinfo(res); - - if(bind(stream->sock, (struct sockaddr *)&stream->self.in6, - stream->self.len) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - } - else // client - { - stream->self.len = sizeof(stream->self.in6); - stream->self.in6.sin6_family = stream->socket_family; - stream->self.in6.sin6_port = htons(0); - stream->self.in6.sin6_addr = in6addr_any; - if(iface) - { - stream->self.in6.sin6_scope_id = if_nametoindex(iface); - } - - if(bind(stream->sock, (struct sockaddr *)&stream->self.in6, - stream->self.len) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - // resolve peer address - struct addrinfo hints; - memset(&hints, 0x0, sizeof(struct addrinfo)); - hints.ai_family = stream->socket_family; - hints.ai_socktype = stream->socket_type; - hints.ai_protocol = stream->protocol; - - struct addrinfo *res; - if(getaddrinfo(node, service, &hints, &res) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - if(res->ai_addrlen != sizeof(stream->peer.in6)) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EPROTOTYPE); - goto fail; - } - - stream->peer.len = res->ai_addrlen; - memcpy(&stream->peer.in6, res->ai_addr, res->ai_addrlen); - - if(iface) - { - stream->peer.in6.sin6_scope_id = if_nametoindex(iface); - } - - freeaddrinfo(res); - } - - if(stream->socket_type == SOCK_DGRAM) - { - // nothing to do - } - else if(stream->socket_type == SOCK_STREAM) - { - const int flag = 1; - - if(setsockopt(stream->sock, stream->protocol, - TCP_NODELAY, &flag, sizeof(flag)) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(setsockopt(stream->sock, SOL_SOCKET, - SO_KEEPALIVE, &flag, sizeof(flag)) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - - if(stream->server) - { - if(listen(stream->sock, 1) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - goto fail; - } - } - else // client - { - if(connect(stream->sock, (struct sockaddr *)&stream->peer.in6, - stream->peer.len) == 0) - { - stream->connected = true; - } - } - } - else - { - ev = LV2_OSC_STREAM_ERRNO(ev, EPROTOTYPE); - goto fail; - } - } - else - { - ev = LV2_OSC_STREAM_ERRNO(ev, EPROTOTYPE); - goto fail; - } - } - - free(dup); - - return ev; - -fail: - if(dup) - { - free(dup); - } - - _close_socket(&stream->sock); - - return ev; -} - -static inline int -lv2_osc_stream_init(LV2_OSC_Stream *stream, const char *url, - const LV2_OSC_Driver *driv, void *data) -{ - memset(stream, 0x0, sizeof(LV2_OSC_Stream)); - - strncpy(stream->url, url, sizeof(stream->url) - 1); - stream->driv = driv; - stream->data = data; - stream->sock = -1; - stream->fd = -1; - - return _lv2_osc_stream_reinit(stream); -} - -#define SLIP_END 0300 // 0xC0, 192, indicates end of packet -#define SLIP_ESC 0333 // 0xDB, 219, indicates byte stuffing -#define SLIP_END_REPLACE 0334 // 0xDC, 220, ESC ESC_END means END data byte -#define SLIP_ESC_REPLACE 0335 // 0xDD, 221, ESC ESC_ESC means ESC data byte - -// SLIP encoding -static inline size_t -lv2_osc_slip_encode_inline(uint8_t *dst, size_t len) -{ - if(len == 0) - return 0; - - const uint8_t *end = dst + len; - - // estimate new size - size_t size = 2; // double ended SLIP - for(const uint8_t *from=dst; from=dst; from--) - { - if(*from == SLIP_END) - { - *to-- = SLIP_END_REPLACE; - *to-- = SLIP_ESC; - } - else if(*from == SLIP_ESC) - { - *to-- = SLIP_ESC_REPLACE; - *to-- = SLIP_ESC; - } - else - *to-- = *from; - } - *to-- = SLIP_END; - - return size; -} - -// SLIP decoding -static inline size_t -lv2_osc_slip_decode_inline(uint8_t *dst, size_t len, size_t *size) -{ - const uint8_t *src = dst; - const uint8_t *end = dst + len; - uint8_t *ptr = dst; - - bool whole = false; - - if( (src < end) && (*src == SLIP_END) ) - { - whole = true; - src++; - } - - while(src < end) - { - if(*src == SLIP_ESC) - { - if(src == end-1) - break; - - src++; - if(*src == SLIP_END_REPLACE) - *ptr++ = SLIP_END; - else if(*src == SLIP_ESC_REPLACE) - *ptr++ = SLIP_ESC; - src++; - } - else if(*src == SLIP_END) - { - src++; - - *size = whole ? ptr - dst : 0; - return src - dst; - } - else - { - *ptr++ = *src++; - } - } - - *size = 0; - return 0; -} - -static inline LV2_OSC_Enum -_lv2_osc_stream_run_udp(LV2_OSC_Stream *stream) -{ - LV2_OSC_Enum ev = LV2_OSC_NONE; - - // send everything - if(stream->peer.len) // has a peer - { - const uint8_t *buf; - size_t tosend; - - while( (buf = stream->driv->read_req(stream->data, &tosend)) ) - { - const ssize_t sent = sendto(stream->sock, buf, tosend, 0, - (struct sockaddr *)&stream->peer.in6, stream->peer.len); - - if(sent == -1) - { - if( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) - { - // full queue - break; - } - - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - break; - } - else if(sent != (ssize_t)tosend) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EIO); - break; - } - - stream->driv->read_adv(stream->data); - ev |= LV2_OSC_SEND; - } - } - - // recv everything - { - uint8_t *buf; - size_t max_len; - - while( (buf = stream->driv->write_req(stream->data, - LV2_OSC_STREAM_REQBUF, &max_len)) ) - { - struct sockaddr_in6 in; - socklen_t in_len = sizeof(in); - - memset(&in, 0, in_len); - const ssize_t recvd = recvfrom(stream->sock, buf, max_len, 0, - (struct sockaddr *)&in, &in_len); - - if(recvd == -1) - { - if( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) - { - // empty queue - break; - } - - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - break; - } - else if(recvd == 0) - { - // peer has shut down - break; - } - - stream->peer.len = in_len; - memcpy(&stream->peer.in6, &in, in_len); - - stream->driv->write_adv(stream->data, recvd); - ev |= LV2_OSC_RECV; - } - } - - return ev; -} - -static inline LV2_OSC_Enum -_lv2_osc_stream_run_tcp(LV2_OSC_Stream *stream) -{ - LV2_OSC_Enum ev = LV2_OSC_NONE; - - // handle connections - if(!stream->connected) // no peer - { - if(stream->server) - { - stream->peer.len = sizeof(stream->peer.in6); - stream->fd = accept(stream->sock, (struct sockaddr *)&stream->peer.in6, - &stream->peer.len); - - if(stream->fd >= 0) - { - const int flag = 1; - const int sendbuff = LV2_OSC_STREAM_SNDBUF; - const int recvbuff = LV2_OSC_STREAM_RCVBUF; - - if(fcntl(stream->fd, F_SETFL, O_NONBLOCK) == -1) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - } - - if(setsockopt(stream->fd, stream->protocol, - TCP_NODELAY, &flag, sizeof(flag)) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - } - - if(setsockopt(stream->sock, SOL_SOCKET, - SO_KEEPALIVE, &flag, sizeof(flag)) != 0) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - } - - if(setsockopt(stream->fd, SOL_SOCKET, - SO_SNDBUF, &sendbuff, sizeof(sendbuff)) == -1) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - } - - if(setsockopt(stream->fd, SOL_SOCKET, - SO_RCVBUF, &recvbuff, sizeof(recvbuff)) == -1) - { - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - } - - stream->connected = true; // orderly accept - } - else - { - //ev = LV2_OSC_STREAM_ERRNO(ev, errno); - } - } - else - { - if(stream->sock < 0) - { - ev = _lv2_osc_stream_reinit(stream); - } - - if(connect(stream->sock, (struct sockaddr *)&stream->peer.in6, - stream->peer.len) == 0) - { - stream->connected = true; // orderly (re)connect - } - else - { - //if(errno == EISCONN) - //{ - // _close_socket(&stream->sock); - //} - - //ev = LV2_OSC_STREAM_ERRNO(ev, errno); - } - } - } - - // send everything - if(stream->connected) - { - int *fd = stream->server - ? &stream->fd - : &stream->sock; - - if(*fd >= 0) - { - const uint8_t *buf; - size_t tosend; - - while( (buf = stream->driv->read_req(stream->data, &tosend)) ) - { - if(stream->slip) // SLIP framed - { - if(tosend <= sizeof(stream->tx_buf)) // check if there is enough memory - { - memcpy(stream->tx_buf, buf, tosend); - tosend = lv2_osc_slip_encode_inline(stream->tx_buf, tosend); - } - else - { - tosend = 0; - } - } - else // uint32_t prefix frames - { - const size_t nsize = tosend + sizeof(uint32_t); - - if(nsize <= sizeof(stream->tx_buf)) // check if there is enough memory - { - const uint32_t prefix = htonl(tosend); - - memcpy(stream->tx_buf, &prefix, sizeof(uint32_t)); - memcpy(stream->tx_buf + sizeof(uint32_t), buf, tosend); - tosend = nsize; - } - else - { - tosend = 0; - } - } - - const ssize_t sent = tosend - ? send(*fd, stream->tx_buf, tosend, 0) - : 0; - - if(sent == -1) - { - if( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) - { - // empty queue - break; - } - - _close_socket(fd); - stream->connected = false; - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - break; - } - else if(sent != (ssize_t)tosend) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EIO); - break; - } - - stream->driv->read_adv(stream->data); - ev |= LV2_OSC_SEND; - } - } - } - - // recv everything - if(stream->connected) - { - int *fd = stream->server - ? &stream->fd - : &stream->sock; - - if(*fd >= 0) - { - if(stream->slip) // SLIP framed - { - while(true) - { - ssize_t recvd = recv(*fd, stream->rx_buf + stream->rx_off, - sizeof(stream->rx_buf) - stream->rx_off, 0); - - if(recvd == -1) - { - if( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) - { - // empty queue - break; - } - - _close_socket(fd); - stream->connected = false; - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - break; - } - else if(recvd == 0) - { - _close_socket(fd); - stream->connected = false; // orderly shutdown - break; - } - - uint8_t *ptr = stream->rx_buf; - recvd += stream->rx_off; - - while(recvd > 0) - { - size_t size; - size_t parsed = lv2_osc_slip_decode_inline(ptr, recvd, &size); - - if(size) // dispatch - { - uint8_t *buf; - - if( (buf = stream->driv->write_req(stream->data, size, NULL)) ) - { - memcpy(buf, ptr, size); - - stream->driv->write_adv(stream->data, size); - ev |= LV2_OSC_RECV; - } - else - { - parsed = 0; - ev = LV2_OSC_STREAM_ERRNO(ev, ENOMEM); - } - } - - if(parsed) - { - ptr += parsed; - recvd -= parsed; - } - else - { - break; - } - } - - if(recvd > 0) // is there remaining chunk for next call? - { - memmove(stream->rx_buf, ptr, recvd); - stream->rx_off = recvd; - } - else - { - stream->rx_off = 0; - } - - break; - } - } - else // uint32_t prefix frames - { - uint8_t *buf; - - while( (buf = stream->driv->write_req(stream->data, - LV2_OSC_STREAM_REQBUF, NULL)) ) - { - uint32_t prefix; - - ssize_t recvd = recv(*fd, &prefix, sizeof(uint32_t), 0); - if(recvd == sizeof(uint32_t)) - { - prefix = ntohl(prefix); //FIXME check prefix <= max_len - recvd = recv(*fd, buf, prefix, 0); - } - else if(recvd == -1) - { - if( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) - { - // empty queue - break; - } - - _close_socket(fd); - stream->connected = false; - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - break; - } - else if(recvd == 0) - { - _close_socket(fd); - stream->connected = false; // orderly shutdown - break; - } - - stream->driv->write_adv(stream->data, recvd); - ev |= LV2_OSC_RECV; - } - } - } - } - - if(stream->connected) - { - ev |= LV2_OSC_CONN; - } - - return ev; -} - -static inline LV2_OSC_Enum -_lv2_osc_stream_run_ser(LV2_OSC_Stream *stream) -{ - LV2_OSC_Enum ev = LV2_OSC_NONE; - - // send everything - { - const int fd = stream->sock; - - if(fd >= 0) - { - const uint8_t *buf; - size_t tosend; - - while( (buf = stream->driv->read_req(stream->data, &tosend)) ) - { - if(stream->slip) // SLIP framed - { - if(tosend <= sizeof(stream->tx_buf)) // check if there is enough memory - { - memcpy(stream->tx_buf, buf, tosend); - tosend = lv2_osc_slip_encode_inline(stream->tx_buf, tosend); - } - else - { - tosend = 0; - } - } - else // uint32_t prefix frames - { - const size_t nsize = tosend + sizeof(uint32_t); - - if(nsize <= sizeof(stream->tx_buf)) // check if there is enough memory - { - const uint32_t prefix = htonl(tosend); - - memcpy(stream->tx_buf, &prefix, sizeof(uint32_t)); - memcpy(stream->tx_buf + sizeof(uint32_t), buf, tosend); - tosend = nsize; - } - else - { - tosend = 0; - } - } - - const ssize_t sent = tosend - ? write(fd, stream->tx_buf, tosend) - : 0; - - if(sent == -1) - { - if( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) - { - // empty queue - break; - } - - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - break; - } - else if(sent != (ssize_t)tosend) - { - ev = LV2_OSC_STREAM_ERRNO(ev, EIO); - break; - } - - stream->driv->read_adv(stream->data); - ev |= LV2_OSC_SEND; - } - } - } - - // recv everything - { - const int fd = stream->sock; - - if(fd >= 0) - { - if(stream->slip) // SLIP framed - { - while(true) - { - ssize_t recvd = read(fd, stream->rx_buf + stream->rx_off, - sizeof(stream->rx_buf) - stream->rx_off); - - if(recvd == -1) - { - if( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) - { - // empty queue - break; - } - - stream->connected = false; - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - break; - } - else if(recvd == 0) - { - // orderly shutdown - break; - } - - uint8_t *ptr = stream->rx_buf; - recvd += stream->rx_off; - - while(recvd > 0) - { - size_t size; - size_t parsed = lv2_osc_slip_decode_inline(ptr, recvd, &size); - - if(size) // dispatch - { - uint8_t *buf; - - if( (buf = stream->driv->write_req(stream->data, size, NULL)) ) - { - memcpy(buf, ptr, size); - - stream->driv->write_adv(stream->data, size); - ev |= LV2_OSC_RECV; - } - else - { - parsed = 0; - ev = LV2_OSC_STREAM_ERRNO(ev, ENOMEM); - } - } - - if(parsed) - { - ptr += parsed; - recvd -= parsed; - } - else - { - break; - } - } - - if(recvd > 0) // is there remaining chunk for next call? - { - memmove(stream->rx_buf, ptr, recvd); - stream->rx_off = recvd; - } - else - { - stream->rx_off = 0; - } - - break; - } - } - else // uint32_t prefix frames - { - uint8_t *buf; - - while( (buf = stream->driv->write_req(stream->data, - LV2_OSC_STREAM_REQBUF, NULL)) ) - { - uint32_t prefix; - - ssize_t recvd = read(fd, &prefix, sizeof(uint32_t)); - if(recvd == sizeof(uint32_t)) - { - prefix = ntohl(prefix); //FIXME check prefix <= max_len - recvd = read(fd, buf, prefix); - } - else if(recvd == -1) - { - if( (errno == EAGAIN) || (errno == EWOULDBLOCK) ) - { - // empty queue - break; - } - - stream->connected = false; - ev = LV2_OSC_STREAM_ERRNO(ev, errno); - break; - } - else if(recvd == 0) - { - // orderly shutdown - break; - } - - stream->driv->write_adv(stream->data, recvd); - ev |= LV2_OSC_RECV; - } - } - } - } - - if(stream->connected) - { - ev |= LV2_OSC_CONN; - } - - return ev; -} - -static inline LV2_OSC_Enum -lv2_osc_stream_run(LV2_OSC_Stream *stream) -{ - LV2_OSC_Enum ev = LV2_OSC_NONE; - - switch(stream->socket_type) - { - case SOCK_DGRAM: - { - ev |= _lv2_osc_stream_run_udp(stream); - } break; - case SOCK_STREAM: - { - ev |= _lv2_osc_stream_run_tcp(stream); - } break; - default: - { - ev |= _lv2_osc_stream_run_ser(stream); - } break; - } - - return ev; -} - -static inline int -lv2_osc_stream_get_file_descriptors(LV2_OSC_Stream *stream, int fds [2]) -{ - if(!fds) - { - return 1; - } - - fds[0] = stream->sock; - fds[1] = stream->fd; - - return 0; -} - -static inline LV2_OSC_Enum -lv2_osc_stream_pollin(LV2_OSC_Stream *stream, int timeout_ms) -{ - int fd [2]; - - if(lv2_osc_stream_get_file_descriptors(stream, fd) != 0) - { - return LV2_OSC_STREAM_ERRNO(LV2_OSC_NONE, EBADF); - } - - struct pollfd fds [2] = { - [0] = { - .fd = fd[0], - .events = POLLIN, - .revents = 0 - }, - [1] = { - .fd = fd[1], - .events = POLLIN, - .revents = 0 - } - }; - - const int res = poll(fds, 2, timeout_ms); - if(res < 0) - { - return LV2_OSC_STREAM_ERRNO(LV2_OSC_NONE, errno); - } - -#if 0 - fprintf(stderr, "++ %i: %i %i %i %i\n", res, - fds[0].fd, (int)fds[0].revents, - fds[1].fd, (int)fds[1].revents); -#endif - - return lv2_osc_stream_run(stream); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // LV2_OSC_STREAM_H diff --git a/osc.lv2/osc.lv2/util.h b/osc.lv2/osc.lv2/util.h deleted file mode 100644 index fdf2da3..0000000 --- a/osc.lv2/osc.lv2/util.h +++ /dev/null @@ -1,631 +0,0 @@ -/* - * Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the Artistic License 2.0 as published by - * The Perl Foundation. - * - * This source 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 - * Artistic License 2.0 for more details. - * - * You should have received a copy of the Artistic License 2.0 - * along the source as a COPYING file. If not, obtain it from - * http://www.perlfoundation.org/artistic_license_2_0. - */ - -#ifndef LV2_OSC_UTIL_H -#define LV2_OSC_UTIL_H - -#include -#include -#include -#include -#include -#if !defined(_WIN32) -# include -#endif - -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef __unused -# define __unused __attribute__((unused)) -#endif - -#undef LV2_ATOM_TUPLE_FOREACH // there is a bug in LV2 1.10.0 -#define LV2_ATOM_TUPLE_FOREACH(tuple, iter) \ - for (LV2_Atom* (iter) = lv2_atom_tuple_begin(tuple); \ - !lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), (tuple)->atom.size, (iter)); \ - (iter) = lv2_atom_tuple_next(iter)) - -typedef void (*LV2_OSC_Method)(const char *path, - const LV2_Atom_Tuple *arguments, void *data); - -typedef struct _LV2_OSC_Hook LV2_OSC_Hook; - -struct _LV2_OSC_Hook { - const char *name; - const LV2_OSC_Hook *hooks; - LV2_OSC_Method method; - void *data; -}; - -// characters not allowed in OSC path string -static const char invalid_path_chars [] = { - ' ', '#', - '\0' -}; - -// allowed characters in OSC format string -static const char valid_format_chars [] = { - LV2_OSC_INT32, LV2_OSC_FLOAT, LV2_OSC_STRING, LV2_OSC_BLOB, - LV2_OSC_TRUE, LV2_OSC_FALSE, LV2_OSC_NIL, LV2_OSC_IMPULSE, - LV2_OSC_INT64, LV2_OSC_DOUBLE, LV2_OSC_TIMETAG, - LV2_OSC_SYMBOL, LV2_OSC_MIDI, - '\0' -}; - -static inline bool -lv2_osc_pattern_match(const char *from, const char *name, size_t len) -{ -#if !defined(_WIN32) - size_t nbrace = 0; - -# if defined(FNM_EXTMATCH) - // count opening curly braces - for(size_t i = 0; i < len; i++) - { - if(from[i] == '{') - { - nbrace++; - } - } -# endif - - // allocate temporary pattern buffer - char *pattern = alloca(len + nbrace + 1); - - if(!pattern) - { - return false; - } - -# if defined(FNM_EXTMATCH) - // convert {x,y} to @(x|y) for extended fnmatch - if(nbrace) - { - char *ptr = pattern; - - for(size_t i = 0; i < len; i++) - { - switch(from[i]) - { - case '{': - { - *ptr++ = '@'; - *ptr++ = '('; - } break; - case ',': - { - *ptr++ = '|'; - } break; - case '}': - { - *ptr++ = ')'; - } break; - default: - { - *ptr++ = from[i]; - } break; - } - } - } - else -# endif - { - memcpy(pattern, from, len); - } - - // terminate pattern string with null terminator - pattern[len + nbrace] = '\0'; - -# if defined(FNM_EXTMATCH) - return fnmatch(pattern, name, FNM_NOESCAPE | FNM_EXTMATCH) == 0 ? true : false; -# else - return fnmatch(pattern, name, FNM_NOESCAPE) == 0 ? true : false; -# endif -#else - return strncmp(from, name, len) == 0 ? true : false; -#endif -} - -static inline void -_lv2_osc_hooks_internal(const char *path, const char *from, - const LV2_Atom_Tuple *arguments, const LV2_OSC_Hook *hooks) -{ - const char *ptr = strchr(from, '/'); - - const size_t len = ptr - ? (size_t)(ptr - from) - : strlen(from); - - for(const LV2_OSC_Hook *hook = hooks; hook && hook->name; hook++) - { - if(lv2_osc_pattern_match(from, hook->name, len)) - { - if(hook->hooks && ptr) - { - from = &ptr[1]; - - _lv2_osc_hooks_internal(path, from, arguments, hook->hooks); - } - else if(hook->method && !ptr) - { - hook->method(path, arguments, hook->data); - } - } - } -} - -/** - TODO -*/ -static inline void -lv2_osc_hooks(const char *path, const LV2_Atom_Tuple *arguments, void *data) -{ - const LV2_OSC_Hook *hooks = data; - const char *from = &path[1]; - - _lv2_osc_hooks_internal(path, from, arguments, hooks); -} - -/** - TODO -*/ -static inline bool -lv2_osc_check_path(const char *path) -{ - assert(path); - - if(path[0] != '/') - return false; - - for(const char *ptr=path+1; *ptr!='\0'; ptr++) - if( (isprint(*ptr) == 0) || (strchr(invalid_path_chars, *ptr) != NULL) ) - return false; - - return true; -} - -/** - TODO -*/ -static inline bool -lv2_osc_check_fmt(const char *format, int offset) -{ - assert(format); - - if(offset && (format[0] != ',') ) - return false; - - for(const char *ptr=format+offset; *ptr!='\0'; ptr++) - if(strchr(valid_format_chars, *ptr) == NULL) - return false; - - return true; -} - -/** - TODO -*/ -static inline uint64_t -lv2_osc_timetag_parse(const LV2_OSC_Timetag *timetag) -{ - return ((uint64_t)timetag->integral << 32) | timetag->fraction; -} - -/** - TODO -*/ -static inline LV2_OSC_Timetag * -lv2_osc_timetag_create(LV2_OSC_Timetag *timetag, uint64_t tt) -{ - timetag->integral = tt >> 32; - timetag->fraction = tt & 0xffffffff; - - return timetag; -} - -#define LV2_OSC_TIMETAG_CREATE(tt) \ - lv2_osc_timetag_create(&(LV2_OSC_Timetag){.integral = 0, .fraction = 0}, (tt)) - -/** - TODO -*/ -static inline bool -lv2_osc_is_packet_type(LV2_OSC_URID *osc_urid, LV2_URID type) -{ - return type == osc_urid->OSC_Packet; -} - -/** - TODO -*/ -static inline bool -lv2_osc_is_bundle_type(LV2_OSC_URID *osc_urid, LV2_URID type) -{ - return type == osc_urid->OSC_Bundle; -} - -/** - TODO -*/ -static inline bool -lv2_osc_is_message_type(LV2_OSC_URID *osc_urid, LV2_URID type) -{ - return type == osc_urid->OSC_Message; -} - -/** - TODO -*/ -static inline bool -lv2_osc_is_message_or_bundle_type(LV2_OSC_URID *osc_urid, LV2_URID type) -{ - return lv2_osc_is_message_type(osc_urid, type) - || lv2_osc_is_bundle_type(osc_urid, type); -} - -static inline LV2_OSC_Type -lv2_osc_argument_type(LV2_OSC_URID *osc_urid, const LV2_Atom *atom) -{ - const LV2_Atom_Object *obj = (const LV2_Atom_Object *)atom; - - if(atom->type == osc_urid->ATOM_Int) - return LV2_OSC_INT32; - else if(atom->type == osc_urid->ATOM_Float) - return LV2_OSC_FLOAT; - else if(atom->type == osc_urid->ATOM_String) - return LV2_OSC_STRING; - else if(atom->type == osc_urid->ATOM_Chunk) - return LV2_OSC_BLOB; - - else if(atom->type == osc_urid->ATOM_Long) - return LV2_OSC_INT64; - else if(atom->type == osc_urid->ATOM_Double) - return LV2_OSC_DOUBLE; - else if( (atom->type == osc_urid->ATOM_Object) && (obj->body.otype == osc_urid->OSC_Timetag) ) - return LV2_OSC_TIMETAG; - - else if(atom->type == osc_urid->ATOM_Bool) - { - if(((const LV2_Atom_Bool *)atom)->body) - return LV2_OSC_TRUE; - else - return LV2_OSC_FALSE; - } - else if(atom->type == osc_urid->ATOM_Literal) - { - const LV2_Atom_Literal *lit = (const LV2_Atom_Literal *)atom; - if(lit->body.datatype == osc_urid->OSC_Nil) - return LV2_OSC_NIL; - else if(lit->body.datatype == osc_urid->OSC_Impulse) - return LV2_OSC_IMPULSE; - else if(lit->body.datatype == osc_urid->OSC_Char) - return LV2_OSC_CHAR; - else if(lit->body.datatype == osc_urid->OSC_RGBA) - return LV2_OSC_RGBA; - } - - else if(atom->type == osc_urid->ATOM_URID) - return LV2_OSC_SYMBOL; - else if(atom->type == osc_urid->MIDI_MidiEvent) - return LV2_OSC_MIDI; - - return '\0'; -} - -static inline const LV2_Atom * -lv2_osc_int32_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - int32_t *i) -{ - assert(i); - *i = ((const LV2_Atom_Int *)atom)->body; - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_float_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - float *f) -{ - assert(f); - *f = ((const LV2_Atom_Float *)atom)->body; - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_string_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - const char **s) -{ - assert(s); - *s = LV2_ATOM_BODY_CONST(atom); - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_blob_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - uint32_t *size, const uint8_t **b) -{ - assert(size && b); - *size = atom->size; - *b = LV2_ATOM_BODY_CONST(atom); - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_int64_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - int64_t *h) -{ - assert(h); - *h = ((const LV2_Atom_Long *)atom)->body; - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_double_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - double *d) -{ - assert(d); - *d = ((const LV2_Atom_Double *)atom)->body; - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_timetag_get(LV2_OSC_URID *osc_urid, const LV2_Atom *atom, - LV2_OSC_Timetag *timetag) -{ - assert(timetag); - - const LV2_Atom_Long *integral = NULL; - const LV2_Atom_Long *fraction = NULL; - - lv2_atom_object_get((const LV2_Atom_Object *)atom, - osc_urid->OSC_timetagIntegral, &integral, - osc_urid->OSC_timetagFraction, &fraction, - 0); - - if( integral && (integral->atom.type == osc_urid->ATOM_Long) - && fraction && (fraction->atom.type == osc_urid->ATOM_Long) ) - { - timetag->integral = integral->body; - timetag->fraction = fraction->body; - } - else - { - // set to immediate - timetag->integral = 0; - timetag->fraction = 1; - } - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_true_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom) -{ - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_false_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom) -{ - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_nil_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom) -{ - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_impulse_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom) -{ - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_symbol_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - LV2_URID *S) -{ - assert(S); - *S = ((const LV2_Atom_URID *)atom)->body; - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_midi_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - uint32_t *size, const uint8_t **m) -{ - assert(size && m); - *size = atom->size; - *m = LV2_ATOM_BODY_CONST(atom); - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_char_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, char *c) -{ - assert(c); - const char *str = LV2_ATOM_CONTENTS_CONST(LV2_Atom_Literal, atom); - *c = str[0]; - - return lv2_atom_tuple_next(atom); -} - -static inline const LV2_Atom * -lv2_osc_rgba_get(LV2_OSC_URID *osc_urid __unused, const LV2_Atom *atom, - uint8_t *r, uint8_t *g, uint8_t *b, uint8_t *a) -{ - assert(r && g && b && a); - const char *str = LV2_ATOM_CONTENTS_CONST(LV2_Atom_Literal, atom); - - uint8_t *key [4] = { - r, g, b, a - }; - - const char *pos = str; - char *endptr; - - for(unsigned count = 0; count < 4; count++, pos += 2) - { - char buf [5] = {'0', 'x', pos[0], pos[1], '\0'}; - - *key[count] = strtol(buf, &endptr, 16); - } - - return lv2_atom_tuple_next(atom); -} - -/** - TODO -*/ -static inline bool -lv2_osc_bundle_body_get(LV2_OSC_URID *osc_urid, uint32_t size, const LV2_Atom_Object_Body *body, - const LV2_Atom_Object **timetag, const LV2_Atom_Tuple **items) -{ - assert(timetag && items); - - *timetag = NULL; - *items = NULL; - - lv2_atom_object_body_get(size, body, - osc_urid->OSC_bundleTimetag, timetag, - osc_urid->OSC_bundleItems, items, - 0); - - if(!*timetag || ((*timetag)->atom.type != osc_urid->ATOM_Object) || ((*timetag)->body.otype != osc_urid->OSC_Timetag)) - return false; - if(!*items || ((*items)->atom.type != osc_urid->ATOM_Tuple)) - return false; - - return true; -} - -/** - TODO -*/ -static inline bool -lv2_osc_bundle_get(LV2_OSC_URID *osc_urid, const LV2_Atom_Object *obj, - const LV2_Atom_Object **timetag, const LV2_Atom_Tuple **items) -{ - return lv2_osc_bundle_body_get(osc_urid, obj->atom.size, &obj->body, - timetag, items); -} - -/** - TODO -*/ -static inline bool -lv2_osc_message_body_get(LV2_OSC_URID *osc_urid, uint32_t size, const LV2_Atom_Object_Body *body, - const LV2_Atom_String **path, const LV2_Atom_Tuple **arguments) -{ - assert(path && arguments); - - *path = NULL; - *arguments = NULL; - - lv2_atom_object_body_get(size, body, - osc_urid->OSC_messagePath, path, - osc_urid->OSC_messageArguments, arguments, - 0); - - if(!*path || ((*path)->atom.type != osc_urid->ATOM_String)) - return false; - // message without arguments is valid - if( *arguments && ((*arguments)->atom.type != osc_urid->ATOM_Tuple)) - return false; - - return true; -} - -/** - TODO -*/ -static inline bool -lv2_osc_message_get(LV2_OSC_URID *osc_urid, const LV2_Atom_Object *obj, - const LV2_Atom_String **path, const LV2_Atom_Tuple **arguments) -{ - return lv2_osc_message_body_get(osc_urid, obj->atom.size, &obj->body, - path, arguments); -} - -static inline bool -lv2_osc_body_unroll(LV2_OSC_URID *osc_urid, uint32_t size, const LV2_Atom_Object_Body *body, - LV2_OSC_Method method, void *data) -{ - if(body->otype == osc_urid->OSC_Bundle) - { - const LV2_Atom_Object *timetag = NULL; - const LV2_Atom_Tuple *items = NULL; - - if(!lv2_osc_bundle_body_get(osc_urid, size, body, &timetag, &items)) - return false; - - LV2_OSC_Timetag tt; - lv2_osc_timetag_get(osc_urid, &timetag->atom, &tt); - - LV2_ATOM_TUPLE_FOREACH(items, atom) - { - const LV2_Atom_Object *obj= (const LV2_Atom_Object *)atom; - - if(!lv2_osc_body_unroll(osc_urid, obj->atom.size, &obj->body, method, data)) - return false; - } - - return true; - } - else if(body->otype == osc_urid->OSC_Message) - { - const LV2_Atom_String *path = NULL; - const LV2_Atom_Tuple *arguments = NULL; - - if(!lv2_osc_message_body_get(osc_urid, size, body, &path, &arguments)) - return false; - - if(method) - method(LV2_ATOM_BODY_CONST(path), arguments, data); - - return true; - } - - return false; -} - -static inline bool -lv2_osc_unroll(LV2_OSC_URID *osc_urid, const LV2_Atom_Object *obj, - LV2_OSC_Method method, void *data) -{ - return lv2_osc_body_unroll(osc_urid, obj->atom.size, &obj->body, method, data); -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // LV2_OSC_UTIL_H diff --git a/osc.lv2/osc.lv2/writer.h b/osc.lv2/osc.lv2/writer.h deleted file mode 100644 index 037d44c..0000000 --- a/osc.lv2/osc.lv2/writer.h +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) - * - * This is free software: you can redistribute it and/or modify - * it under the terms of the Artistic License 2.0 as published by - * The Perl Foundation. - * - * This source 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 - * Artistic License 2.0 for more details. - * - * You should have received a copy of the Artistic License 2.0 - * along the source as a COPYING file. If not, obtain it from - * http://www.perlfoundation.org/artistic_license_2_0. - */ - -#ifndef LV2_OSC_WRITER_H -#define LV2_OSC_WRITER_H - -#include -#include - -#include -#include -#include - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#undef LV2_ATOM_TUPLE_FOREACH // there is a bug in LV2 1.10.0 -#define LV2_ATOM_TUPLE_FOREACH(tuple, iter) \ - for (LV2_Atom* (iter) = lv2_atom_tuple_begin(tuple); \ - !lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), (tuple)->atom.size, (iter)); \ - (iter) = lv2_atom_tuple_next(iter)) - -typedef struct _LV2_OSC_Writer LV2_OSC_Writer; -typedef struct _LV2_OSC_Writer_Frame LV2_OSC_Writer_Frame; - -struct _LV2_OSC_Writer { - uint8_t *buf; - uint8_t *ptr; - const uint8_t *end; -}; - -struct _LV2_OSC_Writer_Frame { - uint8_t *ref; -}; - -static inline void -lv2_osc_writer_initialize(LV2_OSC_Writer *writer, uint8_t *buf, size_t size) -{ - writer->buf = buf; - writer->ptr = buf; - writer->end = buf + size; -} - -static inline size_t -lv2_osc_writer_get_size(LV2_OSC_Writer *writer) -{ - if(writer->ptr > writer->buf) - return writer->ptr - writer->buf; - - return 0; -} - -static inline uint8_t * -lv2_osc_writer_finalize(LV2_OSC_Writer *writer, size_t *size) -{ - *size = lv2_osc_writer_get_size(writer); - - if(*size) - return writer->buf; - - return NULL; -} - -static inline bool -lv2_osc_writer_overflow(LV2_OSC_Writer *writer, size_t size) -{ - return writer->ptr + size >= writer->end; -} - -static inline bool -lv2_osc_writer_htobe32(LV2_OSC_Writer *writer, union swap32_t *s32) -{ - if(lv2_osc_writer_overflow(writer, 4)) - return false; - - s32->u = htobe32(s32->u); - *(uint32_t *)writer->ptr = s32->u; - writer->ptr += 4; - - return true; -} - -static inline bool -lv2_osc_writer_htobe64(LV2_OSC_Writer *writer, union swap64_t *s64) -{ - if(lv2_osc_writer_overflow(writer, 8)) - return false; - - s64->u = htobe64(s64->u); - *(uint64_t *)writer->ptr = s64->u; - writer->ptr += 8; - - return true; -} - -static inline bool -lv2_osc_writer_add_int32(LV2_OSC_Writer *writer, int32_t i) -{ - return lv2_osc_writer_htobe32(writer, &(union swap32_t){ .i = i }); -} - -static inline bool -lv2_osc_writer_add_float(LV2_OSC_Writer *writer, float f) -{ - return lv2_osc_writer_htobe32(writer, &(union swap32_t){ .f = f }); -} - -static inline bool -lv2_osc_writer_add_string(LV2_OSC_Writer *writer, const char *s) -{ - const size_t rawlen = strlen(s) + 1; - const size_t padded = LV2_OSC_PADDED_SIZE(rawlen); - if(lv2_osc_writer_overflow(writer, padded)) - return false; - - const uint32_t blank = 0; - memcpy(writer->ptr + padded - sizeof(uint32_t), &blank, sizeof(uint32_t)); - memcpy(writer->ptr, s, rawlen); - writer->ptr += padded; - - return true; -} - -static inline bool -lv2_osc_writer_add_symbol(LV2_OSC_Writer *writer, const char *S) -{ - return lv2_osc_writer_add_string(writer, S); -} - -static inline bool -lv2_osc_writer_add_int64(LV2_OSC_Writer *writer, int64_t h) -{ - return lv2_osc_writer_htobe64(writer, &(union swap64_t){ .h = h }); -} - -static inline bool -lv2_osc_writer_add_double(LV2_OSC_Writer *writer, double d) -{ - return lv2_osc_writer_htobe64(writer, &(union swap64_t){ .d = d }); -} - -static inline bool -lv2_osc_writer_add_timetag(LV2_OSC_Writer *writer, uint64_t u) -{ - return lv2_osc_writer_htobe64(writer, &(union swap64_t){ .u = u }); -} - -static inline bool -lv2_osc_writer_add_blob_inline(LV2_OSC_Writer *writer, int32_t len, uint8_t **body) -{ - const size_t len_padded = LV2_OSC_PADDED_SIZE(len); - const size_t size = 4 + len_padded; - if(lv2_osc_writer_overflow(writer, size)) - return false; - - if(!lv2_osc_writer_add_int32(writer, len)) - return false; - - *body = writer->ptr; - //memset(&writer->ptr[len], 0x0, len_padded - len); - writer->ptr += len_padded; - - return true; -} - -static inline bool -lv2_osc_writer_add_blob(LV2_OSC_Writer *writer, int32_t len, const uint8_t *body) -{ - uint8_t *dst; - if(!lv2_osc_writer_add_blob_inline(writer, len, &dst)) - return false; - - memcpy(dst, body, len); - - return true; -} - -static inline bool -lv2_osc_writer_add_midi_inline(LV2_OSC_Writer *writer, int32_t len, uint8_t **m) -{ - if( (len > 4) || lv2_osc_writer_overflow(writer, 4)) - return false; - - *m = writer->ptr; - //memset(&writer->ptr[len], 0x0, 4 - len); - writer->ptr += 4; - - return true; -} - -static inline bool -lv2_osc_writer_add_midi(LV2_OSC_Writer *writer, int32_t len, const uint8_t *m) -{ - uint8_t *dst; - if(!lv2_osc_writer_add_midi_inline(writer, len, &dst)) - return false; - - memcpy(dst, m, len); - - return true; -} - -static inline bool -lv2_osc_writer_add_rgba(LV2_OSC_Writer *writer, uint8_t r, uint8_t g, uint8_t b, uint8_t a) -{ - if(lv2_osc_writer_overflow(writer, 4)) - return false; - - writer->ptr[0] = r; - writer->ptr[1] = g; - writer->ptr[2] = b; - writer->ptr[3] = a; - writer->ptr += 4; - - return true; -} - -static inline bool -lv2_osc_writer_add_char(LV2_OSC_Writer *writer, char c) -{ - return lv2_osc_writer_add_int32(writer, (int32_t)c); -} - -static inline bool -lv2_osc_writer_push_bundle(LV2_OSC_Writer *writer, LV2_OSC_Writer_Frame *frame, uint64_t t) -{ - if(lv2_osc_writer_overflow(writer, 16)) - return false; - - frame->ref = writer->ptr; - - strncpy((char *)writer->ptr, "#bundle", 8); - writer->ptr += 8; - - return lv2_osc_writer_add_timetag(writer, t); -} - -static inline bool -lv2_osc_writer_pop_bundle(LV2_OSC_Writer *writer, LV2_OSC_Writer_Frame *frame) -{ - union swap32_t s32 = { .i = writer->ptr - frame->ref - 16}; - - if(s32.i <= 0) - { - writer->ptr = frame->ref; - return false; - } - - return true; -} - -static inline bool -lv2_osc_writer_push_item(LV2_OSC_Writer *writer, LV2_OSC_Writer_Frame *frame) -{ - if(lv2_osc_writer_overflow(writer, 4)) - return false; - - frame->ref = writer->ptr; - writer->ptr += 4; - - return true; -} - -static inline bool -lv2_osc_writer_pop_item(LV2_OSC_Writer *writer, LV2_OSC_Writer_Frame *frame) -{ - union swap32_t s32 = { .i = writer->ptr - frame->ref - 4}; - - if(s32.i <= 0) - { - writer->ptr = frame->ref; - return false; - } - - s32.u = htobe32(s32.u); - *(uint32_t *)frame->ref = s32.u; - - return true; -} - -static inline bool -lv2_osc_writer_add_path(LV2_OSC_Writer *writer, const char *path) -{ - return lv2_osc_writer_add_string(writer, path); -} - -static inline bool -lv2_osc_writer_add_format(LV2_OSC_Writer *writer, const char *fmt) -{ - const size_t rawlen = strlen(fmt) + 1; - const size_t padded = LV2_OSC_PADDED_SIZE(rawlen + 1); - if(lv2_osc_writer_overflow(writer, padded)) - return false; - - const uint32_t blank = 0; - memcpy(writer->ptr + padded - sizeof(uint32_t), &blank, sizeof(uint32_t)); - *writer->ptr++ = ','; - memcpy(writer->ptr, fmt, rawlen); - writer->ptr += padded - 1; - - return true; -} - -static inline bool -lv2_osc_writer_arg_varlist(LV2_OSC_Writer *writer, const char *fmt, va_list args) -{ - for(const char *type = fmt; *type; type++) - { - switch( (LV2_OSC_Type)*type) - { - case LV2_OSC_INT32: - if(!lv2_osc_writer_add_int32(writer, va_arg(args, int32_t))) - return false; - break; - case LV2_OSC_FLOAT: - if(!lv2_osc_writer_add_float(writer, (float)va_arg(args, double))) - return false; - break; - case LV2_OSC_STRING: - if(!lv2_osc_writer_add_string(writer, va_arg(args, const char *))) - return false; - break; - case LV2_OSC_BLOB: - { - const int32_t len = va_arg(args, int32_t); - if(!lv2_osc_writer_add_blob(writer, len, va_arg(args, const uint8_t *))) - return false; - } break; - - case LV2_OSC_TRUE: - case LV2_OSC_FALSE: - case LV2_OSC_NIL: - case LV2_OSC_IMPULSE: - break; - - case LV2_OSC_INT64: - if(!lv2_osc_writer_add_int64(writer, va_arg(args, int64_t))) - return false; - break; - case LV2_OSC_DOUBLE: - if(!lv2_osc_writer_add_double(writer, va_arg(args, double))) - return false; - break; - case LV2_OSC_TIMETAG: - if(!lv2_osc_writer_add_timetag(writer, va_arg(args, uint64_t))) - return false; - break; - - case LV2_OSC_MIDI: - { - const int32_t len = va_arg(args, int32_t); - if(!lv2_osc_writer_add_midi(writer, len, va_arg(args, const uint8_t *))) - return false; - } break; - case LV2_OSC_SYMBOL: - if(!lv2_osc_writer_add_symbol(writer, va_arg(args, const char *))) - return false; - break; - case LV2_OSC_CHAR: - if(!lv2_osc_writer_add_char(writer, va_arg(args, int))) - return false; - break; - case LV2_OSC_RGBA: - { - const uint8_t r = va_arg(args, unsigned); - const uint8_t g = va_arg(args, unsigned); - const uint8_t b = va_arg(args, unsigned); - const uint8_t a = va_arg(args, unsigned); - if(!lv2_osc_writer_add_rgba(writer, r, g, b, a)) - return false; - } break; - } - } - - return true; -} - -static inline bool -lv2_osc_writer_arg_vararg(LV2_OSC_Writer *writer, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - - const bool res = lv2_osc_writer_arg_varlist(writer, fmt, args); - - va_end(args); - - return res; -} - -static inline bool -lv2_osc_writer_message_varlist(LV2_OSC_Writer *writer, const char *path, const char *fmt, va_list args) -{ - if(!lv2_osc_writer_add_path(writer, path)) - return false; - - if(!lv2_osc_writer_add_format(writer, fmt)) - return false; - - return lv2_osc_writer_arg_varlist(writer, fmt, args); -} - -static inline bool -lv2_osc_writer_message_vararg(LV2_OSC_Writer *writer, const char *path, const char *fmt, ...) -{ - va_list args; - va_start(args, fmt); - - const bool res = lv2_osc_writer_message_varlist(writer, path, fmt, args); - - va_end(args); - - return res; -} - -static inline bool -lv2_osc_writer_packet(LV2_OSC_Writer *writer, LV2_OSC_URID *osc_urid, - LV2_URID_Unmap *unmap, uint32_t size, const LV2_Atom_Object_Body *body) -{ - if(body->otype == osc_urid->OSC_Bundle) - { - const LV2_Atom_Object *timetag = NULL; - const LV2_Atom_Tuple *items = NULL; - - if(!lv2_osc_bundle_body_get(osc_urid, size, body, &timetag, &items)) - return false; - - LV2_OSC_Timetag tt; - LV2_OSC_Writer_Frame bndl = { .ref = 0 }; - - lv2_osc_timetag_get(osc_urid, &timetag->atom, &tt); - if(!lv2_osc_writer_push_bundle(writer, &bndl, lv2_osc_timetag_parse(&tt))) - return false; - - LV2_ATOM_TUPLE_FOREACH(items, atom) - { - const LV2_Atom_Object *obj= (const LV2_Atom_Object *)atom; - LV2_OSC_Writer_Frame itm = { .ref = 0 }; - - if( !lv2_osc_writer_push_item(writer, &itm) - || !lv2_osc_writer_packet(writer, osc_urid, unmap, obj->atom.size, &obj->body) - || !lv2_osc_writer_pop_item(writer, &itm) ) - { - return false; - } - } - - return lv2_osc_writer_pop_bundle(writer, &bndl); - } - else if(body->otype == osc_urid->OSC_Message) - { - const LV2_Atom_String *path = NULL; - const LV2_Atom_Tuple *arguments = NULL; - - if(lv2_osc_message_body_get(osc_urid, size, body, &path, &arguments)) - { - if(!lv2_osc_writer_add_path(writer, LV2_ATOM_BODY_CONST(path))) - return false; - - char fmt [128]; //TODO how big? - char *ptr = fmt; - LV2_ATOM_TUPLE_FOREACH(arguments, atom) - { - *ptr++ = lv2_osc_argument_type(osc_urid, atom); - } - *ptr = '\0'; - if(!lv2_osc_writer_add_format(writer, fmt)) - return false; - - LV2_ATOM_TUPLE_FOREACH(arguments, atom) - { - const LV2_Atom_Object *obj= (const LV2_Atom_Object *)atom; - - if(atom->type == osc_urid->ATOM_Int) - { - if(!lv2_osc_writer_add_int32(writer, ((const LV2_Atom_Int *)atom)->body)) - return false; - } - else if(atom->type == osc_urid->ATOM_Float) - { - if(!lv2_osc_writer_add_float(writer, ((const LV2_Atom_Float *)atom)->body)) - return false; - } - else if(atom->type == osc_urid->ATOM_String) - { - if(!lv2_osc_writer_add_string(writer, LV2_ATOM_BODY_CONST(atom))) - return false; - } - else if(atom->type == osc_urid->ATOM_Chunk) - { - if(!lv2_osc_writer_add_blob(writer, atom->size, LV2_ATOM_BODY_CONST(atom))) - return false; - } - - else if(atom->type == osc_urid->ATOM_Long) - { - if(!lv2_osc_writer_add_int64(writer, ((const LV2_Atom_Long *)atom)->body)) - return false; - } - else if(atom->type == osc_urid->ATOM_Double) - { - if(!lv2_osc_writer_add_double(writer, ((const LV2_Atom_Double *)atom)->body)) - return false; - } - else if( (atom->type == osc_urid->ATOM_Object) && (obj->body.otype == osc_urid->OSC_Timetag) ) - { - LV2_OSC_Timetag tt; - lv2_osc_timetag_get(osc_urid, &obj->atom, &tt); - if(!lv2_osc_writer_add_timetag(writer, lv2_osc_timetag_parse(&tt))) - return false; - } - - // there is nothing to do for: true, false, nil, impulse - - else if(atom->type == osc_urid->ATOM_URID) - { - const char *symbol = unmap->unmap(unmap->handle, ((const LV2_Atom_URID *)atom)->body); - if(!symbol || !lv2_osc_writer_add_symbol(writer, symbol)) - return false; - } - else if(atom->type == osc_urid->MIDI_MidiEvent) - { - uint8_t *m = NULL; - if(!lv2_osc_writer_add_midi_inline(writer, atom->size + 1, &m)) - return false; - m[0] = 0x0; // port - memcpy(&m[1], LV2_ATOM_BODY_CONST(atom), atom->size); - } - else if(atom->type == osc_urid->ATOM_Literal) - { - const LV2_Atom_Literal *lit = (LV2_Atom_Literal *)atom; - - if(lit->body.datatype == osc_urid->OSC_Char) - { - const char c = *(const char *)LV2_ATOM_CONTENTS_CONST(LV2_Atom_Literal, lit); - if(!lv2_osc_writer_add_char(writer, c)) - return false; - } - else if(lit->body.datatype == osc_urid->OSC_RGBA) - { - const char *rgba = LV2_ATOM_CONTENTS_CONST(LV2_Atom_Literal, atom); - uint8_t r, g, b, a; - if(sscanf(rgba, "%02"SCNx8"%02"SCNx8"%02"SCNx8"%02"SCNx8, &r, &g, &b, &a) != 4) - return false; - if(!lv2_osc_writer_add_rgba(writer, r, g, b, a)) - return false; - } - } - } - } - - return true; - } - - return false; -} - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // LV2_OSC_WRITER_H diff --git a/osc.lv2/osc.ttl b/osc.lv2/osc.ttl deleted file mode 100644 index db4a048..0000000 --- a/osc.lv2/osc.ttl +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch) -# -# This is free software: you can redistribute it and/or modify -# it under the terms of the Artistic License 2.0 as published by -# The Perl Foundation. -# -# This source 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 -# Artistic License 2.0 for more details. -# -# You should have received a copy of the Artistic License 2.0 -# along the source as a COPYING file. If not, obtain it from -# http://www.perlfoundation.org/artistic_license_2_0. - -@prefix owl: . -@prefix rdfs: . -@prefix xsd: . -@prefix lv2: . -@prefix atom: . -@prefix osc: . - - - a owl:Ontology ; - rdfs:seeAlso , - ; - lv2:documentation """ -

This specification defines event data types for OSC bundles and message. - To signal support for OSC events on an atom:AtomPort with an atom:bufferType - of atom:Sequence, plugin authors should add atom:supports osc:Event to - the plugin specification.

- """ . - -osc:schedule - a lv2:Feature . - -osc:Event - a rdfs:Class , - rdfs:Datatype ; - rdfs:subClassOf atom:Atom ; - owl:onDatatype xsd:hexBinary ; - rdfs:label "OSC Event (Bundle or Message)" . diff --git a/osc.lv2/test/osc_test.c b/osc.lv2/test/osc_test.c deleted file mode 100644 index 2c6a710..0000000 --- a/osc.lv2/test/osc_test.c +++ /dev/null @@ -1,1373 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#if !defined(_WIN32) -# include -#endif - -#define BUF_SIZE 0x100000 -#define MAX_URIDS 512 - -typedef void (*test_t)(LV2_OSC_Writer *writer); -typedef struct _urid_t urid_t; -typedef struct _app_t app_t; - -struct _urid_t { - LV2_URID urid; - char *uri; -}; - -struct _app_t { - urid_t urids [MAX_URIDS]; - LV2_URID urid; -}; - -static app_t __app; -static uint8_t buf0 [BUF_SIZE]; -static uint8_t buf1 [BUF_SIZE]; -static uint8_t buf2 [BUF_SIZE]; -static const LV2_Atom_Object *obj2= (const LV2_Atom_Object *)buf2; - -const uint8_t raw_0 [] = { - '/', 0x0, 0x0, 0x0, - ',', 0x0, 0x0, 0x0 -}; - -const uint8_t raw_1 [] = { - '/', 'p', 'i', 'n', - 'g', 0x0, 0x0, 0x0, - ',', 'i', 'f', 's', - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, - 0x40, 0x59, 0x99, 0x9a, - 'w', 'o', 'r', 'l', - 'd', 0x0, 0x0, 0x0 -}; - -const uint8_t raw_2 [] = { - '/', 'p', 'i', 'n', - 'g', 0x0, 0x0, 0x0, - ',', 'h', 'd', 'S', - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0xc, - 0x40, 0x0b, 0x33, 0x33, - 0x33, 0x33, 0x33, 0x33, - 'h', 't', 't', 'p', - ':', '/', '/', 'e', - 'x', 'a', 'm', 'p', - 'l', 'e', '.', 'c', - 'o', 'm', 0x0, 0x0 -}; - -const uint8_t raw_3 [] = { - '/', 'p', 'i', 'n', - 'g', 0x0, 0x0, 0x0, - ',', 'T', 'F', 'N', - 'I', 0x0, 0x0, 0x0 -}; - -const uint8_t raw_4 [] = { - '/', 'm', 'i', 'd', - 'i', 0x0, 0x0, 0x0, - ',', 'm', 0x0, 0x0, - 0x0, 0x90, 24, 0x7f -}; - -const uint8_t raw_5 [] = { - '/', 'b', 'l', 'o', - 'b', 0x0, 0x0, 0x0, - ',', 'b', 0x0, 0x0, - 0x0, 0x0, 0x0, 0x6, - 0x1, 0x2, 0x3, 0x4, - 0x5, 0x6, 0x0, 0x0 -}; - -const uint8_t raw_6 [] = { - '#', 'b', 'u', 'n', - 'd', 'l', 'e', 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, - - 0x0, 0x0, 0x0, 0x8, - '/', 0x0, 0x0, 0x0, - ',', 0x0, 0x0, 0x0 -}; - -const uint8_t raw_7 [] = { - '#', 'b', 'u', 'n', - 'd', 'l', 'e', 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, - - 0x0, 0x0, 0x0, 0x1c, - '#', 'b', 'u', 'n', - 'd', 'l', 'e', 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, - - 0x0, 0x0, 0x0, 0x8, - '/', 0x0, 0x0, 0x0, - ',', 0x0, 0x0, 0x0, - - 0x0, 0x0, 0x0, 0x8, - '/', 0x0, 0x0, 0x0, - ',', 0x0, 0x0, 0x0 -}; - -const uint8_t raw_8 [] = { - '/', 'p', 'i', 'n', - 'g', 0x0, 0x0, 0x0, - ',', 't', 'c', 'r', - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x0, - 0x0, 0x0, 0x0, 0x1, - 0x0, 0x0, 0x0, 'o', - 0x1, 0x2, 0x3, 0x4 -}; - -static LV2_URID -_map(LV2_URID_Map_Handle instance, const char *uri) -{ - app_t *app = instance; - - urid_t *itm; - for(itm=app->urids; itm->urid; itm++) - { - if(!strcmp(itm->uri, uri)) - return itm->urid; - } - - assert(app->urid + 1 < MAX_URIDS); - - // create new - itm->urid = ++app->urid; - itm->uri = strdup(uri); - - return itm->urid; -} - -static const char * -_unmap(LV2_URID_Unmap_Handle instance, LV2_URID urid) -{ - app_t *app = instance; - - urid_t *itm; - for(itm=app->urids; itm->urid; itm++) - { - if(itm->urid == urid) - return itm->uri; - } - - // not found - return NULL; -} - -static LV2_URID_Map map = { - .handle = &__app, - .map = _map -}; - -static LV2_URID_Unmap unmap = { - .handle = &__app, - .unmap = _unmap -}; - -//#define DUMP -#if defined(DUMP) -static void -_dump(const uint8_t *src, const uint8_t *dst, size_t size) -{ - for(size_t i = 0; i < size; i++) - printf("%zu %02x %02x\n", i, src[i], dst[i]); - printf("\n"); -} -#endif - -static void -_clone(LV2_OSC_Reader *reader, LV2_OSC_Writer *writer, size_t size) -{ - if(lv2_osc_reader_is_bundle(reader)) - { - LV2_OSC_Item *itm = OSC_READER_BUNDLE_BEGIN(reader, size); - assert(itm); - - LV2_OSC_Writer_Frame frame_bndl = { .ref = 0 }; - assert(lv2_osc_writer_push_bundle(writer, &frame_bndl, itm->timetag)); - - OSC_READER_BUNDLE_ITERATE(reader, itm) - { - LV2_OSC_Reader reader2; - lv2_osc_reader_initialize(&reader2, itm->body, itm->size); - - LV2_OSC_Writer_Frame frame_itm = { .ref = 0 }; - assert(lv2_osc_writer_push_item(writer, &frame_itm)); - _clone(&reader2, writer, itm->size); - assert(lv2_osc_writer_pop_item(writer, &frame_itm)); - } - - assert(lv2_osc_writer_pop_bundle(writer, &frame_bndl)); - } - else if(lv2_osc_reader_is_message(reader)) - { - LV2_OSC_Arg *arg = OSC_READER_MESSAGE_BEGIN(reader, size); - assert(arg); - - assert(lv2_osc_writer_add_path(writer, arg->path)); - assert(lv2_osc_writer_add_format(writer, arg->type)); - - OSC_READER_MESSAGE_ITERATE(reader, arg) - { - switch((LV2_OSC_Type)*arg->type) - { - case LV2_OSC_INT32: - assert(lv2_osc_writer_add_int32(writer, arg->i)); - break; - case LV2_OSC_FLOAT: - assert(lv2_osc_writer_add_float(writer, arg->f)); - break; - case LV2_OSC_STRING: - assert(lv2_osc_writer_add_string(writer, arg->s)); - break; - case LV2_OSC_BLOB: - assert(lv2_osc_writer_add_blob(writer, arg->size, arg->b)); - break; - - case LV2_OSC_INT64: - assert(lv2_osc_writer_add_int64(writer, arg->h)); - break; - case LV2_OSC_DOUBLE: - assert(lv2_osc_writer_add_double(writer, arg->d)); - break; - case LV2_OSC_TIMETAG: - assert(lv2_osc_writer_add_timetag(writer, arg->t)); - break; - - case LV2_OSC_TRUE: - case LV2_OSC_FALSE: - case LV2_OSC_NIL: - case LV2_OSC_IMPULSE: - break; - - case LV2_OSC_MIDI: - assert(lv2_osc_writer_add_midi(writer, arg->size, arg->m)); - break; - case LV2_OSC_SYMBOL: - assert(lv2_osc_writer_add_symbol(writer, arg->S)); - break; - case LV2_OSC_CHAR: - assert(lv2_osc_writer_add_char(writer, arg->c)); - break; - case LV2_OSC_RGBA: - assert(lv2_osc_writer_add_rgba(writer, arg->R, arg->G, arg->B, arg->A)); - break; - } - } - } -} - -static void -_test_a(LV2_OSC_Writer *writer, const uint8_t *raw, size_t size) -{ - LV2_OSC_URID osc_urid; - lv2_osc_urid_init(&osc_urid, &map); - - // check writer against raw bytes - size_t len; - assert(lv2_osc_writer_finalize(writer, &len) == buf0); - assert(len == size); -#if defined(DUMP) - if(memcmp(raw, buf0, size) != 0) - _dump(raw, buf0, size); -#endif - assert(memcmp(raw, buf0, size) == 0); - - // check reader & writer - LV2_OSC_Reader reader; - lv2_osc_reader_initialize(&reader, buf0, size); - lv2_osc_writer_initialize(writer, buf1, BUF_SIZE); - _clone(&reader, writer, size); - - // check cloned against raw bytes - assert(lv2_osc_writer_finalize(writer, &len) == buf1); - assert(len == size); -#if defined(DUMP) - if(memcmp(raw, buf1, size) != 0) - _dump(raw, buf1, size); -#endif - assert(memcmp(raw, buf1, size) == 0); - - // check forge - LV2_Atom_Forge forge; - lv2_atom_forge_init(&forge, &map); - lv2_atom_forge_set_buffer(&forge, buf2, BUF_SIZE); - assert(lv2_osc_forge_packet(&forge, &osc_urid, &map, buf0, size)); - - // check deforge - lv2_osc_writer_initialize(writer, buf1, BUF_SIZE); - assert(lv2_osc_writer_packet(writer, &osc_urid, &unmap, obj2->atom.size, &obj2->body)); - - // check deforged against raw bytes - assert(lv2_osc_writer_finalize(writer, &len) == buf1); - assert(len == size); -#if defined(DUMP) - if(memcmp(raw, buf1, size) != 0) - _dump(raw, buf1, size); -#endif - assert(memcmp(raw, buf1, size) == 0); -} - -static void -test_0_a(LV2_OSC_Writer *writer) -{ - assert(lv2_osc_writer_message_vararg(writer, "/", "")); - _test_a(writer, raw_0, sizeof(raw_0)); -} - -static void -test_1_a(LV2_OSC_Writer *writer) -{ - assert(lv2_osc_writer_message_vararg(writer, "/ping", "ifs", - 12, 3.4f, "world")); - _test_a(writer, raw_1, sizeof(raw_1)); -} - -static void -test_2_a(LV2_OSC_Writer *writer) -{ - assert(lv2_osc_writer_message_vararg(writer, "/ping", "hdS", - (int64_t)12, (double)3.4, "http://example.com")); - _test_a(writer, raw_2, sizeof(raw_2)); -} - -static void -test_3_a(LV2_OSC_Writer *writer) -{ - assert(lv2_osc_writer_message_vararg(writer, "/ping", "TFNI")); - _test_a(writer, raw_3, sizeof(raw_3)); -} - -static void -test_4_a(LV2_OSC_Writer *writer) -{ - const uint8_t m [] = {0x00, 0x90, 24, 0x7f}; - const int32_t len = sizeof(m); - assert(lv2_osc_writer_message_vararg(writer, "/midi", "m", len, m)); - _test_a(writer, raw_4, sizeof(raw_4)); -} - -static void -test_5_a(LV2_OSC_Writer *writer) -{ - const uint8_t b [] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6}; - const int32_t len = sizeof(b); - assert(lv2_osc_writer_message_vararg(writer, "/blob", "b", len, b)); - _test_a(writer, raw_5, sizeof(raw_5)); -} - -static void -test_6_a(LV2_OSC_Writer *writer) -{ - LV2_OSC_Writer_Frame frame_bndl = { .ref = 0 }; - LV2_OSC_Writer_Frame frame_itm = { .ref = 0 }; - - assert(lv2_osc_writer_push_bundle(writer, &frame_bndl, LV2_OSC_IMMEDIATE)); - { - assert(lv2_osc_writer_push_item(writer, &frame_itm)); - { - assert(lv2_osc_writer_message_vararg(writer, "/", "")); - } - assert(lv2_osc_writer_pop_item(writer, &frame_itm)); - } - assert(lv2_osc_writer_pop_bundle(writer, &frame_bndl)); - - _test_a(writer, raw_6, sizeof(raw_6)); -} - -static void -test_7_a(LV2_OSC_Writer *writer) -{ - LV2_OSC_Writer_Frame frame_bndl[2] = { { .ref = 0 }, { .ref = 0 } }; - LV2_OSC_Writer_Frame frame_itm[2] = { { .ref = 0 }, { .ref = 0 } };; - - assert(lv2_osc_writer_push_bundle(writer, &frame_bndl[0], LV2_OSC_IMMEDIATE)); - { - assert(lv2_osc_writer_push_item(writer, &frame_itm[0])); - { - assert(lv2_osc_writer_push_bundle(writer, &frame_bndl[1], LV2_OSC_IMMEDIATE)); - { - assert(lv2_osc_writer_push_item(writer, &frame_itm[1])); - { - assert(lv2_osc_writer_message_vararg(writer, "/", "")); - } - assert(lv2_osc_writer_pop_item(writer, &frame_itm[1])); - } - assert(lv2_osc_writer_pop_bundle(writer, &frame_bndl[1])); - } - assert(lv2_osc_writer_pop_item(writer, &frame_itm[0])); - - assert(lv2_osc_writer_push_item(writer, &frame_itm[0])); - { - assert(lv2_osc_writer_message_vararg(writer, "/", "")); - } - assert(lv2_osc_writer_pop_item(writer, &frame_itm[0])); - } - assert(lv2_osc_writer_pop_bundle(writer, &frame_bndl[0])); - - _test_a(writer, raw_7, sizeof(raw_7)); -} - -static void -test_8_a(LV2_OSC_Writer *writer) -{ - assert(lv2_osc_writer_message_vararg(writer, "/ping", "tcr", - 1ULL, - 'o', - 0x1, 0x2, 0x3, 0x4)); - _test_a(writer, raw_8, sizeof(raw_8)); -} - -static test_t tests [] = { - test_0_a, - test_1_a, - test_2_a, - test_3_a, - test_4_a, - test_5_a, - test_6_a, - test_7_a, - test_8_a, - - NULL -} -; -static int -_run_tests() -{ - LV2_OSC_Writer writer; - - for(test_t *test=tests; *test; test++) - { - test_t cb = *test; - - memset(buf0, 0x0, BUF_SIZE); - memset(buf1, 0x0, BUF_SIZE); - - lv2_osc_writer_initialize(&writer, buf0, BUF_SIZE); - - cb(&writer); - } - - assert(unmap.unmap(unmap.handle, 0)== NULL); - - return 0; -} - -#if !defined(_WIN32) -typedef struct _item_t item_t; -typedef struct _stash_t stash_t; - -struct _item_t { - size_t size; - uint8_t buf []; -}; - -struct _stash_t { - size_t size; - item_t **items; - item_t *rsvd; -}; - -static uint8_t * -_stash_write_req(stash_t *stash, size_t minimum, size_t *maximum) -{ - if(!stash->rsvd || (stash->rsvd->size < minimum)) - { - const size_t sz = sizeof(item_t) + minimum; - stash->rsvd = realloc(stash->rsvd, sz); - assert(stash->rsvd); - stash->rsvd->size = minimum; - } - - if(maximum) - { - *maximum = stash->rsvd->size; - } - - return stash->rsvd->buf; -} - -static void -_stash_write_adv(stash_t *stash, size_t written) -{ - assert(stash->rsvd); - assert(stash->rsvd->size >= written); - stash->rsvd->size = written; - stash->size += 1; - stash->items = realloc(stash->items, sizeof(item_t *) * stash->size); - stash->items[stash->size - 1] = stash->rsvd; - stash->rsvd = NULL; -} - -static const uint8_t * -_stash_read_req(stash_t *stash, size_t *size) -{ - if(stash->size == 0) - { - if(size) - { - *size = 0; - } - - return NULL; - } - - item_t *item = stash->items[0]; - - if(size) - { - *size = item->size; - } - - return item->buf; -} - -static void -_stash_read_adv(stash_t *stash) -{ - assert(stash->size); - - free(stash->items[0]); - stash->size -= 1; - - for(unsigned i = 0; i < stash->size; i++) - { - stash->items[i] = stash->items[i+1]; - } - - stash->items = realloc(stash->items, sizeof(item_t *) * stash->size); -} - -static void * -_write_req(void *data, size_t minimum, size_t *maximum) -{ - stash_t *stash = data; - - return _stash_write_req(&stash[0], minimum, maximum); -} - -static void -_write_adv(void *data, size_t written) -{ - stash_t *stash = data; - - _stash_write_adv(&stash[0], written); -} - -static const void * -_read_req(void *data, size_t *toread) -{ - stash_t *stash = data; - - return _stash_read_req(&stash[1], toread); -} - -static void -_read_adv(void *data) -{ - stash_t *stash = data; - - _stash_read_adv(&stash[1]); -} - -static const LV2_OSC_Driver driv = { - .write_req = _write_req, - .write_adv = _write_adv, - .read_req = _read_req, - .read_adv = _read_adv -}; - -#define COUNT 128 - -typedef struct _pair_t pair_t; - -struct _pair_t { - const char *server; - const char *client; - bool lossy; -}; - -static void * -_thread_1(void *data) -{ - const pair_t *pair = data; - const char *uri = pair->server; - - LV2_OSC_Stream stream; - stash_t stash [2]; - uint8_t check [COUNT]; - - memset(&stream, 0x0, sizeof(stream)); - memset(stash, 0x0, sizeof(stash)); - memset(check, 0x0, sizeof(check)); - - assert(lv2_osc_stream_init(&stream, uri, &driv, stash) == 0); - - time_t t0 = time(NULL); - unsigned count = 0; - while(true) - { - const time_t t1 = time(NULL); - const LV2_OSC_Enum ev = lv2_osc_stream_run(&stream); - - if(ev & LV2_OSC_ERR) - { - fprintf(stderr, "%s: %s\n", __func__, strerror(ev & LV2_OSC_ERR)); - } - - if(ev & LV2_OSC_RECV) - { - const uint8_t *buf_rx; - size_t reat; - - while( (buf_rx = _stash_read_req(&stash[0], &reat)) ) - { - LV2_OSC_Reader reader; - - lv2_osc_reader_initialize(&reader, buf_rx, reat); - assert(lv2_osc_reader_is_message(&reader)); - - OSC_READER_MESSAGE_FOREACH(&reader, arg, reat) - { - assert(strcmp(arg->path, "/trip") == 0); - assert(*arg->type == 'i'); - assert(arg->size == sizeof(int32_t)); - assert(check[arg->i] == 0); - check[arg->i] = 1; - } - - count++; - - while(true) - { - // send back - uint8_t *buf_tx; - if( (buf_tx = _stash_write_req(&stash[1], reat, NULL)) ) - { - memcpy(buf_tx, buf_rx, reat); - - _stash_write_adv(&stash[1], reat); - break; - } - } - - _stash_read_adv(&stash[0]); - } - - t0 = t1; - } - - if(count >= COUNT) - { - break; - } - else if(pair->lossy && (difftime(t1, t0) >= 1.0) ) - { - fprintf(stderr, "%s: timeout: %i\n", __func__, count); - break; - } - } - - LV2_OSC_Enum ev; - do - { - ev = lv2_osc_stream_run(&stream); - - if(ev & LV2_OSC_ERR) - { - fprintf(stderr, "%s: %s\n", __func__, strerror(ev & LV2_OSC_ERR)); - } - } while( (ev & LV2_OSC_SEND) || (ev & LV2_OSC_CONN) ); - - assert(pair->lossy || (count == COUNT) ); - - assert(lv2_osc_stream_deinit(&stream) == 0); - - free(stash[0].rsvd); - while(stash[0].size) - { - _stash_read_adv(&stash[0]); - } - free(stash[0].items); - - free(stash[1].rsvd); - while(stash[1].size) - { - _stash_read_adv(&stash[1]); - } - free(stash[1].items); - - return NULL; -} - -static void * -_thread_2(void *data) -{ - const pair_t *pair = data; - const char *uri = pair->client; - - LV2_OSC_Stream stream; - stash_t stash [2]; - uint8_t check [COUNT]; - - memset(&stream, 0x0, sizeof(stream)); - memset(stash, 0x0, sizeof(stash)); - memset(check, 0x0, sizeof(check)); - - assert(lv2_osc_stream_init(&stream, uri, &driv, stash) == 0); - - unsigned count = 0; - for(int32_t i = 0; i < COUNT; i++) - { - LV2_OSC_Writer writer; - - while(true) - { - uint8_t *buf_tx; - size_t max; - if( (buf_tx = _stash_write_req(&stash[1], 1024, &max)) ) - { - size_t writ; - lv2_osc_writer_initialize(&writer, buf_tx, max); - assert(lv2_osc_writer_message_vararg(&writer, "/trip", "i", i)); - assert(lv2_osc_writer_finalize(&writer, &writ) == buf_tx); - assert(writ == 16); - assert(check[i] == 0); - check[i] = 1; - - _stash_write_adv(&stash[1], writ); - break; - } - } - - const LV2_OSC_Enum ev = lv2_osc_stream_run(&stream); - - if(ev & LV2_OSC_ERR) - { - fprintf(stderr, "%s: %s\n", __func__, strerror(ev & LV2_OSC_ERR)); - } - - if(ev & LV2_OSC_RECV) - { - const uint8_t *buf_rx; - size_t reat; - - while( (buf_rx = _stash_read_req(&stash[0], &reat)) ) - { - LV2_OSC_Reader reader; - - lv2_osc_reader_initialize(&reader, buf_rx, reat); - assert(lv2_osc_reader_is_message(&reader)); - - OSC_READER_MESSAGE_FOREACH(&reader, arg, reat) - { - assert(strcmp(arg->path, "/trip") == 0); - assert(*arg->type == 'i'); - assert(arg->size == sizeof(int32_t)); - assert(check[arg->i] == 1); - check[arg->i] = 2; - } - - count++; - - _stash_read_adv(&stash[0]); - } - } - } - - time_t t0 = time(NULL); - while(true) - { - const time_t t1 = time(NULL); - const LV2_OSC_Enum ev = lv2_osc_stream_run(&stream); - - if(ev & LV2_OSC_ERR) - { - fprintf(stderr, "%s: %s\n", __func__, strerror(ev & LV2_OSC_ERR)); - } - - if(ev & LV2_OSC_RECV) - { - const uint8_t *buf_rx; - size_t reat; - - while( (buf_rx = _stash_read_req(&stash[0], &reat)) ) - { - LV2_OSC_Reader reader; - - lv2_osc_reader_initialize(&reader, buf_rx, reat); - assert(lv2_osc_reader_is_message(&reader)); - - OSC_READER_MESSAGE_FOREACH(&reader, arg, reat) - { - assert(strcmp(arg->path, "/trip") == 0); - assert(*arg->type == 'i'); - assert(arg->size == sizeof(int32_t)); - assert(check[arg->i] == 1); - check[arg->i] = 2; - } - - count++; - - _stash_read_adv(&stash[0]); - } - - t0 = t1; - } - - if(count >= COUNT) - { - break; - } - else if(pair->lossy && (difftime(t1, t0) >= 1.0) ) - { - fprintf(stderr, "%s: timeout: %i\n", __func__, count); - break; - } - } - - assert(pair->lossy || (count == COUNT) ); - - assert(lv2_osc_stream_deinit(&stream) == 0); - - free(stash[0].rsvd); - while(stash[0].size) - { - _stash_read_adv(&stash[0]); - } - free(stash[0].items); - - free(stash[1].rsvd); - while(stash[1].size) - { - _stash_read_adv(&stash[1]); - } - free(stash[1].items); - - return NULL; -} - -static const pair_t pairs [] = { - { - .server = "osc.udp://:2222", - .client = "osc.udp://localhost:2222", - .lossy = true - }, - { - .server = "osc.udp://[]:3333", - .client = "osc.udp://[::1]:3333", - .lossy = true - }, - - { - .server = "osc.udp://:3344", - .client = "osc.udp://255.255.255.255:3344", - .lossy = true - }, - - { - .server = "osc.tcp://:4444", - .client = "osc.tcp://localhost:4444", - .lossy = false - }, - { - .server = "osc.tcp://[]:5555", - .client = "osc.tcp://[::1]:5555", - .lossy = false - }, - - { - .server = "osc.slip.tcp://:6666", - .client = "osc.slip.tcp://localhost:6666", - .lossy = false - }, - { - .server = "osc.slip.tcp://[]:7777", - .client = "osc.slip.tcp://[::1]:7777", - .lossy = false - }, - - { - .server = "osc.prefix.tcp://:8888", - .client = "osc.prefix.tcp://localhost:8888", - .lossy = false - }, - { - .server = "osc.prefix.tcp://[%lo]:9999", - .client = "osc.prefix.tcp://[::1%lo]:9999", - .lossy = false - }, - -#if 0 - { - .server = "osc.serial:///dev/pts/4", //FIXME baudrate - .client = "osc.serial:///dev/pts/5", - .lossy = false - }, -#endif - - { - .server = NULL, - .client = NULL, - .lossy = false - } -}; -#endif - -#if !defined(_WIN32) -static unsigned foo_sub_one = 0; -static unsigned foo_sub_two [2] = { 0, 0 }; -static unsigned foo = 0; -static unsigned bar = 0; - -static void -_one(const char *path, unsigned *flag) -{ - *flag += 1; - - if(!path) - { - return; - } - - assert(!strcmp(path, "/sub/one") - || !strcmp(path, "/*/one") - || !strcmp(path, "/s*/one") - || !strcmp(path, "/su*/one") - || !strcmp(path, "/sub*/one") - || !strcmp(path, "/sub/*") - || !strcmp(path, "/*sub/one") - || !strcmp(path, "/*s*u*b*/one") - || !strcmp(path, "/su[ab]/one") - || !strcmp(path, "/su[a-b]/[!a-np-z]ne") - || !strcmp(path, "/su[a-b]/one") - || !strcmp(path, "/s?b/?ne") - || !strcmp(path, "/s?*/?ne") - || !strcmp(path, "/s?*/*?e") - || !strcmp(path, "/sub/{one,two}")); -} - -static void -_two(const char *path, unsigned *flag) -{ - *flag += 1; - - if(!path) - { - return; - } - - assert(!strcmp(path, "/sub/two") - || !strcmp(path, "/sub/*") - || !strcmp(path, "/sub/{one,two}")); -} - -static void -_foo(const char *path, unsigned *flag) -{ - *flag += 1; - - if(!path) - { - return; - } - - assert(!strcmp(path, "/foo") - || !strcmp(path, "/{foo,bar}")); -} - -static void -_bar(const char *path, unsigned *flag) -{ - *flag += 1; - - if(!path) - { - return; - } - - assert(!strcmp(path, "/bar") - || !strcmp(path, "/{foo,bar}")); -} - -static void -_hook_one(const char *path, const LV2_Atom_Tuple *arguments __attribute__((unused)), - void *data) -{ - _one(path, data); -} - -static void -_hook_two(const char *path, const LV2_Atom_Tuple *arguments __attribute__((unused)), - void *data) -{ - _two(path, data); -} - -static void -_hook_foo(const char *path, const LV2_Atom_Tuple *arguments __attribute__((unused)), - void *data) -{ - _foo(path, data); -} - -static void -_hook_bar(const char *path, const LV2_Atom_Tuple *arguments __attribute__((unused)), - void *data) -{ - _bar(path, data); -} - -static LV2_OSC_Hook hook_sub [] = { - { .name = "one", .method = _hook_one, .data = &foo_sub_one }, - { .name = "two", .method = _hook_two, .data = &foo_sub_two[0] }, - { .name = "two", .method = _hook_two, .data = &foo_sub_two[1] }, - { .name = NULL } -}; - -static LV2_OSC_Hook hook_root [] = { - { .name = "foo", .method = _hook_foo, .data = &foo }, - { .name = "bar", .method = _hook_bar, .data = &bar }, - { .name = "sub", .hooks = hook_sub }, - { .name = NULL } -}; - -static LV2_OSC_Tree tree_sub [4]; - -static void -_branch_one(LV2_OSC_Reader *reader __attribute__((unused)), - LV2_OSC_Arg *arg __attribute__((unused)), - const LV2_OSC_Tree *tree __attribute__((unused)), - void *data __attribute__((unused))) -{ - _one(NULL, &foo_sub_one); -} - -static void -_branch_two(LV2_OSC_Reader *reader __attribute__((unused)), - LV2_OSC_Arg *arg __attribute__((unused)), - const LV2_OSC_Tree *tree __attribute__((unused)), - void *data __attribute__((unused))) -{ - const size_t idx = tree - &tree_sub[1]; - - _two(NULL, &foo_sub_two[idx]); -} - -static void -_branch_foo(LV2_OSC_Reader *reader __attribute__((unused)), - LV2_OSC_Arg *arg __attribute__((unused)), - const LV2_OSC_Tree *tree __attribute__((unused)), - void *data __attribute__((unused))) -{ - _foo(NULL, &foo); -} - -static void -_branch_bar(LV2_OSC_Reader *reader __attribute__((unused)), - LV2_OSC_Arg *arg __attribute__((unused)), - const LV2_OSC_Tree *tree __attribute__((unused)), - void *data __attribute__((unused))) -{ - _bar(NULL, &bar); -} - -static LV2_OSC_Tree tree_sub [] = { - { .name = "one", .branch = _branch_one }, - { .name = "two", .branch = _branch_two }, - { .name = "two", .branch = _branch_two }, - { .name = NULL } -}; - -static LV2_OSC_Tree tree_root [] = { - { .name = "foo", .branch = _branch_foo }, - { .name = "bar", .branch = _branch_bar }, - { .name = "sub", .trees = tree_sub }, - { .name = NULL } -}; - -static bool -_run_test_hooks_internal(const char *path) -{ - foo_sub_one = foo_sub_two[0] = foo_sub_two[1] = foo = bar = false; - - { - LV2_OSC_URID osc_urid; - LV2_Atom_Forge forge; - - lv2_osc_urid_init(&osc_urid, &map); - lv2_atom_forge_init(&forge, &map); - - lv2_atom_forge_set_buffer(&forge, buf0, BUF_SIZE); - assert(lv2_osc_forge_message_vararg(&forge, &osc_urid, path, "")); - - const LV2_Atom_Object *obj = (const LV2_Atom_Object *)buf0;; - assert(lv2_osc_unroll(&osc_urid, obj, lv2_osc_hooks, hook_root) == true); - } - - { - LV2_OSC_Writer writer; - LV2_OSC_Reader reader; - - lv2_osc_writer_initialize(&writer, buf1, BUF_SIZE); - assert(lv2_osc_writer_message_vararg(&writer, path, "") == true); - - size_t len; - const uint8_t *buf = lv2_osc_writer_finalize(&writer, &len); - assert(buf); - assert(len); - - lv2_osc_reader_initialize(&reader, buf, len); - lv2_osc_reader_match(&reader, len, tree_root, NULL); - } - - return true; -} - -static int -_run_test_hooks() -{ - { - assert(_run_test_hooks_internal("/nil") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 0); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/foo") == true); - assert(foo == 2); - assert(bar == 0); - assert(foo_sub_one == 0); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/bar") == true); - assert(foo == 0); - assert(bar == 2); - assert(foo_sub_one == 0); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/sub/nil") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 0); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/sub/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/sub/two") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 0); - assert(foo_sub_two[0] == 2); - assert(foo_sub_two[1] == 2); - } - - { - assert(_run_test_hooks_internal("/sub/*") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 2); - assert(foo_sub_two[1] == 2); - } - - { - assert(_run_test_hooks_internal("/*/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/s*/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/su*/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/sub*/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/*sub/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/*s*u*b*/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/su[ab]/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/su[a-b]/[!a-np-z]ne") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/su[!a-b]/one") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 0); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/s?b/?ne") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/s?*/*?e") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/{foo,bar}") == true); - assert(foo == 2); - assert(bar == 2); - assert(foo_sub_one == 0); - assert(foo_sub_two[0] == 0); - assert(foo_sub_two[1] == 0); - } - - { - assert(_run_test_hooks_internal("/sub/{one,two}") == true); - assert(foo == 0); - assert(bar == 0); - assert(foo_sub_one == 2); - assert(foo_sub_two[0] == 2); - assert(foo_sub_two[1] == 2); - } - - return 0; -} -#endif - -int -main(int argc __attribute__((unused)), char **argv __attribute__((unused))) -{ -#if !defined(_WIN32) - (void)lv2_osc_stream_pollin; //FIXME -#endif - - fprintf(stdout, "running main tests:\n"); - assert(_run_tests() == 0); - -#if !defined(_WIN32) - fprintf(stdout, "running hook tests:\n"); - assert(_run_test_hooks() == 0); -#else - (void)lv2_osc_hooks; //FIXME -#endif - -#if !defined(_WIN32) - for(const pair_t *pair = pairs; pair->server; pair++) - { - pthread_t thread_1; - pthread_t thread_2; - - fprintf(stdout, "running stream test: <%s> <%s> %i\n", - pair->server, pair->client, pair->lossy); - - assert(pthread_create(&thread_1, NULL, _thread_1, (void *)pair) == 0); - assert(pthread_create(&thread_2, NULL, _thread_2, (void *)pair) == 0); - - assert(pthread_join(thread_1, NULL) == 0); - assert(pthread_join(thread_2, NULL) == 0); - } -#endif - - for(unsigned i=0; i<__app.urid; i++) - { - urid_t *itm = &__app.urids[i]; - - free(itm->uri); - } - - return 0; -} -- 2.38.5