static void processAmpersandInQueryString()

in source/sigv4.c [1807:1877]


    static void processAmpersandInQueryString( bool fieldHasValue,
                                               size_t currQueryIndex,
                                               size_t * pStartOfFieldOrValue,
                                               size_t * pCurrParamCount,
                                               const char * pQuery,
                                               CanonicalContext_t * pCanonicalRequest )
    {
        bool previousParamIsValid = true;

        assert( pCurrParamCount != NULL );
        assert( pStartOfFieldOrValue != NULL );
        assert( pQuery != NULL );
        assert( pCanonicalRequest != NULL );

        /* Process scenarios when a value for the previous parameter entry has been detected. */
        if( fieldHasValue )
        {
            /* Case when parameter has empty value even though the query parameter entry has the form
             * "<param>=". */
            if( ( currQueryIndex - *pStartOfFieldOrValue ) == 0U )
            {
                /* Store the previous parameter's empty value information. Use NULL to represent empty value. */
                setQueryParameterValue( *pCurrParamCount, NULL, 0U, pCanonicalRequest );
            }

            /* This represents the case when the previous parameter has a value associated with it. */
            else
            {
                /* End of value reached, so store a pointer to the previously set value. */
                setQueryParameterValue( *pCurrParamCount, &( pQuery[ *pStartOfFieldOrValue ] ), currQueryIndex - *pStartOfFieldOrValue, pCanonicalRequest );
            }
        }
        /* A parameter value has not been found for the previous parameter. */
        else
        {
            /* Ignore unnecessary '&' that represent empty parameter names.
             * Trimmable '&'s can be leading, trailing or repeated as separators between parameter
             * pairs.
             * For example, this function will prune "&p1=v1&&p2=v2&" to "p1=v1&p2=v2". */
            if( ( currQueryIndex - *pStartOfFieldOrValue ) == 0U )
            {
                /* Do nothing as previous parameter name is empty. */
                previousParamIsValid = false;
            }

            /* Case when a new query parameter pair has begun without the previous parameter having an associated value,
             * i.e. of the format "<param1>&<param2>=<value>" where "<param1>".
             * In thus case, as the previous parameter does not have a value, we will store an empty value for it. */
            else
            {
                /* Store information about previous query parameter name. The query parameter has no associated value. */
                setQueryParameterKey( *pCurrParamCount, &( pQuery[ *pStartOfFieldOrValue ] ), currQueryIndex - *pStartOfFieldOrValue, pCanonicalRequest );

                /* Store the previous parameter's empty value information. Use NULL to represent empty value. */
                setQueryParameterValue( *pCurrParamCount, NULL, 0U, pCanonicalRequest );
            }
        }

        /* Increment the parameter count if the previous parameter is not empty
         * An empty previous parameter is caused in query strings where the '&' are unnecessary. */
        if( previousParamIsValid == true )
        {
            /* As the previous parameter is valid, increment the total parameters
             * parsed so far from the query string. */
            ( *pCurrParamCount )++;
        }

        /* As '&' is always treated as a separator, update the starting index to represent the next
         * query parameter. */
        *pStartOfFieldOrValue = currQueryIndex + 1U;
    }