uri.h 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #ifndef COMMON_HDFS_URI_H_
  19. #define COMMON_HDFS_URI_H_
  20. #include <iostream>
  21. #include <string>
  22. #include <optional.hpp>
  23. #include <vector>
  24. namespace hdfs
  25. {
  26. template <class T>
  27. using optional = std::experimental::optional<T>;
  28. class URI
  29. {
  30. // These are stored in encoded form
  31. std::string scheme;
  32. std::string user;
  33. std::string pass;
  34. std::string host;
  35. optional<uint16_t> port;
  36. std::vector<std::string> path;
  37. std::vector<std::pair<std::string,std::string> > query;
  38. std::string fragment;
  39. template <class T>
  40. static T from_encoded(bool encoded_output, const T & input) {return encoded_output ? input : decode(input);}
  41. template <class T>
  42. static T to_encoded(bool encoded_input, const T & input) {return encoded_input ? input : encode(input);}
  43. bool has_authority() const;
  44. std::string build_authority(bool encoded_output) const;
  45. std::string build_path(bool encoded_output) const;
  46. void parse_path(bool input_encoded, const std::string &input_path);
  47. public:
  48. // Parse a string into a URI. Returns nullopt if the URI is malformed.
  49. static optional<URI> parse_from_string(const std::string &str);
  50. static std::string encode (const std::string &input);
  51. static std::string decode (const std::string &input);
  52. std::string get_scheme(bool encoded_output=false) const
  53. { return from_encoded(encoded_output,scheme); }
  54. void set_scheme(const std::string &s, bool encoded_input=false)
  55. { scheme = to_encoded(encoded_input,s); }
  56. // empty if none.
  57. std::string get_host(bool encoded_output=false) const
  58. { return from_encoded(encoded_output,host); }
  59. void set_host(const std::string& h, bool encoded_input=false)
  60. { host = to_encoded(encoded_input,h); }
  61. // -1 if the port is undefined.
  62. optional<uint16_t> get_port() const
  63. { return port; }
  64. void set_port(uint16_t p)
  65. { port = p; }
  66. void clear_port()
  67. { port = std::experimental::nullopt; }
  68. std::string get_path(bool encoded_output=false) const;
  69. std::vector<std::string> get_path_elements(bool encoded_output=false) const;
  70. void set_path(const std::string &p, bool encoded_input=false) {
  71. parse_path(encoded_input, p);
  72. }
  73. void add_path(const std::string &p, bool encoded_input=false);
  74. std::string get_query(bool encoded_output=false) const;
  75. std::vector< std::pair<std::string, std::string> > get_query_elements(bool encoded_output=false) const;
  76. // Not that set_query must always pass in encoded strings
  77. void set_query(const std::string &q);
  78. // Adds a parameter onto the query; does not check if it already exists
  79. // e.g. parseFromString("foo?bar=baz").addQuery("bing","bang")
  80. // would leave "bar=baz&bing=bang" as the query
  81. void add_query(const std::string &name, const std::string & value, bool encoded_input=false);
  82. // Removes the query part if exists
  83. // e.g. parseFromString("foo?bar=baz&bing=bang&bar=bong").removeQueries("bar")
  84. // would leave bing=bang as the query
  85. void remove_queries(const std::string &q_name, bool encoded_input=false);
  86. std::string get_fragment(bool encoded_output=false) const
  87. { return from_encoded(encoded_output, fragment); }
  88. void set_fragment(const std::string &f, bool encoded_input=false)
  89. { fragment = to_encoded(encoded_input,f); }
  90. std::string str(bool encoded_output=true) const;
  91. // Get a string with each URI field printed on a seperate line
  92. std::string GetDebugString() const;
  93. };
  94. inline std::ostream& operator<<(std::ostream &out, const URI &uri)
  95. { return out << uri.str(); }
  96. }
  97. #endif