/* -*- mona-c++ -*-
*
* Copyright (c) Leipzig, Madrid 2004 - 2009
* Max-Planck-Institute for Human Cognitive and Brain Science
* Max-Planck-Institute for Evolutionary Anthropology
* BIT, ETSI Telecomunicacion, UPM
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 PUcRPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include <miaconfig.h>
#include <sstream>
#include <cstring>
#include <climits>
#include "boost/filesystem/operations.hpp" // includes boost/filesystem/path.hpp
#include "boost/filesystem/fstream.hpp" // ditto
#include <mia/core/msgstream.hh>
#include <mia/core/filetools.hh>
#ifdef WIN32
#define snprintf _snprintf
#define strdup _strdup
#endif
NS_MIA_BEGIN
using namespace std;
using namespace mia;
namespace bfs = ::boost::filesystem;
#ifndef MAX_PATH
#define MAX_PATH 4096
#endif
vector<string> get_consecutive_numbered_files_from_pattern(string const& in_filename, int start, int end)
{
char buffer[MAX_PATH];
int num = start;
vector<string> result;
snprintf(buffer, MAX_PATH, in_filename.c_str(), num);
string first_filename(buffer);
while (!bfs::exists(buffer) && num < end) {
++num;
snprintf(buffer, MAX_PATH, in_filename.c_str(), num);
// no file found
if (first_filename == string(buffer))
return result;
}
while (bfs::exists(buffer) && num < end) {
result.push_back(string(buffer));
++num;
snprintf(buffer, MAX_PATH, in_filename.c_str(), num);
// run through all possible file names
if (first_filename == string(buffer))
break;
}
return result;
}
const std::string get_filename_pattern_and_range(std::string const& in_filename, size_t& start_filenum, size_t& end_filenum, size_t& format_width)
{
string base_name;
size_t nwidth = format_width = fname_to_cformat(in_filename.c_str(), base_name, false);
if (nwidth > 0) { // probably more then one slice
size_t max_num = 1;
while (nwidth--)
max_num *= 10;
start_filenum = end_filenum = 0;
cvdebug() << "trying files of pattern " << base_name << " n=" << nwidth << "\n";
// search for the first existing file
string filename = create_filename(base_name.c_str(), start_filenum);
while (!bfs::exists(filename) && start_filenum < max_num) {
++start_filenum;
filename = create_filename(base_name.c_str(), start_filenum);
}
end_filenum = start_filenum;
while (bfs::exists(filename) && end_filenum < max_num) {
++end_filenum;
filename = create_filename(base_name.c_str(), end_filenum);
if (end_filenum == 0)
break;
}
}
return base_name;
}
vector<string> get_consecutive_numbered_files(string const& in_filename)
{
vector<string> src_names;
string base_name;
// get all possible file names
size_t nwidth = fname_to_cformat(in_filename.c_str(), base_name, false);
if (nwidth > 0) { // probably more then one slice
// check, how many consecutive files we have
int n_files = 0;
size_t start_filenum = 0;
cvdebug() << "trying files of pattern " << base_name << " n="
<< nwidth << "\n";
// search for the first existing file
string filename = create_filename(base_name.c_str(), start_filenum);
string first_filename = filename;
size_t max_num = 1;
while (nwidth--)
max_num *= 10;
while (!bfs::exists(filename) && start_filenum < max_num) {
++start_filenum;
filename = create_filename(base_name.c_str(), start_filenum);
}
while (bfs::exists(filename) && start_filenum < max_num) {
src_names.push_back(filename);
++start_filenum;
++n_files;
filename = create_filename(base_name.c_str(), start_filenum);
if (filename == src_names[0])
break;
}
cvdebug() << "Found " << n_files << " input files\n";
}else{
src_names.push_back(in_filename);
}
return src_names;
}
size_t fname_to_cformat(const char *fname, string& base, bool wildcard)
{
char *help = strdup(fname);
char *suffix = strrchr(help, '.');
if (suffix == help) {
base.assign(fname);
free(help);
return 0;
}
char *num = suffix ? suffix : help + strlen(help);
--num;
size_t nwidth = 0;
while (isdigit(*num)) {
++nwidth;
if (num == help)
break;
--num;
}
if (nwidth == 0) {
base.assign(fname);
free(help);
return 0;
}
stringstream result;
if (num != help) {
num[1] = '\0'; // cut of the tail
result << help;
}
if (wildcard) {
for (size_t i = 0; i < nwidth; ++i)
result << "?";
}else {
result << "%0" << nwidth << "d";
}
if (suffix)
result << suffix;
base = result.str();
free(help);
return nwidth;
}
void split_dir_fname(const char *in_name, std::string& dir, std::string& fname)
{
char *help = strdup(in_name);
char *filename = strrchr(help, '/');
if (filename) {
*filename = 0;
++filename;
dir.assign(help);
fname.assign(filename);
}else {
dir.assign("./");
fname.assign(help);
}
free(help);
}
// ugly
string create_filename(const char *cformat, size_t num)
{
char buf[FILENAME_MAX];
snprintf(buf, FILENAME_MAX, cformat, num);
return string(buf);
}
NS_MIA_END