00001
00002
00003 #ifndef AITOOLS_UTIL_SYSTEMIO_HPP
00004 #define AITOOLS_UTIL_SYSTEMIO_HPP
00005
00006 #include <limits.h>
00007 #include <cstring>
00008 #include <boost/filesystem.hpp>
00009
00010 #include "util/exception.hpp"
00011
00012 namespace bfs = boost::filesystem;
00013
00017 namespace aitools {
00018 namespace util {
00019
00020 inline void
00021 signal_error(const std::string& msg)
00022 {
00023 std::perror(msg.c_str());
00024 throw_runtime_error(msg);
00025 }
00026
00027 template <typename T>
00028 void
00029 signal_error(const std::string& msg, const T& obj)
00030 {
00031 std::perror(msg.c_str());
00032 throw_runtime_error(msg, obj);
00033 }
00034
00035 inline uint64_t
00036 directory_size(const bfs::path& dir)
00037 {
00038 uint64_t byte_size(0);
00039 const bfs::directory_iterator end;
00040 for (bfs::directory_iterator it(dir); it != end; ++it)
00041 {
00042 if (bfs::is_regular_file(it->path()))
00043 {
00044 byte_size += bfs::file_size(it->path());
00045 }
00046 else if (bfs::is_directory(it->path()))
00047 {
00048 byte_size += directory_size(it->path());
00049 }
00050 }
00051 return byte_size;
00052 }
00053
00054 inline void
00055 fclose(FILE* fs)
00056 {
00057 if (fs == NULL) return;
00058 if (std::fclose(fs) == EOF)
00059 {
00060 signal_error("std::fclose failed");
00061 }
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093 inline FILE*
00094 fopen(const bfs::path& path, const std::string& mode)
00095 {
00096 FILE* fs(std::fopen(path.string().c_str(), mode.c_str()));
00097 if (fs == NULL)
00098 {
00099 signal_error("std::fopen failed", path);
00100 }
00101 return fs;
00102 }
00103
00104 inline void
00105 fread(void* data, size_t size, size_t count, FILE* fs)
00106 {
00107 assert(fs != NULL);
00108 assert(data != NULL);
00109 if (std::fread(data, size, count, fs) != count)
00110 {
00111 signal_error("std::fread failed");
00112 }
00113 }
00114
00115 inline void
00116 fseek(FILE* fs, long offset, int origin)
00117 {
00118 assert(fs != NULL);
00119 if (std::fseek(fs, offset, origin) != 0)
00120 {
00121 signal_error("std::fseek failed");
00122 }
00123 }
00124
00125 inline void
00126 fwrite(const void* data, size_t size, size_t count, FILE* fs)
00127 {
00128 assert(fs != NULL);
00129 assert(data != NULL);
00130 if (std::fwrite(data, size, count, fs) != count)
00131 {
00132 signal_error("std::fwrite failed");
00133 }
00134 }
00135
00136 inline size_t
00137 ftell(FILE* fs)
00138 {
00139 assert(fs != NULL);
00140 const long offset(std::ftell(fs));
00141 if (offset == -1)
00142 {
00143 signal_error("std::ftell failed");
00144 }
00145 return offset;
00146 }
00147
00148 inline void
00149 rewind(FILE* fs)
00150 {
00151 if (fs == NULL) return;
00152 std::rewind(fs);
00153 }
00154
00155 inline FILE*
00156 tmpfile()
00157 {
00158 FILE* fs(std::tmpfile());
00159 if (fs == NULL)
00160 {
00161 signal_error("std::tmpfile failed");
00162 }
00163 return fs;
00164 }
00165
00166 inline const bfs::path
00167 tmpdir(const bfs::path& parent_dir)
00168 {
00169 char tmpdir[PATH_MAX];
00170 const std::string pattern("/tmp_XXXXXX");
00171 const std::string parent_str(parent_dir.string());
00172 std::strncpy(tmpdir, parent_str.c_str(), parent_str.size() + 1);
00173 std::strncat(tmpdir, pattern.c_str(), pattern.size() + 1);
00174 if (mkdtemp(tmpdir) == NULL)
00175 {
00176 signal_error("mkdtemp failed");
00177 }
00178 return tmpdir;
00179 }
00180
00181 }
00182
00183 using util::signal_error;
00184 using util::directory_size;
00185 using util::fclose;
00186 using util::fopen;
00187 using util::fread;
00188 using util::fseek;
00189 using util::fwrite;
00190 using util::ftell;
00191 using util::rewind;
00192 using util::tmpfile;
00193 using util::tmpdir;
00194
00195 }
00196
00197 #endif // AITOOLS_UTIL_SYSTEMIO_HPP