Skip to content

Commit

Permalink
add file types
Browse files Browse the repository at this point in the history
git-svn-id: https://projectname.googlecode.com/svn/trunk@6 c416075f-80b4-e980-4839-00ea3ed24e77
  • Loading branch information
valery.isaev@gmail.com committed Mar 16, 2011
1 parent ec42fe6 commit 26178ed
Show file tree
Hide file tree
Showing 19 changed files with 366 additions and 88 deletions.
7 changes: 5 additions & 2 deletions trunk/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ LIBS = boost_program_options boost_filesystem boost_system
CFLAGS = -O2 -Wall -pedantic
PROJECT_NAME = pn
SRC_DIR = src
SRCS = $(wildcard $(SRC_DIR)/*.cpp)
SRCS = $(wildcard $(SRC_DIR)/*.cpp $(SRC_DIR)/*/*.cpp)
OBJS = $(patsubst $(SRC_DIR)/%.cpp,%.o,$(SRCS))

builds = debug release
Expand All @@ -19,6 +19,9 @@ clean:
-include $(patsubst $(SRC_DIR)/%.cpp,.depend/%.dep,$(SRCS))

$(addsuffix /%.o,$(builds)): $(SRC_DIR)/%.cpp
g++ $< -c -o $@ $(CFLAGS) $($(D@)_flags) -MMD -MT $@ -MF .depend/$*.dep
g++ $< -c -o $@ $(CFLAGS) $($(@D)_flags) -MMD -MT $@ -MF .depend/$*.dep
$(addsuffix /$(PROJECT_NAME),$(builds)): %$(PROJECT_NAME): $(addprefix %,$(OBJS))
g++ $^ -o $@ $(addprefix -l,$(LIBS))

%:
$(info target $@ not found)
10 changes: 10 additions & 0 deletions trunk/src/clusterization.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
#ifndef _CLUSTERIZATION_H_
#define _CLUSTERIZATION_H_

#include "kleisli.h"

template<typename T>
class clusterization: public arr<T, T> {
public:
void next(const T& t) {
(*this)(t);
}
};

#endif
2 changes: 2 additions & 0 deletions trunk/src/comparator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include "comparator.h"

/*
void comparator::next(const typed_file& filename1, const typed_file& filename2) {
if (fs::file_size(filename1.path()) != fs::file_size(filename2.path())) {
return;
Expand Down Expand Up @@ -37,3 +38,4 @@ std::ostream& operator<<(std::ostream& o, const compare_result& r) {
o << "files " << r.file1() << " and " << r.file2() << " are equal";
return o;
}
*/
2 changes: 2 additions & 0 deletions trunk/src/comparator.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#ifndef _COMPARATOR_H_
#define _COMPARATOR_H_

/*
#include "filesystem.h"
#include "kleisli.h"
#include "file_type.h"
Expand All @@ -19,5 +20,6 @@ std::ostream& operator<<(std::ostream& o, const compare_result& r);
struct comparator: category::kleisli::arr< std::pair<typed_file, typed_file>, compare_result> {
void next(const typed_file& file1, const typed_file& file2);
};
*/

#endif
21 changes: 0 additions & 21 deletions trunk/src/file_type.h

This file was deleted.

46 changes: 46 additions & 0 deletions trunk/src/file_typer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#ifndef _FILE_TYPE_H_
#define _FILE_TYPE_H_

#include <vector>
#include <iostream>
#include <typeinfo>

#include "filesystem.h"
#include "kleisli.h"
#include "file_types.h"

enum match_options
{ match_first
, match_all
};

template<match_options o> class file_typer: public category::kleisli::arr<fs::path, file_type::base> {
template<typename F, typename T> struct try_file_types;
template<typename F>
struct try_file_types<F, nil> {
static void try_file(const F& file, category::kleisli::arr<fs::path, file_type::base>& cont) {
cont(file);
}
};
template<typename F, typename H, typename T>
struct try_file_types<F, cons<H, T> > {
static void try_file(const F& file, category::kleisli::arr<fs::path, file_type::base>& cont) {
//TODO: smart ptrs
H value;
if (H::try_file(file, &value)) {
try_file_types<H, typename filter<H, T>::descendant>::try_file(value, cont);
if (o == match_all) {
try_file_types<F, typename filter<H, T>::not_descendant>::try_file(file, cont);
}
} else {
try_file_types<F, T>::try_file(file, cont);
}
}
};
public:
void next(const fs::path& p) {
try_file_types<fs::path, file_types_list>::try_file(p, *this);
}
};

#endif
19 changes: 19 additions & 0 deletions trunk/src/file_types.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#ifndef _FILE_TYPES_H_
#define _FILE_TYPES_H_

#include "type_list.h"

#include "file_types/text.h"
#include "file_types/img.h"
#include "file_types/base.h"

typedef
cons< file_type::base,
cons< file_type::text,
cons< file_type::img,
nil > > > unsorted_file_types_list;

// typedef type_sort<unsorted_file_types_list>::result file_types_list;
typedef unsorted_file_types_list file_types_list;

#endif
49 changes: 49 additions & 0 deletions trunk/src/file_types/base.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#include <boost/filesystem/fstream.hpp>
#include <cstring>
#include <cassert>

