~ubuntu-branches/ubuntu/saucy/kopete/saucy-proposed

« back to all changes in this revision

Viewing changes to protocols/jabber/googletalk/libjingle/talk/base/pathutils.cc

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-06-21 02:22:39 UTC
  • Revision ID: package-import@ubuntu.com-20130621022239-63l3zc8p0nf26pt6
Tags: upstream-4.10.80
ImportĀ upstreamĀ versionĀ 4.10.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * libjingle
 
3
 * Copyright 2004--2005, Google Inc.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions are met:
 
7
 *
 
8
 *  1. Redistributions of source code must retain the above copyright notice,
 
9
 *     this list of conditions and the following disclaimer.
 
10
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 
11
 *     this list of conditions and the following disclaimer in the documentation
 
12
 *     and/or other materials provided with the distribution.
 
13
 *  3. The name of the author may not be used to endorse or promote products
 
14
 *     derived from this software without specific prior written permission.
 
15
 *
 
16
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 
17
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 
18
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 
19
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 
20
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 
21
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 
22
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 
23
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 
24
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 
25
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
26
 */
 
27
 
 
28
#ifdef WIN32
 
29
#include "talk/base/win32.h"
 
30
#include <shellapi.h>
 
31
#include <shlobj.h>
 
32
#include <tchar.h>
 
33
#endif  // WIN32
 
34
 
 
35
#include "talk/base/common.h"
 
36
#include "talk/base/fileutils.h"
 
37
#include "talk/base/logging.h"
 
38
#include "talk/base/pathutils.h"
 
39
#include "talk/base/stringutils.h"
 
40
#include "talk/base/urlencode.h"
 
41
 
 
42
namespace talk_base {
 
43
 
 
44
static const char EMPTY_STR[] = "";
 
45
 
 
46
// EXT_DELIM separates a file basename from extension
 
47
const char EXT_DELIM = '.';
 
48
 
 
49
// FOLDER_DELIMS separate folder segments and the filename
 
50
const char* const FOLDER_DELIMS = "/\\";
 
51
 
 
52
// DEFAULT_FOLDER_DELIM is the preferred delimiter for this platform
 
53
#if WIN32
 
54
const char DEFAULT_FOLDER_DELIM = '\\';
 
55
#else  // !WIN32
 
56
const char DEFAULT_FOLDER_DELIM = '/';
 
57
#endif  // !WIN32
 
58
 
 
59
///////////////////////////////////////////////////////////////////////////////
 
60
// Pathname - parsing of pathnames into components, and vice versa
 
61
///////////////////////////////////////////////////////////////////////////////
 
62
 
 
63
bool Pathname::IsFolderDelimiter(char ch) {
 
64
  return (NULL != ::strchr(FOLDER_DELIMS, ch));
 
65
}
 
66
 
 
67
char Pathname::DefaultFolderDelimiter() {
 
68
  return DEFAULT_FOLDER_DELIM;
 
69
}
 
70
 
 
71
Pathname::Pathname()
 
72
    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
 
73
}
 
74
 
 
75
Pathname::Pathname(const std::string& pathname)
 
76
    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
 
77
  SetPathname(pathname);
 
78
}
 
79
 
 
80
Pathname::Pathname(const std::string& folder, const std::string& filename)
 
81
    : folder_delimiter_(DEFAULT_FOLDER_DELIM) {
 
82
  SetPathname(folder, filename);
 
83
}
 
84
 
 
85
void Pathname::SetFolderDelimiter(char delimiter) {
 
86
  ASSERT(IsFolderDelimiter(delimiter));
 
87
  folder_delimiter_ = delimiter;
 
88
}
 
89
 
 
90
void Pathname::Normalize() {
 
91
  for (size_t i=0; i<folder_.length(); ++i) {
 
92
    if (IsFolderDelimiter(folder_[i])) {
 
93
      folder_[i] = folder_delimiter_;
 
94
    }
 
95
  }
 
96
}
 
97
 
 
98
void Pathname::clear() {
 
99
  folder_.clear();
 
100
  basename_.clear();
 
101
  extension_.clear();
 
102
}
 
103
 
 
104
bool Pathname::empty() const {
 
105
  return folder_.empty() && basename_.empty() && extension_.empty();
 
106
}
 
107
 
 
108
std::string Pathname::pathname() const {
 
109
  std::string pathname(folder_);
 
110
  pathname.append(basename_);
 
111
  pathname.append(extension_);
 
112
  if (pathname.empty()) {
 
113
    // Instead of the empty pathname, return the current working directory.
 
114
    pathname.push_back('.');
 
115
    pathname.push_back(folder_delimiter_);
 
116
  }
 
117
  return pathname;
 
118
}
 
119
 
 
120
std::string Pathname::url() const {
 
121
  std::string s = "file:///";
 
122
  for (size_t i=0; i<folder_.length(); ++i) {
 
123
    if (IsFolderDelimiter(folder_[i]))
 
124
      s += '/';
 
125
    else
 
126
      s += folder_[i];
 
127
  }
 
128
  s += basename_;
 
129
  s += extension_;
 
130
  return UrlEncodeStringForOnlyUnsafeChars(s);
 
131
}
 
