// File: alfanick[P]rest-cpp/src/rest/utils.cpp
// Function: REST::Utils::uri_decode(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
std::string uri_decode(const std::string & sSrc) {
   // Note from RFC1630: "Sequences which start with a percent
   // sign but are not followed by two hexadecimal characters
   // (0-9, A-F) are reserved for future extension"

   const unsigned char * pSrc = (const unsigned char *)sSrc.c_str();
   const int SRC_LEN = sSrc.length();
   const unsigned char * const SRC_END = pSrc + SRC_LEN;
   // last decodable '%'
   const unsigned char * const SRC_LAST_DEC = SRC_END - 2;

   char * const pStart = new char[SRC_LEN];
   char * pEnd = pStart;

   while (pSrc < SRC_LAST_DEC)
   {
      if (*pSrc == '%')
      {
         char dec1, dec2;
         if (-1 != (dec1 = HEX2DEC[*(pSrc + 1)])
            && -1 != (dec2 = HEX2DEC[*(pSrc + 2)]))
         {
            *pEnd++ = (dec1 << 4) + dec2;
            pSrc += 3;
            continue;
         }
      }

      *pEnd++ = *pSrc++;
   }

   // the last 2- chars
   while (pSrc < SRC_END)
      *pEnd++ = *pSrc++;

   std::string sResult(pStart, pEnd);
   delete [] pStart;
   return sResult;
}

// Assembly:
subq $0x88, %rsp
movq %rdi, 0x20(%rsp)
movq %rdi, %rax
movq %rax, 0x28(%rsp)
movq %rdi, 0x80(%rsp)
movq %rsi, 0x78(%rsp)
movq 0x78(%rsp), %rdi
callq 0x8f110
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rdi
callq 0x964d0
movl %eax, 0x6c(%rsp)
movq 0x70(%rsp), %rax
movslq 0x6c(%rsp), %rcx
addq %rcx, %rax
movq %rax, 0x60(%rsp)
movq 0x60(%rsp), %rax
addq $-0x2, %rax
movq %rax, 0x58(%rsp)
movslq 0x6c(%rsp), %rdi
movq $-0x1, %rax
cmpq $0x0, %rdi
cmovlq %rax, %rdi
callq 0x8d0d0
movq %rax, 0x50(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x70(%rsp), %rax
cmpq 0x58(%rsp), %rax
jae 0xd5235
movq 0x70(%rsp), %rax
movzbl (%rax), %eax
cmpl $0x25, %eax
jne 0xd520a
movq 0x70(%rsp), %rax
movzbl 0x1(%rax), %eax
movl %eax, %ecx
leaq 0x10f87(%rip), %rax     # 0xe6120
movb (%rax,%rcx), %al
movb %al, 0x47(%rsp)
movsbl %al, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl %ecx, %eax
je 0xd5208
movq 0x70(%rsp), %rax
movzbl 0x2(%rax), %eax
movl %eax, %ecx
leaq 0x10f62(%rip), %rax     # 0xe6120
movb (%rax,%rcx), %al
movb %al, 0x46(%rsp)
movsbl %al, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmpl %ecx, %eax
je 0xd5208
movsbl 0x47(%rsp), %eax
shll $0x4, %eax
movsbl 0x46(%rsp), %ecx
addl %ecx, %eax
movb %al, %cl
movq 0x48(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x48(%rsp)
movb %cl, (%rax)
movq 0x70(%rsp), %rax
addq $0x3, %rax
movq %rax, 0x70(%rsp)
jmp 0xd5166
jmp 0xd520a
movq 0x70(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x70(%rsp)
movb (%rax), %cl
movq 0x48(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x48(%rsp)
movb %cl, (%rax)
jmp 0xd5166
jmp 0xd5237
movq 0x70(%rsp), %rax
cmpq 0x60(%rsp), %rax
jae 0xd526b
movq 0x70(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x70(%rsp)
movb (%rax), %cl
movq 0x48(%rsp), %rax
movq %rax, %rdx
addq $0x1, %rdx
movq %rdx, 0x48(%rsp)
movb %cl, (%rax)
jmp 0xd5237
movb $0x0, 0x45(%rsp)
movq 0x50(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x48(%rsp), %rax
movq %rax, 0x10(%rsp)
leaq 0x44(%rsp), %rdi
movq %rdi, 0x18(%rsp)
callq 0x98200
movq 0x20(%rsp), %rdi
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %rcx
callq 0x8ed50
jmp 0xd52ae
leaq 0x44(%rsp), %rdi
callq 0x938a0
movq 0x50(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0xd52d0
movq (%rsp), %rdi
callq 0x94de0
movb $0x1, 0x45(%rsp)
testb $0x1, 0x45(%rsp)
jne 0xd5302
jmp 0xd52f8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x38(%rsp)
movl %eax, 0x34(%rsp)
leaq 0x44(%rsp), %rdi
callq 0x938a0
jmp 0xd530f
movq 0x20(%rsp), %rdi
callq 0x99830
movq 0x28(%rsp), %rax
addq $0x88, %rsp
retq
movq 0x38(%rsp), %rdi
callq 0x981c0
nopl (%rax)