diff --git a/libretroshare/src/dbase/fimonitor.cc b/libretroshare/src/dbase/fimonitor.cc index 93cae47ee..fc0f12369 100644 --- a/libretroshare/src/dbase/fimonitor.cc +++ b/libretroshare/src/dbase/fimonitor.cc @@ -65,6 +65,22 @@ int FileIndexMonitor::SearchKeywords(std::list keywords, std::list< std::list firesults; fi.searchTerms(keywords, firesults); + + return filterResults(firesults,results,flags) ; +} + +int FileIndexMonitor::SearchBoolExp(Expression *exp, std::list& results,uint32_t flags) const +{ + results.clear(); + std::list firesults; + + fi.searchBoolExp(exp, firesults); + + return filterResults(firesults,results,flags) ; +} + +int FileIndexMonitor::filterResults(std::list& firesults,std::list& results,uint32_t flags) const +{ time_t now = time(NULL) ; /* translate/filter results */ diff --git a/libretroshare/src/dbase/fimonitor.h b/libretroshare/src/dbase/fimonitor.h index efb96d468..37c6a5c38 100644 --- a/libretroshare/src/dbase/fimonitor.h +++ b/libretroshare/src/dbase/fimonitor.h @@ -76,6 +76,9 @@ class FileIndexMonitor: public CacheSource, public RsThread /* external interface for filetransfer */ bool findLocalFile(std::string hash,uint32_t f, std::string &fullpath, uint64_t &size) const; int SearchKeywords(std::list keywords, std::list &results,uint32_t flags) ; + int SearchBoolExp(Expression *exp, std::list &results,uint32_t flags) const ; + int filterResults(std::list& firesults,std::list& results,uint32_t flags) const ; + /* external interface for local access to files */ bool convertSharedFilePath(std::string path, std::string &fullpath); diff --git a/libretroshare/src/dbase/rsexpr.cc b/libretroshare/src/dbase/rsexpr.cc index 5c8aeebef..73110a644 100644 --- a/libretroshare/src/dbase/rsexpr.cc +++ b/libretroshare/src/dbase/rsexpr.cc @@ -29,12 +29,20 @@ #include #include - /****************************************************************************************** eval functions of relational expressions. ******************************************************************************************/ +template<> +void RelExpression::linearize(LinearizedExpression& e) const +{ + e._ints.push_back(Op) ; + e._ints.push_back(LowerValue) ; + e._ints.push_back(HigherValue) ; +} + + bool DateExpression::eval(FileEntry *file) { return evalRel(file->modtime); @@ -148,3 +156,125 @@ bool StringExpression :: evalStr ( std::string &str ){ } 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::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& strings,bool& b,StringOperator& op) +{ + op = static_cast(e._ints[n_ints++]) ; + b = e._ints[n_ints++] ; + int n = e._ints[n_ints++] ; + + strings.clear() ; + for(int i=0;i(e._tokens[n_tok++]) ; + + switch(tok) + { + case EXPR_COMP: { + LogicalOperator op = static_cast(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_POP: { + RelOperator op = static_cast(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(e._ints[n_ints++]) ; + int lv = e._ints[n_ints++] ; + int hv = e._ints[n_ints++] ; + + return new SizeExpression(op,lv,hv) ; + } + case EXPR_DATE: { + RelOperator op = static_cast(e._ints[n_ints++]) ; + int lv = e._ints[n_ints++] ; + int hv = e._ints[n_ints++] ; + + return new DateExpression(op,lv,hv) ; + } + case EXPR_HASH: { + std::list strings ; + StringOperator op ; + bool b ; + + readStringExpr(e,n_ints,n_strings,strings,b,op) ; + return new HashExpression(op,strings) ; + } + case EXPR_EXT: + { + std::list strings ; + StringOperator op ; + bool b ; + + readStringExpr(e,n_ints,n_strings,strings,b,op) ; + + return new ExtExpression(op,strings,b) ; + } + case EXPR_PATH: + { + std::list strings ; + StringOperator op ; + bool b ; + + readStringExpr(e,n_ints,n_strings,strings,b,op) ; + + return new ExtExpression(op,strings,b) ; + } + case EXPR_NAME: + { + std::list strings ; + StringOperator op ; + bool b ; + + readStringExpr(e,n_ints,n_strings,strings,b,op) ; + + return new NameExpression(op,strings,b) ; + } + default: + std::cerr << "No expression match the current value " << tok << std::endl ; + return NULL ; + } +} + + diff --git a/libretroshare/src/ft/ftserver.cc b/libretroshare/src/ft/ftserver.cc index 2f21bff0c..ea5c2a5ce 100644 --- a/libretroshare/src/ft/ftserver.cc +++ b/libretroshare/src/ft/ftserver.cc @@ -457,9 +457,12 @@ int ftServer::SearchKeywords(std::list keywords, std::listSearchKeywords(keywords, results,flags); } -int ftServer::SearchBoolExp(Expression * exp, std::list &results) +int ftServer::SearchBoolExp(Expression * exp, std::list &results,uint32_t flags) { - return mFiStore->searchBoolExp(exp, results); + if(flags & DIR_FLAGS_LOCAL) + return mFiMon->SearchBoolExp(exp,results,flags) ; + else + return mFiStore->searchBoolExp(exp, results); } diff --git a/libretroshare/src/ft/ftserver.h b/libretroshare/src/ft/ftserver.h index fa8c563e8..ae1c50977 100644 --- a/libretroshare/src/ft/ftserver.h +++ b/libretroshare/src/ft/ftserver.h @@ -158,7 +158,7 @@ virtual int RequestDirDetails(std::string uid, std::string path, DirDetails &det virtual int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags); virtual int SearchKeywords(std::list keywords, std::list &results,uint32_t flags); -virtual int SearchBoolExp(Expression * exp, std::list &results); +virtual int SearchBoolExp(Expression * exp, std::list &results,uint32_t flags); /*** * Utility Functions diff --git a/libretroshare/src/rsiface/rsexpr.h b/libretroshare/src/rsiface/rsexpr.h index 07e9dfcad..e8865585f 100755 --- a/libretroshare/src/rsiface/rsexpr.h +++ b/libretroshare/src/rsiface/rsexpr.h @@ -37,28 +37,59 @@ Enumerations defining the Operators usable in the Boolean search expressions enum LogicalOperator{ AndOp=0, /* exp AND exp */ - OrOp, /* exp OR exp */ - XorOp /* exp XOR exp */ + OrOp=1, /* exp OR exp */ + XorOp=2 /* exp XOR exp */ }; /*Operators for String Queries*/ enum StringOperator{ ContainsAnyStrings = 0, /* e.g. name contains any of 'conference' 'meeting' 'presentation' */ - ContainsAllStrings, /* same as above except that it contains ALL of the strings */ - EqualsString /* exactly equal*/ + ContainsAllStrings = 1, /* same as above except that it contains ALL of the strings */ + EqualsString = 2 /* exactly equal*/ }; /*Relational operators ( >, <, >=, <=, == and InRange )*/ enum RelOperator{ Equals = 0, - GreaterEquals, - Greater, - SmallerEquals, - Smaller, - InRange /* lower limit <= value <= upper limit*/ + GreaterEquals = 1, + Greater = 2, + SmallerEquals = 3, + Smaller = 4, + InRange = 5 /* lower limit <= value <= upper limit*/ }; +/******************************************************************************************** + * Helper class for further serialisation + ********************************************************************************************/ + +class StringExpression ; +class Expression ; + +class LinearizedExpression +{ + public: + std::vector _tokens ; + std::vector _ints ; + std::vector _strings ; + + typedef enum { EXPR_DATE= 0, + EXPR_POP = 1, + EXPR_SIZE= 2, + EXPR_HASH= 3, + EXPR_NAME= 4, + EXPR_PATH= 5, + EXPR_EXT = 6, + EXPR_COMP= 7 } token ; + + static Expression *toExpr(const LinearizedExpression& e) ; + + private: + static Expression *toExpr(const LinearizedExpression& e,int&,int&,int&) ; + static void readStringExpr(const LinearizedExpression& e,int& n_ints,int& n_strings,std::list& strings,bool& b,StringOperator& op) ; +}; + + /****************************************************************************************** Boolean Search Expression classes: @@ -74,69 +105,81 @@ classes: class FileEntry; -class Expression{ -public: - virtual bool eval (FileEntry *file) = 0; - virtual ~Expression() {}; +class Expression +{ + public: + virtual bool eval (FileEntry *file) = 0; + virtual ~Expression() {}; + + virtual void linearize(LinearizedExpression& e) const = 0 ; }; -class CompoundExpression : public Expression { -public: - CompoundExpression( enum LogicalOperator op, Expression * exp1, Expression *exp2) - : Lexp(exp1), Rexp(exp2), Op(op){ } - - bool eval (FileEntry *file) { - if (Lexp == NULL or Rexp == NULL) { - return false; +class CompoundExpression : public Expression +{ + public: + CompoundExpression( enum LogicalOperator op, Expression * exp1, Expression *exp2) + : Lexp(exp1), Rexp(exp2), Op(op){ } + + bool eval (FileEntry *file) { + if (Lexp == NULL or Rexp == NULL) { + return false; + } + switch (Op){ + case AndOp: + return Lexp->eval(file) && Rexp->eval(file); + case OrOp: + return Lexp->eval(file) || Rexp->eval(file); + case XorOp: + return Lexp->eval(file) ^ Rexp->eval(file); + default: + return false; + } } - switch (Op){ - case AndOp: - return Lexp->eval(file) && Rexp->eval(file); - case OrOp: - return Lexp->eval(file) || Rexp->eval(file); - case XorOp: - return Lexp->eval(file) ^ Rexp->eval(file); - default: - return false; - } - } - virtual ~CompoundExpression(){ - delete Lexp; - delete Rexp; - } -private: - Expression *Lexp; - Expression *Rexp; - enum LogicalOperator Op; + virtual ~CompoundExpression(){ + delete Lexp; + delete Rexp; + } + + virtual void linearize(LinearizedExpression& e) const ; + private: + Expression *Lexp; + Expression *Rexp; + enum LogicalOperator Op; }; -class StringExpression: public Expression { -public: - StringExpression(enum StringOperator op, std::list &t, - bool ic): Op(op),terms(t), IgnoreCase(ic){} -protected: - bool evalStr(std::string &str); -private: - enum StringOperator Op; - std::list terms; - bool IgnoreCase; +class StringExpression: public Expression +{ + public: + StringExpression(enum StringOperator op, std::list &t, bool ic): Op(op),terms(t), IgnoreCase(ic){} + + virtual void linearize(LinearizedExpression& e) const ; + protected: + bool evalStr(std::string &str); + + enum StringOperator Op; + std::list terms; + bool IgnoreCase; }; template -class RelExpression: public Expression { -public: - RelExpression(enum RelOperator op, T lv, T hv): - Op(op), LowerValue(lv), HigherValue(hv) {} -protected: - bool evalRel(T val); -private: - enum RelOperator Op; - T LowerValue; - T HigherValue; +class RelExpression: public Expression +{ + public: + RelExpression(enum RelOperator op, T lv, T hv): Op(op), LowerValue(lv), HigherValue(hv) {} + + virtual void linearize(LinearizedExpression& e) const ; + protected: + bool evalRel(T val); + + enum RelOperator Op; + T LowerValue; + T HigherValue; }; +template<> void RelExpression::linearize(LinearizedExpression& e) const ; + template bool RelExpression::evalRel(T val) { switch (Op) { @@ -181,11 +224,18 @@ Some implementations of StringExpressions. ******************************************************************************************/ -class NameExpression: public StringExpression { -public: - NameExpression(enum StringOperator op, std::list &t, bool ic): - StringExpression(op,t,ic) {} - bool eval(FileEntry *file); +class NameExpression: public StringExpression +{ + public: + NameExpression(enum StringOperator op, std::list &t, bool ic): + StringExpression(op,t,ic) {} + bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_NAME) ; + StringExpression::linearize(e) ; + } }; class PathExpression: public StringExpression { @@ -193,6 +243,12 @@ public: PathExpression(enum StringOperator op, std::list &t, bool ic): StringExpression(op,t,ic) {} bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_PATH) ; + StringExpression::linearize(e) ; + } }; class ExtExpression: public StringExpression { @@ -200,6 +256,12 @@ public: ExtExpression(enum StringOperator op, std::list &t, bool ic): StringExpression(op,t,ic) {} bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_EXT) ; + StringExpression::linearize(e) ; + } }; class HashExpression: public StringExpression { @@ -207,6 +269,12 @@ public: HashExpression(enum StringOperator op, std::list &t): StringExpression(op,t, true) {} bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_HASH) ; + StringExpression::linearize(e) ; + } }; /****************************************************************************************** @@ -214,28 +282,50 @@ Some implementations of Relational Expressions. ******************************************************************************************/ -class DateExpression: public RelExpression { -public: - DateExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - DateExpression(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(FileEntry *file); +class DateExpression: public RelExpression +{ + public: + DateExpression(enum RelOperator op, int v): RelExpression(op,v,v){} + DateExpression(enum RelOperator op, int lv, int hv): + RelExpression(op,lv,hv) {} + bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_DATE) ; + RelExpression::linearize(e) ; + } }; -class SizeExpression: public RelExpression { -public: - SizeExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - SizeExpression(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(FileEntry *file); +class SizeExpression: public RelExpression +{ + public: + SizeExpression(enum RelOperator op, int v): RelExpression(op,v,v){} + SizeExpression(enum RelOperator op, int lv, int hv): + RelExpression(op,lv,hv) {} + bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_SIZE) ; + RelExpression::linearize(e) ; + } }; -class PopExpression: public RelExpression { -public: - PopExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - PopExpression(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(FileEntry *file); +class PopExpression: public RelExpression +{ + public: + PopExpression(enum RelOperator op, int v): RelExpression(op,v,v){} + PopExpression(enum RelOperator op, int lv, int hv): RelExpression(op,lv,hv) {} + PopExpression(const LinearizedExpression& e) ; + bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_POP) ; + RelExpression::linearize(e) ; + } }; #endif /* RS_EXPRESSIONS_H */ + diff --git a/libretroshare/src/rsiface/rsfiles.h b/libretroshare/src/rsiface/rsfiles.h index 5122d1b38..f70271d56 100644 --- a/libretroshare/src/rsiface/rsfiles.h +++ b/libretroshare/src/rsiface/rsfiles.h @@ -150,7 +150,7 @@ virtual int RequestDirDetails(std::string uid, std::string path, DirDetails &det virtual int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) = 0; virtual int SearchKeywords(std::list keywords, std::list &results,uint32_t flags) = 0; -virtual int SearchBoolExp(Expression * exp, std::list &results) = 0; +virtual int SearchBoolExp(Expression * exp, std::list &results,uint32_t flags) = 0; /*** * Utility Functions. diff --git a/libretroshare/src/rsiface/rsnotify.h b/libretroshare/src/rsiface/rsnotify.h index 685908c98..0d2940048 100644 --- a/libretroshare/src/rsiface/rsnotify.h +++ b/libretroshare/src/rsiface/rsnotify.h @@ -44,6 +44,7 @@ const uint32_t RS_POPUP_MSG = 0x0001; const uint32_t RS_POPUP_CHAT = 0x0002; const uint32_t RS_POPUP_CALL = 0x0004; const uint32_t RS_POPUP_CONNECT = 0x0008; +const uint32_t RS_SYSTRAY_GROUP_MSG = 0x0010; /* CHAT flags are here - so they are in the same place as * other Notify flags... not used by libretroshare though diff --git a/libretroshare/src/rsiface/rsturtle.h b/libretroshare/src/rsiface/rsturtle.h index f80f04939..61cd0ea21 100644 --- a/libretroshare/src/rsiface/rsturtle.h +++ b/libretroshare/src/rsiface/rsturtle.h @@ -31,6 +31,8 @@ #include #include +class LinearizedExpression ; + class RsTurtle; extern RsTurtle *rsTurtle ; @@ -67,6 +69,7 @@ class RsTurtle // as they come back. // virtual TurtleRequestId turtleSearch(const std::string& match_string) = 0 ; + virtual TurtleRequestId turtleSearch(const LinearizedExpression& expr) = 0 ; // Initiates tunnel handling for the given file hash. tunnels. Launches // an exception if an error occurs during the initialization process. The diff --git a/libretroshare/src/serialiser/rsbaseserial.cc b/libretroshare/src/serialiser/rsbaseserial.cc index 1d6ebd149..5a8abed1f 100644 --- a/libretroshare/src/serialiser/rsbaseserial.cc +++ b/libretroshare/src/serialiser/rsbaseserial.cc @@ -32,6 +32,40 @@ #include +/* UInt8 get/set */ + +bool getRawUInt8(void *data, uint32_t size, uint32_t *offset, uint8_t *out) +{ + /* first check there is space */ + if (size < *offset + 1) + { + return false; + } + void *buf = (void *) &(((uint8_t *) data)[*offset]); + + /* extract the data */ + memcpy(out, buf, sizeof(uint8_t)); + (*offset) += 1; + + return true; +} + +bool setRawUInt8(void *data, uint32_t size, uint32_t *offset, uint8_t in) +{ + /* first check there is space */ + if (size < *offset + 1) + { + return false; + } + + void *buf = (void *) &(((uint8_t *) data)[*offset]); + + /* pack it in */ + memcpy(buf, &in, sizeof(uint8_t)); + + (*offset) += 1; + return true; +} /* UInt16 get/set */ bool getRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t *out) diff --git a/libretroshare/src/serialiser/rsbaseserial.h b/libretroshare/src/serialiser/rsbaseserial.h index 9c2e5ac7b..50070c205 100644 --- a/libretroshare/src/serialiser/rsbaseserial.h +++ b/libretroshare/src/serialiser/rsbaseserial.h @@ -48,6 +48,9 @@ ******************************************************************/ +bool getRawUInt8(void *data, uint32_t size, uint32_t *offset, uint8_t *out); +bool setRawUInt8(void *data, uint32_t size, uint32_t *offset, uint8_t in); + bool getRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t *out); bool setRawUInt16(void *data, uint32_t size, uint32_t *offset, uint16_t in); diff --git a/libretroshare/src/turtle/p3turtle.cc b/libretroshare/src/turtle/p3turtle.cc index e0b4f19a0..be8ac44ce 100644 --- a/libretroshare/src/turtle/p3turtle.cc +++ b/libretroshare/src/turtle/p3turtle.cc @@ -526,8 +526,9 @@ int p3turtle::handleIncoming() switch(item->PacketSubType()) { - case RS_TURTLE_SUBTYPE_SEARCH_REQUEST: handleSearchRequest(dynamic_cast(item)) ; - break ; + case RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST: + case RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST: handleSearchRequest(dynamic_cast(item)) ; + break ; case RS_TURTLE_SUBTYPE_SEARCH_RESULT : handleSearchResult(dynamic_cast(item)) ; break ; @@ -596,7 +597,8 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item) if(_sharing_strategy != SHARE_FRIENDS_ONLY || item->depth < 2) { std::list result ; - performLocalSearch(item->match_string,result) ; + + item->performLocalSearch(result) ; RsTurtleSearchResultItem *res_item = NULL ; uint32_t item_size = 0 ; @@ -658,7 +660,7 @@ void p3turtle::handleSearchRequest(RsTurtleSearchRequestItem *item) std::cerr << " Forwarding request to peer = " << *it << std::endl ; #endif // Copy current item and modify it. - RsTurtleSearchRequestItem *fwd_item = new RsTurtleSearchRequestItem(*item) ; + RsTurtleSearchRequestItem *fwd_item = item->clone() ; ++(fwd_item->depth) ; // increase search depth fwd_item->PeerId(*it) ; @@ -767,9 +769,8 @@ void p3turtle::handleRecvFileRequest(RsTurtleFileRequestItem *item) } else // No, it's a request we should forward down the pipe. { - RsTurtleFileRequestItem *res_item = new RsTurtleFileRequestItem ; + RsTurtleFileRequestItem *res_item = new RsTurtleFileRequestItem(*item) ; - *res_item = *item ; res_item->PeerId(tunnel.local_dst) ; sendItem(res_item) ; @@ -812,6 +813,8 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item) // Only file data transfer updates tunnels time_stamp field, to avoid maintaining tunnel that are incomplete. tunnel.time_stamp = time(NULL) ; + // also update the hash time stamp to show that it's actually being downloaded. + _incoming_file_hashes[tunnel.hash].time_stamp = time(NULL) ; // Let's figure out whether this reuqest is for us or not. @@ -845,9 +848,7 @@ void p3turtle::handleRecvFileData(RsTurtleFileDataItem *item) #ifdef P3TURTLE_DEBUG std::cerr << " Forwarding data chunk to peer " << tunnel.local_src << std::endl ; #endif - RsTurtleFileDataItem *res_item = new RsTurtleFileDataItem ; - - *res_item = *item ; + RsTurtleFileDataItem *res_item = new RsTurtleFileDataItem(*item) ; res_item->chunk_data = malloc(res_item->chunk_size) ; @@ -1298,14 +1299,14 @@ void p3turtle::handleTunnelResult(RsTurtleTunnelOkItem *item) // ------------------------------ IO with libretroshare ----------------------------// // -----------------------------------------------------------------------------------// // -void p3turtle::performLocalSearch(const std::string& s,std::list& result) +void RsTurtleStringSearchRequestItem::performLocalSearch(std::list& result) const { /* call to core */ std::list initialResults; std::list words ; // to do: split search string into words. - words.push_back(s) ; + words.push_back(match_string) ; // now, search! rsFiles->SearchKeywords(words, initialResults,DIR_FLAGS_LOCAL | DIR_FLAGS_NETWORK_WIDE); @@ -1322,6 +1323,30 @@ void p3turtle::performLocalSearch(const std::string& s,std::list result.push_back(i) ; } } +void RsTurtleRegExpSearchRequestItem::performLocalSearch(std::list& result) const +{ + /* call to core */ + std::list initialResults; + + // to do: split search string into words. + Expression *exp = LinearizedExpression::toExpr(expr) ; + + // now, search! + rsFiles->SearchBoolExp(exp,initialResults,DIR_FLAGS_LOCAL | DIR_FLAGS_NETWORK_WIDE); + + result.clear() ; + + for(std::list::const_iterator it(initialResults.begin());it!=initialResults.end();++it) + { + TurtleFileInfo i ; + i.hash = it->hash ; + i.size = it->size ; + i.name = it->name ; + + result.push_back(i) ; + } + delete exp ; +} TurtleRequestId p3turtle::turtleSearch(const std::string& string_to_match) { @@ -1331,7 +1356,7 @@ TurtleRequestId p3turtle::turtleSearch(const std::string& string_to_match) // Form a request packet that simulates a request from us. // - RsTurtleSearchRequestItem *item = new RsTurtleSearchRequestItem ; + RsTurtleStringSearchRequestItem *item = new RsTurtleStringSearchRequestItem ; #ifdef P3TURTLE_DEBUG std::cerr << "performing search. OwnId = " << mConnMgr->getOwnId() << std::endl ; @@ -1359,6 +1384,42 @@ TurtleRequestId p3turtle::turtleSearch(const std::string& string_to_match) return id ; } +TurtleRequestId p3turtle::turtleSearch(const LinearizedExpression& expr) +{ + // generate a new search id. + + TurtleRequestId id = generateRandomRequestId() ; + + // Form a request packet that simulates a request from us. + // + RsTurtleRegExpSearchRequestItem *item = new RsTurtleRegExpSearchRequestItem ; + +#ifdef P3TURTLE_DEBUG + std::cerr << "performing search. OwnId = " << mConnMgr->getOwnId() << std::endl ; +#endif + while(mConnMgr->getOwnId() == "") + { + std::cerr << "... waitting for connect manager to form own id." << std::endl ; +#ifdef WIN32 + Sleep(1000) ; +#else + sleep(1) ; +#endif + } + + item->PeerId(mConnMgr->getOwnId()) ; + item->expr = expr ; + item->request_id = id ; + item->depth = 0 ; + + // send it + + handleSearchRequest(item) ; + + delete item ; + + return id ; +} void p3turtle::monitorFileTunnels(const std::string& name,const std::string& file_hash,uint64_t size) { @@ -1395,7 +1456,7 @@ void p3turtle::returnSearchResult(RsTurtleSearchResultItem *item) // just cout for now, but it should be notified to the gui #ifdef P3TURTLE_DEBUG - std::cerr << " Returning result for search request " << item->request_id << " upwards." << std::endl ; + std::cerr << " Returning result for search request " << (void*)item->request_id << " upwards." << std::endl ; #endif rsicontrol->getNotify().notifyTurtleSearchResult(item->request_id,item->result) ; @@ -1459,7 +1520,7 @@ void p3turtle::getInfo( std::vector >& hashes_info, tunnel.push_back(rsPeers->getPeerName(it->second.local_src)) ; tunnel.push_back(rsPeers->getPeerName(it->second.local_dst)) ; tunnel.push_back(it->second.hash) ; - tunnel.push_back(printNumber(now-it->second.time_stamp)) ; + tunnel.push_back(printNumber(now-it->second.time_stamp) + " secs ago") ; } search_reqs_info.clear(); @@ -1471,7 +1532,7 @@ void p3turtle::getInfo( std::vector >& hashes_info, search_req.push_back(printNumber(it->first,true)) ; search_req.push_back(rsPeers->getPeerName(it->second.origin)) ; - search_req.push_back(printNumber(now - it->second.time_stamp)) ; + search_req.push_back(printNumber(now - it->second.time_stamp) + " secs ago") ; } tunnel_reqs_info.clear(); @@ -1483,7 +1544,7 @@ void p3turtle::getInfo( std::vector >& hashes_info, tunnel_req.push_back(printNumber(it->first,true)) ; tunnel_req.push_back(rsPeers->getPeerName(it->second.origin)) ; - tunnel_req.push_back(printNumber(now - it->second.time_stamp)) ; + tunnel_req.push_back(printNumber(now - it->second.time_stamp) + " secs ago") ; } } diff --git a/libretroshare/src/turtle/p3turtle.h b/libretroshare/src/turtle/p3turtle.h index 4e71b63f3..889fcbcc8 100644 --- a/libretroshare/src/turtle/p3turtle.h +++ b/libretroshare/src/turtle/p3turtle.h @@ -207,6 +207,7 @@ class p3turtle: public p3Service, public pqiMonitor, public RsTurtle, public ftS // as they come back. // virtual TurtleSearchRequestId turtleSearch(const std::string& string_to_match) ; + virtual TurtleSearchRequestId turtleSearch(const LinearizedExpression& expr) ; // Initiates tunnel handling for the given file hash. tunnels. Launches // an exception if an error occurs during the initialization process. The diff --git a/libretroshare/src/turtle/rsturtleitem.cc b/libretroshare/src/turtle/rsturtleitem.cc index c308656db..12e3e9ca4 100644 --- a/libretroshare/src/turtle/rsturtleitem.cc +++ b/libretroshare/src/turtle/rsturtleitem.cc @@ -13,14 +13,35 @@ // // ---------------------------------- Packet sizes -----------------------------------// // -uint32_t RsTurtleSearchRequestItem::serial_size() + +uint32_t RsTurtleStringSearchRequestItem::serial_size() { uint32_t s = 0 ; s += 8 ; // header - s += GetTlvStringSize(match_string) ; s += 4 ; // request_id s += 2 ; // depth + s += GetTlvStringSize(match_string) ; // match_string + + return s ; +} +uint32_t RsTurtleRegExpSearchRequestItem::serial_size() +{ + uint32_t s = 0 ; + + s += 8 ; // header + s += 4 ; // request_id + s += 2 ; // depth + + s += 4 ; // number of strings + + for(uint i=0;i&) const = 0 ; // abstracts the search method - std::string match_string ; // string to match uint32_t request_id ; // randomly generated request id. uint16_t depth ; // Used for limiting search depth. +}; + +class RsTurtleStringSearchRequestItem: public RsTurtleSearchRequestItem +{ + public: + RsTurtleStringSearchRequestItem() : RsTurtleSearchRequestItem(RS_TURTLE_SUBTYPE_STRING_SEARCH_REQUEST) {} + RsTurtleStringSearchRequestItem(void *data,uint32_t size) ; + + std::string match_string ; // string to match + + virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleStringSearchRequestItem(*this) ; } + virtual void performLocalSearch(std::list&) const ; virtual std::ostream& print(std::ostream& o, uint16_t) ; - protected: virtual bool serialize(void *data,uint32_t& size) ; virtual uint32_t serial_size() ; }; +class RsTurtleRegExpSearchRequestItem: public RsTurtleSearchRequestItem +{ + public: + RsTurtleRegExpSearchRequestItem() : RsTurtleSearchRequestItem(RS_TURTLE_SUBTYPE_REGEXP_SEARCH_REQUEST) {} + RsTurtleRegExpSearchRequestItem(void *data,uint32_t size) ; + + LinearizedExpression expr ; // Reg Exp in linearised mode + + virtual RsTurtleSearchRequestItem *clone() const { return new RsTurtleRegExpSearchRequestItem(*this) ; } + virtual void performLocalSearch(std::list&) const ; + + virtual std::ostream& print(std::ostream& o, uint16_t) ; + protected: + virtual bool serialize(void *data,uint32_t& size) ; + virtual uint32_t serial_size() ; +}; + +/***********************************************************************************/ +/* Turtle Tunnel Item classes */ +/***********************************************************************************/ + class RsTurtleOpenTunnelItem: public RsTurtleItem { public: @@ -99,6 +142,7 @@ class RsTurtleTunnelOkItem: public RsTurtleItem virtual uint32_t serial_size() ; }; +#ifdef A_VIRER class RsTurtleCloseTunnelItem: public RsTurtleItem { public: @@ -126,6 +170,11 @@ class RsTurtleTunnelClosedItem: public RsTurtleItem virtual bool serialize(void *data,uint32_t& size) ; virtual uint32_t serial_size() ; }; +#endif + +/***********************************************************************************/ +/* Turtle File Transfer item classes */ +/***********************************************************************************/ class RsTurtleFileRequestItem: public RsTurtleItem { @@ -161,8 +210,10 @@ class RsTurtleFileDataItem: public RsTurtleItem virtual uint32_t serial_size() ; }; -// Class responsible for serializing/deserializing all turtle items. -// +/***********************************************************************************/ +/* Turtle Serialiser class */ +/***********************************************************************************/ + class RsTurtleSerialiser: public RsSerialType { public: diff --git a/retroshare-gui/src/gui/SearchDialog.cpp b/retroshare-gui/src/gui/SearchDialog.cpp index 948af3bd8..130dc3aea 100644 --- a/retroshare-gui/src/gui/SearchDialog.cpp +++ b/retroshare-gui/src/gui/SearchDialog.cpp @@ -412,11 +412,23 @@ void SearchDialog::advancedSearch(Expression* expression) /* call to core */ std::list results; - rsFiles -> SearchBoolExp(expression, results); - qulonglong searchId = rand() ; // for now, because we need to call the turtle search to get a proper id. - /* abstraction to allow reusee of tree rendering code */ - resultsToTree((advSearchDialog->getSearchAsString()).toStdString(),searchId, results); + // send a turtle search request + LinearizedExpression e ; + expression->linearize(e) ; + + TurtleRequestId req_id = rsTurtle->turtleSearch(e) ; + + rsFiles -> SearchBoolExp(expression, results, DIR_FLAGS_REMOTE | DIR_FLAGS_NETWORK_WIDE | DIR_FLAGS_BROWSABLE); + + /* abstraction to allow reusee of tree rendering code */ + resultsToTree((advSearchDialog->getSearchAsString()).toStdString(),req_id, results); + + // debug stuff + Expression *expression2 = LinearizedExpression::toExpr(e) ; + results.clear() ; + rsFiles -> SearchBoolExp(expression2, results, DIR_FLAGS_REMOTE | DIR_FLAGS_NETWORK_WIDE | DIR_FLAGS_BROWSABLE); + resultsToTree((advSearchDialog->getSearchAsString()).toStdString(),req_id+1, results); } diff --git a/retroshare-gui/src/rsiface/rsexpr.h b/retroshare-gui/src/rsiface/rsexpr.h index 07e9dfcad..e8865585f 100755 --- a/retroshare-gui/src/rsiface/rsexpr.h +++ b/retroshare-gui/src/rsiface/rsexpr.h @@ -37,28 +37,59 @@ Enumerations defining the Operators usable in the Boolean search expressions enum LogicalOperator{ AndOp=0, /* exp AND exp */ - OrOp, /* exp OR exp */ - XorOp /* exp XOR exp */ + OrOp=1, /* exp OR exp */ + XorOp=2 /* exp XOR exp */ }; /*Operators for String Queries*/ enum StringOperator{ ContainsAnyStrings = 0, /* e.g. name contains any of 'conference' 'meeting' 'presentation' */ - ContainsAllStrings, /* same as above except that it contains ALL of the strings */ - EqualsString /* exactly equal*/ + ContainsAllStrings = 1, /* same as above except that it contains ALL of the strings */ + EqualsString = 2 /* exactly equal*/ }; /*Relational operators ( >, <, >=, <=, == and InRange )*/ enum RelOperator{ Equals = 0, - GreaterEquals, - Greater, - SmallerEquals, - Smaller, - InRange /* lower limit <= value <= upper limit*/ + GreaterEquals = 1, + Greater = 2, + SmallerEquals = 3, + Smaller = 4, + InRange = 5 /* lower limit <= value <= upper limit*/ }; +/******************************************************************************************** + * Helper class for further serialisation + ********************************************************************************************/ + +class StringExpression ; +class Expression ; + +class LinearizedExpression +{ + public: + std::vector _tokens ; + std::vector _ints ; + std::vector _strings ; + + typedef enum { EXPR_DATE= 0, + EXPR_POP = 1, + EXPR_SIZE= 2, + EXPR_HASH= 3, + EXPR_NAME= 4, + EXPR_PATH= 5, + EXPR_EXT = 6, + EXPR_COMP= 7 } token ; + + static Expression *toExpr(const LinearizedExpression& e) ; + + private: + static Expression *toExpr(const LinearizedExpression& e,int&,int&,int&) ; + static void readStringExpr(const LinearizedExpression& e,int& n_ints,int& n_strings,std::list& strings,bool& b,StringOperator& op) ; +}; + + /****************************************************************************************** Boolean Search Expression classes: @@ -74,69 +105,81 @@ classes: class FileEntry; -class Expression{ -public: - virtual bool eval (FileEntry *file) = 0; - virtual ~Expression() {}; +class Expression +{ + public: + virtual bool eval (FileEntry *file) = 0; + virtual ~Expression() {}; + + virtual void linearize(LinearizedExpression& e) const = 0 ; }; -class CompoundExpression : public Expression { -public: - CompoundExpression( enum LogicalOperator op, Expression * exp1, Expression *exp2) - : Lexp(exp1), Rexp(exp2), Op(op){ } - - bool eval (FileEntry *file) { - if (Lexp == NULL or Rexp == NULL) { - return false; +class CompoundExpression : public Expression +{ + public: + CompoundExpression( enum LogicalOperator op, Expression * exp1, Expression *exp2) + : Lexp(exp1), Rexp(exp2), Op(op){ } + + bool eval (FileEntry *file) { + if (Lexp == NULL or Rexp == NULL) { + return false; + } + switch (Op){ + case AndOp: + return Lexp->eval(file) && Rexp->eval(file); + case OrOp: + return Lexp->eval(file) || Rexp->eval(file); + case XorOp: + return Lexp->eval(file) ^ Rexp->eval(file); + default: + return false; + } } - switch (Op){ - case AndOp: - return Lexp->eval(file) && Rexp->eval(file); - case OrOp: - return Lexp->eval(file) || Rexp->eval(file); - case XorOp: - return Lexp->eval(file) ^ Rexp->eval(file); - default: - return false; - } - } - virtual ~CompoundExpression(){ - delete Lexp; - delete Rexp; - } -private: - Expression *Lexp; - Expression *Rexp; - enum LogicalOperator Op; + virtual ~CompoundExpression(){ + delete Lexp; + delete Rexp; + } + + virtual void linearize(LinearizedExpression& e) const ; + private: + Expression *Lexp; + Expression *Rexp; + enum LogicalOperator Op; }; -class StringExpression: public Expression { -public: - StringExpression(enum StringOperator op, std::list &t, - bool ic): Op(op),terms(t), IgnoreCase(ic){} -protected: - bool evalStr(std::string &str); -private: - enum StringOperator Op; - std::list terms; - bool IgnoreCase; +class StringExpression: public Expression +{ + public: + StringExpression(enum StringOperator op, std::list &t, bool ic): Op(op),terms(t), IgnoreCase(ic){} + + virtual void linearize(LinearizedExpression& e) const ; + protected: + bool evalStr(std::string &str); + + enum StringOperator Op; + std::list terms; + bool IgnoreCase; }; template -class RelExpression: public Expression { -public: - RelExpression(enum RelOperator op, T lv, T hv): - Op(op), LowerValue(lv), HigherValue(hv) {} -protected: - bool evalRel(T val); -private: - enum RelOperator Op; - T LowerValue; - T HigherValue; +class RelExpression: public Expression +{ + public: + RelExpression(enum RelOperator op, T lv, T hv): Op(op), LowerValue(lv), HigherValue(hv) {} + + virtual void linearize(LinearizedExpression& e) const ; + protected: + bool evalRel(T val); + + enum RelOperator Op; + T LowerValue; + T HigherValue; }; +template<> void RelExpression::linearize(LinearizedExpression& e) const ; + template bool RelExpression::evalRel(T val) { switch (Op) { @@ -181,11 +224,18 @@ Some implementations of StringExpressions. ******************************************************************************************/ -class NameExpression: public StringExpression { -public: - NameExpression(enum StringOperator op, std::list &t, bool ic): - StringExpression(op,t,ic) {} - bool eval(FileEntry *file); +class NameExpression: public StringExpression +{ + public: + NameExpression(enum StringOperator op, std::list &t, bool ic): + StringExpression(op,t,ic) {} + bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_NAME) ; + StringExpression::linearize(e) ; + } }; class PathExpression: public StringExpression { @@ -193,6 +243,12 @@ public: PathExpression(enum StringOperator op, std::list &t, bool ic): StringExpression(op,t,ic) {} bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_PATH) ; + StringExpression::linearize(e) ; + } }; class ExtExpression: public StringExpression { @@ -200,6 +256,12 @@ public: ExtExpression(enum StringOperator op, std::list &t, bool ic): StringExpression(op,t,ic) {} bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_EXT) ; + StringExpression::linearize(e) ; + } }; class HashExpression: public StringExpression { @@ -207,6 +269,12 @@ public: HashExpression(enum StringOperator op, std::list &t): StringExpression(op,t, true) {} bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_HASH) ; + StringExpression::linearize(e) ; + } }; /****************************************************************************************** @@ -214,28 +282,50 @@ Some implementations of Relational Expressions. ******************************************************************************************/ -class DateExpression: public RelExpression { -public: - DateExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - DateExpression(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(FileEntry *file); +class DateExpression: public RelExpression +{ + public: + DateExpression(enum RelOperator op, int v): RelExpression(op,v,v){} + DateExpression(enum RelOperator op, int lv, int hv): + RelExpression(op,lv,hv) {} + bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_DATE) ; + RelExpression::linearize(e) ; + } }; -class SizeExpression: public RelExpression { -public: - SizeExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - SizeExpression(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(FileEntry *file); +class SizeExpression: public RelExpression +{ + public: + SizeExpression(enum RelOperator op, int v): RelExpression(op,v,v){} + SizeExpression(enum RelOperator op, int lv, int hv): + RelExpression(op,lv,hv) {} + bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_SIZE) ; + RelExpression::linearize(e) ; + } }; -class PopExpression: public RelExpression { -public: - PopExpression(enum RelOperator op, int v): RelExpression(op,v,v){} - PopExpression(enum RelOperator op, int lv, int hv): - RelExpression(op,lv,hv) {} - bool eval(FileEntry *file); +class PopExpression: public RelExpression +{ + public: + PopExpression(enum RelOperator op, int v): RelExpression(op,v,v){} + PopExpression(enum RelOperator op, int lv, int hv): RelExpression(op,lv,hv) {} + PopExpression(const LinearizedExpression& e) ; + bool eval(FileEntry *file); + + virtual void linearize(LinearizedExpression& e) const + { + e._tokens.push_back(LinearizedExpression::EXPR_POP) ; + RelExpression::linearize(e) ; + } }; #endif /* RS_EXPRESSIONS_H */ + diff --git a/retroshare-gui/src/rsiface/rsfiles.h b/retroshare-gui/src/rsiface/rsfiles.h index 5122d1b38..f70271d56 100644 --- a/retroshare-gui/src/rsiface/rsfiles.h +++ b/retroshare-gui/src/rsiface/rsfiles.h @@ -150,7 +150,7 @@ virtual int RequestDirDetails(std::string uid, std::string path, DirDetails &det virtual int RequestDirDetails(void *ref, DirDetails &details, uint32_t flags) = 0; virtual int SearchKeywords(std::list keywords, std::list &results,uint32_t flags) = 0; -virtual int SearchBoolExp(Expression * exp, std::list &results) = 0; +virtual int SearchBoolExp(Expression * exp, std::list &results,uint32_t flags) = 0; /*** * Utility Functions. diff --git a/retroshare-gui/src/rsiface/rsturtle.h b/retroshare-gui/src/rsiface/rsturtle.h index f80f04939..61cd0ea21 100644 --- a/retroshare-gui/src/rsiface/rsturtle.h +++ b/retroshare-gui/src/rsiface/rsturtle.h @@ -31,6 +31,8 @@ #include #include +class LinearizedExpression ; + class RsTurtle; extern RsTurtle *rsTurtle ; @@ -67,6 +69,7 @@ class RsTurtle // as they come back. // virtual TurtleRequestId turtleSearch(const std::string& match_string) = 0 ; + virtual TurtleRequestId turtleSearch(const LinearizedExpression& expr) = 0 ; // Initiates tunnel handling for the given file hash. tunnels. Launches // an exception if an error occurs during the initialization process. The