// file : web/mime-url-encoding.cxx -*- C++ -*- // copyright : Copyright (c) 2014-2015 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #include #include // hex, uppercase, right #include #include // setw(), setfill () #include #include #include // size_t, strspn() #include // invalid_argument using namespace std; namespace web { // Encode characters different from unreserved ones specified in // "2.3. Unreserved Characters" of http://tools.ietf.org/html/rfc3986. // void mime_url_encode (const char* v, ostream& o) { char f (o.fill ()); ostream::fmtflags g (o.flags ()); o << hex << uppercase << right << setfill ('0'); char c; while ((c = *v++) != '\0') { if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) { o << c; } else { switch (c) { case ' ': o << '+'; break; case '.': case '_': case '-': case '~': o << c; break; default: { o << "%" << setw (2) << static_cast (c); break; } } } } o.flags (g); o.fill (f); } string mime_url_encode (const char* v) { stringstream o; mime_url_encode (v, o); return o.str (); } string mime_url_encode (const string& v) { return mime_url_encode (v.c_str ()); } string mime_url_decode (const char* b, const char* e, bool trim) { if (trim) { b += strspn (b, " "); if (b >= e) return string (); while (*--e == ' '); ++e; } string value; value.reserve (e - b); char bf[3]; bf[2] = '\0'; while (b != e) { char c (*b++); switch (c) { case '+': { value.append (" "); break; } case '%': { if (*b == '\0' || b[1] == '\0') { throw invalid_argument ("::web::mime_url_decode short"); } *bf = *b; bf[1] = b[1]; char* ebf (nullptr); size_t vl (strtoul (bf, &ebf, 16)); if (*ebf != '\0') { throw invalid_argument ("::web::mime_url_decode wrong"); } value.append (1, static_cast (vl)); b += 2; break; } default: { value.append (1, c); break; } } } return value; } }