/[debian]/mimetic/branches/upstream/current/examples/search.cxx
ViewVC logotype

Contents of /mimetic/branches/upstream/current/examples/search.cxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 128 - (show annotations)
Sat Feb 25 16:49:20 2006 UTC (15 years, 5 months ago) by gregoa
File size: 8126 byte(s)
[svn-inject] Installing original source of mimetic
1 /***************************************************************************
2 copyright : (C) 2002-2005 by Stefano Barbato
3 email : stefano@codesink.org
4
5 $Id: search.cxx,v 1.2 2005/02/23 10:26:14 tat Exp $
6 ***************************************************************************/
7
8 /***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 ***************************************************************************/
16 /** \example search.cc
17 * extract a Part based on command line parameters
18 * more info on:
19 * search -h
20 */
21 #include <iostream>
22 #include <sstream>
23 #include <iterator>
24 #include <fstream>
25 #include <cassert>
26 #include <mimetic/mimetic.h>
27
28 using namespace std;
29 using namespace mimetic;
30
31 unsigned int g_matches = 0;
32
33 void usage()
34 {
35 cout << "search [params] [in_file...]" << endl;
36 cout << "\t-I filename use index (disables '-r')" << endl;
37 cout << "\t-r looks for matches in nested entities"<<endl;
38 cout << "\t-t type[/subtype] matches Content-Type" << endl;
39 cout << "\t-p param[=value] matches Content-Type param" << endl;
40 cout << "\t-f name[=value] matches an header field" << endl;
41 cout << "\t-l doesn't write anything but filename" << endl;
42 cout << "\t-q totaly quiet; exit code = num of matches" << endl;
43 exit(-1);
44 }
45
46
47 struct MatchParamRq
48 {
49 typedef pair<istring,istring> Param;
50 typedef pair<istring,istring> Field;
51 MatchParamRq()
52 : recursive(0), quiet(0)
53 {
54 }
55 bool operator()(const MimeEntity* pMe) const
56 {
57 // check for content type match
58 const Header& h = pMe->header();
59 if(type.length() && type != h.contentType().type())
60 return false;
61 if(subtype.length() && subtype != h.contentType().subtype())
62 return false;
63
64 bool matched;
65 // check for params matches
66 if(paramList.size())
67 {
68 ContentType::ParamList::const_iterator ctpbit,ctpeit;
69 ctpbit = h.contentType().paramList().begin();
70 ctpeit = h.contentType().paramList().end();
71 matched = 0;
72 for(; !matched && ctpbit != ctpeit; ++ctpbit)
73 {
74 list<Param>::const_iterator pbit, peit;
75 pbit = paramList.begin(), peit = paramList.end();
76 for(; pbit != peit; ++pbit)
77 {
78 if(ctpbit->name() != pbit->first)
79 break;
80 // case insensitive
81 istring value = ctpbit->value();
82 if(value.find(pbit->second) != string::npos)
83 matched++;
84 }
85 }
86 if(!matched)
87 return false;
88 }
89
90 // check for field matches
91 if(fieldList.size())
92 {
93 matched = 0;
94 Header::const_iterator hbit, heit;
95 hbit = h.begin();
96 heit = h.end();
97 for(; !matched && hbit != heit; ++hbit)
98 {
99 list<Field>::const_iterator fbit, feit;
100 fbit = fieldList.begin(), feit = fieldList.end();
101 for(; fbit != feit; ++fbit)
102 {
103 if(hbit->name() != fbit->first)
104 break;
105 // case insensitive
106 istring value = hbit->value();
107 if(value.find(fbit->second) != string::npos)
108 matched++;
109 }
110 }
111 if(!matched)
112 return false;
113 }
114
115 return true;
116
117 }
118 istring type, subtype;
119 list<Param> paramList;
120 list<Field> fieldList;
121 bool recursive, quiet;
122 };
123
124 void die(bool b, const string& msg)
125 {
126 if(b)
127 {
128 cerr << "Error: " << msg << endl << endl;
129 usage();
130 }
131 }
132
133 void printPart(const MimeEntity& me, const MatchParamRq& mpr, string& fqn)
134 {
135 while(mpr(&me))
136 {
137 ++g_matches;
138 if(mpr.quiet)
139 break;
140 if(fqn.length() == 0)
141 break;
142 cout << fqn << endl;
143 fqn.clear();
144 break; // never loop
145 }
146 if(!mpr.recursive)
147 return; // just top level entity
148 MimeEntityList::const_iterator mbit, meit;
149 mbit = me.body().parts().begin(), meit = me.body().parts().end();
150 for(; mbit != meit; ++mbit)
151 printPart(**mbit, mpr, fqn);
152 }
153
154 // search the whole index for matches
155 void searchIndex(const MimeEntity& me, const MatchParamRq& mpr)
156 {
157 cout << "PARTS COUNT: " << me.body().parts().size() << endl;
158 MimeEntityList::const_iterator mbit, meit;
159 mbit = me.body().parts().begin(), meit = me.body().parts().end();
160 for(; mbit != meit; ++mbit)
161 {
162 MimeEntity* pMe = *mbit;
163 if(mpr(pMe))
164 cout << pMe->header().field("x-filename").value() << endl;
165 }
166 }
167 int main(int argc, char** argv)
168 {
169 std::ios_base::sync_with_stdio(false);
170 MatchParamRq mpr;
171 int ignoreMask = imChildParts | imBody;
172 string indexFqn;
173 bool useIndex = 0;
174
175 int p = 1;
176 while(p < argc)
177 {
178 string param = argv[p];
179 if(param == "-h")
180 usage();
181 else if (param == "-r") {
182 mpr.recursive = 1;
183 ignoreMask = ignoreMask & ~imChildParts;
184 } else if (param == "-q") {
185 mpr.quiet = 1;
186 } else if (param == "-t") {
187 die( ++p == argc, param + " requires an argument");
188 ContentType ct(argv[p]);
189 die(mpr.type.length() != 0, "just one -t allowed");
190 mpr.type = ct.type();
191 mpr.subtype = ct.subtype();
192 } else if (param == "-I") {
193 die( ++p == argc, param + " requires an argument");
194 indexFqn = argv[p];
195 useIndex = 1;
196 } else if (param == "-p") {
197 die( ++p == argc, param + " requires an argument");
198 string switch_param = argv[p];
199 StringTokenizer stok(&switch_param, "=");
200 pair<string,string> item;
201 stok.next(item.first) && stok.next(item.second);
202 mpr.paramList.push_back(item);
203 } else if (param == "-f") {
204 die( ++p == argc, param + " requires an argument");
205 string switch_param = argv[p];
206 StringTokenizer stok(&switch_param, "=");
207 pair<string,string> item;
208 stok.next(item.first) && stok.next(item.second);
209 mpr.fieldList.push_back(item);
210 } else if( param.length() == 2 && param[0] == '-') {
211 usage();
212 } else {
213 // filename list starts here
214 // first filename: argv[p]
215 break;
216 }
217 ++p;
218 }
219
220 string fqn;
221 if(useIndex) {
222 File in(indexFqn);
223 die(!in, "Error opening index file");
224 mpr.recursive = 0;
225 MimeEntity idxEntity;
226 idxEntity.load(in.begin(), in.end());
227 searchIndex(idxEntity, mpr);
228 } else if(argc == p) {
229 // read from stdin
230 istreambuf_iterator<char> bit(cin), eit;
231 MimeEntity me;
232 me.load(bit, eit, ignoreMask);
233 fqn = "stdin";
234 printPart(me, mpr, fqn);
235 } else
236 for(int fc = p; fc < argc; ++fc)
237 {
238 fqn = argv[fc];
239 File in(fqn);
240 if(!in)
241 {
242 cerr << "ERR: unable to open file " << argv[fc]
243 << endl;
244 continue;
245 }
246 MimeEntity me;
247 me.load(in.begin(), in.end(), ignoreMask);
248 printPart(me,mpr, fqn);
249 }
250 return g_matches;
251 }
252

  ViewVC Help
Powered by ViewVC 1.1.26