annotate osx/include/lo/lo_lowlevel.h @ 129:90a976269628

Updated MSVC
author Chris Cannam <cannam@all-day-breakfast.com>
date Tue, 18 Oct 2016 15:58:42 +0100
parents 241db1b1eff2
children
rev   line source
matthiasmauch@114 1 /*
matthiasmauch@114 2 * Copyright (C) 2004 Steve Harris
matthiasmauch@114 3 *
matthiasmauch@114 4 * This program is free software; you can redistribute it and/or
matthiasmauch@114 5 * modify it under the terms of the GNU Lesser General Public License
matthiasmauch@114 6 * as published by the Free Software Foundation; either version 2.1
matthiasmauch@114 7 * of the License, or (at your option) any later version.
matthiasmauch@114 8 *
matthiasmauch@114 9 * This program is distributed in the hope that it will be useful,
matthiasmauch@114 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
matthiasmauch@114 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
matthiasmauch@114 12 * GNU Lesser General Public License for more details.
matthiasmauch@114 13 *
matthiasmauch@114 14 * $Id$
matthiasmauch@114 15 */
matthiasmauch@114 16
matthiasmauch@114 17 #ifndef LO_LOWLEVEL_H
matthiasmauch@114 18 #define LO_LOWLEVEL_H
matthiasmauch@114 19
matthiasmauch@114 20 #include "lo/lo_osc_types.h"
matthiasmauch@114 21
matthiasmauch@114 22 /**
matthiasmauch@114 23 * \file lo_lowlevel.h The liblo headerfile defining the low-level API
matthiasmauch@114 24 * functions.
matthiasmauch@114 25 */
matthiasmauch@114 26
matthiasmauch@114 27 #ifdef __cplusplus
matthiasmauch@114 28 extern "C" {
matthiasmauch@114 29 #endif
matthiasmauch@114 30
matthiasmauch@114 31 #include <stdarg.h>
matthiasmauch@114 32 #ifdef _MSC_VER
matthiasmauch@114 33 #define ssize_t SSIZE_T
matthiasmauch@114 34 #define uint32_t unsigned __int32
matthiasmauch@114 35 #else
matthiasmauch@114 36 #include <stdint.h>
matthiasmauch@114 37 #endif
matthiasmauch@114 38
matthiasmauch@114 39 #include "lo/lo_types.h"
matthiasmauch@114 40 #include "lo/lo_errors.h"
matthiasmauch@114 41
matthiasmauch@114 42 /**
matthiasmauch@114 43 * \defgroup liblolowlevel Low-level OSC API
matthiasmauch@114 44 *
matthiasmauch@114 45 * Use these functions if you require more precise control over OSC message
matthiasmauch@114 46 * contruction or handling that what is provided in the high-level functions
matthiasmauch@114 47 * described in liblo.
matthiasmauch@114 48 * @{
matthiasmauch@114 49 */
matthiasmauch@114 50
matthiasmauch@114 51 /**
matthiasmauch@114 52 * \brief Type used to represent numerical values in conversions between OSC
matthiasmauch@114 53 * types.
matthiasmauch@114 54 */
matthiasmauch@114 55 typedef long double lo_hires;
matthiasmauch@114 56
matthiasmauch@114 57
matthiasmauch@114 58
matthiasmauch@114 59
matthiasmauch@114 60 /**
matthiasmauch@114 61 * \brief Send a lo_message object to target targ
matthiasmauch@114 62 *
matthiasmauch@114 63 * This is slightly more efficient than lo_send() if you want to send a lot of
matthiasmauch@114 64 * similar messages. The messages are constructed with the lo_message_new() and
matthiasmauch@114 65 * \ref lo_message_add_int32 "lo_message_add*()" functions.
matthiasmauch@114 66 */
matthiasmauch@114 67 int lo_send_message(lo_address targ, const char *path, lo_message msg);
matthiasmauch@114 68
matthiasmauch@114 69 /**
matthiasmauch@114 70 * \brief Send a lo_message object to target targ from address of serv
matthiasmauch@114 71 *
matthiasmauch@114 72 * This is slightly more efficient than lo_send() if you want to send a lot of
matthiasmauch@114 73 * similar messages. The messages are constructed with the lo_message_new() and
matthiasmauch@114 74 * \ref lo_message_add_int32 "lo_message_add*()" functions.
matthiasmauch@114 75 *
matthiasmauch@114 76 * \param targ The address to send the message to
matthiasmauch@114 77 * \param serv The server socket to send the message from
matthiasmauch@114 78 * (can be NULL to use new socket)
matthiasmauch@114 79 * \param path The path to send the message to
matthiasmauch@114 80 * \param msg The bundle itself
matthiasmauch@114 81 */
matthiasmauch@114 82 int lo_send_message_from(lo_address targ, lo_server serv,
matthiasmauch@114 83 const char *path, lo_message msg);
matthiasmauch@114 84
matthiasmauch@114 85 /**
matthiasmauch@114 86 * \brief Send a lo_bundle object to address targ
matthiasmauch@114 87 *
matthiasmauch@114 88 * Bundles are constructed with the
matthiasmauch@114 89 * lo_bundle_new() and lo_bundle_add_message() functions.
matthiasmauch@114 90 */
matthiasmauch@114 91 int lo_send_bundle(lo_address targ, lo_bundle b);
matthiasmauch@114 92
matthiasmauch@114 93 /**
matthiasmauch@114 94 * \brief Send a lo_bundle object to address targ from address of serv
matthiasmauch@114 95 *
matthiasmauch@114 96 * Bundles are constructed with the
matthiasmauch@114 97 * lo_bundle_new() and lo_bundle_add_message() functions.
matthiasmauch@114 98 *
matthiasmauch@114 99 * \param targ The address to send the bundle to
matthiasmauch@114 100 * \param serv The server socket to send the bundle from
matthiasmauch@114 101 * (can be NULL to use new socket)
matthiasmauch@114 102 * \param b The bundle itself
matthiasmauch@114 103 */
matthiasmauch@114 104 int lo_send_bundle_from(lo_address targ, lo_server serv, lo_bundle b);
matthiasmauch@114 105
matthiasmauch@114 106 /**
matthiasmauch@114 107 * \brief Create a new lo_message object
matthiasmauch@114 108 */
matthiasmauch@114 109 lo_message lo_message_new();
matthiasmauch@114 110
matthiasmauch@114 111 /**
matthiasmauch@114 112 * \brief Free memory allocated by lo_message_new() and any subsequent
matthiasmauch@114 113 * \ref lo_message_add_int32 lo_message_add*() calls.
matthiasmauch@114 114 */
matthiasmauch@114 115 void lo_message_free(lo_message m);
matthiasmauch@114 116
matthiasmauch@114 117 /**
matthiasmauch@114 118 * \brief Append a number of arguments to a message.
matthiasmauch@114 119 *
matthiasmauch@114 120 * The data will be added in OSC byteorder (bigendian).
matthiasmauch@114 121 *
matthiasmauch@114 122 * \param m The message to be extended.
matthiasmauch@114 123 * \param types The types of the data items in the message, types are defined in
matthiasmauch@114 124 * lo_types_common.h
matthiasmauch@114 125 * \param ... The data values to be transmitted. The types of the arguments
matthiasmauch@114 126 * passed here must agree with the types specified in the type parameter.
matthiasmauch@114 127 *
matthiasmauch@114 128 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 129 */
matthiasmauch@114 130 int lo_message_add(lo_message m, const char *types, ...);
matthiasmauch@114 131
matthiasmauch@114 132 /** \internal \brief the real message_add function (don't call directly) */
matthiasmauch@114 133 int lo_message_add_internal(lo_message m, const char *file, const int line,
matthiasmauch@114 134 const char *types, ...);
matthiasmauch@114 135
matthiasmauch@114 136 /**
matthiasmauch@114 137 * \brief Append a varargs list to a message.
matthiasmauch@114 138 *
matthiasmauch@114 139 * The data will be added in OSC byteorder (bigendian).
matthiasmauch@114 140 * IMPORTANT: args list must be terminated with LO_ARGS_END, or this call will
matthiasmauch@114 141 * fail. This is used to do simple error checking on the sizes of parameters
matthiasmauch@114 142 * passed.
matthiasmauch@114 143 *
matthiasmauch@114 144 * \param m The message to be extended.
matthiasmauch@114 145 * \param types The types of the data items in the message, types are defined in
matthiasmauch@114 146 * lo_types_common.h
matthiasmauch@114 147 * \param ap The va_list created by a C function declared with an
matthiasmauch@114 148 * ellipsis (...) argument, and pre-initialised with
matthiasmauch@114 149 * "va_start(ap)". The types of the arguments passed here must agree
matthiasmauch@114 150 * with the types specified in the type parameter.
matthiasmauch@114 151 *
matthiasmauch@114 152 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 153 */
matthiasmauch@114 154 int lo_message_add_varargs(lo_message m, const char *types, va_list ap);
matthiasmauch@114 155
matthiasmauch@114 156 /** \internal \brief the real message_add_varargs function (don't call directly) */
matthiasmauch@114 157 int lo_message_add_varargs_internal(lo_message m, const char *types, va_list ap,
matthiasmauch@114 158 const char *file, const int line);
matthiasmauch@114 159
matthiasmauch@114 160 /**
matthiasmauch@114 161 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 162 *
matthiasmauch@114 163 * The data will be added in OSC byteorder (bigendian).
matthiasmauch@114 164 *
matthiasmauch@114 165 * \param m The message to be extended.
matthiasmauch@114 166 * \param a The data item.
matthiasmauch@114 167 *
matthiasmauch@114 168 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 169 */
matthiasmauch@114 170 int lo_message_add_int32(lo_message m, int32_t a);
matthiasmauch@114 171
matthiasmauch@114 172 /**
matthiasmauch@114 173 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 174 * See lo_message_add_int32() for details.
matthiasmauch@114 175 *
matthiasmauch@114 176 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 177 */
matthiasmauch@114 178 int lo_message_add_float(lo_message m, float a);
matthiasmauch@114 179
matthiasmauch@114 180 /**
matthiasmauch@114 181 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 182 * See lo_message_add_int32() for details.
matthiasmauch@114 183 *
matthiasmauch@114 184 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 185 */
matthiasmauch@114 186 int lo_message_add_string(lo_message m, const char *a);
matthiasmauch@114 187
matthiasmauch@114 188 /**
matthiasmauch@114 189 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 190 * See lo_message_add_int32() for details.
matthiasmauch@114 191 *
matthiasmauch@114 192 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 193 */
matthiasmauch@114 194 int lo_message_add_blob(lo_message m, lo_blob a);
matthiasmauch@114 195
matthiasmauch@114 196 /**
matthiasmauch@114 197 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 198 * See lo_message_add_int32() for details.
matthiasmauch@114 199 *
matthiasmauch@114 200 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 201 */
matthiasmauch@114 202 int lo_message_add_int64(lo_message m, int64_t a);
matthiasmauch@114 203
matthiasmauch@114 204 /**
matthiasmauch@114 205 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 206 * See lo_message_add_int32() for details.
matthiasmauch@114 207 *
matthiasmauch@114 208 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 209 */
matthiasmauch@114 210 int lo_message_add_timetag(lo_message m, lo_timetag a);
matthiasmauch@114 211
matthiasmauch@114 212 /**
matthiasmauch@114 213 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 214 * See lo_message_add_int32() for details.
matthiasmauch@114 215 *
matthiasmauch@114 216 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 217 */
matthiasmauch@114 218 int lo_message_add_double(lo_message m, double a);
matthiasmauch@114 219
matthiasmauch@114 220 /**
matthiasmauch@114 221 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 222 * See lo_message_add_int32() for details.
matthiasmauch@114 223 *
matthiasmauch@114 224 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 225 */
matthiasmauch@114 226 int lo_message_add_symbol(lo_message m, const char *a);
matthiasmauch@114 227
matthiasmauch@114 228 /**
matthiasmauch@114 229 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 230 * See lo_message_add_int32() for details.
matthiasmauch@114 231 *
matthiasmauch@114 232 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 233 */
matthiasmauch@114 234 int lo_message_add_char(lo_message m, char a);
matthiasmauch@114 235
matthiasmauch@114 236 /**
matthiasmauch@114 237 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 238 * See lo_message_add_int32() for details.
matthiasmauch@114 239 *
matthiasmauch@114 240 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 241 */
matthiasmauch@114 242 int lo_message_add_midi(lo_message m, uint8_t a[4]);
matthiasmauch@114 243
matthiasmauch@114 244 /**
matthiasmauch@114 245 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 246 * See lo_message_add_int32() for details.
matthiasmauch@114 247 *
matthiasmauch@114 248 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 249 */
matthiasmauch@114 250 int lo_message_add_true(lo_message m);
matthiasmauch@114 251
matthiasmauch@114 252 /**
matthiasmauch@114 253 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 254 * See lo_message_add_int32() for details.
matthiasmauch@114 255 *
matthiasmauch@114 256 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 257 */
matthiasmauch@114 258 int lo_message_add_false(lo_message m);
matthiasmauch@114 259
matthiasmauch@114 260 /**
matthiasmauch@114 261 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 262 * See lo_message_add_int32() for details.
matthiasmauch@114 263 *
matthiasmauch@114 264 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 265 */
matthiasmauch@114 266 int lo_message_add_nil(lo_message m);
matthiasmauch@114 267
matthiasmauch@114 268 /**
matthiasmauch@114 269 * \brief Append a data item and typechar of the specified type to a message.
matthiasmauch@114 270 * See lo_message_add_int32() for details.
matthiasmauch@114 271 *
matthiasmauch@114 272 * \return Less than 0 on failure, 0 on success.
matthiasmauch@114 273 */
matthiasmauch@114 274 int lo_message_add_infinitum(lo_message m);
matthiasmauch@114 275
matthiasmauch@114 276 /**
matthiasmauch@114 277 * \brief Returns the source (lo_address) of an incoming message.
matthiasmauch@114 278 *
matthiasmauch@114 279 * Returns NULL if the message is outgoing. Do not free the returned address.
matthiasmauch@114 280 */
matthiasmauch@114 281 lo_address lo_message_get_source(lo_message m);
matthiasmauch@114 282
matthiasmauch@114 283 /**
matthiasmauch@114 284 * \brief Returns the timestamp (lo_timetag *) of a bundled incoming message.
matthiasmauch@114 285 *
matthiasmauch@114 286 * Returns LO_TT_IMMEDIATE if the message is outgoing, or did not arrive
matthiasmauch@114 287 * contained in a bundle. Do not free the returned timetag.
matthiasmauch@114 288 */
matthiasmauch@114 289 lo_timetag lo_message_get_timestamp(lo_message m);
matthiasmauch@114 290
matthiasmauch@114 291 /**
matthiasmauch@114 292 * \brief Return the message type tag string.
matthiasmauch@114 293 *
matthiasmauch@114 294 * The result is valid until further data is added with lo_message_add*().
matthiasmauch@114 295 */
matthiasmauch@114 296 char *lo_message_get_types(lo_message m);
matthiasmauch@114 297
matthiasmauch@114 298 /**
matthiasmauch@114 299 * \brief Return the message argument count.
matthiasmauch@114 300 *
matthiasmauch@114 301 * The result is valid until further data is added with lo_message_add*().
matthiasmauch@114 302 */
matthiasmauch@114 303 int lo_message_get_argc(lo_message m);
matthiasmauch@114 304
matthiasmauch@114 305 /**
matthiasmauch@114 306 * \brief Return the message arguments. Do not free the returned data.
matthiasmauch@114 307 *
matthiasmauch@114 308 * The result is valid until further data is added with lo_message_add*().
matthiasmauch@114 309 */
matthiasmauch@114 310 lo_arg **lo_message_get_argv(lo_message m);
matthiasmauch@114 311
matthiasmauch@114 312 /**
matthiasmauch@114 313 * \brief Return the length of a message in bytes.
matthiasmauch@114 314 *
matthiasmauch@114 315 * \param m The message to be sized
matthiasmauch@114 316 * \param path The path the message will be sent to
matthiasmauch@114 317 */
matthiasmauch@114 318 size_t lo_message_length(lo_message m, const char *path);
matthiasmauch@114 319
matthiasmauch@114 320 /**
matthiasmauch@114 321 * \brief Serialise the lo_message object to an area of memory and return a
matthiasmauch@114 322 * pointer to the serialised form. Opposite of lo_message_deserialise().
matthiasmauch@114 323 *
matthiasmauch@114 324 * \param m The message to be serialised
matthiasmauch@114 325 * \param path The path the message will be sent to
matthiasmauch@114 326 * \param to The address to serialise to, memory will be allocated if to is
matthiasmauch@114 327 * NULL.
matthiasmauch@114 328 * \param size If this pointer is non-NULL the size of the memory area
matthiasmauch@114 329 * will be written here
matthiasmauch@114 330 *
matthiasmauch@114 331 * The returned form is suitable to be sent over a low level OSC transport,
matthiasmauch@114 332 * having the correct endianess and bit-packed structure.
matthiasmauch@114 333 */
matthiasmauch@114 334 void *lo_message_serialise(lo_message m, const char *path, void *to,
matthiasmauch@114 335 size_t *size);
matthiasmauch@114 336
matthiasmauch@114 337 /**
matthiasmauch@114 338 * \brief Deserialise a raw OSC message and return a new lo_message object.
matthiasmauch@114 339 * Opposite of lo_message_serialise().
matthiasmauch@114 340 *
matthiasmauch@114 341 * \param data Pointer to the raw OSC message data in network transmission form
matthiasmauch@114 342 * (network byte order where appropriate).
matthiasmauch@114 343 * \param size The size of data in bytes
matthiasmauch@114 344 * \param result If this pointer is non-NULL, the result or error code will
matthiasmauch@114 345 * be written here.
matthiasmauch@114 346 *
matthiasmauch@114 347 * Returns a new lo_message, or NULL if deserialisation fails.
matthiasmauch@114 348 * Use lo_message_free() to free the resulting object.
matthiasmauch@114 349 */
matthiasmauch@114 350 lo_message lo_message_deserialise(void *data, size_t size, int *result);
matthiasmauch@114 351
matthiasmauch@114 352 /**
matthiasmauch@114 353 * \brief Dispatch a raw block of memory containing an OSC message.
matthiasmauch@114 354 *
matthiasmauch@114 355 * This is useful when a raw block of memory is available that is
matthiasmauch@114 356 * structured as OSC, and you wish to use liblo to dispatch the
matthiasmauch@114 357 * message to a handler function as if it had been received over the
matthiasmauch@114 358 * network.
matthiasmauch@114 359 *
matthiasmauch@114 360 * \param s The lo_server to use for dispatching.
matthiasmauch@114 361 * \param data Pointer to the raw OSC message data in network transmission form
matthiasmauch@114 362 * (network byte order where appropriate).
matthiasmauch@114 363 * \param size The size of data in bytes
matthiasmauch@114 364 *
matthiasmauch@114 365 * Returns the number of bytes used if successful, or less than 0 otherwise.
matthiasmauch@114 366 */
matthiasmauch@114 367 int lo_server_dispatch_data(lo_server s, void *data, size_t size);
matthiasmauch@114 368
matthiasmauch@114 369 /**
matthiasmauch@114 370 * \brief Return the hostname of a lo_address object
matthiasmauch@114 371 *
matthiasmauch@114 372 * Returned value must not be modified or free'd. Value will be a dotted quad,
matthiasmauch@114 373 * colon'd IPV6 address, or resolvable name.
matthiasmauch@114 374 */
matthiasmauch@114 375 const char *lo_address_get_hostname(lo_address a);
matthiasmauch@114 376
matthiasmauch@114 377 /**
matthiasmauch@114 378 * \brief Return the port/service name of a lo_address object
matthiasmauch@114 379 *
matthiasmauch@114 380 * Returned value must not be modified or free'd. Value will be a service name
matthiasmauch@114 381 * or ASCII representation of the port number.
matthiasmauch@114 382 */
matthiasmauch@114 383 const char *lo_address_get_port(lo_address a);
matthiasmauch@114 384
matthiasmauch@114 385 /**
matthiasmauch@114 386 * \brief Return the protocol of a lo_address object
matthiasmauch@114 387 *
matthiasmauch@114 388 * Returned value will be one of LO_UDP, LO_TCP or LO_UNIX.
matthiasmauch@114 389 */
matthiasmauch@114 390 int lo_address_get_protocol(lo_address a);
matthiasmauch@114 391
matthiasmauch@114 392 /**
matthiasmauch@114 393 * \brief Return a URL representing an OSC address
matthiasmauch@114 394 *
matthiasmauch@114 395 * Returned value must be free'd.
matthiasmauch@114 396 */
matthiasmauch@114 397 char *lo_address_get_url(lo_address a);
matthiasmauch@114 398
matthiasmauch@114 399 /**
matthiasmauch@114 400 * \brief Set the Time-to-Live value for a given target address.
matthiasmauch@114 401 *
matthiasmauch@114 402 * This is required for sending multicast UDP messages. A value of 1
matthiasmauch@114 403 * (the usual case) keeps the message within the subnet, while 255
matthiasmauch@114 404 * means a global, unrestricted scope.
matthiasmauch@114 405 *
matthiasmauch@114 406 * \param t An OSC address.
matthiasmauch@114 407 * \param ttl An integer specifying the scope of a multicast UDP message.
matthiasmauch@114 408 */
matthiasmauch@114 409 void lo_address_set_ttl(lo_address t, int ttl);
matthiasmauch@114 410
matthiasmauch@114 411 /**
matthiasmauch@114 412 * \brief Get the Time-to-Live value for a given target address.
matthiasmauch@114 413 *
matthiasmauch@114 414 * \param t An OSC address.
matthiasmauch@114 415 * \return An integer specifying the scope of a multicast UDP message.
matthiasmauch@114 416 */
matthiasmauch@114 417 int lo_address_get_ttl(lo_address t);
matthiasmauch@114 418
matthiasmauch@114 419 /**
matthiasmauch@114 420 * \brief Create a new bundle object.
matthiasmauch@114 421 *
matthiasmauch@114 422 * OSC Bundles encapsulate one or more OSC messages and may include a timestamp
matthiasmauch@114 423 * indicating when the bundle should be dispatched.
matthiasmauch@114 424 *
matthiasmauch@114 425 * \param tt The timestamp when the bundle should be handled by the receiver.
matthiasmauch@114 426 * Pass LO_TT_IMMEDIATE if you want the receiving server to dispatch
matthiasmauch@114 427 * the bundle as soon as it receives it.
matthiasmauch@114 428 */
matthiasmauch@114 429 lo_bundle lo_bundle_new(lo_timetag tt);
matthiasmauch@114 430
matthiasmauch@114 431 /**
matthiasmauch@114 432 * \brief Adds an OSC message to an existing bundle.
matthiasmauch@114 433 *
matthiasmauch@114 434 * The message passed is appended to the list of messages in the bundle to be
matthiasmauch@114 435 * dispatched to 'path'.
matthiasmauch@114 436 *
matthiasmauch@114 437 * \return 0 if successful, less than 0 otherwise.
matthiasmauch@114 438 */
matthiasmauch@114 439 int lo_bundle_add_message(lo_bundle b, const char *path, lo_message m);
matthiasmauch@114 440
matthiasmauch@114 441 /**
matthiasmauch@114 442 * \brief Return the length of a bundle in bytes.
matthiasmauch@114 443 *
matthiasmauch@114 444 * Includes the marker and typetage length.
matthiasmauch@114 445 *
matthiasmauch@114 446 * \param b The bundle to be sized
matthiasmauch@114 447 */
matthiasmauch@114 448 size_t lo_bundle_length(lo_bundle b);
matthiasmauch@114 449
matthiasmauch@114 450 /**
matthiasmauch@114 451 * \brief Serialise the bundle object to an area of memory and return a
matthiasmauch@114 452 * pointer to the serialised form.
matthiasmauch@114 453 *
matthiasmauch@114 454 * \param b The bundle to be serialised
matthiasmauch@114 455 * \param to The address to serialise to, memory will be allocated if to is
matthiasmauch@114 456 * NULL.
matthiasmauch@114 457 * \param size If this pointer is non-NULL the size of the memory area
matthiasmauch@114 458 * will be written here
matthiasmauch@114 459 *
matthiasmauch@114 460 * The returned form is suitable to be sent over a low level OSC transport,
matthiasmauch@114 461 * having the correct endianess and bit-packed structure.
matthiasmauch@114 462 */
matthiasmauch@114 463 void *lo_bundle_serialise(lo_bundle b, void *to, size_t *size);
matthiasmauch@114 464
matthiasmauch@114 465 /**
matthiasmauch@114 466 * \brief Frees the memory taken by a bundle object.
matthiasmauch@114 467 *
matthiasmauch@114 468 * \param b The bundle to be freed.
matthiasmauch@114 469 */
matthiasmauch@114 470 void lo_bundle_free(lo_bundle b);
matthiasmauch@114 471
matthiasmauch@114 472 /**
matthiasmauch@114 473 * \brief Frees the memory taken by a bundle object and messages in the bundle.
matthiasmauch@114 474 *
matthiasmauch@114 475 * \param b The bundle, which may contain messages, to be freed.
matthiasmauch@114 476 */
matthiasmauch@114 477 void lo_bundle_free_messages(lo_bundle b);
matthiasmauch@114 478
matthiasmauch@114 479 /**
matthiasmauch@114 480 * \brief Return true if the type specified has a numerical value, such as
matthiasmauch@114 481 * LO_INT32, LO_FLOAT etc.
matthiasmauch@114 482 *
matthiasmauch@114 483 * \param a The type to be tested.
matthiasmauch@114 484 */
matthiasmauch@114 485 int lo_is_numerical_type(lo_type a);
matthiasmauch@114 486
matthiasmauch@114 487 /**
matthiasmauch@114 488 * \brief Return true if the type specified has a textual value, such as
matthiasmauch@114 489 * LO_STRING or LO_SYMBOL.
matthiasmauch@114 490 *
matthiasmauch@114 491 * \param a The type to be tested.
matthiasmauch@114 492 */
matthiasmauch@114 493 int lo_is_string_type(lo_type a);
matthiasmauch@114 494
matthiasmauch@114 495 /**
matthiasmauch@114 496 * \brief Attempt to convert one OSC type to another.
matthiasmauch@114 497 *
matthiasmauch@114 498 * Numerical types (eg LO_INT32, LO_FLOAT etc.) may be converted to other
matthiasmauch@114 499 * numerical types and string types (LO_STRING and LO_SYMBOL) may be converted
matthiasmauch@114 500 * to the other type. This is done automatically if a received message matches
matthiasmauch@114 501 * the path, but not the exact types, and is coercible (ie. all numerical
matthiasmauch@114 502 * types in numerical positions).
matthiasmauch@114 503 *
matthiasmauch@114 504 * On failure no translation occurs and false is returned.
matthiasmauch@114 505 *
matthiasmauch@114 506 * \param type_to The type of the destination variable.
matthiasmauch@114 507 * \param to A pointer to the destination variable.
matthiasmauch@114 508 * \param type_from The type of the source variable.
matthiasmauch@114 509 * \param from A pointer to the source variable.
matthiasmauch@114 510 */
matthiasmauch@114 511 int lo_coerce(lo_type type_to, lo_arg *to, lo_type type_from, lo_arg *from);
matthiasmauch@114 512
matthiasmauch@114 513 /**
matthiasmauch@114 514 * \brief Return the numerical value of the given argument with the
matthiasmauch@114 515 * maximum native system precision.
matthiasmauch@114 516 */
matthiasmauch@114 517 lo_hires lo_hires_val(lo_type type, lo_arg *p);
matthiasmauch@114 518
matthiasmauch@114 519 /**
matthiasmauch@114 520 * \brief Create a new server instance.
matthiasmauch@114 521 *
matthiasmauch@114 522 * Using lo_server_recv(), lo_servers block until they receive OSC
matthiasmauch@114 523 * messages. If you want non-blocking behaviour see
matthiasmauch@114 524 * lo_server_recv_noblock() or the \ref lo_server_thread_new
matthiasmauch@114 525 * "lo_server_thread_*" functions.
matthiasmauch@114 526 *
matthiasmauch@114 527 * \param port If NULL is passed then an unused UDP port will be chosen by the
matthiasmauch@114 528 * system, its number may be retrieved with lo_server_thread_get_port()
matthiasmauch@114 529 * so it can be passed to clients. Otherwise a decimal port number, service
matthiasmauch@114 530 * name or UNIX domain socket path may be passed.
matthiasmauch@114 531 * \param err_h An error callback function that will be called if there is an
matthiasmauch@114 532 * error in messge reception or server creation. Pass NULL if you do not want
matthiasmauch@114 533 * error handling.
matthiasmauch@114 534 */
matthiasmauch@114 535 lo_server lo_server_new(const char *port, lo_err_handler err_h);
matthiasmauch@114 536
matthiasmauch@114 537 /**
matthiasmauch@114 538 * \brief Create a new server instance, specifying protocol.
matthiasmauch@114 539 *
matthiasmauch@114 540 * Using lo_server_recv(), lo_servers block until they receive OSC
matthiasmauch@114 541 * messages. If you want non-blocking behaviour see
matthiasmauch@114 542 * lo_server_recv_noblock() or the \ref lo_server_thread_new
matthiasmauch@114 543 * "lo_server_thread_*" functions.
matthiasmauch@114 544 *
matthiasmauch@114 545 * \param port If using UDP then NULL may be passed to find an unused port.
matthiasmauch@114 546 * Otherwise a decimal port number orservice name or may be passed.
matthiasmauch@114 547 * If using UNIX domain sockets then a socket path should be passed here.
matthiasmauch@114 548 * \param proto The protocol to use, should be one of LO_UDP, LO_TCP or LO_UNIX.
matthiasmauch@114 549 * \param err_h An error callback function that will be called if there is an
matthiasmauch@114 550 * error in messge reception or server creation. Pass NULL if you do not want
matthiasmauch@114 551 * error handling.
matthiasmauch@114 552 */
matthiasmauch@114 553 lo_server lo_server_new_with_proto(const char *port, int proto,
matthiasmauch@114 554 lo_err_handler err_h);
matthiasmauch@114 555
matthiasmauch@114 556 /**
matthiasmauch@114 557 * \brief Create a new server instance, and join a UDP multicast group.
matthiasmauch@114 558 *
matthiasmauch@114 559 * \param group The multicast group to join. See documentation on IP
matthiasmauch@114 560 * multicast for the acceptable address range; e.g., http://tldp.org/HOWTO/Multicast-HOWTO-2.html
matthiasmauch@114 561 * \param port If using UDP then NULL may be passed to find an unused port.
matthiasmauch@114 562 * Otherwise a decimal port number or service name or may be passed.
matthiasmauch@114 563 * If using UNIX domain sockets then a socket path should be passed here.
matthiasmauch@114 564 * \param err_h An error callback function that will be called if there is an
matthiasmauch@114 565 * error in messge reception or server creation. Pass NULL if you do not want
matthiasmauch@114 566 * error handling.
matthiasmauch@114 567 */
matthiasmauch@114 568 lo_server lo_server_new_multicast(const char *group, const char *port,
matthiasmauch@114 569 lo_err_handler err_h);
matthiasmauch@114 570
matthiasmauch@114 571 /**
matthiasmauch@114 572 * \brief Free up memory used by the lo_server object
matthiasmauch@114 573 */
matthiasmauch@114 574 void lo_server_free(lo_server s);
matthiasmauch@114 575
matthiasmauch@114 576 /**
matthiasmauch@114 577 * \brief Wait for an OSC message to be received
matthiasmauch@114 578 *
matthiasmauch@114 579 * \param s The server to wait for connections on.
matthiasmauch@114 580 * \param timeout A timeout in milliseconds to wait for the incoming packet.
matthiasmauch@114 581 * a value of 0 will return immediately.
matthiasmauch@114 582 *
matthiasmauch@114 583 * The return value is 1 if there is a message waiting or 0 if
matthiasmauch@114 584 * there is no message. If there is a message waiting you can now
matthiasmauch@114 585 * call lo_server_recv() to receive that message.
matthiasmauch@114 586 */
matthiasmauch@114 587 int lo_server_wait(lo_server s, int timeout);
matthiasmauch@114 588
matthiasmauch@114 589 /**
matthiasmauch@114 590 * \brief Look for an OSC message waiting to be received
matthiasmauch@114 591 *
matthiasmauch@114 592 * \param s The server to wait for connections on.
matthiasmauch@114 593 * \param timeout A timeout in milliseconds to wait for the incoming packet.
matthiasmauch@114 594 * a value of 0 will return immediately.
matthiasmauch@114 595 *
matthiasmauch@114 596 * The return value is the number of bytes in the received message or 0 if
matthiasmauch@114 597 * there is no message. The message will be dispatched to a matching method
matthiasmauch@114 598 * if one is found.
matthiasmauch@114 599 */
matthiasmauch@114 600 int lo_server_recv_noblock(lo_server s, int timeout);
matthiasmauch@114 601
matthiasmauch@114 602 /**
matthiasmauch@114 603 * \brief Block, waiting for an OSC message to be received
matthiasmauch@114 604 *
matthiasmauch@114 605 * The return value is the number of bytes in the received message. The message
matthiasmauch@114 606 * will be dispatched to a matching method if one is found.
matthiasmauch@114 607 */
matthiasmauch@114 608 int lo_server_recv(lo_server s);
matthiasmauch@114 609
matthiasmauch@114 610 /**
matthiasmauch@114 611 * \brief Add an OSC method to the specifed server.
matthiasmauch@114 612 *
matthiasmauch@114 613 * \param s The server the method is to be added to.
matthiasmauch@114 614 * \param path The OSC path to register the method to. If NULL is passed the
matthiasmauch@114 615 * method will match all paths.
matthiasmauch@114 616 * \param typespec The typespec the method accepts. Incoming messages with
matthiasmauch@114 617 * similar typespecs (e.g. ones with numerical types in the same position) will
matthiasmauch@114 618 * be coerced to the typespec given here.
matthiasmauch@114 619 * \param h The method handler callback function that will be called if a
matthiasmauch@114 620 * matching message is received
matthiasmauch@114 621 * \param user_data A value that will be passed to the callback function, h,
matthiasmauch@114 622 * when its invoked matching from this method.
matthiasmauch@114 623 */
matthiasmauch@114 624 lo_method lo_server_add_method(lo_server s, const char *path,
matthiasmauch@114 625 const char *typespec, lo_method_handler h,
matthiasmauch@114 626 void *user_data);
matthiasmauch@114 627
matthiasmauch@114 628 /**
matthiasmauch@114 629 * \brief Delete an OSC method from the specifed server.
matthiasmauch@114 630 *
matthiasmauch@114 631 * \param s The server the method is to be removed from.
matthiasmauch@114 632 * \param path The OSC path of the method to delete. If NULL is passed the
matthiasmauch@114 633 * method will match the generic handler.
matthiasmauch@114 634 * \param typespec The typespec the method accepts.
matthiasmauch@114 635 */
matthiasmauch@114 636 void lo_server_del_method(lo_server s, const char *path,
matthiasmauch@114 637 const char *typespec);
matthiasmauch@114 638
matthiasmauch@114 639 /**
matthiasmauch@114 640 * \brief Return the file descriptor of the server socket.
matthiasmauch@114 641 *
matthiasmauch@114 642 * If the server protocol supports exposing the server's underlying
matthiasmauch@114 643 * receive mechanism for monitoring with select() or poll(), this function
matthiasmauch@114 644 * returns the file descriptor needed, otherwise, it returns -1.
matthiasmauch@114 645 *
matthiasmauch@114 646 * WARNING: when using this function beware that not all OSC packets that are
matthiasmauch@114 647 * received are dispatched immediately. lo_server_events_pending() and
matthiasmauch@114 648 * lo_server_next_event_delay() can be used to tell if there are pending
matthiasmauch@114 649 * events and how long before you should attempt to receive them.
matthiasmauch@114 650 */
matthiasmauch@114 651 int lo_server_get_socket_fd(lo_server s);
matthiasmauch@114 652
matthiasmauch@114 653 /**
matthiasmauch@114 654 * \brief Return the port number that the server has bound to.
matthiasmauch@114 655 *
matthiasmauch@114 656 * Useful when NULL is passed for the port number and you wish to know how to
matthiasmauch@114 657 * address the server.
matthiasmauch@114 658 */
matthiasmauch@114 659 int lo_server_get_port(lo_server s);
matthiasmauch@114 660
matthiasmauch@114 661 /**
matthiasmauch@114 662 * \brief Return the protocol that the server is using.
matthiasmauch@114 663 *
matthiasmauch@114 664 * Returned value will be one of LO_UDP, LO_TCP or LO_UNIX.
matthiasmauch@114 665 */
matthiasmauch@114 666 int lo_server_get_protocol(lo_server s);
matthiasmauch@114 667
matthiasmauch@114 668 /**
matthiasmauch@114 669 * \brief Return an OSC URL that can be used to contact the server.
matthiasmauch@114 670 *
matthiasmauch@114 671 * The return value should be free()'d when it is no longer needed.
matthiasmauch@114 672 */
matthiasmauch@114 673 char *lo_server_get_url(lo_server s);
matthiasmauch@114 674
matthiasmauch@114 675 /**
matthiasmauch@114 676 * \brief Return true if there are scheduled events (eg. from bundles)
matthiasmauch@114 677 * waiting to be dispatched by the server
matthiasmauch@114 678 */
matthiasmauch@114 679 int lo_server_events_pending(lo_server s);
matthiasmauch@114 680
matthiasmauch@114 681 /**
matthiasmauch@114 682 * \brief Return the time in seconds until the next scheduled event.
matthiasmauch@114 683 *
matthiasmauch@114 684 * If the delay is greater than 100 seconds then it will return 100.0.
matthiasmauch@114 685 */
matthiasmauch@114 686 double lo_server_next_event_delay(lo_server s);
matthiasmauch@114 687
matthiasmauch@114 688 /**
matthiasmauch@114 689 * \brief Return the protocol portion of an OSC URL, eg. udp, tcp.
matthiasmauch@114 690 *
matthiasmauch@114 691 * This library uses OSC URLs of the form: osc.prot://hostname:port/path if the
matthiasmauch@114 692 * prot part is missing, UDP is assumed.
matthiasmauch@114 693 *
matthiasmauch@114 694 * The return value should be free()'d when it is no longer needed.
matthiasmauch@114 695 */
matthiasmauch@114 696 char *lo_url_get_protocol(const char *url);
matthiasmauch@114 697
matthiasmauch@114 698 /**
matthiasmauch@114 699 * \brief Return the protocol ID of an OSC URL.
matthiasmauch@114 700 *
matthiasmauch@114 701 * This library uses OSC URLs of the form: osc.prot://hostname:port/path if the
matthiasmauch@114 702 * prot part is missing, UDP is assumed.
matthiasmauch@114 703 * Returned value will be one of LO_UDP, LO_TCP, LO_UNIX or -1.
matthiasmauch@114 704 *
matthiasmauch@114 705 * \return An integer specifying the protocol. Return -1 when the protocol is
matthiasmauch@114 706 * not supported by liblo.
matthiasmauch@114 707 *
matthiasmauch@114 708 */
matthiasmauch@114 709 int lo_url_get_protocol_id(const char *url);
matthiasmauch@114 710
matthiasmauch@114 711 /**
matthiasmauch@114 712 * \brief Return the hostname portion of an OSC URL.
matthiasmauch@114 713 *
matthiasmauch@114 714 * The return value should be free()'d when it is no longer needed.
matthiasmauch@114 715 */
matthiasmauch@114 716 char *lo_url_get_hostname(const char *url);
matthiasmauch@114 717
matthiasmauch@114 718 /**
matthiasmauch@114 719 * \brief Return the port portion of an OSC URL.
matthiasmauch@114 720 *
matthiasmauch@114 721 * The return value should be free()'d when it is no longer needed.
matthiasmauch@114 722 */
matthiasmauch@114 723 char *lo_url_get_port(const char *url);
matthiasmauch@114 724
matthiasmauch@114 725 /**
matthiasmauch@114 726 * \brief Return the path portion of an OSC URL.
matthiasmauch@114 727 *
matthiasmauch@114 728 * The return value should be free()'d when it is no longer needed.
matthiasmauch@114 729 */
matthiasmauch@114 730 char *lo_url_get_path(const char *url);
matthiasmauch@114 731
matthiasmauch@114 732 /* utility functions */
matthiasmauch@114 733
matthiasmauch@114 734 /**
matthiasmauch@114 735 * \brief A function to calculate the amount of OSC message space required by a
matthiasmauch@114 736 * C char *.
matthiasmauch@114 737 *
matthiasmauch@114 738 * Returns the storage size in bytes, which will always be a multiple of four.
matthiasmauch@114 739 */
matthiasmauch@114 740 int lo_strsize(const char *s);
matthiasmauch@114 741
matthiasmauch@114 742 /**
matthiasmauch@114 743 * \brief A function to calculate the amount of OSC message space required by a
matthiasmauch@114 744 * lo_blob object.
matthiasmauch@114 745 *
matthiasmauch@114 746 * Returns the storage size in bytes, which will always be a multiple of four.
matthiasmauch@114 747 */
matthiasmauch@114 748 uint32_t lo_blobsize(lo_blob b);
matthiasmauch@114 749
matthiasmauch@114 750 /**
matthiasmauch@114 751 * \brief Test a string against an OSC pattern glob
matthiasmauch@114 752 *
matthiasmauch@114 753 * \param str The string to test
matthiasmauch@114 754 * \param p The pattern to test against
matthiasmauch@114 755 */
matthiasmauch@114 756 int lo_pattern_match(const char *str, const char *p);
matthiasmauch@114 757
matthiasmauch@114 758 /** \internal \brief the real send function (don't call directly) */
matthiasmauch@114 759 int lo_send_internal(lo_address t, const char *file, const int line,
matthiasmauch@114 760 const char *path, const char *types, ...);
matthiasmauch@114 761 /** \internal \brief the real send_timestamped function (don't call directly) */
matthiasmauch@114 762 int lo_send_timestamped_internal(lo_address t, const char *file, const int line,
matthiasmauch@114 763 lo_timetag ts, const char *path, const char *types, ...);
matthiasmauch@114 764 /** \internal \brief the real lo_send_from() function (don't call directly) */
matthiasmauch@114 765 int lo_send_from_internal(lo_address targ, lo_server from, const char *file,
matthiasmauch@114 766 const int line, const lo_timetag ts,
matthiasmauch@114 767 const char *path, const char *types, ...);
matthiasmauch@114 768
matthiasmauch@114 769
matthiasmauch@114 770 /** \brief Find the time difference between two timetags
matthiasmauch@114 771 *
matthiasmauch@114 772 * Returns a - b in seconds.
matthiasmauch@114 773 */
matthiasmauch@114 774 double lo_timetag_diff(lo_timetag a, lo_timetag b);
matthiasmauch@114 775
matthiasmauch@114 776 /** \brief Return a timetag for the current time
matthiasmauch@114 777 *
matthiasmauch@114 778 * On exit the timetag pointed to by t is filled with the OSC
matthiasmauch@114 779 * representation of this instant in time.
matthiasmauch@114 780 */
matthiasmauch@114 781 void lo_timetag_now(lo_timetag *t);
matthiasmauch@114 782
matthiasmauch@114 783 /**
matthiasmauch@114 784 * \brief Return the storage size, in bytes, of the given argument.
matthiasmauch@114 785 */
matthiasmauch@114 786 size_t lo_arg_size(lo_type type, void *data);
matthiasmauch@114 787
matthiasmauch@114 788 /**
matthiasmauch@114 789 * \brief Given a raw OSC message, return the message path.
matthiasmauch@114 790 *
matthiasmauch@114 791 * \param data A pointer to the raw OSC message data.
matthiasmauch@114 792 * \param size The size of data in bytes (total buffer bytes).
matthiasmauch@114 793 *
matthiasmauch@114 794 * Returns the message path or NULL if an error occurs.
matthiasmauch@114 795 * Do not free() the returned pointer.
matthiasmauch@114 796 */
matthiasmauch@114 797 char *lo_get_path(void *data, ssize_t size);
matthiasmauch@114 798
matthiasmauch@114 799 /**
matthiasmauch@114 800 * \brief Convert the specified argument to host byte order where necessary.
matthiasmauch@114 801 *
matthiasmauch@114 802 * \param type The OSC type of the data item (eg. LO_FLOAT).
matthiasmauch@114 803 * \param data A pointer to the data item to be converted. It is changed
matthiasmauch@114 804 * in-place.
matthiasmauch@114 805 */
matthiasmauch@114 806 void lo_arg_host_endian(lo_type type, void *data);
matthiasmauch@114 807
matthiasmauch@114 808 /**
matthiasmauch@114 809 * \brief Convert the specified argument to network byte order where necessary.
matthiasmauch@114 810 *
matthiasmauch@114 811 * \param type The OSC type of the data item (eg. LO_FLOAT).
matthiasmauch@114 812 * \param data A pointer to the data item to be converted. It is changed
matthiasmauch@114 813 * in-place.
matthiasmauch@114 814 */
matthiasmauch@114 815 void lo_arg_network_endian(lo_type type, void *data);
matthiasmauch@114 816
matthiasmauch@114 817 /** @} */
matthiasmauch@114 818
matthiasmauch@114 819 /* prettyprinters */
matthiasmauch@114 820
matthiasmauch@114 821 /**
matthiasmauch@114 822 * \defgroup pp Prettyprinting functions
matthiasmauch@114 823 *
matthiasmauch@114 824 * These functions all print an ASCII representation of their argument to
matthiasmauch@114 825 * stdout. Useful for debugging.
matthiasmauch@114 826 * @{
matthiasmauch@114 827 */
matthiasmauch@114 828
matthiasmauch@114 829 /** \brief Pretty-print a lo_bundle object. */
matthiasmauch@114 830 void lo_bundle_pp(lo_bundle b);
matthiasmauch@114 831
matthiasmauch@114 832 /** \brief Pretty-print a lo_message object. */
matthiasmauch@114 833 void lo_message_pp(lo_message m);
matthiasmauch@114 834
matthiasmauch@114 835 /** \brief Pretty-print a set of typed arguments.
matthiasmauch@114 836 * \param type A type string in the form provided to lo_send().
matthiasmauch@114 837 * \param data An OSC data pointer, like that provided in the
matthiasmauch@114 838 * lo_method_handler.
matthiasmauch@114 839 */
matthiasmauch@114 840 void lo_arg_pp(lo_type type, void *data);
matthiasmauch@114 841
matthiasmauch@114 842 /** \brief Pretty-print a lo_server object. */
matthiasmauch@114 843 void lo_server_pp(lo_server s);
matthiasmauch@114 844
matthiasmauch@114 845 /** \brief Pretty-print a lo_method object. */
matthiasmauch@114 846 void lo_method_pp(lo_method m);
matthiasmauch@114 847
matthiasmauch@114 848 /** \brief Pretty-print a lo_method object, but prepend a given prefix
matthiasmauch@114 849 * to all field names. */
matthiasmauch@114 850 void lo_method_pp_prefix(lo_method m, const char *p);
matthiasmauch@114 851
matthiasmauch@114 852 /** \brief Pretty-print a lo_server_thread object. */
matthiasmauch@114 853 void lo_server_thread_pp(lo_server_thread st);
matthiasmauch@114 854 /** @} */
matthiasmauch@114 855
matthiasmauch@114 856 #ifdef __cplusplus
matthiasmauch@114 857 }
matthiasmauch@114 858 #endif
matthiasmauch@114 859
matthiasmauch@114 860 #endif