Merge branch 'master' into android

This commit is contained in:
Gio 2016-10-26 13:43:24 +02:00
commit ea42d822c2
257 changed files with 11438 additions and 22401 deletions

View file

@ -1,12 +1,41 @@
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifdef WINDOWS_SYS
#include "util/rswin.h"
#endif
#include "folderiterator.h"
#include "rsstring.h"
//#define DEBUG_FOLDER_ITERATOR 1
namespace librs { namespace util {
FolderIterator::FolderIterator(const std::string& folderName)
: mFolderName(folderName)
{
// Grab the last modification time for the directory
struct stat64 buf ;
#ifdef WINDOWS_SYS
std::wstring wfullname;
librs::util::ConvertUtf8ToUtf16(folderName, wfullname);
if ( 0 == _wstati64(wfullname.c_str(), &buf))
#else
if ( 0 == stat64(folderName.c_str(), &buf))
#endif
{
mFolderModTime = buf.st_mtime ;
}
// Now open directory content and read the first entry
#ifdef WINDOWS_SYS
std::wstring utf16Name;
if(! ConvertUtf8ToUtf16(folderName, utf16Name)) {
@ -17,11 +46,11 @@ FolderIterator::FolderIterator(const std::string& folderName)
utf16Name += L"/*.*";
handle = FindFirstFileW(utf16Name.c_str(), &fileInfo);
validity = handle != INVALID_HANDLE_VALUE;
isFirstCall = true;
is_open = validity = handle != INVALID_HANDLE_VALUE;
#else
handle = opendir(folderName.c_str());
validity = handle != NULL;
is_open = validity = handle != NULL;
next();
#endif
}
@ -30,48 +59,113 @@ FolderIterator::~FolderIterator()
closedir();
}
bool FolderIterator::readdir() {
void FolderIterator::next()
{
while(readdir())
{
#ifdef WINDOWS_SYS
ConvertUtf16ToUtf8(fileInfo.cFileName, mFileName) ;
#else
mFileName = ent->d_name ;
#endif
if(mFileName == "." || mFileName == "..")
continue ;
mFullPath = mFolderName + "/" + mFileName ;
struct stat64 buf ;
#ifdef DEBUG_FOLDER_ITERATOR
std::cerr << "FolderIterator: next. Looking into file " << mFileName ;
#endif
#ifdef WINDOWS_SYS
std::wstring wfullname;
librs::util::ConvertUtf8ToUtf16(mFullPath, wfullname);
if ( 0 == _wstati64(wfullname.c_str(), &buf))
#else
if ( 0 == stat64(mFullPath.c_str(), &buf))
#endif
{
mFileModTime = buf.st_mtime ;
mStatInfoOk = true;
if (S_ISDIR(buf.st_mode))
{
#ifdef DEBUG_FOLDER_ITERATOR
std::cerr << ": is a directory" << std::endl;
#endif
mType = TYPE_DIR ;
mFileSize = 0 ;
mFileModTime = buf.st_mtime;
return ;
}
if (S_ISREG(buf.st_mode))
{
#ifdef DEBUG_FOLDER_ITERATOR
std::cerr << ": is a file" << std::endl;
#endif
mType = TYPE_FILE ;
mFileSize = buf.st_size;
mFileModTime = buf.st_mtime;
return ;
}
}
#ifdef DEBUG_FOLDER_ITERATOR
std::cerr << ": is unknown skipping" << std::endl;
#endif
mType = TYPE_UNKNOWN ;
mFileSize = 0 ;
mFileModTime = 0;
}
#ifdef DEBUG_FOLDER_ITERATOR
std::cerr << "End of directory." << std::endl;
#endif
mType = TYPE_UNKNOWN ;
mFileSize = 0 ;
mFileModTime = 0;
validity = false ;
}
bool FolderIterator::readdir()
{
if(!validity)
return false;
#ifdef WINDOWS_SYS
if(isFirstCall) {
isFirstCall = false;
return true;
}
return FindNextFileW(handle, &fileInfo) != 0;
#else
ent = ::readdir(handle);
return ent != 0;
return ent != NULL;
#endif
}
bool FolderIterator::d_name(std::string& dest)
{
if(!validity)
return false;
time_t FolderIterator::dir_modtime() const { return mFolderModTime ; }
#ifdef WINDOWS_SYS
if(! ConvertUtf16ToUtf8(fileInfo.cFileName, dest)) {
validity = false;
return false;
}
#else
if(ent == 0)
return false;
dest = ent->d_name;
#endif
return true;
}
const std::string& FolderIterator::file_fullpath() { return mFullPath ; }
const std::string& FolderIterator::file_name() { return mFileName ; }
uint64_t FolderIterator::file_size() { return mFileSize ; }
time_t FolderIterator::file_modtime() { return mFileModTime ; }
uint8_t FolderIterator::file_type() { return mType ; }
bool FolderIterator::closedir()
{
if(!validity)
return false;
validity = false;
if(!is_open)
return true ;
is_open = false ;
#ifdef WINDOWS_SYS
return FindClose(handle) != 0;
#else

View file

@ -2,6 +2,7 @@
#define FOLDERITERATOR_H
#include <stdint.h>
#include <iostream>
#include <cstdio>
@ -24,15 +25,30 @@ public:
FolderIterator(const std::string& folderName);
~FolderIterator();
enum { TYPE_UNKNOWN = 0x00,
TYPE_FILE = 0x01,
TYPE_DIR = 0x02
};
// info about current parent directory
time_t dir_modtime() const ;
// info about directory content
bool isValid() const { return validity; }
bool readdir();
bool d_name(std::string& dest);
void next();
bool closedir();
const std::string& file_name() ;
const std::string& file_fullpath() ;
uint64_t file_size() ;
uint8_t file_type() ;
time_t file_modtime() ;
private:
bool is_open;
bool validity;
#ifdef WINDOWS_SYS
@ -43,7 +59,16 @@ private:
DIR* handle;
struct dirent* ent;
#endif
void updateStatsInfo() ;
bool mStatInfoOk ;
time_t mFileModTime ;
time_t mFolderModTime ;
uint64_t mFileSize ;
uint8_t mType ;
std::string mFileName ;
std::string mFullPath ;
std::string mFolderName ;
};

View file

@ -34,6 +34,7 @@
#include "util/rsstring.h"
#include "util/rsrandom.h"
#include "util/rsmemory.h"
#include "util/folderiterator.h"
#include "retroshare/rstypes.h"
#include "rsthreads.h"
#include <iostream>
@ -437,200 +438,13 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
bool RsDirUtil::cleanupDirectory(const std::string& cleandir, const std::set<std::string> &keepFiles)
{
for(librs::util::FolderIterator it(cleandir);it.isValid();it.next())
if(it.file_type() == librs::util::FolderIterator::TYPE_FILE && (keepFiles.end() == std::find(keepFiles.begin(), keepFiles.end(), it.file_name())))
remove( (cleandir + "/" + it.file_name()).c_str() ) ;
/* check for the dir existance */
#ifdef WINDOWS_SYS
std::wstring wcleandir;
librs::util::ConvertUtf8ToUtf16(cleandir, wcleandir);
_WDIR *dir = _wopendir(wcleandir.c_str());
#else
DIR *dir = opendir(cleandir.c_str());
#endif
if (!dir)
{
return false;
}
#ifdef WINDOWS_SYS
struct _wdirent *dent;
struct _stat buf;
while(NULL != (dent = _wreaddir(dir)))
#else
struct dirent *dent;
struct stat buf;
while(NULL != (dent = readdir(dir)))
#endif
{
/* check entry type */
#ifdef WINDOWS_SYS
const std::wstring &wfname = dent -> d_name;
std::wstring wfullname = wcleandir + L"/" + wfname;
#else
const std::string &fname = dent -> d_name;
std::string fullname = cleandir + "/" + fname;
#endif
#ifdef WINDOWS_SYS
if (-1 != _wstat(wfullname.c_str(), &buf))
#else
if (-1 != stat(fullname.c_str(), &buf))
#endif
{
/* only worry about files */
if (S_ISREG(buf.st_mode))
{
#ifdef WINDOWS_SYS
std::string fname;
librs::util::ConvertUtf16ToUtf8(wfname, fname);
#endif
/* check if we should keep it */
if (keepFiles.end() == std::find(keepFiles.begin(), keepFiles.end(), fname))
{
/* can remove */
#ifdef WINDOWS_SYS
_wremove(wfullname.c_str());
#else
remove(fullname.c_str());
#endif
}
}
}
}
/* close directory */
#ifdef WINDOWS_SYS
_wclosedir(dir);
#else
closedir(dir);
#endif
return true;
return true;
}
/* faster cleanup - first construct two sets - then iterate over together */
bool RsDirUtil::cleanupDirectoryFaster(const std::string& cleandir, const std::set<std::string> &keepFiles)
{
/* check for the dir existance */
#ifdef WINDOWS_SYS
std::map<std::string, std::wstring> fileMap;
std::map<std::string, std::wstring>::const_iterator fit;
std::wstring wcleandir;
librs::util::ConvertUtf8ToUtf16(cleandir, wcleandir);
_WDIR *dir = _wopendir(wcleandir.c_str());
#else
std::map<std::string, std::string> fileMap;
std::map<std::string, std::string>::const_iterator fit;
DIR *dir = opendir(cleandir.c_str());
#endif
if (!dir)
{
return false;
}
#ifdef WINDOWS_SYS
struct _wdirent *dent;
struct _stat buf;
while(NULL != (dent = _wreaddir(dir)))
{
const std::wstring &wfname = dent -> d_name;
std::wstring wfullname = wcleandir + L"/" + wfname;
if (-1 != _wstat(wfullname.c_str(), &buf))
{
/* only worry about files */
if (S_ISREG(buf.st_mode))
{
std::string fname;
librs::util::ConvertUtf16ToUtf8(wfname, fname);
fileMap[fname] = wfullname;
}
}
}
#else
struct dirent *dent;
struct stat buf;
while(NULL != (dent = readdir(dir)))
{
const std::string &fname = dent -> d_name;
std::string fullname = cleandir + "/" + fname;
if (-1 != stat(fullname.c_str(), &buf))
{
/* only worry about files */
if (S_ISREG(buf.st_mode))
{
fileMap[fname] = fullname;
}
}
}
#endif
std::set<std::string>::const_iterator kit;
fit = fileMap.begin();
kit = keepFiles.begin();
while(fit != fileMap.end() && kit != keepFiles.end())
{
if (fit->first < *kit) // fit is not in keep list;
{
#ifdef WINDOWS_SYS
_wremove(fit->second.c_str());
#else
remove(fit->second.c_str());
#endif
++fit;
}
else if (*kit < fit->first) // keepitem doesn't exist.
{
++kit;
}
else // in keep list.
{
++fit;
++kit;
}
}
// cleanup extra that aren't in keep list.
while(fit != fileMap.end())
{
#ifdef WINDOWS_SYS
_wremove(fit->second.c_str());
#else
remove(fit->second.c_str());
#endif
++fit;
}
/* close directory */
#ifdef WINDOWS_SYS
_wclosedir(dir);
#else
closedir(dir);
#endif
return true;
}
/* slightly nicer helper function */
bool RsDirUtil::hashFile(const std::string& filepath,
std::string &name, RsFileHash &hash, uint64_t &size)

View file

@ -0,0 +1,287 @@
/*
* rs-core/src/dbase: rsexpr.cc
*
* RetroShare C++ Interface.
*
* Copyright 2007-2008 by Kashif Kaleem.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License Version 2 as published by the Free Software Foundation.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA.
*
* Please report all bugs and problems to "retroshare@lunamutt.com".
*
*/
#include "retroshare/rsexpr.h"
#include "retroshare/rstypes.h"
#include <algorithm>
#include <functional>
/******************************************************************************************
eval functions of relational expressions.
******************************************************************************************/
namespace RsRegularExpression
{
template<>
void RelExpression<int>::linearize(LinearizedExpression& e) const
{
e._ints.push_back(Op) ;
e._ints.push_back(LowerValue) ;
e._ints.push_back(HigherValue) ;
}
bool DateExpression::eval(const ExpFileEntry& file)
{
return evalRel(file.file_modtime());
}
bool SizeExpressionMB::eval(const ExpFileEntry& file)
{
return evalRel((int)(file.file_size()/(uint64_t)(1024*1024)));
}
bool SizeExpression::eval(const ExpFileEntry& file)
{
return evalRel(file.file_size());
}
bool PopExpression::eval(const ExpFileEntry& file)
{
return evalRel(file.file_popularity());
}
/******************************************************************************************
Code for evaluating string expressions
******************************************************************************************/
bool NameExpression::eval(const ExpFileEntry& file)
{
return evalStr(file.file_name());
}
bool PathExpression::eval(const ExpFileEntry& file)
{
return evalStr(file.file_parent_path());
}
bool ExtExpression::eval(const ExpFileEntry& file)
{
std::string ext;
/*Get the part of the string after the last instance of . in the filename */
size_t index = file.file_name().find_last_of('.');
if (index != std::string::npos) {
ext = file.file_name().substr(index+1);
if (ext != "" ){
return evalStr(ext);
}
}
return false;
}
bool HashExpression::eval(const ExpFileEntry& file){
return evalStr(file.file_hash().toStdString());
}
/*Check whether two strings are 'equal' to each other*/
static bool StrEquals(const std::string & str1, const std::string & str2,
bool IgnoreCase ){
if ( str1.size() != str2.size() ){
return false;
} else if (IgnoreCase) {
std::equal( str1.begin(), str1.end(),
str2.begin(), CompareCharIC() );
}
return std::equal( str1.begin(), str1.end(),
str2.begin());
}
/*Check whether one string contains the other*/
static bool StrContains( const std::string & str1, const std::string & str2,
bool IgnoreCase){
std::string::const_iterator iter ;
if (IgnoreCase) {
iter = std::search( str1.begin(), str1.end(),
str2.begin(), str2.end(), CompareCharIC() );
} else {
iter = std::search( str1.begin(), str1.end(),
str2.begin(), str2.end());
}
return ( iter != str1.end() );
}
bool StringExpression :: evalStr ( const std::string &str ){
std::list<std::string>::iterator iter;
switch (Op) {
case ContainsAllStrings:
for ( iter = terms.begin(); iter != terms.end(); ++iter ) {
if ( StrContains (str, *iter, IgnoreCase) == false ){
return false;
}
}
return true;
break;
case ContainsAnyStrings:
for ( iter = terms.begin(); iter != terms.end(); ++iter ) {
if ( StrContains (str,*iter, IgnoreCase) == true ) {
return true;
}
}
break;
case EqualsString:
for ( iter = terms.begin(); iter != terms.end(); ++iter ) {
if ( StrEquals (str,*iter, IgnoreCase) == true ) {
return true;
}
}
break;
default:
return false;
}
return false;
}
/*************************************************************************
* linearization code
*************************************************************************/
void CompoundExpression::linearize(LinearizedExpression& e) const
{
e._tokens.push_back(LinearizedExpression::EXPR_COMP) ;
e._ints.push_back(Op) ;
Lexp->linearize(e) ;
Rexp->linearize(e) ;
}
void StringExpression::linearize(LinearizedExpression& e) const
{
e._ints.push_back(Op) ;
e._ints.push_back(IgnoreCase) ;
e._ints.push_back(terms.size()) ;
for(std::list<std::string>::const_iterator it(terms.begin());it!=terms.end();++it)
e._strings.push_back(*it) ;
}
Expression *LinearizedExpression::toExpr(const LinearizedExpression& e)
{
int i=0,j=0,k=0 ;
return toExpr(e,i,j,k) ;
}
void LinearizedExpression::readStringExpr(const LinearizedExpression& e,int& n_ints,int& n_strings,std::list<std::string>& strings,bool& b,StringOperator& op)
{
op = static_cast<StringOperator>(e._ints[n_ints++]) ;
b = e._ints[n_ints++] ;
int n = e._ints[n_ints++] ;
strings.clear() ;
for(int i=0;i<n;++i)
strings.push_back(e._strings[n_strings++]) ;
}
Expression *LinearizedExpression::toExpr(const LinearizedExpression& e,int& n_tok,int& n_ints,int& n_strings)
{
LinearizedExpression::token tok = static_cast<LinearizedExpression::token>(e._tokens[n_tok++]) ;
switch(tok)
{
case EXPR_DATE: {
RelOperator op = static_cast<RelOperator>(e._ints[n_ints++]) ;
int lv = e._ints[n_ints++] ;
int hv = e._ints[n_ints++] ;
return new DateExpression(op,lv,hv) ;
}
case EXPR_POP: {
RelOperator op = static_cast<RelOperator>(e._ints[n_ints++]) ;
int lv = e._ints[n_ints++] ;
int hv = e._ints[n_ints++] ;
return new PopExpression(op,lv,hv) ;
}
case EXPR_SIZE: {
RelOperator op = static_cast<RelOperator>(e._ints[n_ints++]) ;
int lv = e._ints[n_ints++] ;
int hv = e._ints[n_ints++] ;
return new SizeExpression(op,lv,hv) ;
}
case EXPR_HASH: {
std::list<std::string> strings ;
StringOperator op ;
bool b ;
readStringExpr(e,n_ints,n_strings,strings,b,op) ;
return new HashExpression(op,strings) ;
}
case EXPR_NAME: {
std::list<std::string> strings ;
StringOperator op ;
bool b ;
readStringExpr(e,n_ints,n_strings,strings,b,op) ;
return new NameExpression(op,strings,b) ;
}
case EXPR_PATH: {
std::list<std::string> strings ;
StringOperator op ;
bool b ;
readStringExpr(e,n_ints,n_strings,strings,b,op) ;
return new ExtExpression(op,strings,b) ;
}
case EXPR_EXT: {
std::list<std::string> strings ;
StringOperator op ;
bool b ;
readStringExpr(e,n_ints,n_strings,strings,b,op) ;
return new ExtExpression(op,strings,b) ;
}
case EXPR_COMP: {
LogicalOperator op = static_cast<LogicalOperator>(e._ints[n_ints++]) ;
Expression *e1 = toExpr(e,n_tok,n_ints,n_strings) ;
Expression *e2 = toExpr(e,n_tok,n_ints,n_strings) ;
return new CompoundExpression(op,e1,e2) ;
}
case EXPR_SIZE_MB: {
RelOperator op = static_cast<RelOperator>(e._ints[n_ints++]) ;
int lv = e._ints[n_ints++] ;
int hv = e._ints[n_ints++] ;
return new SizeExpressionMB(op,lv,hv) ;
}
default:
std::cerr << "No expression match the current value " << tok << std::endl ;
return NULL ;
}
}
}