ReNamer:Scripts:URL decode

From den4b Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Decode a URL encoded filename, also known as Percent-encoding.

Note: Native URLEncode and URLDecode functions have been added in v5.74.4 Beta.

Tested

  • ReNamer 5.50+ Beta

Code

Author: Denis Kozlov. Date: 4 June 2011. Derived from: DelphiDabbler URLDecode snippet

Input Output
Ba%C5%9Fer%20Kafao%C4%9Flu.pdf Başer Kafaoğlu.pdf
%D0%9F%D1%80%D0%B8%D0%BC%D0%B5%D1%80.doc Пример.doc
%Invalid URL encoded name% ***ERROR***
function URLDecode(const S: AnsiString; out Output: AnsiString): Boolean;
var
  Idx: Integer;   // loops thru chars in string
  Hex: string;    // string of hex characters
  Code: Integer;  // hex character code (-1 on error)
begin
  // Intialise result and string index
  Result := False;
  Output := '';
  Idx := 1;
  // Loop thru string decoding each character
  while Idx <= Length(S) do
  begin
    case S[Idx] of
      '%':
      begin
        // % should be followed by two hex digits - exception otherwise
        if Idx <= Length(S) - 2 then
        begin
          // there are sufficient digits - try to decode hex digits
          Hex := S[Idx+1] + S[Idx+2];
          Code := StrToIntDef('$' + Hex, -1);
          Idx := Idx + 2;
        end
        else
          // insufficient digits - error
          Code := -1;
        // check for error and raise exception if found
        if Code = -1 then Exit;
        // decoded OK - add character to result
        Output := Output + Chr(Code);
      end;
      '+':
        // + is decoded as a space
        Output := Output + ' '
      else
        // All other characters pass thru unchanged
        Output := Output + S[Idx];
    end;
    Inc(Idx);
  end;
  Result := True;
end;

var
  Encoded, Decoded: AnsiString;

begin
  Encoded := WideToAnsi(FileName);
  if URLDecode(Encoded, Decoded) then
    FileName := UTF8Decode(Decoded)
  else
    FileName := '***ERROR***';
end.