URLEncode\URLDecode UTF-8 & windows1251

URLEncode \ URLDecode для кодировок UTF-8 и windows1251 согласно RFC 1738.

const
  sErrorDecodingURLText = 'Error decoding URL style (%%XX) encoded string at position %d';
  sInvalidURLEncodedChar = 'Invalid URL encoded character (%s) at position %d';


function HTTPEncode(const AStr: String): String; // The NoConversion set contains characters as specificed in RFC 1738 and // should not be modified unless the standard changes. const NoConversion = ['A'..'Z','a'..'z','*','@','.','_','-','0'..'9','$','!','''','(',')']; var Sp, Rp: PAnsiChar; begin SetLength(Result, Length(AStr) * 3); Sp:= PAnsiChar(AStr); Rp:= PAnsiChar(Result); while Sp^ <> #0 do begin if Sp^ in NoConversion then Rp^ := Sp^ else if Sp^ = ' ' then Rp^ := '+' else begin FormatBuf(Rp^, 3, '%%%.2x', 6, [Ord(Sp^)]); Inc(Rp,2); end; Inc(Rp); Inc(Sp); end; SetLength(Result, Rp - PAnsiChar(Result)); end;
type TCharacters = (UTF8, win1251);
function URLEncode(const Url: String; &Type: TCharacters = UTF8): String; begin case &Type of UTF8: Result:= HttpEncode(UTF8Encode(Url)); win1251: Result:= HttpEncode(Url); end; end;

URLDecode для кодировок UTF-8 и windows1251 согласно RFC 1738.

function HTTPDecode(const AStr: String): String;
var
  Sp, Rp, Cp: PAnsiChar;
  S: String;
begin
  SetLength(Result, Length(AStr));
  Sp:= PAnsiChar(AStr);
  Rp:= PAnsiChar(Result);
  Cp:= Sp;
  try
    while Sp^ <> #0 do begin
      case Sp^ of
        '+': Rp^:= ' ';
        '%':
          begin
            // Look for an escaped % (%%) or % < hex > encoded character
            Inc(Sp);
            if Sp^ = '%' then Rp^ := '%' else begin
              Cp := Sp;
              Inc(Sp);
              if (Cp^ <> #0) and (Sp^ <> #0) then begin
                S := '$' + Cp^ + Sp^;
                Rp^:= chr (StrToInt(S));
              end else
                raise Exception.CreateFmt(sErrorDecodingURLText, [Cp - PAnsiChar(AStr)]);
            end;
          end;
        else Rp^:= Sp^;
      end;
      Inc(Rp);
      Inc(Sp);
    end;
  except
    on E: EConvertError do
      raise EConvertError.CreateFmt(sInvalidURLEncodedChar, ['%' + Cp^ + Sp^, Cp - PAnsiChar(AStr)])
  end;
  SetLength(Result, Rp - PAnsiChar(Result));
end;

function URLDecode(const Url: String; &Type: TCharacters = UTF8): String; begin case &Type of UTF8: Result:= UTF8Decode(HTTPDecode(Url)); win1251: Result:= HTTPDecode(Url); end; end;