[ create a new paste ] login | about

Link: http://codepad.org/EagJ1YnB    [ raw code | fork ]

C++, pasted on May 17:
/**
 * Licensed under the LGPL, is this code too much like the function
 * reencode_escapes in wget/src/urls.c that it should be licensed under
 * the GPL?
 */

namespace ISO
{
  typedef Size_T std::string::size_type ;
}


bool
is_reserved( const unsigned char c )
{
  // Check if the passed char is in the set of reserved chars
  const char *  found = strchr( "#$&+,.:;=?@[]" , c ) ;

  return  0 != found ;

} /* is_reserved( const unsigned char ) */


bool
is_unsafe( const unsigned char c )
{
  // Check some outliers in the range of normally unsafe chars
  if( strchr( "!$~" , c ) )
  {
    return  false ;

  } /* if */

  // Check some outliers in the range of normally safe chars
  if( strchr( ":<>@[\\]^`" , c ) )
  {
    return  true ;

  } /* if */

  // Check if we are in the range of unsafe chars
  if( ( c <= '%' ) or ( '{' <= c ) )
  {
    return  true ;

  } /* if */

  return  false ;

} /* is_unsafe( const unsigned char ) */


bool
should_escape( const std::string & test , const ISO::Size_T idx )
{
  const ISO::Size_T   length  = test.size() ;

  if( length == 0  or length <= idx )
  {
    return  false ;

  } /* if */

  const char          c       = test[idx] ;

  // Need to check if this is a previously escaped sequence "%xx"
  if( '%' == c )
  {
    // If we haven't 2 digits following, return true (we need to escape) since this can't be "%xx"
    if( ( length <= idx + 2 ) or !std::isxdigit( test[idx+1] ) or !std::isxdigit( test[idx+2] ) )
    {
      return  true ;

    } /* if */

    return  false ;

  } /* if */

  if( is_unsafe( c ) and !is_reserved( c ) )
  {
    return  true ;

  } /* if */

  return  false ;

} /* should_escape( const std::string & , const ISO::Size_T ) */

std::string
escape_url( const std::string & url )
{
  std::string       result ;

  for( ISO::Size_T i = 0 ; i < url.length() ; i++ )
  {
    // Make this easy to print in a debugger :)
    const char  curr  = url[i] ;

    if( should_escape( url , i ) )
    {
      result += '%' ;
      result += ( "0123456789ABCDEF"[(curr >> 4)] ) ;
      result += ( "0123456789ABCDEF"[(curr & 0x0F)] ) ;

    } /* if */
    else
    {
      // Pass the character through unchanged and unescaped
      result += curr ;

    } /* else */

  } /* for */

  return  result ;

} /* escape_url( const std::string & ) */


Create a new paste based on this one


Comments: