void conn_string_parser:: parse_conn_string()

in source/pdo_sqlsrv/pdo_parser.cpp [186:392]


void conn_string_parser:: parse_conn_string( void ) 
{
    States state = FirstKeyValuePair; // starting state
    int start_pos = -1;

    try {

        while( !this->is_eos() ) {
        
            switch( state ) {
            
                case FirstKeyValuePair:
                {
                    // discard leading spaces
                    if( !next() || !discard_white_spaces() ) {
                        
                        THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_STRING ); //EOS
                    }
                  
                    state = Key;
                    break;
                }

                case Key:
                {
                    start_pos = this->pos;

                    // read the key name
                    while( this->orig_str[pos] != '=' ) {
                    
                        if( !next() ) {
                            
                            THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_DSN_STRING_ENDED_UNEXPECTEDLY ); //EOS 
                        }      
                    } 

                    this->validate_key( &( this->orig_str[start_pos] ), ( pos - start_pos ) ); 
                
                    state = Value;

                    break;
                }

                case Value:
                {
                    SQLSRV_ASSERT(( this->orig_str[pos] == '=' ), "conn_string_parser:: parse_conn_string: "
                                   "Equal was expected" );

                    next(); // skip "="

                    // if EOS encountered after 0 or more spaces OR semi-colon encountered.
                    if( !discard_white_spaces() || this->orig_str[pos] == ';' ) {

                        add_key_value_pair( NULL, 0 );

                        if( this->is_eos() ) {
                            
                            break; // EOS
                        }
                        else {

                            // this->orig_str[pos] == ';' 
                            state = NextKeyValuePair;
                        }
                    }
                    
                    // if LCB
                    else if( this->orig_str[pos] == '{' ) {
                        
                        start_pos = this->pos; // starting character is LCB
                        state = ValueContent1;
                    }
                    
                    // If NonSP-LCB-SC
                    else  {

                        start_pos = this->pos;
                        state = ValueContent2;
                    }

                    break;
                }

                case ValueContent1:
                {
                    while ( this->orig_str[pos] != '}' ) {
                    
                        if ( ! next() ) {

                            THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_RCB_MISSING_IN_DSN_VALUE, this->current_key_name ); 
                        }
                    }

                    // If we reached here than RCB encountered
                    state = RCBEncountered;

                    break;
                }

                case ValueContent2:
                {
                    while( this->orig_str[pos] != ';' ) {

                        if( ! next() ) {
                            
                            break; //EOS
                        }
                    }

                    if( !this->is_eos() && this->orig_str[pos] == ';' ) {
                    
                        // semi-colon encountered, so go to next key-value pair
                        state = NextKeyValuePair;
                    }
                    
                    add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos );
              
                    SQLSRV_ASSERT((( state == NextKeyValuePair ) || ( this->is_eos() )), 
                                  "conn_string_parser::parse_conn_string: Invalid state encountered " );

                    break;
                }

                case RCBEncountered:
                {
                    
                    // Read the next character after RCB.
                    if( !next() ) {

                        // EOS
                        add_key_value_pair( &( this->orig_str[start_pos] ), this->pos - start_pos );
                        break;
                    }

                    SQLSRV_ASSERT( !this->is_eos(), "conn_string_parser::parse_conn_string: Unexpected EOS encountered" );

                    // if second RCB encountered than go back to ValueContent1
                    if( this->orig_str[pos] == '}' ) {
                        
                        if( !next() ) {

                            // EOS after a second RCB is error
                            THROW_PDO_ERROR( this->ctx, SQLSRV_ERROR_UNESCAPED_RIGHT_BRACE_IN_DSN, this->current_key_name );                              
                        }

                        state = ValueContent1;
                        break;
                    }

                    int end_pos = this->pos;

                    // discard any trailing white-spaces.
                    if( this->is_white_space( this->orig_str[pos] )) {
                    
                        if( ! this->discard_white_spaces() ) {
                            
                            //EOS
                            add_key_value_pair( &( this->orig_str[start_pos] ), end_pos - start_pos );
                            break;
                        }
                    }

                    // if semi-colon than go to next key-value pair
                    if ( this->orig_str[pos] == ';' ) {
                        
                        add_key_value_pair( &( this->orig_str[start_pos] ), end_pos - start_pos );
                        state = NextKeyValuePair;
                        break;
                    }

                    // Non - (RCB, SP*, SC, EOS) character. Any other character after an RCB is an error.
                    THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_INVALID_DSN_VALUE, this->current_key_name );      
                    break;    
                }
                case NextKeyValuePair:
                {
                    SQLSRV_ASSERT(( this->orig_str[pos] == ';' ), 
                                  "conn_string_parser::parse_conn_string: semi-colon was expected." );

                    // Call next() to skip the semi-colon.
                    if( !next() || !this->discard_white_spaces() ) {
                    
                        // EOS
                        break;
                    }
                    
                    if( this->orig_str[pos] == ';' ) {
                    
                        // a second semi-colon is error case.
                        THROW_PDO_ERROR( this->ctx, PDO_SQLSRV_ERROR_EXTRA_SEMI_COLON_IN_DSN_STRING, this->pos );      
                    }

                    else {

                        // any other character leads to the next key
                        state = Key;
                        break;
                    }
                } //case NextKeyValuePair
            } // switch
        } //while
    } 
    catch( pdo::PDOException& ) {

        throw;
    }
}