// ---------------------------------------------------------------------
// $Id: DiskUsage.h 214 2008-07-30 09:56:16Z daaugusto $
//
//   DiskUsage.h (created on Tue Aug 23 01:08:35 BRT 2005)
// 
//   Genetic Algorithm File Fitter (gaffitter)
//
//   Copyright (C) 2005-2008 Douglas A. Augusto
// 
// This file is part of gaffitter.
// 
// gaffitter is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 3 of the License, or (at
// your option) any later version.
// 
// gaffitter is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with gaffitter; if not, see <http://www.gnu.org/licenses/>.
//
// ---------------------------------------------------------------------

#ifndef disk_usage_hh
#define disk_usage_hh

#include "Params.h"

//----------------------------------------------------------------------
/** \class DiskUsage
 *
 * Provides a method to extract sizes of a given file or directory
 * (recursively). 
 *
 * This class uses POSIX functions (lstat, chdir, opendir, closedir,
 * S_ISDIR) and POSIX structures (stat, dirent). So, this class
 * requires a POSIX-compatible environment to work.
 */
class DiskUsage {
public:
  /**
   * Returns the size of the given file or directory.
   *
   * If the given file/directory could not be read then GetSize returns
   * "0". Note: 0-sized files returns \ref m_block_size.
   */
  static Params::UBigInt GetSize(const char*);
  /**
   * Set the block size used by \ref AllocationSize(Params::UBigInt).
   */
  static void SetBlockSize(unsigned bs) { m_block_size = bs; }
  /**
   * This function returns the real size (allocated) of a given "size".
   *
   * When size=0 then it occupies exactly \ref m_block_size.
   */
  static Params::UBigInt AllocationSize(Params::UBigInt);
  /**
   * Same as \ref AllocationSize(Params::UBigInt) but casts the given
   * size to UBigInt datatype. */
  static Params::Size_t  AllocationSize(Params::Size_t size)
  {
     // instead of doing a cast to long long int (UBigInt), it is
     // possible to use a floor, ceil or "round" function.
     return AllocationSize(static_cast<Params::UBigInt>(size));
  }

private:
  /**
   * This function travels a given directory recursively.
   *
   * \return Total size of the given directory.
   */
  static Params::UBigInt DepthFirstTraversal(const char*);

private:
  /**
   * The smallest amount of bytes a file/directory can occupy.
   */
  static unsigned m_block_size;
  /**
   * Maximum size of a path name. This variable is used by the getcwd
   * function.
   */
  static const int m_max_path_name = 4096;
};
  
//----------------------------------------------------------------------
#endif
