コード例 #1
0
void ReceivedMessageArgumentIterator::Advance()
{
    if( !value_.typeTag_ )
        return;
        
    switch( *value_.typeTag_++ ){
        case '\0':
            // don't advance past end
            --value_.typeTag_;
            break;
            
        case TRUE_TYPE_TAG:
        case FALSE_TYPE_TAG:
        case NIL_TYPE_TAG:
        case INFINITUM_TYPE_TAG:
        case ARRAY_START_TYPE_TAG:
        case ARRAY_END_TYPE_TAG:

            // zero length
            break;

        case INT32_TYPE_TAG:
        case FLOAT_TYPE_TAG: 					
        case CHAR_TYPE_TAG:
        case RGBA_COLOR_TYPE_TAG:
        case MIDI_MESSAGE_TYPE_TAG:

            value_.argument_ += 4;
            break;

        case INT64_TYPE_TAG:
        case TIME_TAG_TYPE_TAG:
        case DOUBLE_TYPE_TAG:
				
            value_.argument_ += 8;
            break;

        case STRING_TYPE_TAG: 
        case SYMBOL_TYPE_TAG:

            // we use the unsafe function FindStr4End(char*) here because all of
            // the arguments have already been validated in
            // ReceivedMessage::Init() below.
            
            value_.argument_ = FindStr4End( value_.argument_ );
            break;

        case BLOB_TYPE_TAG:
            {
                uint32 blobSize = ToUInt32( value_.argument_ );
                value_.argument_ = value_.argument_ + 4 + RoundUp4( (unsigned long)blobSize );
            }
            break;

        default:    // unknown type tag
            // don't advance
            --value_.typeTag_;
            break;
    }
}
コード例 #2
0
Errors OutboundPacketStream::CheckForAvailableArgumentSpace( std::size_t argumentLength )
{
    // plus three for extra type tag, comma and null terminator
    std::size_t required = (argumentCurrent_ - data_) + argumentLength
            + RoundUp4( (end_ - typeTagsCurrent_) + 3 );

    return (required > Capacity()) ? OUT_OF_BUFFER_MEMORY_ERROR : SUCCESS;
}
コード例 #3
0
Errors OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )
{
    // plus 4 for at least four bytes of type tag
    std::size_t required = Size() + ((ElementSizeSlotRequired())?4:0)
            + RoundUp4(std::strlen(addressPattern) + 1) + 4;

    return (required > Capacity()) ? OUT_OF_BUFFER_MEMORY_ERROR : SUCCESS;
}
コード例 #4
0
void OutboundPacketStream::CheckForAvailableMessageSpace( const char *addressPattern )
{
    // plus 4 for at least four bytes of type tag
    unsigned long required = Size() + ((ElementSizeSlotRequired()) ? 4 : 0) + RoundUp4(static_cast<unsigned long>(strlen(addressPattern)) + 1) + 4;

    if( required > Capacity() )
        throw OutOfBufferMemoryException();
}
コード例 #5
0
	void NxDeviceOscOutputMessage::CheckForAvailableMessageSpace( const char *addressPattern )
	{
		// plus 4 for at least four bytes of type tag
		unsigned long required = Size() + ((ElementSizeSlotRequired())?4:0)
			+ RoundUp4(strlen(addressPattern) + 1) + 4;

		if( required > Capacity() )
			throw OutOfBufferMemoryException();
	}
