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
26 #include <sys/types.h>
32 #include <dpl/log/log.h>
33 #include <dpl/foreach.h>
34 #include <folder_size.h>
39 size_t getObjectSize(const std::string& path)
43 if (stat(path.c_str(), &tmp) == -1) {
44 LogError("Failed to open file" << path);
47 //it is not a file nor a directory
49 if (!S_ISDIR(tmp.st_mode) && !S_ISREG(tmp.st_mode)) {
50 LogWarning("Not a regular file nor a directory: " << path);
57 size_t getFolderSize(const std::string& path)
62 std::vector<std::string> localDirs;
63 if ((dir=opendir(path.c_str())) == NULL) {
64 LogError("Cannot open dir " << path);
68 while ((el = readdir(dir)) != 0) {
69 if (strcmp(el->d_name, ".") == 0 || strcmp(el->d_name, "..") == 0) {
73 std::string local = path + el->d_name;
74 if (stat(local.c_str(), &tmp) == -1) {
75 LogError("Failed to open file " << local);
76 char* errstring = strerror(errno);
77 LogError("Reason: " << errstring);
81 size += getObjectSize(local);
82 if (S_ISDIR(tmp.st_mode)) {
83 localDirs.push_back(local + "/");
89 FOREACH (localDir, localDirs) {
90 size += getFolderSize(*localDir);
101 #define DECLARE_PREFIX_STRUCT(name) \
102 struct Prefix##name \
104 static std::string get() \
106 return std::string(#name); \
110 DECLARE_PREFIX_STRUCT(B)
111 DECLARE_PREFIX_STRUCT(KB)
112 DECLARE_PREFIX_STRUCT(MB)
113 DECLARE_PREFIX_STRUCT(GB)
115 #undef DECLARE_PREFIX_STRUCT
118 const int stepSize = 1024;
119 template<typename... Rest>
122 template<typename Postfix, typename... Rest>
123 struct Pre<Postfix, Rest...>
125 static const double value = Pre<Rest...>::value * stepSize;
126 static std::string printSize(double fileSize)
128 if(fileSize >= Pre<Rest...>::value) {
129 double now = fileSize / Pre<Rest...>::value;
130 std::ostringstream outputStream;
131 outputStream.setf(std::ios::fixed, std::ios::floatfield);
132 outputStream.precision(2);
133 outputStream << now << Postfix::get();
134 return outputStream.str();
136 return Pre<Rest...>::printSize(fileSize);
145 static const double value;
146 static std::string printSize(double /*fileSize*/)
152 const double Pre<>::value = 1.0;
154 typedef Pre<PrefixGB, PrefixMB, PrefixKB, PrefixB> FolderSizeToStringType;
155 } //anonymous namespace
158 DPL::String fromFileSizeString(size_t fileSize)
162 FolderSizeToStringType::printSize(static_cast<double>(fileSize));
163 return DPL::FromUTF8String(output);
166 } // end of namespace Utils