diff options
Diffstat (limited to 'decoder/fdict.cc')
| -rw-r--r-- | decoder/fdict.cc | 129 | 
1 files changed, 129 insertions, 0 deletions
diff --git a/decoder/fdict.cc b/decoder/fdict.cc new file mode 100644 index 00000000..7e1b0e1f --- /dev/null +++ b/decoder/fdict.cc @@ -0,0 +1,129 @@ +#include "fdict.h" + +#include <string> + +using namespace std; + +Dict FD::dict_; +bool FD::frozen_ = false; + +static int HexPairValue(const char * code) { +  int value = 0; +  const char * pch = code; +  for (;;) { +    int digit = *pch++; +    if (digit >= '0' && digit <= '9') { +      value += digit - '0'; +    } +    else if (digit >= 'A' && digit <= 'F') { +      value += digit - 'A' + 10; +    } +    else if (digit >= 'a' && digit <= 'f') { +      value += digit - 'a' + 10; +    } +    else { +      return -1; +    } +    if (pch == code + 2) +      return value; +    value <<= 4; +  } +} + +int UrlDecode(const char *source, char *dest) +{ +  char * start = dest; + +  while (*source) { +    switch (*source) { +    case '+': +      *(dest++) = ' '; +      break; +    case '%': +      if (source[1] && source[2]) { +        int value = HexPairValue(source + 1); +        if (value >= 0) { +          *(dest++) = value; +          source += 2; +        } +        else { +          *dest++ = '?'; +        } +      } +      else { +        *dest++ = '?'; +      } +      break; +    default: +      *dest++ = *source; +    } +    source++; +  } +   +  *dest = 0; +  return dest - start; +}   + +int UrlEncode(const char *source, char *dest, unsigned max) { +  static const char *digits = "0123456789ABCDEF"; +  unsigned char ch; +  unsigned len = 0; +  char *start = dest; + +  while (len < max - 4 && *source) +  { +    ch = (unsigned char)*source; +    if (*source == ' ') { +      *dest++ = '+'; +    } +    else if (strchr("=:;,_| %", ch)) { +      *dest++ = '%'; +      *dest++ = digits[(ch >> 4) & 0x0F]; +      *dest++ = digits[       ch & 0x0F]; +    } +    else { +      *dest++ = *source; +    }   +    source++; +  } +  *dest = 0; +  return start - dest; +} + +std::string UrlDecodeString(const std::string & encoded) { +  const char * sz_encoded = encoded.c_str(); +  size_t needed_length = encoded.length(); +  for (const char * pch = sz_encoded; *pch; pch++) { +    if (*pch == '%') +      needed_length += 2; +  } +  needed_length += 10; +  char stackalloc[64]; +  char * buf = needed_length > sizeof(stackalloc)/sizeof(*stackalloc) ? +    (char *)malloc(needed_length) : stackalloc; +  UrlDecode(encoded.c_str(), buf); +  std::string result(buf); +  if (buf != stackalloc) { +    free(buf); +  } +  return result; +} + +std::string UrlEncodeString(const std::string & decoded) { +  const char * sz_decoded = decoded.c_str(); +  size_t needed_length = decoded.length() * 3 + 3; +  char stackalloc[64]; +  char * buf = needed_length > sizeof(stackalloc)/sizeof(*stackalloc) ? +    (char *)malloc(needed_length) : stackalloc; +  UrlEncode(decoded.c_str(), buf, needed_length); +  std::string result(buf); +  if (buf != stackalloc) { +    free(buf); +  } +  return result; +} + +string FD::Escape(const string& s) { +  return UrlEncodeString(s); +} +  | 
