public:\r
shared_ptr<T> shared_from_this() \r
{\r
- return shared_ptr<T>(this->shared_from_this());\r
+ return shared_ptr<T>(std::enable_shared_from_this<T>::shared_from_this());\r
}\r
\r
shared_ptr<T const> shared_from_this() const \r
{\r
- return shared_ptr<T const>(this->shared_from_this());\r
+ return shared_ptr<T const>(std::enable_shared_from_this<T>::shared_from_this());\r
}\r
protected:\r
enable_shared_from_this()\r
public:\r
follow_producer_proxy(spl::shared_ptr<frame_producer>&& producer) \r
: producer_proxy_base(std::move(producer))\r
- , event_subject_(new monitor::subject("asd"))\r
{\r
producer->subscribe(event_subject_);\r
}\r
} \r
\r
graph_->set_value("produce-time", frame_timer.elapsed()*format_desc.fps*0.5);\r
- //*event_subject_ << monitor::event("profiler/time") % frame_timer.elapsed() % (1.0/format_desc.fps);\r
+ *event_subject_ << monitor::event("profiler/time") % frame_timer.elapsed() % (1.0/format_desc.fps);\r
\r
return frames;\r
});\r
\r
graph_->set_value("tick-time", frame_timer.elapsed()*format_desc.fps*0.5);\r
\r
- //*event_subject_ << monitor::event("debug/profiler") % frame_timer.elapsed() % (1.0/format_desc_.fps);\r
- //*event_subject_ << monitor::event("format") % u8(format_desc.name);\r
+ *event_subject_ << monitor::event("debug/profiler") % frame_timer.elapsed() % (1.0/format_desc_.fps);\r
+ *event_subject_ << monitor::event("format") % u8(format_desc.name);\r
}\r
catch(...)\r
{\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#ifndef INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H\r
+#define INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H\r
+\r
+#include <string.h>\r
+#include <map>\r
+\r
+#include "OscPacketListener.h"\r
+\r
+\r
+\r
+namespace osc{\r
+\r
+template< class T >\r
+class MessageMappingOscPacketListener : public OscPacketListener{\r
+public:\r
+ typedef void (T::*function_type)(const osc::ReceivedMessage&, const IpEndpointName&);\r
+\r
+protected:\r
+ void RegisterMessageFunction( const char *addressPattern, function_type f )\r
+ {\r
+ functions_.insert( std::make_pair( addressPattern, f ) );\r
+ }\r
+\r
+ virtual void ProcessMessage( const osc::ReceivedMessage& m,\r
+ const IpEndpointName& remoteEndpoint )\r
+ {\r
+ typename function_map_type::iterator i = functions_.find( m.AddressPattern() );\r
+ if( i != functions_.end() )\r
+ (dynamic_cast<T*>(this)->*(i->second))( m, remoteEndpoint );\r
+ }\r
+ \r
+private:\r
+ struct cstr_compare{\r
+ bool operator()( const char *lhs, const char *rhs ) const\r
+ { return strcmp( lhs, rhs ) < 0; }\r
+ };\r
+\r
+ typedef std::map<const char*, function_type, cstr_compare> function_map_type;\r
+ function_map_type functions_;\r
+};\r
+\r
+} // namespace osc\r
+\r
+#endif /* INCLUDED_MESSAGEMAPPINGOSCPACKETLISTENER_H */
\ No newline at end of file
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#ifndef INCLUDED_OSC_EXCEPTION_H\r
+#define INCLUDED_OSC_EXCEPTION_H\r
+\r
+#include <exception>\r
+\r
+namespace osc{\r
+\r
+class Exception : public std::exception {\r
+ const char *what_;\r
+ \r
+public:\r
+ Exception() throw() {}\r
+ Exception( const Exception& src ) throw()\r
+ : what_( src.what_ ) {}\r
+ Exception( const char *w ) throw()\r
+ : what_( w ) {}\r
+ Exception& operator=( const Exception& src ) throw()\r
+ { what_ = src.what_; return *this; }\r
+ virtual ~Exception() throw() {}\r
+ virtual const char* what() const throw() { return what_; }\r
+};\r
+\r
+} // namespace osc\r
+\r
+#endif /* INCLUDED_OSC_EXCEPTION_H */\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#ifndef OSC_HOSTENDIANNESS_H\r
+#define OSC_HOSTENDIANNESS_H\r
+\r
+/*\r
+ Make sure either OSC_HOST_LITTLE_ENDIAN or OSC_HOST_BIG_ENDIAN is defined\r
+\r
+ If you know a way to enhance the detection below for Linux and/or MacOSX\r
+ please let me know! I've tried a few things which don't work.\r
+*/\r
+\r
+#define OSC_HOST_LITTLE_ENDIAN 1\r
+#undef OSC_HOST_BIG_ENDIAN\r
+\r
+#if defined(OSC_HOST_LITTLE_ENDIAN) || defined(OSC_HOST_BIG_ENDIAN)\r
+\r
+// you can define one of the above symbols from the command line\r
+// then you don't have to edit this file.\r
+\r
+#elif defined(__WIN32__) || defined(WIN32) || defined(WINCE)\r
+\r
+// assume that __WIN32__ is only defined on little endian systems\r
+\r
+#define OSC_HOST_LITTLE_ENDIAN 1\r
+#undef OSC_HOST_BIG_ENDIAN\r
+\r
+#elif defined(__APPLE__)\r
+\r
+#if defined(__LITTLE_ENDIAN__)\r
+\r
+#define OSC_HOST_LITTLE_ENDIAN 1\r
+#undef OSC_HOST_BIG_ENDIAN\r
+\r
+#elif defined(__BIG_ENDIAN__)\r
+\r
+#define OSC_HOST_BIG_ENDIAN 1\r
+#undef OSC_HOST_LITTLE_ENDIAN\r
+\r
+#endif\r
+\r
+#endif\r
+\r
+#if !defined(OSC_HOST_LITTLE_ENDIAN) && !defined(OSC_HOST_BIG_ENDIAN)\r
+\r
+#error please edit OSCHostEndianness.h to configure endianness\r
+\r
+#endif\r
+\r
+\r
+#endif /* OSC_HOSTENDIANNESS_H */\r
+\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#undef _CRT_SECURE_NO_WARNINGS\r
+#define _CRT_SECURE_NO_WARNINGS\r
+\r
+#include "OscOutboundPacketStream.h"\r
+\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <assert.h>\r
+\r
+#if defined(__WIN32__) || defined(WIN32)\r
+#include <malloc.h> // for alloca\r
+#endif\r
+\r
+#include "OscHostEndianness.h"\r
+\r
+\r
+namespace osc{\r
+\r
+static void FromInt32( char *p, int32 x )\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::int32 i;\r
+ char c[4];\r
+ } u;\r
+\r
+ u.i = x;\r
+\r
+ p[3] = u.c[0];\r
+ p[2] = u.c[1];\r
+ p[1] = u.c[2];\r
+ p[0] = u.c[3];\r
+#else\r
+ *reinterpret_cast<int32*>(p) = x;\r
+#endif\r
+}\r
+\r
+\r
+static void FromUInt32( char *p, uint32 x )\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::uint32 i;\r
+ char c[4];\r
+ } u;\r
+\r
+ u.i = x;\r
+\r
+ p[3] = u.c[0];\r
+ p[2] = u.c[1];\r
+ p[1] = u.c[2];\r
+ p[0] = u.c[3];\r
+#else\r
+ *reinterpret_cast<uint32*>(p) = x;\r
+#endif\r
+}\r
+\r
+\r
+static void FromInt64( char *p, int64 x )\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::int64 i;\r
+ char c[8];\r
+ } u;\r
+\r
+ u.i = x;\r
+\r
+ p[7] = u.c[0];\r
+ p[6] = u.c[1];\r
+ p[5] = u.c[2];\r
+ p[4] = u.c[3];\r
+ p[3] = u.c[4];\r
+ p[2] = u.c[5];\r
+ p[1] = u.c[6];\r
+ p[0] = u.c[7];\r
+#else\r
+ *reinterpret_cast<int64*>(p) = x;\r
+#endif\r
+}\r
+\r
+\r
+static void FromUInt64( char *p, uint64 x )\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::uint64 i;\r
+ char c[8];\r
+ } u;\r
+\r
+ u.i = x;\r
+\r
+ p[7] = u.c[0];\r
+ p[6] = u.c[1];\r
+ p[5] = u.c[2];\r
+ p[4] = u.c[3];\r
+ p[3] = u.c[4];\r
+ p[2] = u.c[5];\r
+ p[1] = u.c[6];\r
+ p[0] = u.c[7];\r
+#else\r
+ *reinterpret_cast<uint64*>(p) = x;\r
+#endif\r
+}\r
+\r
+\r
+static inline long RoundUp4( long x )\r
+{\r
+ return ((x-1) & (~0x03L)) + 4;\r
+}\r
+\r
+\r
+OutboundPacketStream::OutboundPacketStream( char *buffer, unsigned long capacity )\r
+ : data_( buffer )\r
+ , end_( data_ + capacity )\r
+ , typeTagsCurrent_( end_ )\r
+ , messageCursor_( data_ )\r
+ , argumentCurrent_( data_ )\r
+ , elementSizePtr_( 0 )\r
+ , messageIsInProgress_( false )\r
+{\r
+\r
+}\r
+\r
+\r
+OutboundPacketStream::~OutboundPacketStream()\r
+{\r
+\r
+}\r
+\r
+\r
+char *OutboundPacketStream::BeginElement( char *beginPtr )\r
+{\r
+ if( elementSizePtr_ == 0 ){\r
+\r
+ elementSizePtr_ = reinterpret_cast<uint32*>(data_);\r
+\r
+ return beginPtr;\r
+\r
+ }else{\r
+ // store an offset to the old element size ptr in the element size slot\r
+ // we store an offset rather than the actual pointer to be 64 bit clean.\r
+ *reinterpret_cast<uint32*>(beginPtr) =\r
+ (uint32)(reinterpret_cast<char*>(elementSizePtr_) - data_);\r
+\r
+ elementSizePtr_ = reinterpret_cast<uint32*>(beginPtr);\r
+\r
+ return beginPtr + 4;\r
+ }\r
+}\r
+\r
+\r
+void OutboundPacketStream::EndElement( char *endPtr )\r
+{\r
+ assert( elementSizePtr_ != 0 );\r
+\r
+ if( elementSizePtr_ == reinterpret_cast<uint32*>(data_) ){\r
+\r
+ elementSizePtr_ = 0;\r
+\r
+ }else{\r
+ // while building an element, an offset to the containing element's\r
+ // size slot is stored in the elements size slot (or a ptr to data_\r
+ // if there is no containing element). We retrieve that here\r
+ uint32 *previousElementSizePtr =\r
+ (uint32*)(data_ + *reinterpret_cast<uint32*>(elementSizePtr_));\r
+\r
+ // then we store the element size in the slot, note that the element\r
+ // size does not include the size slot, hence the - 4 below.\r
+ uint32 elementSize =\r
+ static_cast<uint32>(endPtr - reinterpret_cast<char*>(elementSizePtr_)) - 4;\r
+ FromUInt32( reinterpret_cast<char*>(elementSizePtr_), elementSize );\r
+\r
+ // finally, we reset the element size ptr to the containing element\r
+ elementSizePtr_ = previousElementSizePtr;\r
+ }\r
+}\r
+\r
+\r
+bool OutboundPacketStream::ElementSizeSlotRequired() const\r
+{\r
+ return (elementSizePtr_ != 0);\r
+}\r
+\r
+\r
+void OutboundPacketStream::CheckForAvailableBundleSpace()\r
+{\r
+ unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0) + 16;\r
+\r
+ if( required > Capacity() )\r
+ throw OutOfBufferMemoryException();\r
+}\r
+\r
+\r
+void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )\r
+{\r
+ // plus 4 for at least four bytes of type tag\r
+ unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0)\r
+ + RoundUp4(static_cast<unsigned long>(strlen(addressPattern)) + 1) + 4;\r
+\r
+ if( required > Capacity() )\r
+ throw OutOfBufferMemoryException();\r
+}\r
+\r
+\r
+void OutboundPacketStream::CheckForAvailableArgumentSpace( long argumentLength )\r
+{\r
+ // plus three for extra type tag, comma and null terminator\r
+ unsigned long required = static_cast<unsigned long>(argumentCurrent_ - data_) + argumentLength\r
+ + RoundUp4( static_cast<unsigned long>(end_ - typeTagsCurrent_) + 3 );\r
+\r
+ if( required > Capacity() )\r
+ throw OutOfBufferMemoryException();\r
+}\r
+\r
+\r
+void OutboundPacketStream::Clear()\r
+{\r
+ typeTagsCurrent_ = end_;\r
+ messageCursor_ = data_;\r
+ argumentCurrent_ = data_;\r
+ elementSizePtr_ = 0;\r
+ messageIsInProgress_ = false;\r
+}\r
+\r
+\r
+unsigned int OutboundPacketStream::Capacity() const\r
+{\r
+ return static_cast<int>(end_ - data_);\r
+}\r
+\r
+\r
+unsigned int OutboundPacketStream::Size() const\r
+{\r
+ unsigned int result = static_cast<unsigned long>(argumentCurrent_ - data_);\r
+ if( IsMessageInProgress() ){\r
+ // account for the length of the type tag string. the total type tag\r
+ // includes an initial comma, plus at least one terminating \0\r
+ result += RoundUp4( static_cast<unsigned long>(end_ - typeTagsCurrent_) + 2 );\r
+ }\r
+\r
+ return result;\r
+}\r
+\r
+\r
+const char *OutboundPacketStream::Data() const\r
+{\r
+ return data_;\r
+}\r
+\r
+\r
+bool OutboundPacketStream::IsReady() const\r
+{\r
+ return (!IsMessageInProgress() && !IsBundleInProgress());\r
+}\r
+\r
+\r
+bool OutboundPacketStream::IsMessageInProgress() const\r
+{\r
+ return messageIsInProgress_;\r
+}\r
+\r
+\r
+bool OutboundPacketStream::IsBundleInProgress() const\r
+{\r
+ return (elementSizePtr_ != 0);\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const BundleInitiator& rhs )\r
+{\r
+ if( IsMessageInProgress() )\r
+ throw MessageInProgressException();\r
+\r
+ CheckForAvailableBundleSpace();\r
+\r
+ messageCursor_ = BeginElement( messageCursor_ );\r
+\r
+ memcpy( messageCursor_, "#bundle\0", 8 );\r
+ FromUInt64( messageCursor_ + 8, rhs.timeTag );\r
+\r
+ messageCursor_ += 16;\r
+ argumentCurrent_ = messageCursor_;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const BundleTerminator& rhs )\r
+{\r
+ (void) rhs;\r
+\r
+ if( !IsBundleInProgress() )\r
+ throw BundleNotInProgressException();\r
+ if( IsMessageInProgress() )\r
+ throw MessageInProgressException();\r
+\r
+ EndElement( messageCursor_ );\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const BeginMessage& rhs )\r
+{\r
+ if( IsMessageInProgress() )\r
+ throw MessageInProgressException();\r
+\r
+ CheckForAvailableMessageSpace( rhs.addressPattern );\r
+\r
+ messageCursor_ = BeginElement( messageCursor_ );\r
+\r
+ strcpy( messageCursor_, rhs.addressPattern );\r
+ unsigned long rhsLength = static_cast<unsigned long>(strlen(rhs.addressPattern));\r
+ messageCursor_ += rhsLength + 1;\r
+\r
+ // zero pad to 4-byte boundary\r
+ unsigned long i = rhsLength + 1;\r
+ while( i & 0x3 ){\r
+ *messageCursor_++ = '\0';\r
+ ++i;\r
+ }\r
+\r
+ argumentCurrent_ = messageCursor_;\r
+ typeTagsCurrent_ = end_;\r
+\r
+ messageIsInProgress_ = true;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator& rhs )\r
+{\r
+ (void) rhs;\r
+\r
+ if( !IsMessageInProgress() )\r
+ throw MessageNotInProgressException();\r
+\r
+ int typeTagsCount = static_cast<int>(end_ - typeTagsCurrent_);\r
+\r
+ if( typeTagsCount ){\r
+\r
+ char *tempTypeTags = (char*)alloca(typeTagsCount);\r
+ memcpy( tempTypeTags, typeTagsCurrent_, typeTagsCount );\r
+\r
+ // slot size includes comma and null terminator\r
+ int typeTagSlotSize = RoundUp4( typeTagsCount + 2 );\r
+\r
+ uint32 argumentsSize = static_cast<uint32>(argumentCurrent_ - messageCursor_);\r
+\r
+ memmove( messageCursor_ + typeTagSlotSize, messageCursor_, argumentsSize );\r
+\r
+ messageCursor_[0] = ',';\r
+ // copy type tags in reverse (really forward) order\r
+ for( int i=0; i < typeTagsCount; ++i )\r
+ messageCursor_[i+1] = tempTypeTags[ (typeTagsCount-1) - i ];\r
+\r
+ char *p = messageCursor_ + 1 + typeTagsCount;\r
+ for( int i=0; i < (typeTagSlotSize - (typeTagsCount + 1)); ++i )\r
+ *p++ = '\0';\r
+\r
+ typeTagsCurrent_ = end_;\r
+\r
+ // advance messageCursor_ for next message\r
+ messageCursor_ += typeTagSlotSize + argumentsSize;\r
+\r
+ }else{\r
+ // send an empty type tags string\r
+ memcpy( messageCursor_, ",\0\0\0", 4 );\r
+\r
+ // advance messageCursor_ for next message\r
+ messageCursor_ += 4;\r
+ }\r
+\r
+ argumentCurrent_ = messageCursor_;\r
+\r
+ EndElement( messageCursor_ );\r
+\r
+ messageIsInProgress_ = false;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( bool rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(0);\r
+\r
+ *(--typeTagsCurrent_) = (char)((rhs) ? TRUE_TYPE_TAG : FALSE_TYPE_TAG);\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const NilType& rhs )\r
+{\r
+ (void) rhs;\r
+ CheckForAvailableArgumentSpace(0);\r
+\r
+ *(--typeTagsCurrent_) = NIL_TYPE_TAG;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const InfinitumType& rhs )\r
+{\r
+ (void) rhs;\r
+ CheckForAvailableArgumentSpace(0);\r
+\r
+ *(--typeTagsCurrent_) = INFINITUM_TYPE_TAG;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( int32 rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(4);\r
+\r
+ *(--typeTagsCurrent_) = INT32_TYPE_TAG;\r
+ FromInt32( argumentCurrent_, rhs );\r
+ argumentCurrent_ += 4;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( float rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(4);\r
+\r
+ *(--typeTagsCurrent_) = FLOAT_TYPE_TAG;\r
+\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ float f;\r
+ char c[4];\r
+ } u;\r
+\r
+ u.f = rhs;\r
+\r
+ argumentCurrent_[3] = u.c[0];\r
+ argumentCurrent_[2] = u.c[1];\r
+ argumentCurrent_[1] = u.c[2];\r
+ argumentCurrent_[0] = u.c[3];\r
+#else\r
+ *reinterpret_cast<float*>(argumentCurrent_) = rhs;\r
+#endif\r
+\r
+ argumentCurrent_ += 4;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( char rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(4);\r
+\r
+ *(--typeTagsCurrent_) = CHAR_TYPE_TAG;\r
+ FromInt32( argumentCurrent_, rhs );\r
+ argumentCurrent_ += 4;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const RgbaColor& rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(4);\r
+\r
+ *(--typeTagsCurrent_) = RGBA_COLOR_TYPE_TAG;\r
+ FromUInt32( argumentCurrent_, rhs );\r
+ argumentCurrent_ += 4;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const MidiMessage& rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(4);\r
+\r
+ *(--typeTagsCurrent_) = MIDI_MESSAGE_TYPE_TAG;\r
+ FromUInt32( argumentCurrent_, rhs );\r
+ argumentCurrent_ += 4;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( int64 rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(8);\r
+\r
+ *(--typeTagsCurrent_) = INT64_TYPE_TAG;\r
+ FromInt64( argumentCurrent_, rhs );\r
+ argumentCurrent_ += 8;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const TimeTag& rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(8);\r
+\r
+ *(--typeTagsCurrent_) = TIME_TAG_TYPE_TAG;\r
+ FromUInt64( argumentCurrent_, rhs );\r
+ argumentCurrent_ += 8;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( double rhs )\r
+{\r
+ CheckForAvailableArgumentSpace(8);\r
+\r
+ *(--typeTagsCurrent_) = DOUBLE_TYPE_TAG;\r
+\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ double f;\r
+ char c[8];\r
+ } u;\r
+\r
+ u.f = rhs;\r
+\r
+ argumentCurrent_[7] = u.c[0];\r
+ argumentCurrent_[6] = u.c[1];\r
+ argumentCurrent_[5] = u.c[2];\r
+ argumentCurrent_[4] = u.c[3];\r
+ argumentCurrent_[3] = u.c[4];\r
+ argumentCurrent_[2] = u.c[5];\r
+ argumentCurrent_[1] = u.c[6];\r
+ argumentCurrent_[0] = u.c[7];\r
+#else\r
+ *reinterpret_cast<double*>(argumentCurrent_) = rhs;\r
+#endif\r
+\r
+ argumentCurrent_ += 8;\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )\r
+{\r
+ CheckForAvailableArgumentSpace( RoundUp4(static_cast<long>(strlen(rhs)) + 1) );\r
+\r
+ *(--typeTagsCurrent_) = STRING_TYPE_TAG;\r
+ strcpy( argumentCurrent_, rhs );\r
+ unsigned long rhsLength = static_cast<unsigned long>(strlen(rhs));\r
+ argumentCurrent_ += rhsLength + 1;\r
+\r
+ // zero pad to 4-byte boundary\r
+ unsigned long i = rhsLength + 1;\r
+ while( i & 0x3 ){\r
+ *argumentCurrent_++ = '\0';\r
+ ++i;\r
+ }\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )\r
+{\r
+ CheckForAvailableArgumentSpace( RoundUp4(static_cast<long>(strlen(rhs)) + 1) );\r
+\r
+ *(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;\r
+ strcpy( argumentCurrent_, rhs );\r
+ unsigned long rhsLength = static_cast<unsigned long>(strlen(rhs));\r
+ argumentCurrent_ += rhsLength + 1;\r
+\r
+ // zero pad to 4-byte boundary\r
+ unsigned long i = rhsLength + 1;\r
+ while( i & 0x3 ){\r
+ *argumentCurrent_++ = '\0';\r
+ ++i;\r
+ }\r
+\r
+ return *this;\r
+}\r
+\r
+\r
+OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )\r
+{\r
+ CheckForAvailableArgumentSpace( 4 + RoundUp4(rhs.size) );\r
+\r
+ *(--typeTagsCurrent_) = BLOB_TYPE_TAG;\r
+ FromUInt32( argumentCurrent_, rhs.size );\r
+ argumentCurrent_ += 4;\r
+ \r
+ memcpy( argumentCurrent_, rhs.data, rhs.size );\r
+ argumentCurrent_ += rhs.size;\r
+\r
+ // zero pad to 4-byte boundary\r
+ unsigned long i = rhs.size;\r
+ while( i & 0x3 ){\r
+ *argumentCurrent_++ = '\0';\r
+ ++i;\r
+ }\r
+\r
+ return *this;\r
+}\r
+\r
+} // namespace osc\r
+\r
+\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#ifndef INCLUDED_OSCOUTBOUNDPACKET_H\r
+#define INCLUDED_OSCOUTBOUNDPACKET_H\r
+\r
+#include "OscTypes.h"\r
+#include "OscException.h"\r
+\r
+\r
+namespace osc{\r
+\r
+class OutOfBufferMemoryException : public Exception{\r
+public:\r
+ OutOfBufferMemoryException( const char *w="out of buffer memory" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+class BundleNotInProgressException : public Exception{\r
+public:\r
+ BundleNotInProgressException(\r
+ const char *w="call to EndBundle when bundle is not in progress" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+class MessageInProgressException : public Exception{\r
+public:\r
+ MessageInProgressException(\r
+ const char *w="opening or closing bundle or message while message is in progress" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+class MessageNotInProgressException : public Exception{\r
+public:\r
+ MessageNotInProgressException(\r
+ const char *w="call to EndMessage when message is not in progress" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+\r
+class OutboundPacketStream{\r
+public:\r
+ OutboundPacketStream( char *buffer, unsigned long capacity );\r
+ ~OutboundPacketStream();\r
+\r
+ void Clear();\r
+\r
+ unsigned int Capacity() const;\r
+\r
+ // invariant: size() is valid even while building a message.\r
+ unsigned int Size() const;\r
+\r
+ const char *Data() const;\r
+\r
+ // indicates that all messages have been closed with a matching EndMessage\r
+ // and all bundles have been closed with a matching EndBundle\r
+ bool IsReady() const;\r
+\r
+ bool IsMessageInProgress() const;\r
+ bool IsBundleInProgress() const;\r
+\r
+ OutboundPacketStream& operator<<( const BundleInitiator& rhs );\r
+ OutboundPacketStream& operator<<( const BundleTerminator& rhs );\r
+ \r
+ OutboundPacketStream& operator<<( const BeginMessage& rhs );\r
+ OutboundPacketStream& operator<<( const MessageTerminator& rhs );\r
+\r
+ OutboundPacketStream& operator<<( bool rhs );\r
+ OutboundPacketStream& operator<<( const NilType& rhs );\r
+ OutboundPacketStream& operator<<( const InfinitumType& rhs );\r
+ OutboundPacketStream& operator<<( int32 rhs );\r
+\r
+//#ifndef __x86_64__\r
+// OutboundPacketStream& operator<<( int rhs )\r
+// { *this << (int32)rhs; return *this; }\r
+//#endif\r
+\r
+ OutboundPacketStream& operator<<( float rhs );\r
+ OutboundPacketStream& operator<<( char rhs );\r
+ OutboundPacketStream& operator<<( const RgbaColor& rhs );\r
+ OutboundPacketStream& operator<<( const MidiMessage& rhs );\r
+ OutboundPacketStream& operator<<( int64 rhs );\r
+ OutboundPacketStream& operator<<( const TimeTag& rhs );\r
+ OutboundPacketStream& operator<<( double rhs );\r
+ OutboundPacketStream& operator<<( const char* rhs );\r
+ OutboundPacketStream& operator<<( const Symbol& rhs );\r
+ OutboundPacketStream& operator<<( const Blob& rhs );\r
+\r
+private:\r
+\r
+ char *BeginElement( char *beginPtr );\r
+ void EndElement( char *endPtr );\r
+\r
+ bool ElementSizeSlotRequired() const;\r
+ void CheckForAvailableBundleSpace();\r
+ void CheckForAvailableMessageSpace( const char *addressPattern );\r
+ void CheckForAvailableArgumentSpace( long argumentLength );\r
+\r
+ char *data_;\r
+ char *end_;\r
+\r
+ char *typeTagsCurrent_; // stored in reverse order\r
+ char *messageCursor_;\r
+ char *argumentCurrent_;\r
+\r
+ // elementSizePtr_ has two special values: 0 indicates that a bundle\r
+ // isn't open, and elementSizePtr_==data_ indicates that a bundle is\r
+ // open but that it doesn't have a size slot (ie the outermost bundle)\r
+ uint32 *elementSizePtr_;\r
+\r
+ bool messageIsInProgress_;\r
+};\r
+\r
+} // namespace osc\r
+\r
+#endif /* INCLUDED_OSC_OUTBOUND_PACKET_H */\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#ifndef INCLUDED_OSCPACKETLISTENER_H\r
+#define INCLUDED_OSCPACKETLISTENER_H\r
+\r
+#include "OscReceivedElements.h"\r
+#include "../ip/PacketListener.h"\r
+\r
+\r
+namespace osc{\r
+\r
+class OscPacketListener : public PacketListener{ \r
+protected:\r
+ virtual void ProcessBundle( const osc::ReceivedBundle& b, \r
+ const IpEndpointName& remoteEndpoint )\r
+ {\r
+ // ignore bundle time tag for now\r
+\r
+ for( ReceivedBundle::const_iterator i = b.ElementsBegin(); \r
+ i != b.ElementsEnd(); ++i ){\r
+ if( i->IsBundle() )\r
+ ProcessBundle( ReceivedBundle(*i), remoteEndpoint );\r
+ else\r
+ ProcessMessage( ReceivedMessage(*i), remoteEndpoint );\r
+ }\r
+ }\r
+\r
+ virtual void ProcessMessage( const osc::ReceivedMessage& m, \r
+ const IpEndpointName& remoteEndpoint ) = 0;\r
+ \r
+public:\r
+ virtual void ProcessPacket( const char *data, int size, \r
+ const IpEndpointName& remoteEndpoint )\r
+ {\r
+ osc::ReceivedPacket p( data, size );\r
+ if( p.IsBundle() )\r
+ ProcessBundle( ReceivedBundle(p), remoteEndpoint );\r
+ else\r
+ ProcessMessage( ReceivedMessage(p), remoteEndpoint );\r
+ }\r
+};\r
+\r
+} // namespace osc\r
+\r
+#endif /* INCLUDED_OSCPACKETLISTENER_H */\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#undef _CRT_SECURE_NO_WARNINGS\r
+#define _CRT_SECURE_NO_WARNINGS\r
+\r
+#include "OscPrintReceivedElements.h"\r
+\r
+#include <iostream>\r
+#include <iomanip>\r
+#include <ctime>\r
+#include <cstring>\r
+\r
+\r
+namespace osc{\r
+\r
+\r
+std::ostream& operator<<( std::ostream & os,\r
+ const ReceivedMessageArgument& arg )\r
+{\r
+ switch( arg.TypeTag() ){\r
+ case TRUE_TYPE_TAG:\r
+ os << "bool:true";\r
+ break;\r
+ \r
+ case FALSE_TYPE_TAG:\r
+ os << "bool:false";\r
+ break;\r
+\r
+ case NIL_TYPE_TAG:\r
+ os << "(Nil)";\r
+ break;\r
+\r
+ case INFINITUM_TYPE_TAG:\r
+ os << "(Infinitum)";\r
+ break;\r
+\r
+ case INT32_TYPE_TAG:\r
+ os << "int32:" << arg.AsInt32Unchecked();\r
+ break;\r
+\r
+ case FLOAT_TYPE_TAG:\r
+ os << "float32:" << arg.AsFloatUnchecked();\r
+ break;\r
+\r
+ case CHAR_TYPE_TAG:\r
+ {\r
+ char s[2] = {0};\r
+ s[0] = arg.AsCharUnchecked();\r
+ os << "char:'" << s << "'";\r
+ }\r
+ break;\r
+\r
+ case RGBA_COLOR_TYPE_TAG:\r
+ {\r
+ uint32 color = arg.AsRgbaColorUnchecked();\r
+ \r
+ os << "RGBA:0x"\r
+ << std::hex << std::setfill('0')\r
+ << std::setw(2) << (int)((color>>24) & 0xFF)\r
+ << std::setw(2) << (int)((color>>16) & 0xFF)\r
+ << std::setw(2) << (int)((color>>8) & 0xFF)\r
+ << std::setw(2) << (int)(color & 0xFF)\r
+ << std::setfill(' ');\r
+ os.unsetf(std::ios::basefield);\r
+ }\r
+ break;\r
+\r
+ case MIDI_MESSAGE_TYPE_TAG:\r
+ {\r
+ uint32 m = arg.AsMidiMessageUnchecked();\r
+ os << "midi (port, status, data1, data2):<<"\r
+ << std::hex << std::setfill('0')\r
+ << "0x" << std::setw(2) << (int)((m>>24) & 0xFF)\r
+ << " 0x" << std::setw(2) << (int)((m>>16) & 0xFF)\r
+ << " 0x" << std::setw(2) << (int)((m>>8) & 0xFF)\r
+ << " 0x" << std::setw(2) << (int)(m & 0xFF)\r
+ << std::setfill(' ') << ">>";\r
+ os.unsetf(std::ios::basefield);\r
+ }\r
+ break;\r
+ \r
+ case INT64_TYPE_TAG:\r
+ os << "int64:" << arg.AsInt64Unchecked();\r
+ break;\r
+\r
+ case TIME_TAG_TYPE_TAG:\r
+ {\r
+ os << "OSC-timetag:" << arg.AsTimeTagUnchecked();\r
+\r
+ std::time_t t =\r
+ (unsigned long)( arg.AsTimeTagUnchecked() >> 32 );\r
+\r
+ // strip trailing newline from string returned by ctime\r
+ const char *timeString = std::ctime( &t );\r
+ size_t len = strlen( timeString );\r
+ char *s = new char[ len + 1 ];\r
+ strcpy( s, timeString );\r
+ if( len )\r
+ s[ len - 1 ] = '\0';\r
+ \r
+ os << " " << s;\r
+ }\r
+ break;\r
+ \r
+ case DOUBLE_TYPE_TAG:\r
+ os << "double:" << arg.AsDoubleUnchecked();\r
+ break;\r
+\r
+ case STRING_TYPE_TAG:\r
+ os << "OSC-string:`" << arg.AsStringUnchecked() << "'";\r
+ break;\r
+ \r
+ case SYMBOL_TYPE_TAG: \r
+ os << "OSC-string (symbol):`" << arg.AsSymbolUnchecked() << "'";\r
+ break;\r
+\r
+ case BLOB_TYPE_TAG:\r
+ {\r
+ unsigned long size;\r
+ const void *data;\r
+ arg.AsBlobUnchecked( data, size );\r
+ os << "OSC-blob:<<" << std::hex << std::setfill('0');\r
+ unsigned char *p = (unsigned char*)data;\r
+ for( unsigned long i = 0; i < size; ++i ){\r
+ os << "0x" << std::setw(2) << int(p[i]);\r
+ if( i != size-1 )\r
+ os << ' ';\r
+ }\r
+ os.unsetf(std::ios::basefield);\r
+ os << ">>" << std::setfill(' ');\r
+ }\r
+ break;\r
+\r
+ default:\r
+ os << "unknown";\r
+ }\r
+\r
+ return os;\r
+}\r
+\r
+\r
+std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m )\r
+{\r
+ os << "[";\r
+ if( m.AddressPatternIsUInt32() )\r
+ os << m.AddressPatternAsUInt32();\r
+ else\r
+ os << m.AddressPattern();\r
+ \r
+ bool first = true;\r
+ for( ReceivedMessage::const_iterator i = m.ArgumentsBegin();\r
+ i != m.ArgumentsEnd(); ++i ){\r
+ if( first ){\r
+ os << " ";\r
+ first = false;\r
+ }else{\r
+ os << ", ";\r
+ }\r
+\r
+ os << *i;\r
+ }\r
+\r
+ os << "]";\r
+\r
+ return os;\r
+}\r
+\r
+\r
+std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b )\r
+{\r
+ static int indent = 0;\r
+\r
+ for( int j=0; j < indent; ++j )\r
+ os << " ";\r
+ os << "{ ( ";\r
+ if( b.TimeTag() == 1 )\r
+ os << "immediate";\r
+ else\r
+ os << b.TimeTag();\r
+ os << " )\n";\r
+\r
+ ++indent;\r
+ \r
+ for( ReceivedBundle::const_iterator i = b.ElementsBegin();\r
+ i != b.ElementsEnd(); ++i ){\r
+ if( i->IsBundle() ){\r
+ ReceivedBundle b(*i);\r
+ os << b << "\n";\r
+ }else{\r
+ ReceivedMessage m(*i);\r
+ for( int j=0; j < indent; ++j )\r
+ os << " ";\r
+ os << m << "\n";\r
+ }\r
+ }\r
+\r
+ --indent;\r
+\r
+ for( int j=0; j < indent; ++j )\r
+ os << " ";\r
+ os << "}";\r
+\r
+ return os;\r
+}\r
+\r
+\r
+std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p )\r
+{\r
+ if( p.IsBundle() ){\r
+ ReceivedBundle b(p);\r
+ os << b << "\n";\r
+ }else{\r
+ ReceivedMessage m(p);\r
+ os << m << "\n";\r
+ }\r
+\r
+ return os;\r
+}\r
+\r
+} // namespace osc\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#ifndef INCLUDED_OSCPRINTRECEIVEDELEMENTS_H\r
+#define INCLUDED_OSCPRINTRECEIVEDELEMENTS_H\r
+\r
+#include <iosfwd>\r
+\r
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H\r
+#include "OscReceivedElements.h"\r
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */\r
+\r
+\r
+namespace osc{\r
+\r
+std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p );\r
+std::ostream& operator<<( std::ostream & os, const ReceivedMessageArgument& arg );\r
+std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m );\r
+std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b );\r
+\r
+} // namespace osc\r
+\r
+#endif /* INCLUDED_OSCPRINTRECEIVEDELEMENTS_H */\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#undef _CRT_SECURE_NO_WARNINGS\r
+#define _CRT_SECURE_NO_WARNINGS\r
+\r
+#include "OscReceivedElements.h"\r
+\r
+#include <cassert>\r
+\r
+#include "OscHostEndianness.h"\r
+\r
+\r
+namespace osc{\r
+\r
+\r
+// return the first 4 byte boundary after the end of a str4\r
+// be careful about calling this version if you don't know whether\r
+// the string is terminated correctly.\r
+static inline const char* FindStr4End( const char *p )\r
+{\r
+ if( p[0] == '\0' ) // special case for SuperCollider integer address pattern\r
+ return p + 4;\r
+\r
+ p += 3;\r
+\r
+ while( *p )\r
+ p += 4;\r
+\r
+ return p + 1;\r
+}\r
+\r
+\r
+// return the first 4 byte boundary after the end of a str4\r
+// returns 0 if p == end or if the string is unterminated\r
+static inline const char* FindStr4End( const char *p, const char *end )\r
+{\r
+ if( p >= end )\r
+ return 0;\r
+\r
+ if( p[0] == '\0' ) // special case for SuperCollider integer address pattern\r
+ return p + 4;\r
+\r
+ p += 3;\r
+ end -= 1;\r
+\r
+ while( p < end && *p )\r
+ p += 4;\r
+\r
+ if( *p )\r
+ return 0;\r
+ else\r
+ return p + 1;\r
+}\r
+\r
+\r
+static inline unsigned long RoundUp4( unsigned long x )\r
+{\r
+ unsigned long remainder = x & 0x3UL;\r
+ if( remainder )\r
+ return x + (4 - remainder);\r
+ else\r
+ return x;\r
+}\r
+\r
+\r
+static inline int32 ToInt32( const char *p )\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::int32 i;\r
+ char c[4];\r
+ } u;\r
+\r
+ u.c[0] = p[3];\r
+ u.c[1] = p[2];\r
+ u.c[2] = p[1];\r
+ u.c[3] = p[0];\r
+\r
+ return u.i;\r
+#else\r
+ return *(int32*)p;\r
+#endif\r
+}\r
+\r
+\r
+static inline uint32 ToUInt32( const char *p )\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::uint32 i;\r
+ char c[4];\r
+ } u;\r
+\r
+ u.c[0] = p[3];\r
+ u.c[1] = p[2];\r
+ u.c[2] = p[1];\r
+ u.c[3] = p[0];\r
+\r
+ return u.i;\r
+#else\r
+ return *(uint32*)p;\r
+#endif\r
+}\r
+\r
+\r
+int64 ToInt64( const char *p )\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::int64 i;\r
+ char c[8];\r
+ } u;\r
+\r
+ u.c[0] = p[7];\r
+ u.c[1] = p[6];\r
+ u.c[2] = p[5];\r
+ u.c[3] = p[4];\r
+ u.c[4] = p[3];\r
+ u.c[5] = p[2];\r
+ u.c[6] = p[1];\r
+ u.c[7] = p[0];\r
+\r
+ return u.i;\r
+#else\r
+ return *(int64*)p;\r
+#endif\r
+}\r
+\r
+\r
+uint64 ToUInt64( const char *p )\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::uint64 i;\r
+ char c[8];\r
+ } u;\r
+\r
+ u.c[0] = p[7];\r
+ u.c[1] = p[6];\r
+ u.c[2] = p[5];\r
+ u.c[3] = p[4];\r
+ u.c[4] = p[3];\r
+ u.c[5] = p[2];\r
+ u.c[6] = p[1];\r
+ u.c[7] = p[0];\r
+\r
+ return u.i;\r
+#else\r
+ return *(uint64*)p;\r
+#endif\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+bool ReceivedPacket::IsBundle() const\r
+{\r
+ return (Size() > 0 && Contents()[0] == '#');\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+bool ReceivedBundleElement::IsBundle() const\r
+{\r
+ return (Size() > 0 && Contents()[0] == '#');\r
+}\r
+\r
+\r
+int32 ReceivedBundleElement::Size() const\r
+{\r
+ return ToUInt32( size_ );\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+bool ReceivedMessageArgument::AsBool() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == TRUE_TYPE_TAG )\r
+ return true;\r
+ else if( *typeTag_ == FALSE_TYPE_TAG )\r
+ return false;\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+bool ReceivedMessageArgument::AsBoolUnchecked() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == TRUE_TYPE_TAG )\r
+ return true;\r
+ else\r
+ return false;\r
+}\r
+\r
+\r
+int32 ReceivedMessageArgument::AsInt32() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == INT32_TYPE_TAG )\r
+ return AsInt32Unchecked();\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+int32 ReceivedMessageArgument::AsInt32Unchecked() const\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ osc::int32 i;\r
+ char c[4];\r
+ } u;\r
+\r
+ u.c[0] = argument_[3];\r
+ u.c[1] = argument_[2];\r
+ u.c[2] = argument_[1];\r
+ u.c[3] = argument_[0];\r
+\r
+ return u.i;\r
+#else\r
+ return *(int32*)argument_;\r
+#endif\r
+}\r
+\r
+\r
+float ReceivedMessageArgument::AsFloat() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == FLOAT_TYPE_TAG )\r
+ return AsFloatUnchecked();\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+float ReceivedMessageArgument::AsFloatUnchecked() const\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ float f;\r
+ char c[4];\r
+ } u;\r
+\r
+ u.c[0] = argument_[3];\r
+ u.c[1] = argument_[2];\r
+ u.c[2] = argument_[1];\r
+ u.c[3] = argument_[0];\r
+\r
+ return u.f;\r
+#else\r
+ return *(float*)argument_;\r
+#endif\r
+}\r
+\r
+\r
+char ReceivedMessageArgument::AsChar() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == CHAR_TYPE_TAG )\r
+ return AsCharUnchecked();\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+char ReceivedMessageArgument::AsCharUnchecked() const\r
+{\r
+ return (char)ToInt32( argument_ );\r
+}\r
+\r
+\r
+uint32 ReceivedMessageArgument::AsRgbaColor() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == RGBA_COLOR_TYPE_TAG )\r
+ return AsRgbaColorUnchecked();\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+uint32 ReceivedMessageArgument::AsRgbaColorUnchecked() const\r
+{\r
+ return ToUInt32( argument_ );\r
+}\r
+\r
+\r
+uint32 ReceivedMessageArgument::AsMidiMessage() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == MIDI_MESSAGE_TYPE_TAG )\r
+ return AsMidiMessageUnchecked();\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+uint32 ReceivedMessageArgument::AsMidiMessageUnchecked() const\r
+{\r
+ return ToUInt32( argument_ );\r
+}\r
+\r
+\r
+int64 ReceivedMessageArgument::AsInt64() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == INT64_TYPE_TAG )\r
+ return AsInt64Unchecked();\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+int64 ReceivedMessageArgument::AsInt64Unchecked() const\r
+{\r
+ return ToInt64( argument_ );\r
+}\r
+\r
+\r
+uint64 ReceivedMessageArgument::AsTimeTag() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == TIME_TAG_TYPE_TAG )\r
+ return AsTimeTagUnchecked();\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+uint64 ReceivedMessageArgument::AsTimeTagUnchecked() const\r
+{\r
+ return ToUInt64( argument_ );\r
+}\r
+\r
+\r
+double ReceivedMessageArgument::AsDouble() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == DOUBLE_TYPE_TAG )\r
+ return AsDoubleUnchecked();\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+double ReceivedMessageArgument::AsDoubleUnchecked() const\r
+{\r
+#ifdef OSC_HOST_LITTLE_ENDIAN\r
+ union{\r
+ double d;\r
+ char c[8];\r
+ } u;\r
+\r
+ u.c[0] = argument_[7];\r
+ u.c[1] = argument_[6];\r
+ u.c[2] = argument_[5];\r
+ u.c[3] = argument_[4];\r
+ u.c[4] = argument_[3];\r
+ u.c[5] = argument_[2];\r
+ u.c[6] = argument_[1];\r
+ u.c[7] = argument_[0];\r
+\r
+ return u.d;\r
+#else\r
+ return *(double*)argument_;\r
+#endif\r
+}\r
+\r
+\r
+const char* ReceivedMessageArgument::AsString() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == STRING_TYPE_TAG )\r
+ return argument_;\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+const char* ReceivedMessageArgument::AsSymbol() const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == SYMBOL_TYPE_TAG )\r
+ return argument_;\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+void ReceivedMessageArgument::AsBlob( const void*& data, unsigned long& size ) const\r
+{\r
+ if( !typeTag_ )\r
+ throw MissingArgumentException();\r
+ else if( *typeTag_ == BLOB_TYPE_TAG )\r
+ AsBlobUnchecked( data, size );\r
+ else\r
+ throw WrongArgumentTypeException();\r
+}\r
+\r
+\r
+void ReceivedMessageArgument::AsBlobUnchecked( const void*& data, unsigned long& size ) const\r
+{\r
+ size = ToUInt32( argument_ );\r
+ data = (void*)(argument_+4);\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+void ReceivedMessageArgumentIterator::Advance()\r
+{\r
+ if( !value_.typeTag_ )\r
+ return;\r
+ \r
+ switch( *value_.typeTag_++ ){\r
+ case '\0':\r
+ // don't advance past end\r
+ --value_.typeTag_;\r
+ break;\r
+ \r
+ case TRUE_TYPE_TAG:\r
+ case FALSE_TYPE_TAG:\r
+ case NIL_TYPE_TAG:\r
+ case INFINITUM_TYPE_TAG:\r
+\r
+ // zero length\r
+ break;\r
+\r
+ case INT32_TYPE_TAG:\r
+ case FLOAT_TYPE_TAG: \r
+ case CHAR_TYPE_TAG:\r
+ case RGBA_COLOR_TYPE_TAG:\r
+ case MIDI_MESSAGE_TYPE_TAG:\r
+\r
+ value_.argument_ += 4;\r
+ break;\r
+\r
+ case INT64_TYPE_TAG:\r
+ case TIME_TAG_TYPE_TAG:\r
+ case DOUBLE_TYPE_TAG:\r
+ \r
+ value_.argument_ += 8;\r
+ break;\r
+\r
+ case STRING_TYPE_TAG: \r
+ case SYMBOL_TYPE_TAG:\r
+\r
+ // we use the unsafe function FindStr4End(char*) here because all of\r
+ // the arguments have already been validated in\r
+ // ReceivedMessage::Init() below.\r
+ \r
+ value_.argument_ = FindStr4End( value_.argument_ );\r
+ break;\r
+\r
+ case BLOB_TYPE_TAG:\r
+ {\r
+ uint32 blobSize = ToUInt32( value_.argument_ );\r
+ value_.argument_ = value_.argument_ + 4 + RoundUp4( (unsigned long)blobSize );\r
+ }\r
+ break;\r
+\r
+ default: // unknown type tag\r
+ // don't advance\r
+ --value_.typeTag_;\r
+ break;\r
+ \r
+\r
+ // not handled:\r
+ // [ Indicates the beginning of an array. The tags following are for\r
+ // data in the Array until a close brace tag is reached.\r
+ // ] Indicates the end of an array.\r
+ }\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+ReceivedMessage::ReceivedMessage( const ReceivedPacket& packet )\r
+ : addressPattern_( packet.Contents() )\r
+{\r
+ Init( packet.Contents(), packet.Size() );\r
+}\r
+\r
+\r
+ReceivedMessage::ReceivedMessage( const ReceivedBundleElement& bundleElement )\r
+ : addressPattern_( bundleElement.Contents() )\r
+{\r
+ Init( bundleElement.Contents(), bundleElement.Size() );\r
+}\r
+\r
+\r
+bool ReceivedMessage::AddressPatternIsUInt32() const\r
+{\r
+ return (addressPattern_[0] == '\0');\r
+}\r
+\r
+\r
+uint32 ReceivedMessage::AddressPatternAsUInt32() const\r
+{\r
+ return ToUInt32( addressPattern_ );\r
+}\r
+\r
+\r
+void ReceivedMessage::Init( const char *message, unsigned long size )\r
+{\r
+ if( size == 0 )\r
+ throw MalformedMessageException( "zero length messages not permitted" );\r
+\r
+ if( (size & 0x03L) != 0 )\r
+ throw MalformedMessageException( "message size must be multiple of four" );\r
+\r
+ const char *end = message + size;\r
+\r
+ typeTagsBegin_ = FindStr4End( addressPattern_, end );\r
+ if( typeTagsBegin_ == 0 ){\r
+ // address pattern was not terminated before end\r
+ throw MalformedMessageException( "unterminated address pattern" );\r
+ }\r
+\r
+ if( typeTagsBegin_ == end ){\r
+ // message consists of only the address pattern - no arguments or type tags.\r
+ typeTagsBegin_ = 0;\r
+ typeTagsEnd_ = 0;\r
+ arguments_ = 0;\r
+ \r
+ }else{\r
+ if( *typeTagsBegin_ != ',' )\r
+ throw MalformedMessageException( "type tags not present" );\r
+\r
+ if( *(typeTagsBegin_ + 1) == '\0' ){\r
+ // zero length type tags\r
+ typeTagsBegin_ = 0;\r
+ typeTagsEnd_ = 0;\r
+ arguments_ = 0;\r
+\r
+ }else{\r
+ // check that all arguments are present and well formed\r
+ \r
+ arguments_ = FindStr4End( typeTagsBegin_, end );\r
+ if( arguments_ == 0 ){\r
+ throw MalformedMessageException( "type tags were not terminated before end of message" );\r
+ }\r
+\r
+ ++typeTagsBegin_; // advance past initial ','\r
+ \r
+ const char *typeTag = typeTagsBegin_;\r
+ const char *argument = arguments_;\r
+ \r
+ do{\r
+ switch( *typeTag ){\r
+ case TRUE_TYPE_TAG:\r
+ case FALSE_TYPE_TAG:\r
+ case NIL_TYPE_TAG:\r
+ case INFINITUM_TYPE_TAG:\r
+\r
+ // zero length\r
+ break;\r
+\r
+ case INT32_TYPE_TAG:\r
+ case FLOAT_TYPE_TAG:\r
+ case CHAR_TYPE_TAG:\r
+ case RGBA_COLOR_TYPE_TAG:\r
+ case MIDI_MESSAGE_TYPE_TAG:\r
+\r
+ if( argument == end )\r
+ throw MalformedMessageException( "arguments exceed message size" );\r
+ argument += 4;\r
+ if( argument > end )\r
+ throw MalformedMessageException( "arguments exceed message size" );\r
+ break;\r
+\r
+ case INT64_TYPE_TAG:\r
+ case TIME_TAG_TYPE_TAG:\r
+ case DOUBLE_TYPE_TAG:\r
+\r
+ if( argument == end )\r
+ throw MalformedMessageException( "arguments exceed message size" );\r
+ argument += 8;\r
+ if( argument > end )\r
+ throw MalformedMessageException( "arguments exceed message size" );\r
+ break;\r
+\r
+ case STRING_TYPE_TAG: \r
+ case SYMBOL_TYPE_TAG:\r
+ \r
+ if( argument == end )\r
+ throw MalformedMessageException( "arguments exceed message size" );\r
+ argument = FindStr4End( argument, end );\r
+ if( argument == 0 )\r
+ throw MalformedMessageException( "unterminated string argument" );\r
+ break;\r
+\r
+ case BLOB_TYPE_TAG:\r
+ {\r
+ if( argument + 4 > end )\r
+ MalformedMessageException( "arguments exceed message size" );\r
+ \r
+ uint32 blobSize = ToUInt32( argument );\r
+ argument = argument + 4 + RoundUp4( (unsigned long)blobSize );\r
+ if( argument > end )\r
+ MalformedMessageException( "arguments exceed message size" );\r
+ }\r
+ break;\r
+ \r
+ default:\r
+ throw MalformedMessageException( "unknown type tag" );\r
+\r
+ // not handled:\r
+ // [ Indicates the beginning of an array. The tags following are for\r
+ // data in the Array until a close brace tag is reached.\r
+ // ] Indicates the end of an array.\r
+ }\r
+\r
+ }while( *++typeTag != '\0' );\r
+ typeTagsEnd_ = typeTag;\r
+ }\r
+ }\r
+}\r
+\r
+//------------------------------------------------------------------------------\r
+\r
+ReceivedBundle::ReceivedBundle( const ReceivedPacket& packet )\r
+ : elementCount_( 0 )\r
+{\r
+ Init( packet.Contents(), packet.Size() );\r
+}\r
+\r
+\r
+ReceivedBundle::ReceivedBundle( const ReceivedBundleElement& bundleElement )\r
+ : elementCount_( 0 )\r
+{\r
+ Init( bundleElement.Contents(), bundleElement.Size() );\r
+}\r
+\r
+\r
+void ReceivedBundle::Init( const char *bundle, unsigned long size )\r
+{\r
+ if( size < 16 )\r
+ throw MalformedBundleException( "packet too short for bundle" );\r
+\r
+ if( (size & 0x03L) != 0 )\r
+ throw MalformedBundleException( "bundle size must be multiple of four" );\r
+\r
+ if( bundle[0] != '#'\r
+ || bundle[1] != 'b'\r
+ || bundle[2] != 'u'\r
+ || bundle[3] != 'n'\r
+ || bundle[4] != 'd'\r
+ || bundle[5] != 'l'\r
+ || bundle[6] != 'e'\r
+ || bundle[7] != '\0' )\r
+ throw MalformedBundleException( "bad bundle address pattern" ); \r
+\r
+ end_ = bundle + size;\r
+\r
+ timeTag_ = bundle + 8;\r
+\r
+ const char *p = timeTag_ + 8;\r
+ \r
+ while( p < end_ ){\r
+ if( p + 4 > end_ )\r
+ throw MalformedBundleException( "packet too short for elementSize" );\r
+\r
+ uint32 elementSize = ToUInt32( p );\r
+ if( (elementSize & 0x03L) != 0 )\r
+ throw MalformedBundleException( "bundle element size must be multiple of four" );\r
+\r
+ p += 4 + elementSize;\r
+ if( p > end_ )\r
+ throw MalformedBundleException( "packet too short for bundle element" );\r
+\r
+ ++elementCount_;\r
+ }\r
+\r
+ if( p != end_ )\r
+ throw MalformedBundleException( "bundle contents " );\r
+}\r
+\r
+\r
+uint64 ReceivedBundle::TimeTag() const\r
+{\r
+ return ToUInt64( timeTag_ );\r
+}\r
+\r
+\r
+} // namespace osc\r
+\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#ifndef INCLUDED_OSCRECEIVEDELEMENTS_H\r
+#define INCLUDED_OSCRECEIVEDELEMENTS_H\r
+\r
+#include <cstddef>\r
+\r
+#include "OscTypes.h"\r
+#include "OscException.h"\r
+\r
+\r
+namespace osc{\r
+\r
+\r
+class MalformedMessageException : public Exception{\r
+public:\r
+ MalformedMessageException( const char *w="malformed message" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+class MalformedBundleException : public Exception{\r
+public:\r
+ MalformedBundleException( const char *w="malformed bundle" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+class WrongArgumentTypeException : public Exception{\r
+public:\r
+ WrongArgumentTypeException( const char *w="wrong argument type" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+class MissingArgumentException : public Exception{\r
+public:\r
+ MissingArgumentException( const char *w="missing argument" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+class ExcessArgumentException : public Exception{\r
+public:\r
+ ExcessArgumentException( const char *w="too many arguments" )\r
+ : Exception( w ) {}\r
+};\r
+\r
+\r
+class ReceivedPacket{\r
+public:\r
+ ReceivedPacket( const char *contents, int32 size )\r
+ : contents_( contents )\r
+ , size_( size ) {}\r
+\r
+ bool IsMessage() const { return !IsBundle(); }\r
+ bool IsBundle() const;\r
+\r
+ int32 Size() const { return size_; }\r
+ const char *Contents() const { return contents_; }\r
+\r
+private:\r
+ const char *contents_;\r
+ int32 size_;\r
+};\r
+\r
+\r
+class ReceivedBundleElement{\r
+public:\r
+ ReceivedBundleElement( const char *size )\r
+ : size_( size ) {}\r
+\r
+ friend class ReceivedBundleElementIterator;\r
+\r
+ bool IsMessage() const { return !IsBundle(); }\r
+ bool IsBundle() const;\r
+\r
+ int32 Size() const;\r
+ const char *Contents() const { return size_ + 4; }\r
+\r
+private:\r
+ const char *size_;\r
+};\r
+\r
+\r
+class ReceivedBundleElementIterator{\r
+public:\r
+ ReceivedBundleElementIterator( const char *sizePtr )\r
+ : value_( sizePtr ) {}\r
+\r
+ ReceivedBundleElementIterator operator++()\r
+ {\r
+ Advance();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedBundleElementIterator operator++(int)\r
+ {\r
+ ReceivedBundleElementIterator old( *this );\r
+ Advance();\r
+ return old;\r
+ }\r
+\r
+ const ReceivedBundleElement& operator*() const { return value_; }\r
+\r
+ const ReceivedBundleElement* operator->() const { return &value_; }\r
+\r
+ friend bool operator==(const ReceivedBundleElementIterator& lhs,\r
+ const ReceivedBundleElementIterator& rhs );\r
+\r
+private:\r
+ ReceivedBundleElement value_;\r
+\r
+ void Advance() { value_.size_ = value_.Contents() + value_.Size(); }\r
+\r
+ bool IsEqualTo( const ReceivedBundleElementIterator& rhs ) const\r
+ {\r
+ return value_.size_ == rhs.value_.size_;\r
+ }\r
+};\r
+\r
+inline bool operator==(const ReceivedBundleElementIterator& lhs,\r
+ const ReceivedBundleElementIterator& rhs )\r
+{ \r
+ return lhs.IsEqualTo( rhs );\r
+}\r
+\r
+inline bool operator!=(const ReceivedBundleElementIterator& lhs,\r
+ const ReceivedBundleElementIterator& rhs )\r
+{\r
+ return !( lhs == rhs );\r
+}\r
+\r
+\r
+class ReceivedMessageArgument{\r
+public:\r
+ ReceivedMessageArgument( const char *typeTag, const char *argument )\r
+ : typeTag_( typeTag )\r
+ , argument_( argument ) {}\r
+\r
+ friend class ReceivedMessageArgumentIterator;\r
+ \r
+ const char TypeTag() const { return *typeTag_; }\r
+\r
+ // the unchecked methods below don't check whether the argument actually\r
+ // is of the specified type. they should only be used if you've already\r
+ // checked the type tag or the associated IsType() method.\r
+\r
+ bool IsBool() const\r
+ { return *typeTag_ == TRUE_TYPE_TAG || *typeTag_ == FALSE_TYPE_TAG; }\r
+ bool AsBool() const;\r
+ bool AsBoolUnchecked() const;\r
+\r
+ bool IsNil() const { return *typeTag_ == NIL_TYPE_TAG; }\r
+ bool IsInfinitum() const { return *typeTag_ == INFINITUM_TYPE_TAG; }\r
+\r
+ bool IsInt32() const { return *typeTag_ == INT32_TYPE_TAG; }\r
+ int32 AsInt32() const;\r
+ int32 AsInt32Unchecked() const;\r
+\r
+ bool IsFloat() const { return *typeTag_ == FLOAT_TYPE_TAG; }\r
+ float AsFloat() const;\r
+ float AsFloatUnchecked() const;\r
+\r
+ bool IsChar() const { return *typeTag_ == CHAR_TYPE_TAG; }\r
+ char AsChar() const;\r
+ char AsCharUnchecked() const;\r
+\r
+ bool IsRgbaColor() const { return *typeTag_ == RGBA_COLOR_TYPE_TAG; }\r
+ uint32 AsRgbaColor() const;\r
+ uint32 AsRgbaColorUnchecked() const;\r
+\r
+ bool IsMidiMessage() const { return *typeTag_ == MIDI_MESSAGE_TYPE_TAG; }\r
+ uint32 AsMidiMessage() const;\r
+ uint32 AsMidiMessageUnchecked() const;\r
+\r
+ bool IsInt64() const { return *typeTag_ == INT64_TYPE_TAG; }\r
+ int64 AsInt64() const;\r
+ int64 AsInt64Unchecked() const;\r
+\r
+ bool IsTimeTag() const { return *typeTag_ == TIME_TAG_TYPE_TAG; }\r
+ uint64 AsTimeTag() const;\r
+ uint64 AsTimeTagUnchecked() const;\r
+\r
+ bool IsDouble() const { return *typeTag_ == DOUBLE_TYPE_TAG; }\r
+ double AsDouble() const;\r
+ double AsDoubleUnchecked() const;\r
+\r
+ bool IsString() const { return *typeTag_ == STRING_TYPE_TAG; }\r
+ const char* AsString() const;\r
+ const char* AsStringUnchecked() const { return argument_; }\r
+\r
+ bool IsSymbol() const { return *typeTag_ == SYMBOL_TYPE_TAG; }\r
+ const char* AsSymbol() const;\r
+ const char* AsSymbolUnchecked() const { return argument_; }\r
+\r
+ bool IsBlob() const { return *typeTag_ == BLOB_TYPE_TAG; }\r
+ void AsBlob( const void*& data, unsigned long& size ) const;\r
+ void AsBlobUnchecked( const void*& data, unsigned long& size ) const;\r
+ \r
+private:\r
+ const char *typeTag_;\r
+ const char *argument_;\r
+};\r
+\r
+\r
+class ReceivedMessageArgumentIterator{\r
+public:\r
+ ReceivedMessageArgumentIterator( const char *typeTags, const char *arguments )\r
+ : value_( typeTags, arguments ) {}\r
+\r
+ ReceivedMessageArgumentIterator operator++()\r
+ {\r
+ Advance();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedMessageArgumentIterator operator++(int)\r
+ {\r
+ ReceivedMessageArgumentIterator old( *this );\r
+ Advance();\r
+ return old;\r
+ }\r
+\r
+ const ReceivedMessageArgument& operator*() const { return value_; }\r
+\r
+ const ReceivedMessageArgument* operator->() const { return &value_; }\r
+\r
+ friend bool operator==(const ReceivedMessageArgumentIterator& lhs,\r
+ const ReceivedMessageArgumentIterator& rhs );\r
+\r
+private:\r
+ ReceivedMessageArgument value_;\r
+\r
+ void Advance();\r
+\r
+ bool IsEqualTo( const ReceivedMessageArgumentIterator& rhs ) const\r
+ {\r
+ return value_.typeTag_ == rhs.value_.typeTag_;\r
+ }\r
+};\r
+\r
+inline bool operator==(const ReceivedMessageArgumentIterator& lhs,\r
+ const ReceivedMessageArgumentIterator& rhs )\r
+{ \r
+ return lhs.IsEqualTo( rhs );\r
+}\r
+\r
+inline bool operator!=(const ReceivedMessageArgumentIterator& lhs,\r
+ const ReceivedMessageArgumentIterator& rhs )\r
+{ \r
+ return !( lhs == rhs );\r
+}\r
+\r
+\r
+class ReceivedMessageArgumentStream{\r
+ friend class ReceivedMessage;\r
+ ReceivedMessageArgumentStream( const ReceivedMessageArgumentIterator& begin,\r
+ const ReceivedMessageArgumentIterator& end )\r
+ : p_( begin )\r
+ , end_( end ) {}\r
+\r
+ ReceivedMessageArgumentIterator p_, end_;\r
+ \r
+public:\r
+\r
+ // end of stream\r
+ bool Eos() const { return p_ == end_; }\r
+\r
+ ReceivedMessageArgumentStream& operator>>( bool& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs = (*p_++).AsBool();\r
+ return *this;\r
+ }\r
+\r
+ // not sure if it would be useful to stream Nil and Infinitum\r
+ // for now it's not possible\r
+\r
+ ReceivedMessageArgumentStream& operator>>( int32& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs = (*p_++).AsInt32();\r
+ return *this;\r
+ } \r
+\r
+ ReceivedMessageArgumentStream& operator>>( float& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs = (*p_++).AsFloat();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedMessageArgumentStream& operator>>( char& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs = (*p_++).AsChar();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedMessageArgumentStream& operator>>( RgbaColor& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs.value = (*p_++).AsRgbaColor();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedMessageArgumentStream& operator>>( MidiMessage& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs.value = (*p_++).AsMidiMessage();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedMessageArgumentStream& operator>>( int64& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs = (*p_++).AsInt64();\r
+ return *this;\r
+ }\r
+ \r
+ ReceivedMessageArgumentStream& operator>>( TimeTag& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs.value = (*p_++).AsTimeTag();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedMessageArgumentStream& operator>>( double& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs = (*p_++).AsDouble();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedMessageArgumentStream& operator>>( Blob& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ (*p_++).AsBlob( rhs.data, rhs.size );\r
+ return *this;\r
+ }\r
+ \r
+ ReceivedMessageArgumentStream& operator>>( const char*& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs = (*p_++).AsString();\r
+ return *this;\r
+ }\r
+ \r
+ ReceivedMessageArgumentStream& operator>>( Symbol& rhs )\r
+ {\r
+ if( Eos() )\r
+ throw MissingArgumentException();\r
+\r
+ rhs.value = (*p_++).AsSymbol();\r
+ return *this;\r
+ }\r
+\r
+ ReceivedMessageArgumentStream& operator>>( MessageTerminator& rhs )\r
+ {\r
+ if( !Eos() )\r
+ throw ExcessArgumentException();\r
+\r
+ return *this;\r
+ }\r
+};\r
+\r
+\r
+class ReceivedMessage{\r
+ void Init( const char *bundle, unsigned long size );\r
+public:\r
+ explicit ReceivedMessage( const ReceivedPacket& packet );\r
+ explicit ReceivedMessage( const ReceivedBundleElement& bundleElement );\r
+\r
+ const char *AddressPattern() const { return addressPattern_; }\r
+\r
+ // Support for non-standad SuperCollider integer address patterns:\r
+ bool AddressPatternIsUInt32() const;\r
+ uint32 AddressPatternAsUInt32() const;\r
+\r
+ unsigned long ArgumentCount() const { return static_cast<unsigned long>(typeTagsEnd_ - typeTagsBegin_); }\r
+\r
+ const char *TypeTags() const { return typeTagsBegin_; }\r
+\r
+\r
+ typedef ReceivedMessageArgumentIterator const_iterator;\r
+ \r
+ ReceivedMessageArgumentIterator ArgumentsBegin() const\r
+ {\r
+ return ReceivedMessageArgumentIterator( typeTagsBegin_, arguments_ );\r
+ }\r
+ \r
+ ReceivedMessageArgumentIterator ArgumentsEnd() const\r
+ {\r
+ return ReceivedMessageArgumentIterator( typeTagsEnd_, 0 );\r
+ }\r
+\r
+ ReceivedMessageArgumentStream ArgumentStream() const\r
+ {\r
+ return ReceivedMessageArgumentStream( ArgumentsBegin(), ArgumentsEnd() );\r
+ }\r
+\r
+private:\r
+ const char *addressPattern_;\r
+ const char *typeTagsBegin_;\r
+ const char *typeTagsEnd_;\r
+ const char *arguments_;\r
+};\r
+\r
+\r
+class ReceivedBundle{\r
+ void Init( const char *message, unsigned long size );\r
+public:\r
+ explicit ReceivedBundle( const ReceivedPacket& packet );\r
+ explicit ReceivedBundle( const ReceivedBundleElement& bundleElement );\r
+\r
+ uint64 TimeTag() const;\r
+\r
+ unsigned long ElementCount() const { return elementCount_; }\r
+\r
+ typedef ReceivedBundleElementIterator const_iterator;\r
+ \r
+ ReceivedBundleElementIterator ElementsBegin() const\r
+ {\r
+ return ReceivedBundleElementIterator( timeTag_ + 8 );\r
+ }\r
+ \r
+ ReceivedBundleElementIterator ElementsEnd() const\r
+ {\r
+ return ReceivedBundleElementIterator( end_ );\r
+ }\r
+\r
+private:\r
+ const char *timeTag_;\r
+ const char *end_;\r
+ unsigned long elementCount_;\r
+};\r
+\r
+\r
+} // namespace osc\r
+\r
+\r
+#endif /* INCLUDED_OSCRECEIVEDELEMENTS_H */\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#include "OscTypes.h"\r
+\r
+namespace osc{\r
+\r
+BundleInitiator BeginBundleImmediate(1);\r
+BundleTerminator EndBundle;\r
+MessageTerminator EndMessage;\r
+NilType Nil;\r
+InfinitumType Infinitum;\r
+\r
+} // namespace osc\r
--- /dev/null
+/*\r
+ oscpack -- Open Sound Control packet manipulation library\r
+ http://www.audiomulch.com/~rossb/oscpack\r
+\r
+ Copyright (c) 2004-2005 Ross Bencina <rossb@audiomulch.com>\r
+\r
+ Permission is hereby granted, free of charge, to any person obtaining\r
+ a copy of this software and associated documentation files\r
+ (the "Software"), to deal in the Software without restriction,\r
+ including without limitation the rights to use, copy, modify, merge,\r
+ publish, distribute, sublicense, and/or sell copies of the Software,\r
+ and to permit persons to whom the Software is furnished to do so,\r
+ subject to the following conditions:\r
+\r
+ The above copyright notice and this permission notice shall be\r
+ included in all copies or substantial portions of the Software.\r
+\r
+ Any person wishing to distribute modifications to the Software is\r
+ requested to send the modifications to the original developer so that\r
+ they can be incorporated into the canonical version.\r
+\r
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\r
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR\r
+ ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF\r
+ CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+*/\r
+#ifndef INCLUDED_OSCTYPES_H\r
+#define INCLUDED_OSCTYPES_H\r
+\r
+\r
+namespace osc{\r
+\r
+// basic types\r
+\r
+#if defined(__BORLANDC__) || defined(_MSC_VER)\r
+\r
+typedef __int64 int64;\r
+typedef unsigned __int64 uint64;\r
+\r
+#elif defined(__x86_64__) || defined(_M_X64)\r
+\r
+typedef long int64;\r
+typedef unsigned long uint64;\r
+\r
+#else\r
+\r
+typedef long long int64;\r
+typedef unsigned long long uint64;\r
+\r
+#endif\r
+\r
+\r
+\r
+#if defined(__x86_64__) || defined(_M_X64)\r
+\r
+typedef signed int int32;\r
+typedef unsigned int uint32;\r
+\r
+#else\r
+\r
+typedef signed long int32;\r
+typedef unsigned long uint32;\r
+\r
+#endif\r
+\r
+\r
+\r
+enum TypeTagValues {\r
+ TRUE_TYPE_TAG = 'T',\r
+ FALSE_TYPE_TAG = 'F',\r
+ NIL_TYPE_TAG = 'N',\r
+ INFINITUM_TYPE_TAG = 'I',\r
+ INT32_TYPE_TAG = 'i',\r
+ FLOAT_TYPE_TAG = 'f',\r
+ CHAR_TYPE_TAG = 'c',\r
+ RGBA_COLOR_TYPE_TAG = 'r',\r
+ MIDI_MESSAGE_TYPE_TAG = 'm',\r
+ INT64_TYPE_TAG = 'h',\r
+ TIME_TAG_TYPE_TAG = 't',\r
+ DOUBLE_TYPE_TAG = 'd',\r
+ STRING_TYPE_TAG = 's',\r
+ SYMBOL_TYPE_TAG = 'S',\r
+ BLOB_TYPE_TAG = 'b'\r
+};\r
+\r
+\r
+\r
+// i/o manipulators used for streaming interfaces\r
+\r
+struct BundleInitiator{\r
+ explicit BundleInitiator( uint64 timeTag_ ) : timeTag( timeTag_ ) {}\r
+ uint64 timeTag;\r
+};\r
+\r
+extern BundleInitiator BeginBundleImmediate;\r
+\r
+inline BundleInitiator BeginBundle( uint64 timeTag=1 )\r
+{\r
+ return BundleInitiator(timeTag);\r
+}\r
+\r
+\r
+struct BundleTerminator{\r
+};\r
+\r
+extern BundleTerminator EndBundle;\r
+\r
+struct BeginMessage{\r
+ explicit BeginMessage( const char *addressPattern_ ) : addressPattern( addressPattern_ ) {}\r
+ const char *addressPattern;\r
+};\r
+\r
+struct MessageTerminator{\r
+};\r
+\r
+extern MessageTerminator EndMessage;\r
+\r
+\r
+// osc specific types. they are defined as structs so they can be used\r
+// as separately identifiable types with the streaming operators.\r
+\r
+struct NilType{\r
+};\r
+\r
+extern NilType Nil;\r
+\r
+\r
+struct InfinitumType{\r
+};\r
+\r
+extern InfinitumType Infinitum;\r
+\r
+struct RgbaColor{\r
+ RgbaColor() {}\r
+ explicit RgbaColor( uint32 value_ ) : value( value_ ) {}\r
+ uint32 value;\r
+\r
+ operator uint32() const { return value; }\r
+};\r
+\r
+\r
+struct MidiMessage{\r
+ MidiMessage() {}\r
+ explicit MidiMessage( uint32 value_ ) : value( value_ ) {}\r
+ uint32 value;\r
+\r
+ operator uint32() const { return value; }\r
+};\r
+\r
+\r
+struct TimeTag{\r
+ TimeTag() {}\r
+ explicit TimeTag( uint64 value_ ) : value( value_ ) {}\r
+ uint64 value;\r
+\r
+ operator uint64() const { return value; }\r
+};\r
+\r
+\r
+struct Symbol{\r
+ Symbol() {}\r
+ explicit Symbol( const char* value_ ) : value( value_ ) {}\r
+ const char* value;\r
+\r
+ operator const char *() const { return value; }\r
+};\r
+\r
+\r
+struct Blob{\r
+ Blob() {}\r
+ explicit Blob( const void* data_, unsigned long size_ )\r
+ : data( data_ ), size( size_ ) {}\r
+ const void* data;\r
+ unsigned long size;\r
+};\r
+\r
+} // namespace osc\r
+\r
+\r
+#endif /* INCLUDED_OSCTYPES_H */\r
--- /dev/null
+#include "..\stdafx.h"\r
+\r
+#include "server.h"\r
+\r
+#include "oscpack/oscOutboundPacketStream.h"\r
+\r
+#include <algorithm>\r
+#include <array>\r
+#include <string>\r
+#include <set>\r
+#include <regex>\r
+#include <vector>\r
+\r
+#include <boost/optional.hpp>\r
+#include <boost/foreach.hpp>\r
+#include <boost/asio.hpp>\r
+#include <boost/thread.hpp>\r
+#include <boost/lexical_cast.hpp>\r
+#include <boost/algorithm/string/iter_find.hpp>\r
+#include <boost/algorithm/string/finder.hpp>\r
+#include <boost/algorithm/string/predicate.hpp>\r
+#include <boost/thread/mutex.hpp>\r
+\r
+using namespace boost::asio::ip;\r
+\r
+namespace caspar { namespace protocol { namespace osc {\r
+ \r
+template<typename T>\r
+struct param_visitor : public boost::static_visitor<void>\r
+{\r
+ T& o;\r
+\r
+ param_visitor(T& o)\r
+ : o(o)\r
+ {\r
+ } \r
+ \r
+ void operator()(const bool value) {o << value;}\r
+ void operator()(const int32_t value) {o << value;}\r
+ void operator()(const uint32_t value) {o << value;}\r
+ void operator()(const int64_t value) {o << value;}\r
+ void operator()(const uint64_t value) {o << value;}\r
+ void operator()(const float value) {o << value;}\r
+ void operator()(const double value) {o << static_cast<float>(value);}\r
+ void operator()(const std::string& value) {o << value.c_str();}\r
+ void operator()(const std::vector<int8_t>& value) {o << ::osc::Blob(value.data(), static_cast<unsigned long>(value.size()));}\r
+ void operator()(const monitor::duration& value)\r
+ {\r
+ o << boost::chrono::duration_cast<boost::chrono::duration<double, boost::ratio<1, 1>>>(value).count();\r
+ }\r
+};\r
+\r
+std::vector<char> write_osc_event(const monitor::event& e)\r
+{\r
+ std::array<char, 4096> buffer;\r
+ ::osc::OutboundPacketStream o(buffer.data(), static_cast<unsigned long>(buffer.size()));\r
+\r
+ o << ::osc::BeginMessage(e.path().str().c_str());\r
+ \r
+ param_visitor<decltype(o)> pd_visitor(o);\r
+ BOOST_FOREACH(auto param, e.params())\r
+ boost::apply_visitor(pd_visitor, param);\r
+ \r
+ o << ::osc::EndMessage;\r
+ \r
+ return std::vector<char>(o.Data(), o.Data() + o.Size());\r
+}\r
+\r
+class connection;\r
+\r
+typedef std::set<spl::shared_ptr<connection>> connection_set;\r
+\r
+class connection : public spl::enable_shared_from_this<connection>\r
+{ \r
+ spl::shared_ptr<tcp::socket> socket_; \r
+ boost::optional<std::regex> regex_;\r
+\r
+ std::array<char, 8192> data_;\r
+ \r
+ spl::shared_ptr<connection_set> connection_set_;\r
+\r
+ std::string input_;\r
+\r
+public:\r
+ static spl::shared_ptr<connection> create(spl::shared_ptr<tcp::socket> socket, spl::shared_ptr<connection_set> connection_set)\r
+ {\r
+ auto con = spl::shared_ptr<connection>(new connection(std::move(socket), std::move(connection_set)));\r
+ con->read_some();\r
+ return con;\r
+ }\r
+ \r
+ void stop()\r
+ {\r
+ socket_->close();\r
+ }\r
+ \r
+ std::wstring print() const\r
+ {\r
+ return L"[" + (socket_->is_open() ? u16(socket_->remote_endpoint().address().to_string()) : L"n/a") + L"]";\r
+ }\r
+ \r
+ void on_next(const monitor::event& e)\r
+ { \r
+ if(regex_ && std::regex_search(e.path().str(), *regex_))\r
+ return; \r
+\r
+ auto data_ptr = spl::make_shared<std::vector<char>>(write_osc_event(e));\r
+ auto size = data_ptr->size();\r
+ char* size_ptr = reinterpret_cast<char*>(&size);\r
+\r
+ data_ptr->insert(std::begin(*data_ptr), size_ptr, size_ptr + sizeof(int32_t));\r
+ socket_->async_write_some(boost::asio::buffer(*data_ptr), std::bind(&connection::handle_write, shared_from_this(), data_ptr, std::placeholders::_1, std::placeholders::_2)); \r
+ }\r
+ \r
+private:\r
+ connection(spl::shared_ptr<tcp::socket> socket, spl::shared_ptr<connection_set> connection_set) \r
+ : socket_(std::move(socket))\r
+ , connection_set_(std::move(connection_set))\r
+ {\r
+ }\r
+ \r
+ void handle_read(const boost::system::error_code& error, size_t bytes_transferred) \r
+ { \r
+ if(!error)\r
+ {\r
+ try\r
+ {\r
+ on_read(std::string(data_.begin(), data_.begin() + bytes_transferred));\r
+ }\r
+ catch(...)\r
+ {\r
+ CASPAR_LOG_CURRENT_EXCEPTION();\r
+ }\r
+ \r
+ read_some();\r
+ } \r
+ else if (error != boost::asio::error::operation_aborted)\r
+ connection_set_->erase(shared_from_this());\r
+ else\r
+ read_some();\r
+ }\r
+\r
+ void handle_write(const spl::shared_ptr<std::vector<char>>& data, const boost::system::error_code& error, size_t bytes_transferred)\r
+ {\r
+ if(!error) \r
+ {\r
+ }\r
+ else if (error != boost::asio::error::operation_aborted)\r
+ connection_set_->erase(shared_from_this());\r
+ }\r
+\r
+ void read_some()\r
+ {\r
+ socket_->async_read_some(boost::asio::buffer(data_.data(), data_.size()), std::bind(&connection::handle_read, shared_from_this(), std::placeholders::_1, std::placeholders::_2));\r
+ }\r
+ \r
+ void on_read(std::string str)\r
+ {\r
+ input_ += str;\r
+\r
+ std::vector<std::string> commands;\r
+ boost::iter_split(commands, input_, boost::algorithm::first_finder("\r\n"));\r
+ \r
+ if(commands.size() == 1)\r
+ return;\r
+\r
+ input_ = commands.back();\r
+ commands.pop_back(); \r
+\r
+ if(commands.back() == ".*")\r
+ regex_.reset();\r
+ else\r
+ regex_ = std::regex(commands.back());\r
+ }\r
+};\r
+\r
+class tcp_observer : public reactive::observer<monitor::event>\r
+{\r
+ boost::asio::io_service service_;\r
+ tcp::acceptor acceptor_;\r
+ spl::shared_ptr<connection_set> connection_set_;\r
+ boost::thread thread_;\r
+ \r
+public:\r
+ tcp_observer(unsigned short port)\r
+ : acceptor_(service_, tcp::endpoint(tcp::v4(), port))\r
+ , thread_(std::bind(&boost::asio::io_service::run, &service_))\r
+ {\r
+ start_accept(); \r
+ }\r
+\r
+ ~tcp_observer()\r
+ { \r
+ acceptor_.close();\r
+ BOOST_FOREACH(auto& connection, *connection_set_)\r
+ connection->stop();\r
+\r
+ thread_.join();\r
+ }\r
+ \r
+ void on_next(const monitor::event& e) override\r
+ {\r
+ service_.post([=]\r
+ {\r
+ BOOST_FOREACH(auto& connection, *connection_set_)\r
+ connection->on_next(e);\r
+ });\r
+ } \r
+private: \r
+ void start_accept() \r
+ {\r
+ auto socket = spl::make_shared<tcp::socket>(service_);\r
+ acceptor_.async_accept(*socket, std::bind(&tcp_observer::handle_accept, this, socket, std::placeholders::_1));\r
+ }\r
+\r
+ void handle_accept(const spl::shared_ptr<tcp::socket>& socket, const boost::system::error_code& error) \r
+ {\r
+ if (!acceptor_.is_open())\r
+ return;\r
+\r
+ if (!error) \r
+ connection_set_->insert(connection::create(socket, connection_set_));\r
+ \r
+ start_accept();\r
+ }\r
+};\r
+\r
+server::server(unsigned short port) \r
+ : impl_(new tcp_observer(port)){}\r
+void server::on_next(const monitor::event& e){impl_->on_next(e);}\r
+\r
+}}}
\ No newline at end of file
--- /dev/null
+#pragma once\r
+\r
+#include <common/spl/memory.h>\r
+\r
+#include <core/monitor/monitor.h>\r
+\r
+#include <functional>\r
+\r
+namespace caspar { namespace protocol { namespace osc {\r
+\r
+class server : public reactive::observer<monitor::event>\r
+{\r
+public: \r
+ server(unsigned short port);\r
+ \r
+ virtual void on_next(const monitor::event& e) override;\r
+private:\r
+ spl::shared_ptr<observer<monitor::event>> impl_;\r
+};\r
+\r
+}}}
\ No newline at end of file
<ClInclude Include="cii\CIIProtocolStrategy.h" />\r
<ClInclude Include="clk\CLKCommand.h" />\r
<ClInclude Include="clk\CLKProtocolStrategy.h" />\r
+ <ClInclude Include="osc\oscpack\MessageMappingOscPacketListener.h" />\r
+ <ClInclude Include="osc\oscpack\OscException.h" />\r
+ <ClInclude Include="osc\oscpack\OscHostEndianness.h" />\r
+ <ClInclude Include="osc\oscpack\OscOutboundPacketStream.h" />\r
+ <ClInclude Include="osc\oscpack\OscPacketListener.h" />\r
+ <ClInclude Include="osc\oscpack\OscPrintReceivedElements.h" />\r
+ <ClInclude Include="osc\oscpack\OscReceivedElements.h" />\r
+ <ClInclude Include="osc\oscpack\OscTypes.h" />\r
+ <ClInclude Include="osc\server.h" />\r
<ClInclude Include="StdAfx.h" />\r
<ClInclude Include="util\AsyncEventServer.h" />\r
<ClInclude Include="util\ClientInfo.h" />\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../StdAfx.h</PrecompiledHeaderFile>\r
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../StdAfx.h</PrecompiledHeaderFile>\r
</ClCompile>\r
+ <ClCompile Include="osc\oscpack\OscOutboundPacketStream.cpp">\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>\r
+ </ClCompile>\r
+ <ClCompile Include="osc\oscpack\OscPrintReceivedElements.cpp">\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>\r
+ </ClCompile>\r
+ <ClCompile Include="osc\oscpack\OscReceivedElements.cpp">\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>\r
+ </ClCompile>\r
+ <ClCompile Include="osc\oscpack\OscTypes.cpp">\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">NotUsing</PrecompiledHeader>\r
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NotUsing</PrecompiledHeader>\r
+ </ClCompile>\r
+ <ClCompile Include="osc\server.cpp">\r
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../StdAfx.h</PrecompiledHeaderFile>\r
+ <PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../StdAfx.h</PrecompiledHeaderFile>\r
+ </ClCompile>\r
<ClCompile Include="StdAfx.cpp">\r
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>\r
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>\r
<Filter Include="source\amcp">\r
<UniqueIdentifier>{93331f26-581b-4d15-81a6-0aae31ad3958}</UniqueIdentifier>\r
</Filter>\r
+ <Filter Include="source\osc">\r
+ <UniqueIdentifier>{c42b1c65-4f93-4cde-a3d2-e403f599142b}</UniqueIdentifier>\r
+ </Filter>\r
+ <Filter Include="source\osc\oscpack">\r
+ <UniqueIdentifier>{d6dede65-7a93-4494-aa2d-d18d5267902c}</UniqueIdentifier>\r
+ </Filter>\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="amcp\AMCPCommand.h">\r
<Filter>source\util</Filter>\r
</ClInclude>\r
<ClInclude Include="StdAfx.h" />\r
+ <ClInclude Include="osc\oscpack\OscHostEndianness.h">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="osc\oscpack\OscOutboundPacketStream.h">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="osc\oscpack\OscPacketListener.h">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="osc\oscpack\OscPrintReceivedElements.h">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="osc\oscpack\OscReceivedElements.h">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="osc\oscpack\OscTypes.h">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="osc\oscpack\MessageMappingOscPacketListener.h">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="osc\oscpack\OscException.h">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="osc\server.h">\r
+ <Filter>source\osc</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ClCompile Include="amcp\AMCPCommandQueue.cpp">\r
<Filter>source\util</Filter>\r
</ClCompile>\r
<ClCompile Include="StdAfx.cpp" />\r
+ <ClCompile Include="osc\oscpack\OscOutboundPacketStream.cpp">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="osc\oscpack\OscPrintReceivedElements.cpp">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="osc\oscpack\OscReceivedElements.cpp">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="osc\oscpack\OscTypes.cpp">\r
+ <Filter>source\osc\oscpack</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="osc\server.cpp">\r
+ <Filter>source\osc</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
</Project>
\ No newline at end of file
#include <atlbase.h>\r
\r
#include <protocol/amcp/AMCPProtocolStrategy.h>\r
+#include <protocol/osc/server.h>\r
\r
#include <modules/bluefish/bluefish.h>\r
#include <modules/decklink/decklink.h>\r
#include <boost/property_tree/xml_parser.hpp>\r
#include <boost/foreach.hpp>\r
\r
+using namespace caspar;\r
+ \r
// NOTE: This is needed in order to make CComObject work since this is not a real ATL project.\r
CComModule _AtlModule;\r
extern __declspec(selectany) CAtlModule* _pAtlModule = &_AtlModule;\r
\r
// Set console title.\r
std::wstringstream str;\r
- str << "CasparCG Server " << caspar::env::version() << L" x64 ";\r
+ str << "CasparCG Server " << env::version() << L" x64 ";\r
#ifdef COMPILE_RELEASE\r
str << " Release";\r
#elif COMPILE_PROFILE\r
CASPAR_LOG(info) << L"################################################################################";\r
CASPAR_LOG(info) << L"Copyright (c) 2010 Sveriges Television AB, www.casparcg.com, <info@casparcg.com>";\r
CASPAR_LOG(info) << L"################################################################################";\r
- CASPAR_LOG(info) << L"Starting CasparCG Video and Graphics Playout Server " << caspar::env::version();\r
- CASPAR_LOG(info) << L"on " << caspar::get_win_product_name() << L" " << caspar::get_win_sp_version();\r
- CASPAR_LOG(info) << caspar::get_cpu_info();\r
- CASPAR_LOG(info) << caspar::get_system_product_name();\r
+ CASPAR_LOG(info) << L"Starting CasparCG Video and Graphics Playout Server " << env::version();\r
+ CASPAR_LOG(info) << L"on " << get_win_product_name() << L" " << get_win_sp_version();\r
+ CASPAR_LOG(info) << get_cpu_info();\r
+ CASPAR_LOG(info) << get_system_product_name();\r
\r
- CASPAR_LOG(info) << L"Decklink " << caspar::decklink::get_version();\r
- BOOST_FOREACH(auto device, caspar::decklink::get_device_list())\r
+ CASPAR_LOG(info) << L"Decklink " << decklink::get_version();\r
+ BOOST_FOREACH(auto device, decklink::get_device_list())\r
CASPAR_LOG(info) << L" - " << device; \r
\r
- CASPAR_LOG(info) << L"Bluefish " << caspar::bluefish::get_version();\r
- BOOST_FOREACH(auto device, caspar::bluefish::get_device_list())\r
+ CASPAR_LOG(info) << L"Bluefish " << bluefish::get_version();\r
+ BOOST_FOREACH(auto device, bluefish::get_device_list())\r
CASPAR_LOG(info) << L" - " << device; \r
\r
- CASPAR_LOG(info) << L"Flash " << caspar::flash::get_version();\r
- CASPAR_LOG(info) << L"FreeImage " << caspar::image::get_version();\r
- CASPAR_LOG(info) << L"FFMPEG-avcodec " << caspar::ffmpeg::get_avcodec_version();\r
- CASPAR_LOG(info) << L"FFMPEG-avformat " << caspar::ffmpeg::get_avformat_version();\r
- CASPAR_LOG(info) << L"FFMPEG-avfilter " << caspar::ffmpeg::get_avfilter_version();\r
- CASPAR_LOG(info) << L"FFMPEG-avutil " << caspar::ffmpeg::get_avutil_version();\r
- CASPAR_LOG(info) << L"FFMPEG-swscale " << caspar::ffmpeg::get_swscale_version();\r
+ CASPAR_LOG(info) << L"Flash " << flash::get_version();\r
+ CASPAR_LOG(info) << L"FreeImage " << image::get_version();\r
+ CASPAR_LOG(info) << L"FFMPEG-avcodec " << ffmpeg::get_avcodec_version();\r
+ CASPAR_LOG(info) << L"FFMPEG-avformat " << ffmpeg::get_avformat_version();\r
+ CASPAR_LOG(info) << L"FFMPEG-avfilter " << ffmpeg::get_avfilter_version();\r
+ CASPAR_LOG(info) << L"FFMPEG-avutil " << ffmpeg::get_avutil_version();\r
+ CASPAR_LOG(info) << L"FFMPEG-swscale " << ffmpeg::get_swscale_version();\r
}\r
\r
LONG WINAPI UserUnhandledExceptionFilter(EXCEPTION_POINTERS* info)\r
}\r
\r
int main(int argc, wchar_t* argv[])\r
-{ \r
+{ \r
SetUnhandledExceptionFilter(UserUnhandledExceptionFilter);\r
\r
std::wcout << L"Type \"q\" to close application." << std::endl;\r
SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);\r
\r
// Install structured exception handler.\r
- caspar::win32_exception::install_handler();\r
+ win32_exception::install_handler();\r
\r
// Increase time precision. This will increase accuracy of function like Sleep(1) from 10 ms to 1 ms.\r
struct inc_prec\r
tbb_thread_installer(){observe(true);}\r
void on_scheduler_entry(bool is_worker)\r
{\r
- //caspar::detail::SetThreadName(GetCurrentThreadId(), "tbb-worker-thread");\r
- caspar::win32_exception::install_handler();\r
+ //detail::SetThreadName(GetCurrentThreadId(), "tbb-worker-thread");\r
+ win32_exception::install_handler();\r
}\r
} tbb_thread_installer;\r
\r
try \r
{\r
// Configure environment properties from configuration.\r
- caspar::env::configure(L"casparcg.config");\r
+ env::configure(L"casparcg.config");\r
\r
- caspar::log::set_log_level(caspar::env::properties().get(L"configuration.log-level", L"debug"));\r
+ log::set_log_level(env::properties().get(L"configuration.log-level", L"debug"));\r
\r
#ifdef _DEBUG\r
- if(caspar::env::properties().get(L"configuration.debugging.remote", false))\r
+ if(env::properties().get(L"configuration.debugging.remote", false))\r
MessageBox(nullptr, TEXT("Now is the time to connect for remote debugging..."), TEXT("Debug"), MB_OK | MB_TOPMOST);\r
#endif \r
\r
// Start logging to file.\r
- caspar::log::add_file_sink(caspar::env::log_folder()); \r
- std::wcout << L"Logging [info] or higher severity to " << caspar::env::log_folder() << std::endl << std::endl;\r
+ log::add_file_sink(env::log_folder()); \r
+ std::wcout << L"Logging [info] or higher severity to " << env::log_folder() << std::endl << std::endl;\r
\r
// Setup console window.\r
setup_console_window();\r
\r
std::wstringstream str;\r
boost::property_tree::xml_writer_settings<wchar_t> w(' ', 3);\r
- boost::property_tree::write_xml(str, caspar::env::properties(), w);\r
+ boost::property_tree::write_xml(str, env::properties(), w);\r
CASPAR_LOG(info) << L"casparcg.config:\n-----------------------------------------\n" << str.str().c_str() << L"-----------------------------------------";\r
\r
{\r
// Create server object which initializes channels, protocols and controllers.\r
- caspar::server caspar_server;\r
+ server caspar_server;\r
\r
+ auto server = spl::make_shared<protocol::osc::server>(protocol::osc::server::tcp_params(5253));\r
+ caspar_server.subscribe(server);\r
+\r
// Create a amcp parser for console commands.\r
- caspar::protocol::amcp::AMCPProtocolStrategy amcp(caspar_server.get_channels());\r
+ protocol::amcp::AMCPProtocolStrategy amcp(caspar_server.get_channels());\r
\r
// Create a dummy client which prints amcp responses to console.\r
- auto console_client = std::make_shared<caspar::IO::ConsoleClientInfo>();\r
+ auto console_client = std::make_shared<IO::ConsoleClientInfo>();\r
\r
- //auto console_obs = caspar::reactive::make_observer([](const caspar::monitor::event& e)\r
- //{\r
- // std::cout << e.path().str() << std::endl;\r
- //});\r
- //\r
- //caspar_server.subscribe(console_obs);\r
-\r
std::wstring wcmd;\r
while(true)\r
{\r