#include "base.h"
#include "../kleisli.h"
#include "../filesystem.h"

namespace file_type {

bool base::try_file(const fs::path& file, base* res) {
res->_path = file;
return true;
}

void base::compare(const base& a, category::kleisli::arr<base, compare_result>& cont) const {
if (fs::file_size(_path) != fs::file_size(a._path)) {
return;
}
const int buf_size = 4096;
char buf1[buf_size], buf2[buf_size];
fs::ifstream file1(_path), file2(a._path);
while (true) {
file1.read(buf1, buf_size);
file2.read(buf2, buf_size);
assert(file1.gcount() == file2.gcount());
if (file1.gcount() == file2.gcount()) {
if (memcmp(buf1, buf2, file1.gcount()) != 0) {
return;
}
assert(file1.eof() == file2.eof());
if (file1.eof() && file2.eof()) {
cont(compare_result(_path, a._path));
return;
} else
if (!file1.eof() && !file2.eof()) {
continue;
}
}
return;
}
}

std::ostream& operator<<(std::ostream& o, const compare_result& r) {
o << "files " << r.file1() << " and " << r.file2() << " are equal";
return o;
}

}
38 changes: 38 additions & 0 deletions trunk/src/file_types/base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#ifndef _FILE_TYPE_BASE_H_
#define _FILE_TYPE_BASE_H_

#include "../filesystem.h"
#include "../type_list.h"
#include "../kleisli.h"

namespace file_type {

class compare_result {
const fs::path& _file1;
const fs::path& _file2;
public:
compare_result(const fs::path& f1, const fs::path& f2): _file1(f1), _file2(f2) {}
const fs::path& file1() const { return _file1; }
const fs::path& file2() const { return _file2; }
};

std::ostream& operator<<(std::ostream& o, const compare_result& r);

class base {
fs::path _path;
protected:
void set_path(const fs::path& p) { _path = p; }
public:
base() {}
base(const fs::path& p): _path(p) {}
const fs::path& path() const { return _path; }
//TODO: smart ptrs
static bool try_file(const fs::path& file, base* res);
virtual void compare(const base& a, category::kleisli::arr<base, compare_result>& cont) const;
//TODO: smart ptrs
virtual base* clone() const { return new base(_path); }
};

}

#endif
10 changes: 10 additions & 0 deletions trunk/src/file_types/img.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "img.h"
#include "../kleisli.h"

namespace file_type {

bool img::try_file(const base& file, img* res) {
return false;
}

}
17 changes: 17 additions & 0 deletions trunk/src/file_types/img.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#ifndef _FILE_TYPE_IMG_H_
#define _FILE_TYPE_IMG_H_

#include "base.h"
#include "../type_list.h"

namespace file_type {

struct img: base {
img() {}
img(const fs::path& p): base(p) {}
static bool try_file(const base& file, img* res);
};

}

#endif
25 changes: 25 additions & 0 deletions trunk/src/file_types/text.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <boost/filesystem/fstream.hpp>

#include "text.h"
#include "../kleisli.h"

namespace file_type {

bool text::try_file(const base& file, text* res) {
static const fs::path exts[] = { ".txt" };
static const fs::path* exts_end = exts + sizeof(exts)/sizeof(fs::path);
if (find(exts, exts_end, file.path().extension()) != exts_end) {
res->set_path(file.path());
return true;
}
return false;
}

void text::compare(const base& a, category::kleisli::arr<base, compare_result>& cont) const {
if (fs::file_size(path()) != fs::file_size(a.path())) {
return;
}
cont(compare_result(path(), a.path()));
}

}
21 changes: 21 additions & 0 deletions trunk/src/file_types/text.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef _FILE_TYPE_TEXT_H_
#define _FILE_TYPE_TEXT_H_

#include "base.h"
#include "../type_list.h"

namespace file_type {

struct text: base {
text() {}
text(const fs::path& p): base(p) {}
//TODO: smart ptrs
static bool try_file(const base& file, text* res);
void compare(const base& a, category::kleisli::arr<base, compare_result>& cont) const;
//TODO: smart ptrs
virtual base* clone() const { return new text(path()); }
};

}

#endif
15 changes: 11 additions & 4 deletions trunk/src/filesystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@

#include "filesystem.h"
#include "logger.h"
#include "functor_iterator.h"

template<class It, class F>
void for_each_regular(It p, It q, F & f)
{
for( ; p != q; ++p)
{
if(!is_regular_file(*p))
f(*p);
}
}

namespace fs {

Expand All @@ -11,9 +20,7 @@ void recursive::next(const std::string& value) {
logger::std_stream() << value << " does not exists" << std::endl;
} else
if (is_directory(value)) {
remove_copy_if(recursive_directory_iterator(value), recursive_directory_iterator(),
functor_iterator<recursive, fs::path>(*this),
std::not1(std::ptr_fun((bool(*)(const path&))(&is_regular_file))));
for_each_regular(recursive_directory_iterator(value), recursive_directory_iterator(), *this);
} else
if (is_regular_file(value)) {
(*this)(value);
Expand Down
15 changes: 0 additions & 15 deletions trunk/src/functor_iterator.h

This file was deleted.

0 comments on commit 26178ed

Please sign in to comment.