rob@76: /* rob@76: oscpack -- Open Sound Control (OSC) packet manipulation library rob@76: http://www.rossbencina.com/code/oscpack rob@76: rob@76: Copyright (c) 2004-2013 Ross Bencina rob@76: rob@76: Permission is hereby granted, free of charge, to any person obtaining rob@76: a copy of this software and associated documentation files rob@76: (the "Software"), to deal in the Software without restriction, rob@76: including without limitation the rights to use, copy, modify, merge, rob@76: publish, distribute, sublicense, and/or sell copies of the Software, rob@76: and to permit persons to whom the Software is furnished to do so, rob@76: subject to the following conditions: rob@76: rob@76: The above copyright notice and this permission notice shall be rob@76: included in all copies or substantial portions of the Software. rob@76: rob@76: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, rob@76: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF rob@76: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. rob@76: IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR rob@76: ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF rob@76: CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION rob@76: WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. rob@76: */ rob@76: rob@76: /* rob@76: The text above constitutes the entire oscpack license; however, rob@76: the oscpack developer(s) also make the following non-binding requests: rob@76: rob@76: Any person wishing to distribute modifications to the Software is rob@76: requested to send the modifications to the original developer so that rob@76: they can be incorporated into the canonical version. It is also rob@76: requested that these non-binding requests be included whenever the rob@76: above license is reproduced. rob@76: */ rob@76: #include "OscPrintReceivedElements.h" rob@76: rob@76: #include rob@76: #include rob@76: #include rob@76: #include rob@76: rob@76: #if defined(__BORLANDC__) // workaround for BCB4 release build intrinsics bug rob@76: namespace std { rob@76: using ::__strcpy__; // avoid error: E2316 '__strcpy__' is not a member of 'std'. rob@76: } rob@76: #endif rob@76: rob@76: namespace osc{ rob@76: rob@76: rob@76: std::ostream& operator<<( std::ostream & os, rob@76: const ReceivedMessageArgument& arg ) rob@76: { rob@76: switch( arg.TypeTag() ){ rob@76: case TRUE_TYPE_TAG: rob@76: os << "bool:true"; rob@76: break; rob@76: rob@76: case FALSE_TYPE_TAG: rob@76: os << "bool:false"; rob@76: break; rob@76: rob@76: case NIL_TYPE_TAG: rob@76: os << "(Nil)"; rob@76: break; rob@76: rob@76: case INFINITUM_TYPE_TAG: rob@76: os << "(Infinitum)"; rob@76: break; rob@76: rob@76: case INT32_TYPE_TAG: rob@76: os << "int32:" << arg.AsInt32Unchecked(); rob@76: break; rob@76: rob@76: case FLOAT_TYPE_TAG: rob@76: os << "float32:" << arg.AsFloatUnchecked(); rob@76: break; rob@76: rob@76: case CHAR_TYPE_TAG: rob@76: { rob@76: char s[2] = {0}; rob@76: s[0] = arg.AsCharUnchecked(); rob@76: os << "char:'" << s << "'"; rob@76: } rob@76: break; rob@76: rob@76: case RGBA_COLOR_TYPE_TAG: rob@76: { rob@76: uint32 color = arg.AsRgbaColorUnchecked(); rob@76: rob@76: os << "RGBA:0x" rob@76: << std::hex << std::setfill('0') rob@76: << std::setw(2) << (int)((color>>24) & 0xFF) rob@76: << std::setw(2) << (int)((color>>16) & 0xFF) rob@76: << std::setw(2) << (int)((color>>8) & 0xFF) rob@76: << std::setw(2) << (int)(color & 0xFF) rob@76: << std::setfill(' '); rob@76: os.unsetf(std::ios::basefield); rob@76: } rob@76: break; rob@76: rob@76: case MIDI_MESSAGE_TYPE_TAG: rob@76: { rob@76: uint32 m = arg.AsMidiMessageUnchecked(); rob@76: os << "midi (port, status, data1, data2):<<" rob@76: << std::hex << std::setfill('0') rob@76: << "0x" << std::setw(2) << (int)((m>>24) & 0xFF) rob@76: << " 0x" << std::setw(2) << (int)((m>>16) & 0xFF) rob@76: << " 0x" << std::setw(2) << (int)((m>>8) & 0xFF) rob@76: << " 0x" << std::setw(2) << (int)(m & 0xFF) rob@76: << std::setfill(' ') << ">>"; rob@76: os.unsetf(std::ios::basefield); rob@76: } rob@76: break; rob@76: rob@76: case INT64_TYPE_TAG: rob@76: os << "int64:" << arg.AsInt64Unchecked(); rob@76: break; rob@76: rob@76: case TIME_TAG_TYPE_TAG: rob@76: { rob@76: os << "OSC-timetag:" << arg.AsTimeTagUnchecked() << " "; rob@76: rob@76: std::time_t t = rob@76: (unsigned long)( arg.AsTimeTagUnchecked() >> 32 ); rob@76: rob@76: const char *timeString = std::ctime( &t ); rob@76: size_t len = std::strlen( timeString ); rob@76: rob@76: // -1 to omit trailing newline from string returned by ctime() rob@76: if( len > 1 ) rob@76: os.write( timeString, len - 1 ); rob@76: } rob@76: break; rob@76: rob@76: case DOUBLE_TYPE_TAG: rob@76: os << "double:" << arg.AsDoubleUnchecked(); rob@76: break; rob@76: rob@76: case STRING_TYPE_TAG: rob@76: os << "OSC-string:`" << arg.AsStringUnchecked() << "'"; rob@76: break; rob@76: rob@76: case SYMBOL_TYPE_TAG: rob@76: os << "OSC-string (symbol):`" << arg.AsSymbolUnchecked() << "'"; rob@76: break; rob@76: rob@76: case BLOB_TYPE_TAG: rob@76: { rob@76: const void *data; rob@76: osc_bundle_element_size_t size; rob@76: arg.AsBlobUnchecked( data, size ); rob@76: os << "OSC-blob:<<" << std::hex << std::setfill('0'); rob@76: unsigned char *p = (unsigned char*)data; rob@76: for( osc_bundle_element_size_t i = 0; i < size; ++i ){ rob@76: os << "0x" << std::setw(2) << int(p[i]); rob@76: if( i != size-1 ) rob@76: os << ' '; rob@76: } rob@76: os.unsetf(std::ios::basefield); rob@76: os << ">>" << std::setfill(' '); rob@76: } rob@76: break; rob@76: rob@76: case ARRAY_BEGIN_TYPE_TAG: rob@76: os << "["; rob@76: break; rob@76: rob@76: case ARRAY_END_TYPE_TAG: rob@76: os << "]"; rob@76: break; rob@76: rob@76: default: rob@76: os << "unknown"; rob@76: } rob@76: rob@76: return os; rob@76: } rob@76: rob@76: rob@76: std::ostream& operator<<( std::ostream & os, const ReceivedMessage& m ) rob@76: { rob@76: os << "["; rob@76: if( m.AddressPatternIsUInt32() ) rob@76: os << m.AddressPatternAsUInt32(); rob@76: else rob@76: os << m.AddressPattern(); rob@76: rob@76: bool first = true; rob@76: for( ReceivedMessage::const_iterator i = m.ArgumentsBegin(); rob@76: i != m.ArgumentsEnd(); ++i ){ rob@76: if( first ){ rob@76: os << " "; rob@76: first = false; rob@76: }else{ rob@76: os << ", "; rob@76: } rob@76: rob@76: os << *i; rob@76: } rob@76: rob@76: os << "]"; rob@76: rob@76: return os; rob@76: } rob@76: rob@76: rob@76: std::ostream& operator<<( std::ostream & os, const ReceivedBundle& b ) rob@76: { rob@76: static int indent = 0; rob@76: rob@76: for( int j=0; j < indent; ++j ) rob@76: os << " "; rob@76: os << "{ ( "; rob@76: if( b.TimeTag() == 1 ) rob@76: os << "immediate"; rob@76: else rob@76: os << b.TimeTag(); rob@76: os << " )\n"; rob@76: rob@76: ++indent; rob@76: rob@76: for( ReceivedBundle::const_iterator i = b.ElementsBegin(); rob@76: i != b.ElementsEnd(); ++i ){ rob@76: if( i->IsBundle() ){ rob@76: ReceivedBundle b(*i); rob@76: os << b << "\n"; rob@76: }else{ rob@76: ReceivedMessage m(*i); rob@76: for( int j=0; j < indent; ++j ) rob@76: os << " "; rob@76: os << m << "\n"; rob@76: } rob@76: } rob@76: rob@76: --indent; rob@76: rob@76: for( int j=0; j < indent; ++j ) rob@76: os << " "; rob@76: os << "}"; rob@76: rob@76: return os; rob@76: } rob@76: rob@76: rob@76: std::ostream& operator<<( std::ostream & os, const ReceivedPacket& p ) rob@76: { rob@76: if( p.IsBundle() ){ rob@76: ReceivedBundle b(p); rob@76: os << b << "\n"; rob@76: }else{ rob@76: ReceivedMessage m(p); rob@76: os << m << "\n"; rob@76: } rob@76: rob@76: return os; rob@76: } rob@76: rob@76: } // namespace osc