Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef CPP_URL
- #define CPP_URL
- #include<iostream>
- #include<vector>
- #include<map>
- using std::string;
- enum protocol {
- HTTP,
- HTTPS
- };
- static string map(protocol scheme) {
- switch(scheme) {
- case HTTP:
- return "http";
- default:
- return "https";
- }
- }
- static int defaultPort(protocol scheme) {
- switch (scheme) {
- case HTTP:
- return 80;
- default:
- return 440;
- }
- }
- class url final {
- private:
- using list = std::vector<std::string>;
- using pairs = std::map<std::string, std::string>;
- const list paths;
- const pairs queries;
- const protocol scheme;
- const string domain;
- const string fragment;
- const string username;
- const string password;
- mutable int port;
- public:
- class builder {
- friend url;
- private:
- protocol scheme;
- pairs queries;
- list paths;
- string domain;
- string fragment;
- string username;
- string password;
- int port = -1;
- public:
- builder& setScheme(protocol);
- builder& setFragment(const string&);
- builder& setDomain(const string&);
- builder& setUsername(const string&);
- builder& setPassword(const string&);
- builder& setPort(int port);
- builder& addQuery(const string&, const string&);
- builder& addPath(const string&);
- url& build() const;
- };
- explicit url(const url::builder&);
- string build() const;
- };
- using builder = url::builder;
- inline builder& builder::setScheme(protocol scheme) {
- this->scheme = scheme;
- return *this;
- }
- inline builder& builder::setUsername(const string& username) {
- this->username = username;
- return *this;
- }
- inline builder& builder::setPassword(const string& password) {
- this->password = password;
- return *this;
- }
- inline builder& builder::setFragment(const string& fragment) {
- this->fragment = fragment;
- return *this;
- }
- inline builder& builder::setDomain(const string& domain) {
- this->domain = domain;
- return *this;
- }
- inline builder& builder::setPort(int port) {
- this->port = port;
- return *this;
- }
- inline builder& builder::addQuery(const string& key, const string& value) {
- queries.insert(std::pair<string, string>(key, value));
- return *this;
- }
- inline builder& builder::addPath(const string& path) {
- paths.insert(paths.begin(), path);
- return *this;
- }
- inline url& builder::build() const {
- return *(new url(*this));
- }
- inline url::url(const builder& object)
- : paths(object.paths)
- , queries(object.queries)
- , scheme(object.scheme)
- , domain(object.domain)
- , fragment(object.fragment)
- , username(object.username)
- , password(object.password)
- , port(object.port)
- {}
- string url::build() const {
- string url = map(scheme).append("://");
- if (!username.empty()) {
- url.append(username);
- if (!password.empty()) {
- url.append(":").append(password);
- }
- url.append("@");
- }
- url.append(domain);
- if (port == -1)
- port = defaultPort(scheme);
- url.append(":").append(std::to_string(port));
- for (string path : paths) {
- url.append("/");
- url.append(path);
- }
- auto it = queries.begin();
- if (it != queries.end()) {
- url.append("?").append(it->first)
- .append("=").append(it->second);
- for(it++; it != queries.end(); it++) {
- url.append("&").append(it->first)
- .append("=").append(it->second);
- }
- }
- if (!fragment.empty()) {
- url.append("#").append(fragment);
- }
- return url;
- };
- #endif
- url url = url::builder()
- .setScheme(HTTPS)
- .setDomain(YOUTUBE_DOMAIN)
- .addPath(WATCH_PATH)
- .addQuery(CATEGORY, ITEM)
- .build();
- std::cout<<url.build()<<std::endl;
Add Comment
Please, Sign In to add comment