使用方法数组
OscMessage mesg; mesg.setAddress("m"); mesg.addIntArg(10); mesg.addIntArg(11); mesg.addIntArg(12); g_oscSend.sendMessage(mesg);
先作记录,再作程序ui
整个消息是放在一个数组中spa
前8个字符作头 为#bundle\0code
下面8个字节记录时间 这里都是1, 内存中为 0 0 0 0 0 0 0 1blog
再下面4个字节 整数 ,这里的数字大小指的是,osc地址的地址距离数据末尾的字节数 ,(也就是接收到数据包的长度减去这个值,就是osc消息的Adrrs的位置)内存
再下面就是地址字符串 大小根据字符串大小 ,而后4个字节对齐,不足补到4的倍数字符串
再下面是全部参数的类型 第一个是 逗号,不知为什么这样, 下面才是类型, 这里若是数量不是4的倍数也要补get
接下来是每一个参数的内存string
类型it
enum TypeTagValues { TRUE_TYPE_TAG = 'T', FALSE_TYPE_TAG = 'F', NIL_TYPE_TAG = 'N', INFINITUM_TYPE_TAG = 'I', INT32_TYPE_TAG = 'i', FLOAT_TYPE_TAG = 'f', CHAR_TYPE_TAG = 'c', RGBA_COLOR_TYPE_TAG = 'r', MIDI_MESSAGE_TYPE_TAG = 'm', INT64_TYPE_TAG = 'h', TIME_TAG_TYPE_TAG = 't', DOUBLE_TYPE_TAG = 'd', STRING_TYPE_TAG = 's', SYMBOL_TYPE_TAG = 'S', BLOB_TYPE_TAG = 'b', ARRAY_BEGIN_TYPE_TAG = '[', ARRAY_END_TYPE_TAG = ']' };
其中 bool 没有内存,只有一个tag
int32 4个字节
float 4个字节
char 4个字节
int64 8 个字节
double 8个字节
timetag 8个字节
string 补到4的倍数
2018-4-28
找到了一个代码实现
enum class ArgType : char { INTEGER_32 = 'i', FLOAT = 'f', DOUBLE = 'd', STRING = 's', BLOB = 'b', MIDI = 'm', TIME_TAG = 't', INTEGER_64 = 'h', BOOL_T = 'T', BOOL_F = 'F', CHAR = 'c', NULL_T = 'N', IMPULSE = 'I', NONE = NULL_T };
void Bundle::setTimetag( uint64_t ntp_time ) { uint64_t a = htonll( ntp_time ); ByteArray<8> b; memcpy( b.data(), reinterpret_cast<uint8_t*>( &a ), 8 ); mDataBuffer->insert( mDataBuffer->begin() + 12, b.begin(), b.end() ); } void Bundle::initializeBuffer() { static const std::string id = "#bundle"; mDataBuffer.reset( new std::vector<uint8_t>( 20 ) ); std::copy( id.begin(), id.end(), mDataBuffer->begin() + 4 ); (*mDataBuffer)[19] = 1; }
size_t addressLen = mAddress.size() + getTrailingZeros( mAddress.size() ); auto typesSize = mDataViews.size() + 1; std::vector<char> typesArray( typesSize + getTrailingZeros( typesSize ) , 0 ); typesArray[0] = ','; int i = 1; for( auto & dataView : mDataViews ) typesArray[i++] = Argument::translateArgTypeToCharType( dataView.getType() ); if( ! mCache ) mCache = ByteBufferRef( new ByteBuffer() ); size_t typesArrayLen = typesArray.size(); ByteArray<4> sizeArray; int32_t messageSize = addressLen + typesArrayLen + mDataBuffer.size(); auto endianSize = htonl( messageSize ); memcpy( sizeArray.data(), reinterpret_cast<uint8_t*>( &endianSize ), 4 ); mCache->resize( 4 + messageSize ); std::copy( sizeArray.begin(), sizeArray.end(), mCache->begin() ); std::copy( mAddress.begin(), mAddress.end(), mCache->begin() + 4 ); std::copy( typesArray.begin(), typesArray.end(), mCache->begin() + 4 + addressLen ); std::copy( mDataBuffer.begin(), mDataBuffer.end(), mCache->begin() + 4 + addressLen + typesArrayLen ); auto dataPtr = mCache->data() + 4 + addressLen + typesArrayLen; for( auto & dataView : mDataViews ) { if( dataView.needsEndianSwapForTransmit() ) dataView.swapEndianForTransmit( dataPtr ); }
static uint8_t getTrailingZeros( size_t bufferSize ) { return 4 - ( bufferSize % 4 ); }
和我以前的解释同样,如今这个能够照着本身解析了