コード例 #6
0
void OutboundPacketStream::CheckForAvailableArgumentSpace( long argumentLength )
{
    // plus three for extra type tag, comma and null terminator
     unsigned long required = (argumentCurrent_ - data_) + argumentLength
            + RoundUp4( (end_ - typeTagsCurrent_) + 3 );

    if( required > Capacity() )
        throw OutOfBufferMemoryException();
}
コード例 #7
0
ファイル: GetPropertyReply.cpp プロジェクト: narenas/nx-libs
int GetPropertyReplyStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer,
                                              unsigned int &size, int bigEndian, WriteBuffer *writeBuffer,
                                                  ChannelCache *channelCache) const
{
  ServerCache *serverCache = (ServerCache *) channelCache;

  #ifdef DEBUG
  *logofs << name() << ": Decoding full message identity.\n"
          << logofs_flush;
  #endif

  unsigned char format;

  decodeBuffer.decodeCachedValue(format, 8,
                     serverCache -> getPropertyFormatCache);

  unsigned int length;

  decodeBuffer.decodeValue(length, 32, 9);

  unsigned int numBytes = length;

  if (format == 16)
  {
    numBytes <<= 1;
  }
  else if (format == 32)
  {
    numBytes <<= 2;
  }

  size = 32 + RoundUp4(numBytes);

  buffer = writeBuffer -> addMessage(size);

  *(buffer + 1) = format;

  PutULONG(length, buffer + 16, bigEndian);

  unsigned int value;

  decodeBuffer.decodeCachedValue(value, 29,
                     serverCache -> getPropertyTypeCache, 9);

  PutULONG(value, buffer + 8, bigEndian);

  decodeBuffer.decodeValue(value, 32, 9);

  PutULONG(value, buffer + 12, bigEndian);

  #ifdef DEBUG
  *logofs << name() << ": Decoded full message identity.\n"
          << logofs_flush;
  #endif

  return 1;
}
コード例 #8
0
unsigned int OutboundPacketStream::Size() const
{
    unsigned int result = argumentCurrent_ - data_;
    if( IsMessageInProgress() ){
        // account for the length of the type tag string. the total type tag
        // includes an initial comma, plus at least one terminating \0
        result += RoundUp4( (end_ - typeTagsCurrent_) + 2 );
    }

    return result;
}
コード例 #9
0
OutboundPacketStream& OutboundPacketStream::operator<<( const MessageTerminator& rhs )
{
    (void) rhs;

    if( !IsMessageInProgress() )
        throw MessageNotInProgressException();

    int typeTagsCount = end_ - typeTagsCurrent_;

    if( typeTagsCount ){

        char *tempTypeTags = (char*)alloca(typeTagsCount);
        memcpy( tempTypeTags, typeTagsCurrent_, typeTagsCount );

        // slot size includes comma and null terminator
        int typeTagSlotSize = RoundUp4( typeTagsCount + 2 );

        uint32 argumentsSize = argumentCurrent_ - messageCursor_;

        memmove( messageCursor_ + typeTagSlotSize, messageCursor_, argumentsSize );

        messageCursor_[0] = ',';
        // copy type tags in reverse (really forward) order
        for( int i=0; i < typeTagsCount; ++i )
            messageCursor_[i+1] = tempTypeTags[ (typeTagsCount-1) - i ];

        char *p = messageCursor_ + 1 + typeTagsCount;
        for( int i=0; i < (typeTagSlotSize - (typeTagsCount + 1)); ++i )
            *p++ = '\0';

        typeTagsCurrent_ = end_;

        // advance messageCursor_ for next message
        messageCursor_ += typeTagSlotSize + argumentsSize;

    }else{
        // send an empty type tags string
        memcpy( messageCursor_, ",\0\0\0", 4 );

        // advance messageCursor_ for next message
        messageCursor_ += 4;
    }

    argumentCurrent_ = messageCursor_;

    EndElement( messageCursor_ );

    messageIsInProgress_ = false;

    return *this;
}
コード例 #10
0
ファイル: SetUnpackColormap.cpp プロジェクト: narenas/nx-libs
int SetUnpackColormapStore::decodeIdentity(DecodeBuffer &decodeBuffer, unsigned char *&buffer,
                                               unsigned int &size, int bigEndian, WriteBuffer *writeBuffer,
                                                   ChannelCache *channelCache) const
{
  ClientCache *clientCache = (ClientCache *) channelCache;

  #ifdef DEBUG
  *logofs << name() << ": Decoding full message identity.\n" << logofs_flush;
  #endif

  unsigned int  value;
  unsigned char cValue;

  // SrcLength.
  decodeBuffer.decodeValue(value, 32, 9);

  size = RoundUp4(value) + 16;

  buffer = writeBuffer -> addMessage(size);

  PutULONG(value, buffer + 8, bigEndian);

  // Client.
  decodeBuffer.decodeCachedValue(cValue, 8,
                     clientCache -> resourceCache);

  *(buffer + 1) = cValue;

  // Method.
  decodeBuffer.decodeCachedValue(cValue, 8,
                     clientCache -> methodCache);

  *(buffer + 4) = cValue;

  // DstLength.
  decodeBuffer.decodeValue(value, 32, 9);

  PutULONG(value, buffer + 12, bigEndian);

  #ifdef DEBUG
  *logofs << name() << ": Decoded full message identity.\n" << logofs_flush;
  #endif

  return 1;
}
コード例 #11
0
OutboundPacketStream& OutboundPacketStream::operator<<(const char* rhs)
{
    CheckForAvailableArgumentSpace(RoundUp4(static_cast<long>(strlen(rhs)) + 1));

    *--typeTagsCurrent_ = STRING_TYPE_TAG;
    strcpy(argumentCurrent_, rhs);
    unsigned long rhsLength = static_cast<unsigned long>(strlen(rhs));
    argumentCurrent_ += rhsLength + 1;

    // zero pad to 4-byte boundary
    unsigned long i = rhsLength + 1;
    while (i & 0x3) {
        *argumentCurrent_++ = '\0';
        ++i;
    }

    return *this;
}
コード例 #12
0
	NxDeviceOscOutputMessage& NxDeviceOscOutputMessage::operator<<( const char *rhs )
	{
		CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );

		*(--typeTagsCurrent_) = STRING_TYPE_TAG;
		strcpy( argumentCurrent_, rhs );
		unsigned long rhsLength = strlen(rhs);
		argumentCurrent_ += rhsLength + 1;

		// zero pad to 4-byte boundary
		unsigned long i = rhsLength + 1;
		while( i & 0x3 ){
			*argumentCurrent_++ = '\0';
			++i;
		}

		return *this;
	}
