00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef INDRI_QUERYRESPONSEUNPACKER_HPP
00020 #define INDRI_QUERYRESPONSEUNPACKER_HPP
00021
00022 #include "indri/NetworkMessageStream.hpp"
00023 #include "indri/InferenceNetwork.hpp"
00024 #include "Exception.hpp"
00025 namespace indri
00026 {
00027 namespace net
00028 {
00029 class QueryResponseUnpacker : public MessageStreamHandler {
00030 private:
00031 NetworkMessageStream* _stream;
00032 indri::infnet::InferenceNetwork::MAllResults _results;
00033 std::string _exception;
00034 bool _done;
00035
00036 public:
00037 QueryResponseUnpacker( NetworkMessageStream* stream ) :
00038 _stream(stream),
00039 _done(false)
00040 {
00041 }
00042
00043 indri::infnet::InferenceNetwork::MAllResults& getResults() {
00044 while( !_done && _stream->alive() && !_exception.length() )
00045 _stream->read(*this);
00046
00047 if( _exception.length() )
00048 LEMUR_THROW( LEMUR_RUNTIME_ERROR, _exception );
00049
00050 return _results;
00051 }
00052
00053 void reply( indri::xml::XMLNode* node ) {
00054 assert( false && "Query responses are binary only for now" );
00055 }
00056
00057 void reply( const std::string& name, const void* buffer, unsigned int length ) {
00058 std::string nodeName;
00059 std::string listName;
00060
00061 nodeName = name.substr( 0, name.find(':') );
00062 listName = name.substr( name.find(':')+1 );
00063
00064 indri::api::ScoredExtentResult aligned;
00065 int count = length / (sizeof(INT32)*5 + sizeof(double) + sizeof(INT64));
00066 std::vector<indri::api::ScoredExtentResult>& resultVector = _results[nodeName][listName];
00067
00068 const char* p = (const char*) buffer;
00069
00070 for( int i=0; i<count; i++ ) {
00071
00072 memcpy( &aligned.score, p, sizeof(double) );
00073 p += sizeof(double);
00074
00075 memcpy( &aligned.document, p, sizeof(INT32) );
00076 p += sizeof(INT32);
00077
00078 memcpy( &aligned.begin, p, sizeof(INT32) );
00079 p += sizeof(INT32);
00080
00081 memcpy( &aligned.end, p, sizeof(INT32) );
00082 p += sizeof(INT32);
00083
00084 memcpy( &aligned.number, p, sizeof(UINT64) );
00085 p += sizeof(INT64);
00086
00087 memcpy( &aligned.ordinal, p, sizeof(INT32) );
00088 p += sizeof(INT32);
00089
00090 memcpy( &aligned.parentOrdinal, p, sizeof(INT32) );
00091 p += sizeof(INT32);
00092
00093 aligned.begin = ntohl(aligned.begin);
00094 aligned.end = ntohl(aligned.end);
00095 aligned.document = ntohl(aligned.document);
00096 aligned.score = lemur_compat::ntohd(aligned.score);
00097 aligned.number = lemur_compat::ntohll(aligned.number);
00098 aligned.ordinal = ntohl(aligned.ordinal);
00099 aligned.parentOrdinal = ntohl(aligned.parentOrdinal);
00100
00101 resultVector.push_back(aligned);
00102 }
00103 }
00104
00105 void replyDone() {
00106 _done = true;
00107 }
00108
00109 void request( indri::xml::XMLNode* node ) {
00110 assert( false && "No requests expected from the query server" );
00111 }
00112
00113 void error( const std::string& err ) {
00114 _exception = err;
00115 }
00116
00117 };
00118 }
00119 }
00120
00121 #endif // INDRI_QUERYRESPONSEUNPACKER_HPP
00122
00123