Files
textmate/Frameworks/text/src/decode.cc
Allan Odgaard 9894969e67 Initial commit
2012-08-09 16:25:56 +02:00

380 lines
9.6 KiB
C++
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "decode.h"
#include <oak/oak.h>
static struct name_map_t { std::string const key; std::string const value; } const NameMap[] =
{
{ "AElig", "Æ" },
{ "Aacute", "Á" },
{ "Acirc", "Â" },
{ "Agrave", "À" },
{ "Alpha", "Α" },
{ "Aring", "Å" },
{ "Atilde", "Ã" },
{ "Auml", "Ä" },
{ "Beta", "Β" },
{ "Ccedil", "Ç" },
{ "Chi", "Χ" },
{ "Dagger", "" },
{ "Delta", "Δ" },
{ "ETH", "Ð" },
{ "Eacute", "É" },
{ "Ecirc", "Ê" },
{ "Egrave", "È" },
{ "Epsilon", "Ε" },
{ "Eta", "Η" },
{ "Euml", "Ë" },
{ "Gamma", "Γ" },
{ "Iacute", "Í" },
{ "Icirc", "Î" },
{ "Igrave", "Ì" },
{ "Iota", "Ι" },
{ "Iuml", "Ï" },
{ "Kappa", "Κ" },
{ "Lambda", "Λ" },
{ "Mu", "Μ" },
{ "Ntilde", "Ñ" },
{ "Nu", "Ν" },
{ "OElig", "Œ" },
{ "Oacute", "Ó" },
{ "Ocirc", "Ô" },
{ "Ograve", "Ò" },
{ "Omega", "Ω" },
{ "Omicron", "Ο" },
{ "Oslash", "Ø" },
{ "Otilde", "Õ" },
{ "Ouml", "Ö" },
{ "Phi", "Φ" },
{ "Pi", "Π" },
{ "Prime", "" },
{ "Psi", "Ψ" },
{ "Rho", "Ρ" },
{ "Scaron", "Š" },
{ "Sigma", "Σ" },
{ "THORN", "Þ" },
{ "Tau", "Τ" },
{ "Theta", "Θ" },
{ "Uacute", "Ú" },
{ "Ucirc", "Û" },
{ "Ugrave", "Ù" },
{ "Upsilon", "Υ" },
{ "Uuml", "Ü" },
{ "Xi", "Ξ" },
{ "Yacute", "Ý" },
{ "Yuml", "Ÿ" },
{ "Zeta", "Ζ" },
{ "aacute", "á" },
{ "acirc", "â" },
{ "acute", "´" },
{ "aelig", "æ" },
{ "agrave", "à" },
{ "alefsym", "" },
{ "alpha", "α" },
{ "amp", "&" },
{ "and", "" },
{ "ang", "" },
{ "apos", "'" },
{ "aring", "å" },
{ "asymp", "" },
{ "atilde", "ã" },
{ "auml", "ä" },
{ "bdquo", "" },
{ "beta", "β" },
{ "brvbar", "¦" },
{ "bull", "" },
{ "cap", "" },
{ "ccedil", "ç" },
{ "cedil", "¸" },
{ "cent", "¢" },
{ "chi", "χ" },
{ "circ", "ˆ" },
{ "clubs", "" },
{ "cong", "" },
{ "copy", "©" },
{ "crarr", "" },
{ "cup", "" },
{ "curren", "¤" },
{ "dArr", "" },
{ "dagger", "" },
{ "darr", "" },
{ "deg", "°" },
{ "delta", "δ" },
{ "diams", "" },
{ "divide", "÷" },
{ "eacute", "é" },
{ "ecirc", "ê" },
{ "egrave", "è" },
{ "empty", "" },
{ "emsp", "\u2003" },
{ "ensp", "\u2002" },
{ "epsilon", "ε" },
{ "equiv", "" },
{ "eta", "η" },
{ "eth", "ð" },
{ "euml", "ë" },
{ "euro", "" },
{ "exist", "" },
{ "fnof", "ƒ" },
{ "forall", "" },
{ "frac12", "½" },
{ "frac14", "¼" },
{ "frac34", "¾" },
{ "frasl", "" },
{ "gamma", "γ" },
{ "ge", "" },
{ "gt", ">" },
{ "hArr", "" },
{ "harr", "" },
{ "hearts", "" },
{ "hellip", "" },
{ "iacute", "í" },
{ "icirc", "î" },
{ "iexcl", "¡" },
{ "igrave", "ì" },
{ "image", "" },
{ "infin", "" },
{ "int", "" },
{ "iota", "ι" },
{ "iquest", "¿" },
{ "isin", "" },
{ "iuml", "ï" },
{ "kappa", "κ" },
{ "lArr", "" },
{ "lambda", "λ" },
{ "lang", "" },
{ "laquo", "«" },
{ "larr", "" },
{ "lceil", "" },
{ "ldquo", "" },
{ "le", "" },
{ "lfloor", "" },
{ "lowast", "" },
{ "loz", "" },
{ "lrm", "\u200E" },
{ "lsaquo", "" },
{ "lsquo", "" },
{ "lt", "<" },
{ "macr", "¯" },
{ "mdash", "" },
{ "micro", "µ" },
{ "middot", "·" },
{ "minus", "" },
{ "mu", "μ" },
{ "nabla", "" },
{ "nbsp", "\u00A0" },
{ "ndash", "" },
{ "ne", "" },
{ "ni", "" },
{ "not", "¬" },
{ "notin", "" },
{ "nsub", "" },
{ "ntilde", "ñ" },
{ "nu", "ν" },
{ "oacute", "ó" },
{ "ocirc", "ô" },
{ "oelig", "œ" },
{ "ograve", "ò" },
{ "oline", "" },
{ "omega", "ω" },
{ "omicron", "ο" },
{ "oplus", "" },
{ "or", "" },
{ "ordf", "ª" },
{ "ordm", "º" },
{ "oslash", "ø" },
{ "otilde", "õ" },
{ "otimes", "" },
{ "ouml", "ö" },
{ "para", "" },
{ "part", "" },
{ "permil", "" },
{ "perp", "" },
{ "phi", "φ" },
{ "pi", "π" },
{ "piv", "ϖ" },
{ "plusmn", "±" },
{ "pound", "£" },
{ "prime", "" },
{ "prod", "" },
{ "prop", "" },
{ "psi", "ψ" },
{ "quot", "\"" },
{ "rArr", "" },
{ "radic", "" },
{ "rang", "" },
{ "raquo", "»" },
{ "rarr", "" },
{ "rceil", "" },
{ "rdquo", "" },
{ "real", "" },
{ "reg", "®" },
{ "rfloor", "" },
{ "rho", "ρ" },
{ "rlm", "\u200F" },
{ "rsaquo", "" },
{ "rsquo", "" },
{ "sbquo", "" },
{ "scaron", "š" },
{ "sdot", "" },
{ "sect", "§" },
{ "shy", "\u00AD" },
{ "sigma", "σ" },
{ "sigmaf", "ς" },
{ "sim", "" },
{ "spades", "" },
{ "sub", "" },
{ "sube", "" },
{ "sum", "" },
{ "sup1", "¹" },
{ "sup2", "²" },
{ "sup3", "³" },
{ "sup", "" },
{ "supe", "" },
{ "szlig", "ß" },
{ "tau", "τ" },
{ "there4", "" },
{ "theta", "θ" },
{ "thetasym", "ϑ" },
{ "thinsp", "" },
{ "thorn", "þ" },
{ "tilde", "˜" },
{ "times", "×" },
{ "trade", "" },
{ "uArr", "" },
{ "uacute", "ú" },
{ "uarr", "" },
{ "ucirc", "û" },
{ "ugrave", "ù" },
{ "uml", "¨" },
{ "upsih", "ϒ" },
{ "upsilon", "υ" },
{ "uuml", "ü" },
{ "weierp", "" },
{ "xi", "ξ" },
{ "yacute", "ý" },
{ "yen", "¥" },
{ "yuml", "ÿ" },
{ "zeta", "ζ" },
{ "zwj", "\u200D" },
{ "zwnj", "\u200C" }
};
static bool less (name_map_t const& lhs, name_map_t const& rhs)
{
return lhs.key < rhs.key;
}
static std::string convert_entity (std::string const& str)
{
name_map_t const* res = std::lower_bound(beginof(NameMap), endof(NameMap), (name_map_t){ str }, less);
return (res == endof(NameMap) || str != res->key) ? NULL_STR : res->value;
}
namespace decode
{
std::string base32 (std::string const& src)
{
std::string dst = "";
uint32_t value = 0, bits = 0;
iterate(it, src)
{
char ch = toupper(*it);
if('A' <= ch && ch <= 'Z')
value = (value << 5) | ch-'A';
else if('2' <= ch && ch <= '7')
value = (value << 5) | (('Z'-'A'+1) + ch-'2');
else
continue;
bits += 5;
for(; bits >= 8; bits -= 8)
dst.push_back((value >> (bits-8)) & 255);
}
return dst;
}
std::string base64 (std::string const& src)
{
std::string dst = "";
uint32_t value = 0, bits = 0;
iterate(it, src)
{
static char const Table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
uint32_t i = std::find(Table, Table + 64, *it) - Table;
if(i == 64)
continue;
value = (value << 6) | i;
bits += 6;
for(; bits >= 8; bits -= 8)
dst.push_back((value >> (bits-8)) & 255);
}
return dst;
}
std::string rot13 (std::string src)
{
iterate(ch, src)
{
if('A' <= *ch && *ch <= 'Z')
*ch = *ch-13 >= 'A' ? *ch-13 : *ch-13+'Z'+1-'A';
else if('a' <= *ch && *ch <= 'z')
*ch = *ch-13 >= 'a' ? *ch-13 : *ch-13+'z'+1-'a';
}
return src;
}
std::string entities (std::string const& src)
{
std::string res;
std::string::size_type i = 0;
while(true)
{
std::string::size_type from = src.find('&', i);
std::string::size_type to = src.find(';', from);
res.append(src.substr(i, from-i));
if(from == std::string::npos)
break;
if(to == std::string::npos)
{
res.append(src.substr(from));
break;
}
std::string ch = convert_entity(src.substr(from + 1, to - from - 1));
if(ch == NULL_STR)
{
res.append("&");
i = from + 1;
continue;
}
res.append(ch);
i = to + 1;
}
return res;
}
std::string url_part (std::string const& src)
{
std::string res = "";
for(size_t i = 0; i < src.size(); ++i)
{
if(src[i] == '%' && i + 2 < src.size() && isxdigit(src[i+1]) && isxdigit(src[i+2]))
{
res.append(1, strtol(src.substr(i+1, 2).c_str(), NULL, 16));
i += 2;
}
else
{
res.append(1, src[i]);
}
}
return res;
}
} /* decode */