Music Hub  ..
A session-wide music playback service
uri_check.h
Go to the documentation of this file.
1 /*
2  *
3  * This program is free software: you can redistribute it and/or modify it
4  * under the terms of the GNU Lesser General Public License version 3,
5  * as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU Lesser General Public License for more details.
11  *
12  * You should have received a copy of the GNU Lesser General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  * Authored by: Jim Hodapp <jim.hodapp@canonical.com>
16  *
17  */
18 
19 #ifndef URI_CHECK_H_
20 #define URI_CHECK_H_
21 
22 #include <gio/gio.h>
23 
24 #include <memory>
25 #include <iostream>
26 
27 namespace core
28 {
29 namespace ubuntu
30 {
31 namespace media
32 {
33 
34 class UriCheck
35 {
36 public:
37  typedef std::shared_ptr<UriCheck> Ptr;
38 
40  : is_encoded_(false),
41  is_local_file_(false),
42  local_file_exists_(false)
43  {
44  }
45 
46  UriCheck(const std::string& uri)
47  : uri_(uri),
48  is_encoded_(determine_if_encoded()),
49  is_local_file_(determine_if_local_file()),
50  local_file_exists_(determine_if_file_exists())
51  {
52  }
53 
54  virtual ~UriCheck()
55  {
56  }
57 
58  void set(const std::string& uri)
59  {
60  if (uri.empty())
61  return;
62 
63  uri_ = uri;
64  is_encoded_ = determine_if_encoded();
65  is_local_file_ = determine_if_local_file();
66  local_file_exists_ = determine_if_file_exists();
67  }
68 
69  void clear()
70  {
71  uri_.clear();
72  }
73 
74  bool is_encoded() const
75  {
76  return is_encoded_;
77  }
78 
79  bool is_local_file() const
80  {
81  return is_local_file_;
82  }
83 
84  bool file_exists() const
85  {
86  return local_file_exists_;
87  }
88 
89 protected:
90  UriCheck(const UriCheck&) = delete;
91  UriCheck& operator=(const UriCheck&) = delete;
92 
93 private:
94  bool determine_if_encoded()
95  {
96  if (uri_.empty())
97  return false;
98 
99  gchar *tmp = g_uri_unescape_string(uri_.c_str(), nullptr);
100  if (!tmp)
101  return false;
102 
103  const std::string unescaped_uri{tmp};
104  g_free(tmp);
105  return unescaped_uri.length() < uri_.length();
106  }
107 
108  bool determine_if_local_file()
109  {
110  if (uri_.empty())
111  return false;
112 
113  gchar *tmp = g_uri_parse_scheme(uri_.c_str());
114  std::string uri_scheme;
115  if (tmp)
116  uri_scheme.assign(tmp);
117  g_free(tmp);
118  try {
119  return uri_.at(0) == '/' or
120  (uri_.at(0) == '.' and uri_.at(1) == '/') or
121  uri_scheme == "file";
122  }
123  catch (const std::out_of_range &e) {
124  std::cerr << "Invalid URI string provided: " << uri_ << std::endl;
125  return false;
126  }
127  }
128 
129  bool determine_if_file_exists()
130  {
131  if (!is_local_file_)
132  return false;
133 
134  GError *error = nullptr;
135  // Open the URI and get the mime type from it. This will currently only work for
136  // a local file
137  std::unique_ptr<GFile, void(*)(void *)> file(
138  g_file_new_for_uri(uri_.c_str()), g_object_unref);
139  std::unique_ptr<GFileInfo, void(*)(void *)> info(
140  g_file_query_info(
141  file.get(), G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE ","
142  G_FILE_ATTRIBUTE_ETAG_VALUE, G_FILE_QUERY_INFO_NONE,
143  /* cancellable */ NULL, &error),
144  g_object_unref);
145 
146  return info.get() != nullptr;
147  }
148 
149 private:
150  std::string uri_;
151  bool is_encoded_;
152  bool is_local_file_;
153  bool local_file_exists_;
154 };
155 
156 }
157 }
158 }
159 
160 #endif // URI_CHECK_H_
Definition: player.h:33
UriCheck(const std::string &uri)
Definition: uri_check.h:46
std::shared_ptr< UriCheck > Ptr
Definition: uri_check.h:37
UriCheck & operator=(const UriCheck &)=delete