You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@activemq.apache.org by nm...@apache.org on 2006/12/01 03:07:28 UTC

svn commit: r481132 - in /incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq: connector/stomp/StompCommandReader.cpp connector/stomp/StompCommandReader.h io/BufferedInputStream.cpp

Author: nmittler
Date: Thu Nov 30 18:07:27 2006
New Revision: 481132

URL: http://svn.apache.org/viewvc?view=rev&rev=481132
Log:
[AMQCPP-18] Fixing improper exception handling in StompCommandReader

Modified:
    incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.cpp
    incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.h
    incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/io/BufferedInputStream.cpp

Modified: incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.cpp
URL: http://svn.apache.org/viewvc/incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.cpp?view=diff&rev=481132&r1=481131&r2=481132
==============================================================================
--- incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.cpp (original)
+++ incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.cpp Thu Nov 30 18:07:27 2006
@@ -70,235 +70,261 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 void StompCommandReader::readStompCommandHeader( StompFrame& frame ) 
-   throw ( StompConnectorException )
+   throw ( CommandIOException )
 {  
-    while( true ) 
-    {
-        // The command header is formatted
-        // just like any other stomp header.
-        readStompHeaderLine();
-
-        // Ignore all white space before the command.
-        int offset = -1;
-        for( size_t ix = 0; ix < buffer.size()-1; ++ix )
-        {
-            // Find the first non whitespace character
-            if( !Character::isWhitespace(buffer[ix]) ){
-                offset = ix;
+    try{
+        while( true ) 
+        {
+            // The command header is formatted
+            // just like any other stomp header.
+            readStompHeaderLine();
+    
+            // Ignore all white space before the command.
+            int offset = -1;
+            for( size_t ix = 0; ix < buffer.size()-1; ++ix )
+            {
+                // Find the first non whitespace character
+                if( !Character::isWhitespace(buffer[ix]) ){
+                    offset = ix;
+                    break;
+                }
+            }
+        
+            if( offset >= 0 )
+            {
+                // Set the command in the frame - copy the memory.
+                frame.setCommand( reinterpret_cast<char*>(&buffer[offset]) );
                 break;
             }
+        
         }
-    
-        if( offset >= 0 )
-        {
-            // Set the command in the frame - copy the memory.
-            frame.setCommand( reinterpret_cast<char*>(&buffer[offset]) );
-            break;
-        }
-    
     }
+    AMQ_CATCH_RETHROW( CommandIOException )
+    AMQ_CATCH_EXCEPTION_CONVERT( IOException, CommandIOException )
+    AMQ_CATCHALL_THROW( CommandIOException )
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void StompCommandReader::readStompHeaders( StompFrame& frame ) 
-   throw ( StompConnectorException )
+   throw ( CommandIOException )
 {
-    // Read the command;
-    bool endOfHeaders = false;
-
-    while( !endOfHeaders )
-    {        
-        // Read in the next header line.
-        int numChars = readStompHeaderLine();
-
-        if( numChars == 0 )
-        {
-            // should never get here
-            throw StompConnectorException(
-                __FILE__, __LINE__,
-                "StompCommandReader::readStompHeaders: no characters read" );
-        }
-      
-        // Check for an empty line to demark the end of the header section.
-        // if its not the end then we have a header to process, so parse it.
-        if( numChars == 1 && buffer[0] == '\0' )
-        {
-            endOfHeaders = true;
-        }
-        else
-        {
-            // Search through this line to separate the key/value pair.
-            for( size_t ix = 0; ix < buffer.size(); ++ix )
+    try{
+        // Read the command;
+        bool endOfHeaders = false;
+    
+        while( !endOfHeaders )
+        {        
+            // Read in the next header line.
+            int numChars = readStompHeaderLine();
+    
+            if( numChars == 0 )
             {
-                // If found the key/value separator...
-                if( buffer[ix] == ':' )
+                // should never get here
+                throw StompConnectorException(
+                    __FILE__, __LINE__,
+                    "StompCommandReader::readStompHeaders: no characters read" );
+            }
+          
+            // Check for an empty line to demark the end of the header section.
+            // if its not the end then we have a header to process, so parse it.
+            if( numChars == 1 && buffer[0] == '\0' )
+            {
+                endOfHeaders = true;
+            }
+            else
+            {
+                // Search through this line to separate the key/value pair.
+                for( size_t ix = 0; ix < buffer.size(); ++ix )
                 {
-                    // Null-terminate the key.
-                    buffer[ix] = '\0'; 
-
-                    const char* key = reinterpret_cast<char*>(&buffer[0]);
-                    const char* value = reinterpret_cast<char*>(&buffer[ix+1]);
-               
-                    // Assign the header key/value pair.
-                    frame.getProperties().setProperty(key, value);
-               
-                    // Break out of the for loop.
-                    break;
+                    // If found the key/value separator...
+                    if( buffer[ix] == ':' )
+                    {
+                        // Null-terminate the key.
+                        buffer[ix] = '\0'; 
+    
+                        const char* key = reinterpret_cast<char*>(&buffer[0]);
+                        const char* value = reinterpret_cast<char*>(&buffer[ix+1]);
+                   
+                        // Assign the header key/value pair.
+                        frame.getProperties().setProperty(key, value);
+                   
+                        // Break out of the for loop.
+                        break;
+                    }
                 }
             }
         }
     }
+    AMQ_CATCH_RETHROW( CommandIOException )
+    AMQ_CATCH_EXCEPTION_CONVERT( IOException, CommandIOException )
+    AMQ_CATCHALL_THROW( CommandIOException )
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 int StompCommandReader::readStompHeaderLine(void) 
-    throw ( StompConnectorException )
+    throw ( CommandIOException )
 {
-    // Clear any data from the buffer.
-    buffer.clear();
-        
-    int count = 0;
-  
-    while( true )
-    {
-        // Read the next char from the stream.
-        buffer.push_back( inputStream->read() );
-      
-        // Increment the position pointer.
-        count++;
+    try{
+        // Clear any data from the buffer.
+        buffer.clear();
+            
+        int count = 0;
       
-        // If we reached the line terminator, return the total number
-        // of characters read.
-        if( buffer[count-1] == '\n' )
-        {
-            // Overwrite the line feed with a null character. 
-            buffer[count-1] = '\0';
-         
-            return count;
-        }
-    }
-   
-    // If we get here something bad must have happened.
-    throw StompConnectorException(
-        __FILE__, __LINE__,
-        "StompCommandReader::readStompHeaderLine: "
-        "Unrecoverable, error condition");
+        while( true )
+        {
+            // Read the next char from the stream.
+            buffer.push_back( inputStream->read() );
+          
+            // Increment the position pointer.
+            count++;
+          
+            // If we reached the line terminator, return the total number
+            // of characters read.
+            if( buffer[count-1] == '\n' )
+            {
+                // Overwrite the line feed with a null character. 
+                buffer[count-1] = '\0';
+             
+                return count;
+            }
+        }
+       
+        // If we get here something bad must have happened.
+        throw StompConnectorException(
+            __FILE__, __LINE__,
+            "StompCommandReader::readStompHeaderLine: "
+            "Unrecoverable, error condition");
+    }
+    AMQ_CATCH_EXCEPTION_CONVERT( IOException, CommandIOException )
+    AMQ_CATCHALL_THROW( CommandIOException )
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void StompCommandReader::readStompBody( StompFrame& frame ) 
-   throw ( StompConnectorException )
+   throw ( CommandIOException )
 {
-    // Clear any data from the buffer.
-    buffer.clear();
-    
-    unsigned long content_length = 0;
-   
-    if(frame.getProperties().hasProperty(
-        commands::CommandConstants::toString(
-            commands::CommandConstants::HEADER_CONTENTLENGTH)))
-    {
-        char* stopped_string = NULL;
-      
-        string length = 
-            frame.getProperties().getProperty(
-                commands::CommandConstants::toString(
-                    commands::CommandConstants::HEADER_CONTENTLENGTH));
-            
-        content_length = strtoul(
-            length.c_str(), 
-            &stopped_string, 
-            10 );
-     }
-
-     if( content_length != 0 )
-     {
-        // For this case its assumed that content length indicates how 
-        // much to read.  We reserve space in the buffer for it to 
-        // minimize the number of reallocs that might occur.  We are
-        // assuming that content length doesn't count the trailing null
-        // that indicates the end of frame.  The reserve won't do anything
-        // if the buffer already has that much capacity.  The resize call
-        // basically sets the end iterator to the correct location since
-        // this is a char vector and we already reserve enough space.
-        // Resize doesn't realloc the vector smaller if content_length
-        // is less than capacity of the buffer, it just move the end
-        // iterator.  Reserve adds the benefit that the mem is set to 
-        // zero.  Over time as larger messages come in thsi will cause
-        // us to adapt to that size so that future messages that are
-        // around that size won't alloc any new memory.
-
-        buffer.reserve( content_length );
-        buffer.resize( content_length );
-
-        // Read the Content Length now
-        read( &buffer[0], content_length );
-
-        // Content Length read, now pop the end terminator off (\0\n).
-        if(inputStream->read() != '\0' )
+    try{
+        // Clear any data from the buffer.
+        buffer.clear();
+        
+        unsigned long content_length = 0;
+       
+        if(frame.getProperties().hasProperty(
+            commands::CommandConstants::toString(
+                commands::CommandConstants::HEADER_CONTENTLENGTH)))
         {
-            throw StompConnectorException(
-                __FILE__, __LINE__,
-                "StompCommandReader::readStompBody: "
-                "Read Content Length, and no trailing null");
+            char* stopped_string = NULL;
+          
+            string length = 
+                frame.getProperties().getProperty(
+                    commands::CommandConstants::toString(
+                        commands::CommandConstants::HEADER_CONTENTLENGTH));
+                
+            content_length = strtoul(
+                length.c_str(), 
+                &stopped_string, 
+                10 );
+         }
+    
+         if( content_length != 0 )
+         {
+            // For this case its assumed that content length indicates how 
+            // much to read.  We reserve space in the buffer for it to 
+            // minimize the number of reallocs that might occur.  We are
+            // assuming that content length doesn't count the trailing null
+            // that indicates the end of frame.  The reserve won't do anything
+            // if the buffer already has that much capacity.  The resize call
+            // basically sets the end iterator to the correct location since
+            // this is a char vector and we already reserve enough space.
+            // Resize doesn't realloc the vector smaller if content_length
+            // is less than capacity of the buffer, it just move the end
+            // iterator.  Reserve adds the benefit that the mem is set to 
+            // zero.  Over time as larger messages come in thsi will cause
+            // us to adapt to that size so that future messages that are
+            // around that size won't alloc any new memory.
+    
+            buffer.reserve( content_length );
+            buffer.resize( content_length );
+    
+            // Read the Content Length now
+            read( &buffer[0], content_length );
+    
+            // Content Length read, now pop the end terminator off (\0\n).
+            if(inputStream->read() != '\0' )
+            {
+                throw StompConnectorException(
+                    __FILE__, __LINE__,
+                    "StompCommandReader::readStompBody: "
+                    "Read Content Length, and no trailing null");
+            }
         }
-    }
-    else
-    {
-        // Content length was either zero, or not set, so we read until the
-        // first null is encounted.
-      
-        while( true )
+        else
         {
-            char byte = inputStream->read();
-         
-            buffer.push_back(byte);
-        
-            content_length++;
-
-            if( byte != '\0' )
-            {            
-                continue;
+            // Content length was either zero, or not set, so we read until the
+            // first null is encounted.
+          
+            while( true )
+            {
+                char byte = inputStream->read();
+             
+                buffer.push_back(byte);
+            
+                content_length++;
+    
+                if( byte != '\0' )
+                {            
+                    continue;
+                }
+    
+                break;  // Read null and newline we are done.
             }
-
-            break;  // Read null and newline we are done.
         }
+    
+        if( content_length != 0 )
+        {
+            char* cpyBody = new char[content_length];
+            memcpy( cpyBody, &buffer[0], content_length );
+    
+            // Set the body contents in the frame - copy the memory
+            frame.setBody( cpyBody, content_length );
+        }    
     }
-
-    if( content_length != 0 )
-    {
-        char* cpyBody = new char[content_length];
-        memcpy( cpyBody, &buffer[0], content_length );
-
-        // Set the body contents in the frame - copy the memory
-        frame.setBody( cpyBody, content_length );
-    }    
+    AMQ_CATCH_EXCEPTION_CONVERT( IOException, CommandIOException )
+    AMQ_CATCHALL_THROW( CommandIOException )
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 int StompCommandReader::read( unsigned char* buffer, int count ) 
    throw( io::IOException )
 {
-    if( inputStream == NULL )
-    {
-        throw IOException( 
-            __FILE__, __LINE__, 
-            "StompCommandReader::read(char*,int) - input stream is NULL" );
-    }
-   
-    // Just delegate to the input stream.
-    return inputStream->read( buffer, count );
+    try{
+        if( inputStream == NULL )
+        {
+            throw IOException( 
+                __FILE__, __LINE__, 
+                "StompCommandReader::read(char*,int) - input stream is NULL" );
+        }
+       
+        // Just delegate to the input stream.
+        return inputStream->read( buffer, count );
+    }
+    AMQ_CATCH_RETHROW( IOException )
+    AMQ_CATCHALL_THROW( IOException )
 }
  
 ////////////////////////////////////////////////////////////////////////////////
 unsigned char StompCommandReader::readByte(void) throw( io::IOException )
 {
-    if( inputStream == NULL )
-    {
-        throw IOException( 
-            __FILE__, __LINE__, 
-            "StompCommandReader::read(char*,int) - input stream is NULL" );
+        try{
+        if( inputStream == NULL )
+        {
+            throw IOException( 
+                __FILE__, __LINE__, 
+                "StompCommandReader::read(char*,int) - input stream is NULL" );
+        }
+       
+        return inputStream->read();
     }
-   
-    return inputStream->read();
+    AMQ_CATCH_RETHROW( IOException )
+    AMQ_CATCHALL_THROW( IOException )
 }

Modified: incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.h
URL: http://svn.apache.org/viewvc/incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.h?view=diff&rev=481132&r1=481131&r2=481132
==============================================================================
--- incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.h (original)
+++ incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/connector/stomp/StompCommandReader.h Thu Nov 30 18:07:27 2006
@@ -53,7 +53,7 @@
         /**
          * Deafult Constructor
          */
-        StompCommandReader( void );
+        StompCommandReader();
 
         /**
          * Constructor.
@@ -61,14 +61,14 @@
          */
         StompCommandReader( io::InputStream* is );
 
-        virtual ~StompCommandReader(void) {}
+        virtual ~StompCommandReader() {}
 
         /**
          * Reads a command from the given input stream.
          * @return The next command available on the stream.
          * @throws CommandIOException if a problem occurs during the read.
          */
-        virtual transport::Command* readCommand(void) 
+        virtual transport::Command* readCommand() 
             throw ( transport::CommandIOException );
 
         /**
@@ -83,7 +83,7 @@
          * Gets the target input stream.
          * @return Target Input Stream
          */
-        virtual io::InputStream* getInputStream(void){
+        virtual io::InputStream* getInputStream(){
             return inputStream;
         }
 
@@ -102,7 +102,7 @@
          * @return The byte.
          * @throws IOException thrown if an error occurs.
          */
-        virtual unsigned char readByte(void) throw( io::IOException );
+        virtual unsigned char readByte() throw( io::IOException );
 
     private:
     
@@ -112,7 +112,7 @@
          * @throws StompConnectorException
          */
         void readStompCommandHeader( StompFrame& frame ) 
-            throw ( StompConnectorException );
+            throw ( transport::CommandIOException );
 
         /** 
          * Read all the Stomp Headers for the incoming Frame
@@ -120,21 +120,21 @@
          * @throws StompConnectorException
          */
         void readStompHeaders( StompFrame& frame ) 
-            throw ( StompConnectorException );
+            throw ( transport::CommandIOException );
 
         /**
          * Reads a Stomp Header line and stores it in the buffer object
          * @return number of bytes read, zero if there was a problem.
          * @throws StompConnectorException
          */
-        int readStompHeaderLine(void) throw ( StompConnectorException );
+        int readStompHeaderLine() throw ( transport::CommandIOException );
 
         /**
          * Reads the Stomp Body from the Wire and store it in the frame.
          * @param Stomp Frame to place data in
          */
         void readStompBody( StompFrame& frame ) 
-            throw ( StompConnectorException );                
+            throw ( transport::CommandIOException );                
     
     };
 

Modified: incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/io/BufferedInputStream.cpp
URL: http://svn.apache.org/viewvc/incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/io/BufferedInputStream.cpp?view=diff&rev=481132&r1=481131&r2=481132
==============================================================================
--- incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/io/BufferedInputStream.cpp (original)
+++ incubator/activemq/activemq-cpp/trunk/activemq-cpp/src/main/activemq/io/BufferedInputStream.cpp Thu Nov 30 18:07:27 2006
@@ -62,88 +62,100 @@
 ////////////////////////////////////////////////////////////////////////////////
 unsigned char BufferedInputStream::read() throw ( IOException ){
 
-    // If there's no data left, reset to pointers to the beginning of the
-    // buffer.
-    normalizeBuffer();                
-
-    // If we don't have any data buffered yet - read as much as 
-    // we can. 
-    if( isEmpty() ){
-        bufferData();
+    try{
+        // If there's no data left, reset to pointers to the beginning of the
+        // buffer.
+        normalizeBuffer();                
+    
+        // If we don't have any data buffered yet - read as much as 
+        // we can. 
+        if( isEmpty() ){
+            bufferData();
+        }
+        
+        // Get the next character.
+        char returnValue = buffer[head++];
+        
+        return returnValue;
     }
-    
-    // Get the next character.
-    char returnValue = buffer[head++];
-    
-    return returnValue;
+    AMQ_CATCH_RETHROW( IOException )
+    AMQ_CATCHALL_THROW( IOException )
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 int BufferedInputStream::read( unsigned char* targetBuffer, 
     const int targetBufferSize ) throw ( IOException ){
     
-    // If there's no data left, reset to pointers to the beginning of the
-    // buffer.
-    normalizeBuffer();
-    
-    // If we still haven't filled the output buffer AND there is data
-    // on the input stream to be read, read a buffer's
-    // worth from the stream.
-    int totalRead = 0;
-    while( totalRead < targetBufferSize ){        
-        
-        // Get the remaining bytes to copy.
-        int bytesToCopy = min( tail-head, (targetBufferSize-totalRead) );
-        
-        // Copy the data to the output buffer.  
-        memcpy( targetBuffer+totalRead, this->buffer+head, bytesToCopy );
-        
-        // Increment the total bytes read.
-        totalRead += bytesToCopy;
-        
-        // Increment the head position.
-        head += bytesToCopy;
-        
-        // If the buffer is now empty, reset the positions to the
-        // head of the buffer.
+    try{
+        // If there's no data left, reset to pointers to the beginning of the
+        // buffer.
         normalizeBuffer();
         
-        // If we still haven't satisified the request, 
-        // read more data.
-        if( totalRead < targetBufferSize ){                  
+        // If we still haven't filled the output buffer AND there is data
+        // on the input stream to be read, read a buffer's
+        // worth from the stream.
+        int totalRead = 0;
+        while( totalRead < targetBufferSize ){        
             
-            // Buffer as much data as we can.
-            bufferData();
-        }              
+            // Get the remaining bytes to copy.
+            int bytesToCopy = min( tail-head, (targetBufferSize-totalRead) );
+            
+            // Copy the data to the output buffer.  
+            memcpy( targetBuffer+totalRead, this->buffer+head, bytesToCopy );
+            
+            // Increment the total bytes read.
+            totalRead += bytesToCopy;
+            
+            // Increment the head position.
+            head += bytesToCopy;
+            
+            // If the buffer is now empty, reset the positions to the
+            // head of the buffer.
+            normalizeBuffer();
+            
+            // If we still haven't satisified the request, 
+            // read more data.
+            if( totalRead < targetBufferSize ){                  
+                
+                // Buffer as much data as we can.
+                bufferData();
+            }              
+        }
+        
+        // Return the total number of bytes read.
+        return totalRead;
     }
-    
-    // Return the total number of bytes read.
-    return totalRead;
+    AMQ_CATCH_RETHROW( IOException )
+    AMQ_CATCHALL_THROW( IOException )
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 void BufferedInputStream::bufferData() throw ( IOException ){
     
-    if( getUnusedBytes() == 0 ){
-        throw IOException( __FILE__, __LINE__, 
-            "BufferedInputStream::bufferData - buffer full" );
-    }
-    
-    // Get the number of bytes currently available on the input stream
-    // that could be read without blocking.
-    int available = inputStream->available();
-    
-    // Calculate the number of bytes that we can read.  Always >= 1 byte!
-    int bytesToRead = max( 1, min( available, getUnusedBytes() ) );
-    
-    // Read the bytes from the input stream.
-    int bytesRead = inputStream->read( getTail(), bytesToRead );
-    if( bytesRead == 0 ){
-        throw IOException( __FILE__, __LINE__, 
-            "BufferedInputStream::read() - failed reading bytes from stream");
+    try{
+        if( getUnusedBytes() == 0 ){
+            throw IOException( __FILE__, __LINE__, 
+                "BufferedInputStream::bufferData - buffer full" );
+        }
+        
+        // Get the number of bytes currently available on the input stream
+        // that could be read without blocking.
+        int available = inputStream->available();
+        
+        // Calculate the number of bytes that we can read.  Always >= 1 byte!
+        int bytesToRead = max( 1, min( available, getUnusedBytes() ) );
+        
+        // Read the bytes from the input stream.    
+        int bytesRead = inputStream->read( getTail(), bytesToRead );
+        if( bytesRead == 0 ){
+            throw IOException( __FILE__, __LINE__, 
+                "BufferedInputStream::read() - failed reading bytes from stream");
+        }
+        
+        // Increment the tail to the new end position.
+        tail += bytesRead;
     }
-    
-    // Increment the tail to the new end position.
-    tail += bytesRead;   
+    AMQ_CATCH_RETHROW( IOException )
+    AMQ_CATCHALL_THROW( IOException )
 }