2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @file folder_size.cpp
19 * @author Jaroslaw Osmanski (j.osmanski@samsung.com)
21 * @brief Implementation for function calculating directory size
25 #include <sys/types.h>
32 #include <dpl/log/wrt_log.h>
33 #include <dpl/foreach.h>
34 #include <dpl/utils/folder_size.h>
37 size_t getFolderSize(const std::string& path)
40 char errbuf[512] = {0,};
44 char * const paths[] = { const_cast<char * const>(path.c_str()), NULL };
46 if ((fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR, NULL)) == NULL) {
51 errstr = strerror_r(error, errbuf, sizeof(errbuf));
53 strerror_r(error, errbuf, sizeof(errbuf));
56 WrtLogW("%s: fts_open failed with error: %s",
57 __PRETTY_FUNCTION__, errstr);
61 while ((ftsent = fts_read(fts)) != NULL) {
62 switch (ftsent->fts_info) {
65 //directory in postorder and directory causing a loop
73 //regular files and other objects that can be counted
74 size += ftsent->fts_statp->st_size;
82 errstr = strerror_r(ftsent->fts_errno, errbuf, sizeof(errbuf));
84 strerror_r(ftsent->fts_errno, errbuf, sizeof(errbuf));
87 WrtLogW("%s: traversal failed on file: %s with error: %s",
88 __PRETTY_FUNCTION__, ftsent->fts_path,
94 if (fts_close(fts) == -1) {
97 errstr = strerror_r(error, errbuf, sizeof(errbuf));
99 strerror_r(error, errbuf, sizeof(errbuf));
102 WrtLogW("%s: fts_close failed with error: %s",
103 __PRETTY_FUNCTION__, errstr);
111 #define DECLARE_PREFIX_STRUCT(name) \
112 struct Prefix##name \
114 static std::string get() \
116 return std::string(#name); \
120 DECLARE_PREFIX_STRUCT(B)
121 DECLARE_PREFIX_STRUCT(KB)
122 DECLARE_PREFIX_STRUCT(MB)
123 DECLARE_PREFIX_STRUCT(GB)
125 #undef DECLARE_PREFIX_STRUCT
127 const int stepSize = 1024;
128 template<typename ... Rest>
131 template<typename Postfix, typename ... Rest>
132 struct Pre<Postfix, Rest ...>
134 static const double value;
135 static std::string printSize(double fileSize)
137 if (fileSize >= Pre<Rest ...>::value) {
138 double now = fileSize / Pre<Rest ...>::value;
139 std::ostringstream outputStream;
140 outputStream.setf(std::ios::fixed, std::ios::floatfield);
141 outputStream.precision(2);
142 outputStream << now << Postfix::get();
143 return outputStream.str();
145 return Pre<Rest ...>::printSize(fileSize);
153 static const double value;
154 static std::string printSize(double /*fileSize*/)
160 const double Pre<>::value = 1.0;
161 template<typename Postfix, typename ... Params> const double Pre<Postfix,
163 value(Pre<>::value * stepSize);
165 typedef Pre<PrefixGB, PrefixMB, PrefixKB, PrefixB> FolderSizeToStringType;
166 } //anonymous namespace
168 DPL::String fromFileSizeString(size_t fileSize)
171 FolderSizeToStringType::printSize(static_cast<double>(fileSize));
172 return DPL::FromUTF8String(output);
174 } // end of namespace Utils