2 * Copyright (C) 2008-2009 Patrick Ohly <patrick.ohly@gmx.de>
3 * Copyright (C) 2009 Intel Corporation
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) version 3.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 #ifndef INCL_SYNCEVOLUTION_UTIL
22 # define INCL_SYNCEVOLUTION_UTIL
24 #include <syncevo/SyncML.h>
26 #include <boost/algorithm/string/case_conv.hpp>
27 #include <boost/algorithm/string/predicate.hpp>
28 #include <boost/function.hpp>
39 #include <syncevo/declarations.h>
45 /** case-insensitive less than for assoziative containers */
46 template <class T> class Nocase : public std::binary_function<T, T, bool> {
48 bool operator()(const T &x, const T &y) const { return boost::ilexicographical_compare(x, y); }
51 /** case-insensitive equals */
52 template <class T> class Iequals : public std::binary_function<T, T, bool> {
54 bool operator()(const T &x, const T &y) const { return boost::iequals(x, y); }
57 /** shorthand, primarily useful for BOOST_FOREACH macro */
58 typedef pair<string, string> StringPair;
59 typedef map<string, string> StringMap;
62 * remove multiple slashes in a row and dots directly after a slash if not followed by filename,
65 string normalizePath(const string &path);
68 * convert relative path to canonicalized absolute path
69 * @param path will be turned into absolute path if possible, otherwise left unchanged
70 * @return true if conversion is successful, false otherwise(errno will be set)
72 bool relToAbs(string &path);
74 /** ensure that m_path is writable, otherwise throw error */
75 void mkdir_p(const string &path);
77 inline bool rm_r_all(const string &path, bool isDir) { return true; }
80 * remove a complete directory hierarchy; invoking on non-existant directory is okay
81 * @param path relative or absolute path to be removed
82 * @param filter an optional callback which determines whether an entry really is
83 * to be deleted (return true in that case); called with full path
84 * to entry and true if known to be a directory
86 void rm_r(const string &path, boost::function<bool (const string &,
87 bool)> filter = rm_r_all);
90 * copy complete directory hierarchy
92 * If the source is a directory, then the target
93 * also has to be a directory name. It will be
94 * created if necessary.
96 * Alternatively, both names may refer to files.
97 * In that case the directory which is going to
98 * contain the target file must exist.
100 * @param from source directory or file
101 * @param to target directory or file (must have same type as from)
103 void cp_r(const string &from, const string &to);
105 /** true if the path refers to a directory */
106 bool isDir(const string &path);
109 * try to read a file into the given string, throw exception if fails
111 * @param filename absolute or relative file name
112 * @retval content filled with file content
113 * @return true if file could be read
115 bool ReadFile(const string &filename, string &content);
118 EXECUTE_NO_STDERR = 1<<0, /**< suppress stderr of command */
119 EXECUTE_NO_STDOUT = 1<<1 /**< suppress stdout of command */
123 * system() replacement
125 * If called without output redirection active (see LogRedirect),
126 * then it will simply call system(). If output redirection is
127 * active, the command is executed in a forked process without
128 * blocking the parent process and the parent reads the output,
129 * passing it through LogRedirect for processing.
131 * This is necessary to capture all output reliably: LogRedirect
132 * ensures that we don't deadlock, but to achieve that, it drops
133 * data when the child prints too much of it.
135 * @param cmd command including parameters, without output redirection
136 * @param flags see ExecuteFlags
137 * @return same as in system(): use WEXITSTATUS() et.al. to decode it
139 int Execute(const std::string &cmd, ExecuteFlags flags) throw();
142 * Simple string hash function, derived from Dan Bernstein's algorithm.
144 unsigned long Hash(const char *str);
145 unsigned long Hash(const std::string &str);
148 * SHA-256 implementation, returning hash as lowercase hex string (like sha256sum).
149 * Might not be available, in which case it raises an exception.
151 std::string SHA_256(const std::string &in);
154 * This is a simplified implementation of a class representing and calculating
155 * UUIDs v4 inspired from RFC 4122. We do not use cryptographic pseudo-random
156 * numbers, instead we rely on rand/srand.
158 * We initialize the random generation with the system time given by time(), but
161 * Instantiating this class will generate a new unique UUID, available afterwards
162 * in the base string class.
164 class UUID : public string {
170 * A C++ wrapper around readir() which provides the names of all
171 * directory entries, excluding . and ..
176 ReadDir(const string &path, bool throwError = true);
178 typedef vector<string>::const_iterator const_iterator;
179 typedef vector<string>::iterator iterator;
180 iterator begin() { return m_entries.begin(); }
181 iterator end() { return m_entries.end(); }
182 const_iterator begin() const { return m_entries.begin(); }
183 const_iterator end() const { return m_entries.end(); }
186 * check whether directory contains entry, returns full path
187 * @param caseInsensitive ignore case, pick first entry which matches randomly
189 string find(const string &entry, bool caseSensitive);
193 vector<string> m_entries;
197 * Using this macro ensures that tests, even if defined in
198 * object files which are not normally linked into the test
199 * binary, are included in the test suite under the group
205 #ifdef ENABLE_UNIT_TESTS
207 class Foo : public CppUnit::TestFixture {
208 CPPUNIT_TEST_SUITE(foo);
209 CPPUNIT_TEST(testBar);
210 CPPUNIT_TEST_SUITE_END();
215 # SYNCEVOLUTION_TEST_SUITE_REGISTRATION(classname)
219 #define SYNCEVOLUTION_TEST_SUITE_REGISTRATION( ATestFixtureType ) \
220 CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( ATestFixtureType, "SyncEvolution" ); \
221 extern "C" { int funambolAutoRegisterRegistry ## ATestFixtureType = 12345; }
223 std::string StringPrintf(const char *format, ...)
225 __attribute__((format(printf, 1, 2)))
228 std::string StringPrintfV(const char *format, va_list ap);
231 * an exception which records the source file and line
232 * where it was thrown
234 * @TODO add function name
236 class Exception : public std::runtime_error
239 Exception(const std::string &file,
241 const std::string &what) :
242 std::runtime_error(what),
246 ~Exception() throw() {}
247 const std::string m_file;
251 * Convenience function, to be called inside a catch(..) block.
253 * Rethrows the exception to determine what it is, then logs it as
254 * an error. Turns certain known exceptions into the corresponding
255 * status code if status still was STATUS_OK when called.
256 * Returns updated status code.
258 * @param logger the class which does the logging
260 static SyncMLStatus handle(SyncMLStatus *status = NULL, Logger *logger = NULL);
261 static SyncMLStatus handle(Logger *logger) { return handle(NULL, logger); }
265 * StatusException by wrapping a SyncML status
267 class StatusException : public Exception
270 StatusException(const std::string &file,
272 const std::string &what,
274 : Exception(file, line, what), m_status(status)
277 SyncMLStatus syncMLStatus() const { return m_status; }
279 SyncMLStatus m_status;
283 * replace ${} with environment variables, with
284 * XDG_DATA_HOME, XDG_CACHE_HOME and XDG_CONFIG_HOME having their normal
287 std::string SubstEnvironment(const std::string &str);
289 inline string getHome() {
290 const char *homestr = getenv("HOME");
291 return homestr ? homestr : ".";
295 * Parse a separator splitted set of strings src, the separator itself is
296 * escaped by a backslash. Spaces around the separator is also stripped.
298 std::vector<std::string> unescapeJoinedString (const std::string &src, char separator);
301 * Temporarily set env variable, restore old value on destruction.
302 * Useful for unit tests which depend on the environment.
304 class ScopedEnvChange
307 ScopedEnvChange(const string &var, const string &value);
310 string m_var, m_oldval;
314 std::string getCurrentTime();
316 /** throw a normal SyncEvolution Exception, including source information */
317 #define SE_THROW(_what) \
318 SE_THROW_EXCEPTION(Exception, _what)
320 /** throw a class which accepts file, line, what parameters */
321 #define SE_THROW_EXCEPTION(_class, _what) \
322 throw _class(__FILE__, __LINE__, _what)
324 /** throw a class which accepts file, line, what parameters and status parameters*/
325 #define SE_THROW_EXCEPTION_STATUS(_class, _what, _status) \
326 throw _class(__FILE__, __LINE__, _what, _status)
329 #endif // INCL_SYNCEVOLUTION_UTIL