ReNamer:Scripts:URL decode

From den4b Wiki
Revision as of 19:18, 4 February 2014 by Den4b (talk | contribs) (Native URLEncode and URLDecode functions have been added in v5.74.4 Beta)
Jump to navigation Jump to search

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.