コード例 #13
0
OutboundPacketStream& OutboundPacketStream::operator<<( const char *rhs )
{
    CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) );

    *(--typeTagsCurrent_) = STRING_TYPE_TAG;
    std::strcpy( argumentCurrent_, rhs );
    std::size_t rhsLength = std::strlen(rhs);
    argumentCurrent_ += rhsLength + 1;

    // zero pad to 4-byte boundary
    std::size_t i = rhsLength + 1;
    while( i & 0x3 ){
        *argumentCurrent_++ = '\0';
        ++i;
    }

    return *this;
}
コード例 #14
0
OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
{
    CheckForAvailableArgumentSpace( RoundUp4(strlen(rhs) + 1) );

    *(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;
    strcpy( argumentCurrent_, rhs );
    unsigned long rhsLength = strlen(rhs);
    argumentCurrent_ += rhsLength + 1;

    // zero pad to 4-byte boundary
    unsigned long i = rhsLength + 1;
    while( i & 0x3 ){
        *argumentCurrent_++ = '\0';
        ++i;
    }

    return *this;
}
コード例 #15
0
OutboundPacketStream& OutboundPacketStream::operator<<( const Blob& rhs )
{
    CheckForAvailableArgumentSpace( 4 + RoundUp4(rhs.size) );

    *(--typeTagsCurrent_) = BLOB_TYPE_TAG;
    FromUInt32( argumentCurrent_, rhs.size );
    argumentCurrent_ += 4;
    
    memcpy( argumentCurrent_, rhs.data, rhs.size );
    argumentCurrent_ += rhs.size;

    // zero pad to 4-byte boundary
    unsigned long i = rhs.size;
    while( i & 0x3 ){
        *argumentCurrent_++ = '\0';
        ++i;
    }

    return *this;
}
コード例 #16
0
OutboundPacketStream& OutboundPacketStream::operator<<( const Symbol& rhs )
{
    state_ = CheckForAvailableArgumentSpace( RoundUp4(std::strlen(rhs) + 1) );
    if(state_ == SUCCESS)
    {
        *(--typeTagsCurrent_) = SYMBOL_TYPE_TAG;
        std::strcpy( argumentCurrent_, rhs );
        std::size_t rhsLength = std::strlen(rhs);
        argumentCurrent_ += rhsLength + 1;

        // zero pad to 4-byte boundary
        std::size_t i = rhsLength + 1;
        while( i & 0x3 ){
            *argumentCurrent_++ = '\0';
            ++i;
        }
    }

    return *this;
}
コード例 #17
0
static int32 RoundUpForPixelSize (uint32 x, uint32 pixelSize)
	{
	
	switch (pixelSize)
		{
		
		case 1:
			return RoundUp16 (x);
			
		case 2:
			return RoundUp8 (x);
			
		case 4:
			return RoundUp4 (x);
			
		case 8:
			return RoundUp2 (x);
			
		default:
			return RoundUp16 (x);
					
		}
	
	}
コード例 #18
0
void ReceivedMessageArgumentIterator::Advance()
{
    if( !value_.typeTag_ )
        return;
        
    switch( *value_.typeTag_++ ){
        case '\0':
            // don't advance past end
            --value_.typeTag_;
            break;
            
        case TRUE_TYPE_TAG:
        case FALSE_TYPE_TAG:
        case NIL_TYPE_TAG:
        case INFINITUM_TYPE_TAG:

            // zero length
            break;

        case INT32_TYPE_TAG:
        case FLOAT_TYPE_TAG: 					
        case CHAR_TYPE_TAG:
        case RGBA_COLOR_TYPE_TAG:
        case MIDI_MESSAGE_TYPE_TAG:

            value_.argument_ += 4;
            break;

        case INT64_TYPE_TAG:
        case TIME_TAG_TYPE_TAG:
        case DOUBLE_TYPE_TAG:
				
            value_.argument_ += 8;
            break;

        case STRING_TYPE_TAG: 
        case SYMBOL_TYPE_TAG:

            // we use the unsafe function FindStr4End(char*) here because all of
            // the arguments have already been validated in
            // ReceivedMessage::Init() below.
            
            value_.argument_ = FindStr4End( value_.argument_ );
            break;

        case BLOB_TYPE_TAG:
            {
                uint32 blobSize = ToUInt32( value_.argument_ );
                value_.argument_ = value_.argument_ + 4 + RoundUp4( (unsigned long)blobSize );
            }
            break;

        default:    // unknown type tag
            // don't advance
            --value_.typeTag_;
            break;
            

        //    not handled:
        //    [ Indicates the beginning of an array. The tags following are for
        //        data in the Array until a close brace tag is reached.
        //    ] Indicates the end of an array.
    }
}
コード例 #19
0
void ReceivedMessage::Init( const char *message, unsigned long size )
{
    if( size == 0 )
        throw MalformedMessageException( "zero length messages not permitted" );

    if( (size & 0x03L) != 0 )
        throw MalformedMessageException( "message size must be multiple of four" );

    const char *end = message + size;

    typeTagsBegin_ = FindStr4End( addressPattern_, end );
    if( typeTagsBegin_ == 0 ){
        // address pattern was not terminated before end
        throw MalformedMessageException( "unterminated address pattern" );
    }

    if( typeTagsBegin_ == end ){
        // message consists of only the address pattern - no arguments or type tags.
        typeTagsBegin_ = 0;
        typeTagsEnd_ = 0;
        arguments_ = 0;
            
    }else{
        if( *typeTagsBegin_ != ',' )
            throw MalformedMessageException( "type tags not present" );

        if( *(typeTagsBegin_ + 1) == '\0' ){
            // zero length type tags
            typeTagsBegin_ = 0;
            typeTagsEnd_ = 0;
            arguments_ = 0;

        }else{
            // check that all arguments are present and well formed
                
            arguments_ = FindStr4End( typeTagsBegin_, end );
            if( arguments_ == 0 ){
                throw MalformedMessageException( "type tags were not terminated before end of message" );
            }

            ++typeTagsBegin_; // advance past initial ','
            
            const char *typeTag = typeTagsBegin_;
            const char *argument = arguments_;
                        
            do{
                switch( *typeTag ){
                    case TRUE_TYPE_TAG:
                    case FALSE_TYPE_TAG:
                    case NIL_TYPE_TAG:
                    case INFINITUM_TYPE_TAG:
                    case ARRAY_START_TYPE_TAG:
                    case ARRAY_END_TYPE_TAG:

                        // zero length
                        break;

                    case INT32_TYPE_TAG:
                    case FLOAT_TYPE_TAG:
                    case CHAR_TYPE_TAG:
                    case RGBA_COLOR_TYPE_TAG:
                    case MIDI_MESSAGE_TYPE_TAG:

                        if( argument == end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        argument += 4;
                        if( argument > end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        break;

                    case INT64_TYPE_TAG:
                    case TIME_TAG_TYPE_TAG:
                    case DOUBLE_TYPE_TAG:

                        if( argument == end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        argument += 8;
                        if( argument > end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        break;

                    case STRING_TYPE_TAG: 
                    case SYMBOL_TYPE_TAG:
                    
                        if( argument == end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        argument = FindStr4End( argument, end );
                        if( argument == 0 )
                            throw MalformedMessageException( "unterminated string argument" );
                        break;

                    case BLOB_TYPE_TAG:
                        {
                            if( argument + 4 > end )
                                MalformedMessageException( "arguments exceed message size" );
                                
                            uint32 blobSize = ToUInt32( argument );
                            argument = argument + 4 + RoundUp4( (unsigned long)blobSize );
                            if( argument > end )
                                MalformedMessageException( "arguments exceed message size" );
                        }
                        break;
                        
                    default:
                        throw MalformedMessageException( "unknown type tag" );

                    //    not handled:
                    //    [ Indicates the beginning of an array. The tags following are for
                    //        data in the Array until a close brace tag is reached.
                    //    ] Indicates the end of an array.
                }

            }while( *++typeTag != '\0' );
            typeTagsEnd_ = typeTag;
        }
    }
}
コード例 #20
0
int ClientReadBuffer::locateMessage(const unsigned char *start,
                                        const unsigned char *end,
                                            unsigned int &controlLength,
                                                unsigned int &dataLength,
                                                    unsigned int &trailerLength)
{
  unsigned int size = end - start;

  #ifdef TEST
  *logofs << "ClientReadBuffer: Locating message for FD#"
          << transport_ -> fd() << " with " << size
          << " bytes.\n" << logofs_flush;
  #endif

  if (firstMessage_)
  {
    if (size < 12)
    {
      remaining_ = 12 - size;

      #ifdef TEST
      *logofs << "ClientReadBuffer: No message was located "
              << "with remaining " << remaining_ << ".\n"
              << logofs_flush;
      #endif

      return 0;
    }

    if (*start == 0x42)
    {
      bigEndian_ = 1;
    }
    else
    {
      bigEndian_ = 0;
    }

    channel_ -> setBigEndian(bigEndian_);

    dataLength = 12 + RoundUp4(GetUINT(start + 6, bigEndian_)) +
                          RoundUp4(GetUINT(start + 8, bigEndian_));

    //
    // Send the data immediately if this is unlikely
    // to be a X connection attempt.
    //

    if (dataLength > 4096)
    {
      #ifdef WARNING
      *logofs << "ClientReadBuffer: WARNING! Flushing suspicious X "
              << "connection with first request of " << dataLength
              << " bytes.\n" << logofs_flush;
      #endif

      dataLength = size;
    }
  }
  else
  {
    if (size < 4)
    {
      remaining_ = 4 - size;

      #ifdef TEST
      *logofs << "ClientReadBuffer: No message was located "
              << "with remaining " << remaining_ << ".\n"
              << logofs_flush;
      #endif

      return 0;
    }

    dataLength = (GetUINT(start + 2, bigEndian_) << 2);

    if (dataLength < 4)
    {
      #ifdef TEST
      *logofs << "ClientReadBuffer: WARNING! Assuming length 4 "
              << "for suspicious message of length " << dataLength
              << ".\n" << logofs_flush;
      #endif

      dataLength = 4;
    }
  }

  #ifdef TEST
  *logofs << "ClientReadBuffer: Length of the next message is "
          << dataLength << ".\n" << logofs_flush;
  #endif

  if (size < dataLength)
  {
    remaining_ = dataLength - size;

    #ifdef TEST
    *logofs << "ClientReadBuffer: No message was located "
            << "with remaining " << remaining_ << ".\n"
            << logofs_flush;
    #endif

    return 0;
  }

  firstMessage_ = 0;

  controlLength = 0;
  trailerLength = 0;

  remaining_ = 0;

  #ifdef TEST
  *logofs << "ClientReadBuffer: Located message with "
          << "remaining " << remaining_ << ".\n"
          << logofs_flush;
  #endif

  return 1;
}
コード例 #21
0
void ReceivedMessage::Init( const char *message, osc_bundle_element_size_t size )
{
    if( !IsValidElementSizeValue(size) )
        throw MalformedMessageException( "invalid message size" );

    if( size == 0 )
        throw MalformedMessageException( "zero length messages not permitted" );

    if( !IsMultipleOf4(size) )
        throw MalformedMessageException( "message size must be multiple of four" );

    const char *end = message + size;

    typeTagsBegin_ = FindStr4End( addressPattern_, end );
    if( typeTagsBegin_ == 0 ){
        // address pattern was not terminated before end
        throw MalformedMessageException( "unterminated address pattern" );
    }

    if( typeTagsBegin_ == end ){
        // message consists of only the address pattern - no arguments or type tags.
        typeTagsBegin_ = 0;
        typeTagsEnd_ = 0;
        arguments_ = 0;
            
    }else{
        if( *typeTagsBegin_ != ',' )
            throw MalformedMessageException( "type tags not present" );

        if( *(typeTagsBegin_ + 1) == '\0' ){
            // zero length type tags
            typeTagsBegin_ = 0;
            typeTagsEnd_ = 0;
            arguments_ = 0;

        }else{
            // check that all arguments are present and well formed
                
            arguments_ = FindStr4End( typeTagsBegin_, end );
            if( arguments_ == 0 ){
                throw MalformedMessageException( "type tags were not terminated before end of message" );
            }

            ++typeTagsBegin_; // advance past initial ','
            
            const char *typeTag = typeTagsBegin_;
            const char *argument = arguments_;
            unsigned int arrayLevel = 0;
                        
            do{
                switch( *typeTag ){
                    case TRUE_TYPE_TAG:
                    case FALSE_TYPE_TAG:
                    case NIL_TYPE_TAG:
                    case INFINITUM_TYPE_TAG:
                        // zero length
                        break;

                    //    [ Indicates the beginning of an array. The tags following are for
                    //        data in the Array until a close brace tag is reached.
                    //    ] Indicates the end of an array.
                    case ARRAY_BEGIN_TYPE_TAG:
                        ++arrayLevel;
                        // (zero length argument data)
                        break;

                    case ARRAY_END_TYPE_TAG:
                        --arrayLevel;
                        // (zero length argument data)
                        break;

                    case INT32_TYPE_TAG:
                    case FLOAT_TYPE_TAG:
                    case CHAR_TYPE_TAG:
                    case RGBA_COLOR_TYPE_TAG:
                    case MIDI_MESSAGE_TYPE_TAG:

                        if( argument == end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        argument += 4;
                        if( argument > end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        break;

                    case INT64_TYPE_TAG:
                    case TIME_TAG_TYPE_TAG:
                    case DOUBLE_TYPE_TAG:

                        if( argument == end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        argument += 8;
                        if( argument > end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        break;

                    case STRING_TYPE_TAG: 
                    case SYMBOL_TYPE_TAG:
                    
                        if( argument == end )
                            throw MalformedMessageException( "arguments exceed message size" );
                        argument = FindStr4End( argument, end );
                        if( argument == 0 )
                            throw MalformedMessageException( "unterminated string argument" );
                        break;

                    case BLOB_TYPE_TAG:
                        {
                            if( argument + osc::OSC_SIZEOF_INT32 > end )
                                MalformedMessageException( "arguments exceed message size" );
                                
                            // treat blob size as an unsigned int for the purposes of this calculation
                            uint32 blobSize = ToUInt32( argument );
                            argument = argument + osc::OSC_SIZEOF_INT32 + RoundUp4( blobSize );
                            if( argument > end )
                                MalformedMessageException( "arguments exceed message size" );
                        }
                        break;
                        
                    default:
                        throw MalformedMessageException( "unknown type tag" );
                }

            }while( *++typeTag != '\0' );
            typeTagsEnd_ = typeTag;

            if( arrayLevel !=  0 )
                throw MalformedMessageException( "array was not terminated before end of message (expected ']' end of array tag)" );
        }

        // These invariants should be guaranteed by the above code.
        // we depend on them in the implementation of ArgumentCount()
#ifndef NDEBUG
        std::ptrdiff_t argumentCount = typeTagsEnd_ - typeTagsBegin_;
        assert( argumentCount >= 0 );
        assert( argumentCount <= OSC_INT32_MAX );
#endif
    }
}
コード例 #22
0
void ReceivedMessageArgumentIterator::Advance()
{
    if( !value_.typeTagPtr_ )
        return;
        
    switch( *value_.typeTagPtr_++ ){
        case '\0':
            // don't advance past end
            --value_.typeTagPtr_;
            break;
            
        case TRUE_TYPE_TAG:
        case FALSE_TYPE_TAG:
        case NIL_TYPE_TAG:
        case INFINITUM_TYPE_TAG:
        
            // zero length
            break;

        case INT32_TYPE_TAG:
        case FLOAT_TYPE_TAG: 					
        case CHAR_TYPE_TAG:
        case RGBA_COLOR_TYPE_TAG:
        case MIDI_MESSAGE_TYPE_TAG:

            value_.argumentPtr_ += 4;
            break;

        case INT64_TYPE_TAG:
        case TIME_TAG_TYPE_TAG:
        case DOUBLE_TYPE_TAG:
				
            value_.argumentPtr_ += 8;
            break;

        case STRING_TYPE_TAG: 
        case SYMBOL_TYPE_TAG:

            // we use the unsafe function FindStr4End(char*) here because all of
            // the arguments have already been validated in
            // ReceivedMessage::Init() below.
            
            value_.argumentPtr_ = FindStr4End( value_.argumentPtr_ );
            break;

        case BLOB_TYPE_TAG:
            {
                // treat blob size as an unsigned int for the purposes of this calculation
                uint32 blobSize = ToUInt32( value_.argumentPtr_ );
                value_.argumentPtr_ = value_.argumentPtr_ + osc::OSC_SIZEOF_INT32 + RoundUp4( blobSize );
            }
            break;

        case ARRAY_BEGIN_TYPE_TAG:
        case ARRAY_END_TYPE_TAG: 

            //    [ Indicates the beginning of an array. The tags following are for
            //        data in the Array until a close brace tag is reached.
            //    ] Indicates the end of an array.

            // zero length, don't advance argument ptr
            break;

        default:    // unknown type tag
            // don't advance
            --value_.typeTagPtr_;
            break;
    }
}