132
 
 
133
void Pathname::SetPathname(const std::string& pathname) {
 
134
  std::string::size_type pos = pathname.find_last_of(FOLDER_DELIMS);
 
135
  if (pos != std::string::npos) {
 
136
    SetFolder(pathname.substr(0, pos + 1));
 
137
    SetFilename(pathname.substr(pos + 1));
 
138
  } else {
 
139
    SetFolder(EMPTY_STR);
 
140
    SetFilename(pathname);
 
141
  }
 
142
}
 
143
 
 
144
void Pathname::SetPathname(const std::string& folder,
 
145
                           const std::string& filename) {
 
146
  SetFolder(folder);
 
147
  SetFilename(filename);
 
148
}
 
149
 
 
150
void Pathname::AppendPathname(const std::string& pathname) {
 
151
  std::string full_pathname(folder_);
 
152
  full_pathname.append(pathname);
 
153
  SetPathname(full_pathname);
 
154
}
 
155
 
 
156
std::string Pathname::folder() const {
 
157
  return folder_;
 
158
}
 
159
 
 
160
std::string Pathname::folder_name() const {
 
161
  std::string::size_type pos = std::string::npos;
 
162
  if (folder_.size() >= 2) {
 
163
    pos = folder_.find_last_of(FOLDER_DELIMS, folder_.length() - 2);
 
164
  }
 
165
  if (pos != std::string::npos) {
 
166
    return folder_.substr(pos + 1);
 
167
  } else {
 
168
    return folder_;
 
169
  }
 
170
}
 
171
 
 
172
std::string Pathname::parent_folder() const {
 
173
  std::string::size_type pos = std::string::npos;
 
174
  if (folder_.size() >= 2) {
 
175
    pos = folder_.find_last_of(FOLDER_DELIMS, folder_.length() - 2);
 
176
  }
 
177
  if (pos != std::string::npos) {
 
178
    return folder_.substr(0, pos + 1);
 
179
  } else {
 
180
    return EMPTY_STR;
 
181
  }
 
182
}
 
183
 
 
184
void Pathname::SetFolder(const std::string& folder) {
 
185
  folder_.assign(folder);
 
186
  // Ensure folder ends in a path delimiter
 
187
  if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) {
 
188
    folder_.push_back(folder_delimiter_);
 
189
  }
 
190
}
 
191
 
 
192
void Pathname::AppendFolder(const std::string& folder) {
 
193
  folder_.append(folder);
 
194
  // Ensure folder ends in a path delimiter
 
195
  if (!folder_.empty() && !IsFolderDelimiter(folder_[folder_.length()-1])) {
 
196
    folder_.push_back(folder_delimiter_);
 
197
  }
 
198
}
 
199
 
 
200
std::string Pathname::basename() const {
 
201
  return basename_;
 
202
}
 
203
 
 
204
bool Pathname::SetBasename(const std::string& basename) {
 
205
  if(basename.find_first_of(FOLDER_DELIMS) != std::string::npos) {
 
206
    return false;
 
207
  }
 
208
  basename_.assign(basename);
 
209
  return true;
 
210
}
 
211
 
 
212
std::string Pathname::extension() const {
 
213
  return extension_;
 
214
}
 
215
 
 
216
bool Pathname::SetExtension(const std::string& extension) {
 
217
  if (extension.find_first_of(FOLDER_DELIMS) != std::string::npos ||
 
218
    extension.find_first_of(EXT_DELIM, 1) != std::string::npos) {
 
219
      return false;
 
220
  }
 
221
  extension_.assign(extension);
 
222
  // Ensure extension begins with the extension delimiter
 
223
  if (!extension_.empty() && (extension_[0] != EXT_DELIM)) {
 
224
    extension_.insert(extension_.begin(), EXT_DELIM);
 
225
  }
 
226
  return true;
 
227
}
 
228
 
 
229
std::string Pathname::filename() const {
 
230
  std::string filename(basename_);
 
231
  filename.append(extension_);
 
232
  return filename;
 
233
}
 
234
 
 
235
bool Pathname::SetFilename(const std::string& filename) {
 
236
  std::string::size_type pos = filename.rfind(EXT_DELIM);
 
237
  if ((pos == std::string::npos) || (pos == 0)) {
 
238
    return SetExtension(EMPTY_STR) && SetBasename(filename);
 
239
  } else {
 
240
    return SetExtension(filename.substr(pos)) && SetBasename(filename.substr(0, pos));
 
241
  }
 
242
}
 
243
 
 
244
#ifdef WIN32
 
245
bool Pathname::GetDrive(char *drive, uint32 bytes) const {
 
246
  return GetDrive(drive, bytes, folder_);
 
247
}
 
248
 
 
249
// static
 
250
bool Pathname::GetDrive(char *drive, uint32 bytes,
 
251
                        const std::string& pathname) {
 
252
  // need at lease 4 bytes to save c:
 
253
  if (bytes < 4 || pathname.size() < 3) {
 
254
    return false;
 
255
  }
 
256
 
 
257
  memcpy(drive, pathname.c_str(), 3);
 
258
  drive[3] = 0;
 
259
  // sanity checking
 
260
  return (isalpha(drive[0]) &&
 
261
          drive[1] == ':' &&
 
262
          drive[2] == '\\');
 
263
}
 
264
#endif
 
265
 
 
266
///////////////////////////////////////////////////////////////////////////////
 
267
 
 
268
} // namespace talk_base