00001
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <config.h>
00022
00023 #include "xapian/keymaker.h"
00024
00025 #include "xapian/document.h"
00026
00027 #include <string>
00028 #include <vector>
00029
00030 using namespace std;
00031
00032 namespace Xapian {
00033
00034 KeyMaker::~KeyMaker() { }
00035
00036 string
00037 MultiValueKeyMaker::operator()(const Xapian::Document & doc) const
00038 {
00039 string result;
00040
00041 vector<pair<Xapian::valueno, bool> >::const_iterator i = slots.begin();
00042
00043 if (rare(i == slots.end())) return result;
00044
00045 size_t last_not_empty_forwards = 0;
00046 while (true) {
00047
00048
00049
00050
00051 string v = doc.get_value(i->first);
00052 bool reverse_sort = i->second;
00053
00054 if (reverse_sort || !v.empty())
00055 last_not_empty_forwards = result.size();
00056
00057 if (++i == slots.end() && !reverse_sort) {
00058 if (v.empty()) {
00059
00060 result.resize(last_not_empty_forwards);
00061 } else {
00062
00063 result += v;
00064 }
00065 break;
00066 }
00067
00068 if (reverse_sort) {
00069
00070
00071
00072 for (string::const_iterator j = v.begin(); j != v.end(); ++j) {
00073 unsigned char ch(*j);
00074 result += char(255 - ch);
00075 if (ch == 0) result += '\0';
00076 }
00077 result.append("\xff\xff", 2);
00078 if (i == slots.end()) break;
00079 last_not_empty_forwards = result.size();
00080 } else {
00081
00082
00083
00084 string::size_type j = 0, nul;
00085 while ((nul = v.find('\0', j)) != string::npos) {
00086 ++nul;
00087 result.append(v, j, nul - j);
00088 result += '\xff';
00089 j = nul;
00090 }
00091 result.append(v, j, string::npos);
00092 if (!v.empty())
00093 last_not_empty_forwards = result.size();
00094 result.append("\0", 2);
00095 }
00096 }
00097 return result;
00098 }
00099
00100 string
00101 MultiValueSorter::operator()(const Xapian::Document & doc) const
00102 {
00103 string result;
00104
00105 vector<pair<Xapian::valueno, bool> >::const_iterator i = slots.begin();
00106
00107 if (rare(i == slots.end())) return result;
00108
00109 while (true) {
00110
00111
00112
00113
00114 string v = doc.get_value(i->first);
00115 bool reverse_sort = !i->second;
00116
00117 if (++i == slots.end() && !reverse_sort) {
00118
00119 result += v;
00120 break;
00121 }
00122
00123 if (reverse_sort) {
00124
00125
00126
00127 for (string::const_iterator j = v.begin(); j != v.end(); ++j) {
00128 unsigned char ch(*j);
00129 result += char(255 - ch);
00130 if (ch == 0) result += '\0';
00131 }
00132 result.append("\xff\xff", 2);
00133 if (i == slots.end()) break;
00134 } else {
00135
00136
00137
00138 string::size_type j = 0, nul;
00139 while ((nul = v.find('\0', j)) != string::npos) {
00140 ++nul;
00141 result.append(v, j, nul - j);
00142 result += '\xff';
00143 j = nul;
00144 }
00145 result.append(v, j, string::npos);
00146 result.append("\0", 2);
00147 }
00148 }
00149 return result;
00150 }
00151
00152 }