source: main/trunk/greenstone2/runtime-src/src/recpt/cgiargs.cpp@ 24959

Last change on this file since 24959 was 12512, checked in by kjdon, 18 years ago

Added Stefan's fileupload code to replace use of cgicc by depositor. Changed the signature of some methods; added fileupload_t; cgiargsclass now has fileupload_t variable; cgiargsinfoclass now has 'bool fileupload' variable; added some more debug print methods; in addarginfo, if logout is null I write the error message to stderr

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 13.2 KB
Line 
1/**********************************************************************
2 *
3 * cgiargs.cpp --
4 * Copyright (C) 1999 The New Zealand Digital Library Project
5 *
6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
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 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *********************************************************************/
25
26#include "cgiargs.h"
27#include "gsdlunicode.h"
28
29
30
31void cgiarg_t::clear () {
32 value.clear();
33 source = program_arg;
34 fileupload.clear();
35}
36
37cgiarg_t &cgiarg_t::operator=(const cgiarg_t &x) {
38 value=x.value;
39 source=x.source;
40 return *this;
41}
42
43
44bool operator==(const cgiarg_t &x, const cgiarg_t &y) {
45 return ((x.value == y.value) && (x.source == y.source));
46}
47
48bool operator<(const cgiarg_t &x, const cgiarg_t &y) {
49 return ((x.value < y.value) ||
50 ((x.value == y.value) && (x.source == y.source)));
51}
52
53
54void fileupload_t::clear() {
55 name.clear();
56 type.clear();
57 size = 0;
58 tmp_name.clear();
59}
60
61ostream &operator<<(ostream &outs, const fileupload_t &fu) {
62 utf8outconvertclass text_t2utf8;
63 outs << "*** fileupload\n";
64
65 outs << text_t2utf8 << "name=" << fu.name << ", type="<< fu.type<<", size="<<fu.size<<", tmp_name="<<fu.tmp_name<<"\n";
66 return outs;
67}
68
69
70
71// constructors
72cgiargsclass::cgiargsclass () {
73}
74
75
76// this returns NULL if there isn't an entry with a value of
77// 'key' already defined
78
79void cgiargsclass::setarg (const text_t &key, const text_t &value,
80 cgiarg_t::source_t source) {
81 cgiarg_t temparg;
82 temparg.value = value;
83 temparg.source = source;
84 args[key] = temparg;
85}
86
87void cgiargsclass::setdefaultarg (const text_t &key, const text_t &value,
88 cgiarg_t::source_t source) {
89 if (getarg(key) == NULL) setarg (key, value, source);
90}
91
92void cgiargsclass::setintarg (const text_t &key, int value,
93 cgiarg_t::source_t source) {
94 setarg (key, value, source);
95}
96
97void cgiargsclass::setdefaultintarg (const text_t &key, int value,
98 cgiarg_t::source_t source) {
99 if (getarg(key) == NULL) setintarg (key, value, source);
100}
101
102void cgiargsclass::setcarg (const text_t &key, unsigned short c,
103 cgiarg_t::source_t source) {
104 text_t t;
105 t.push_back(c);
106 setarg(key,t, source);
107}
108
109void cgiargsclass::setdefaultcarg (const text_t &key, unsigned short c,
110 cgiarg_t::source_t source) {
111 if (getarg(key) == NULL) setcarg (key, c, source);
112}
113
114void cgiargsclass::setargfile (const text_t &key, const fileupload_t &fileupload) {
115 iterator here = args.find (key);
116 if (here != args.end()) {
117 (*here).second.fileupload = fileupload;
118 }
119}
120
121text_t *cgiargsclass::getarg (const text_t &key) {
122 iterator here = args.find (key);
123 if (here == args.end()) return NULL;
124
125 return &((*here).second.value);
126}
127
128int cgiargsclass::getintarg (const text_t &key) {
129 text_t *text = getarg (key);
130 if (text == NULL) return 0;
131 return text->getint();
132}
133
134fileupload_t *cgiargsclass::getargfile (const text_t &key) {
135 iterator here = args.find (key);
136 if (here == args.end()) return NULL;
137 return &((*here).second.fileupload);
138}
139
140
141
142
143// stream operators to print cgi arguments for debugging purposes
144ostream &operator<<(ostream &outs, const cgiargsclass &args) {
145 utf8outconvertclass text_t2utf8;
146 cgiargsclass::const_iterator here = args.begin ();
147 cgiargsclass::const_iterator end = args.end ();
148
149 outs << "*** cgiargsclass\n";
150
151 while (here != end) {
152 outs << text_t2utf8 << " \"" << (*here).first << "\"=\"" <<
153 (*here).second.value << "\"\n";
154 ++here;
155 }
156 outs << "\n";
157
158 return outs;
159}
160
161
162
163cgiarginfo::cgiarginfo () {
164 multiplechar = false;
165 multiplevalue = false;
166 fileupload = false;
167 defaultstatus = weak;
168 argdefault.clear();
169 savedarginfo = can;
170}
171
172
173bool operator==(const cgiarginfo &x, const cgiarginfo &y) {
174 return ((x.shortname == y.shortname) &&
175 (x.longname == y.longname) &&
176 (x.multiplechar == y.multiplechar) &&
177 (x.multiplevalue == y.multiplevalue) &&
178 (x.fileupload == y.fileupload) &&
179 (x.defaultstatus == y.defaultstatus) &&
180 (x.argdefault == y.argdefault) &&
181 (x.savedarginfo == y.savedarginfo));
182}
183
184bool operator<(const cgiarginfo &x, const cgiarginfo &y) {
185 return ((x.shortname < y.shortname) ||
186 ((x.shortname == y.shortname) &&
187 ((x.longname < y.longname) ||
188 ((x.longname == y.longname) &&
189 ((x.multiplevalue < y.multiplevalue) ||
190 ((x.multiplevalue == y.multiplevalue) &&
191 ((x.fileupload == y.fileupload) &&
192 ((x.fileupload < y.fileupload) ||
193 ((x.multiplechar < y.multiplechar) ||
194 ((x.multiplechar == y.multiplechar) &&
195 ((x.defaultstatus < y.defaultstatus) ||
196 ((x.defaultstatus == y.defaultstatus) &&
197 ((x.argdefault < y.argdefault) ||
198 ((x.argdefault == y.argdefault) &&
199 ((x.savedarginfo < y.savedarginfo))))))))))))))));
200}
201
202
203// constructor
204cgiargsinfoclass::cgiargsinfoclass () {
205}
206
207// addarginfo will combine the information with the present
208// information. If name clashes were detected then the information
209// will be written to logout (or stderr) and addarginfo will return false. No
210// processing with the arguments should be done if this happens
211// as the results will be meaningless.
212bool cgiargsinfoclass::addarginfo (ostream *logout, cgiarginfo &info) {
213
214 // if info.fileupload is set certain other fields are implicitly
215 // overridden
216 if (info.fileupload) {
217 info.multiplechar = false;
218 info.defaultstatus = cgiarginfo::weak;
219 info.argdefault = "";
220 info.savedarginfo = cgiarginfo::mustnot;
221 }
222 cgiarginfo *orginfo = getarginfo (info.shortname);
223 if (orginfo == NULL) {
224 argsinfo[info.shortname] = info;
225 return true; // no clashes
226 }
227
228 if (orginfo->longname != info.longname) {
229 outconvertclass text_t2ascii;
230 if (logout != NULL) {
231 (*logout) << text_t2ascii << "Error: cgi argument name clash for argument \""
232 << info.shortname << "\".\nOne long name was\n \"" << orginfo->longname
233 << "\"\nand the other was\n \"" << info.longname << "\".\n\n";
234 } else {
235 cerr << text_t2ascii << "Error: cgi argument name clash for argument \""
236 << info.shortname << "\".\nOne long name was\n \"" << orginfo->longname
237 << "\"\nand the other was\n \"" << info.longname << "\".\n\n";
238 }
239 return false; // found a clash
240 }
241
242 if (orginfo->multiplevalue != info.multiplevalue) {
243 outconvertclass text_t2ascii;
244 if (logout != NULL) {
245 (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname
246 << "\" was given as being a single value option\n"
247 << "and a multiple value option.\n\n";
248 } else {
249 cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname
250 << "\" was given as being a single value option\n"
251 << "and a multiple value option.\n\n";
252 }
253 return false; // found a clash
254 }
255
256 if (orginfo->fileupload != info.fileupload) {
257 outconvertclass text_t2ascii;
258 if (logout != NULL) {
259 (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname
260 << "\" was given as being a file upload argument\n"
261 << "and a non file upload argument.\n\n";
262 } else {
263 cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname
264 << "\" was given as being a file upload argument\n"
265 << "and a non file upload argument.\n\n";
266 }
267 return false; // found a clash
268 }
269
270 if (orginfo->multiplechar != info.multiplechar) {
271 outconvertclass text_t2ascii;
272 if (logout != NULL) {
273 (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname
274 << "\" was given as being a single character option\n"
275 << "and a multiple character option.\n\n";
276 } else {
277 cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname
278 << "\" was given as being a single character option\n"
279 << "and a multiple character option.\n\n";
280 }
281 return false; // found a clash
282 }
283
284 if (!info.multiplechar && info.argdefault.size() > 1) {
285 outconvertclass text_t2ascii;
286 if (logout != NULL) {
287 (*logout) << text_t2ascii << "Error: cgi argument \"" << info.shortname
288 << "\" was defined as being a single character option\n"
289 << "but a multiple character default was given.\n\n";
290 } else {
291 cerr << text_t2ascii << "Error: cgi argument \"" << info.shortname
292 << "\" was defined as being a single character option\n"
293 << "but a multiple character default was given.\n\n";
294 }
295 return false; // found a problem
296 }
297
298 // make sure there is no clashes in the savedarginfo
299 if ((orginfo->savedarginfo==cgiarginfo::mustnot &&
300 info.savedarginfo==cgiarginfo::must) ||
301 (orginfo->savedarginfo==cgiarginfo::must &&
302 info.savedarginfo==cgiarginfo::mustnot)) {
303 outconvertclass text_t2ascii;
304 if (logout != NULL) {
305 (*logout) << text_t2ascii << "Error: it was specified that cgi argument \""
306 << info.shortname << "\" should be saved in the state\n"
307 << "information and that it should not be save in the state information.\n\n";
308 } else {
309 cerr << text_t2ascii << "Error: it was specified that cgi argument \""
310 << info.shortname << "\" should be saved in the state\n"
311 << "information and that it should not be save in the state information.\n\n";
312 }
313 return false; // found a clash
314 }
315 // the only time orginfo->savedarginfo can change is when it is set
316 // to "can"
317 if (orginfo->savedarginfo == cgiarginfo::can)
318 orginfo->savedarginfo = info.savedarginfo;
319
320
321 if (orginfo->defaultstatus > info.defaultstatus) {
322 return true;
323 }
324 orginfo->defaultstatus = info.defaultstatus;
325 orginfo->argdefault = info.argdefault;
326
327 return true;
328}
329
330bool cgiargsinfoclass::addarginfo (ostream *logout, cgiargsinfoclass &info) {
331
332 iterator here = info.begin ();
333 iterator end = info.end ();
334
335 while (here != end) {
336 if (!addarginfo (NULL, (*here).second)) {
337 cerr << "returning false\n";
338 return false;
339 }
340 ++here;
341 }
342
343 return true; // made it, no clashes
344}
345
346bool cgiargsinfoclass::addarginfo (ostream *logout, const text_t& argshortname, const text_tmap& mapinfo)
347{
348 cgiarginfo *arginfo = getarginfo (argshortname);
349 if (arginfo == NULL) {
350 arginfo = &(argsinfo[argshortname]);
351 arginfo->shortname = argshortname;
352 arginfo->defaultstatus = cgiarginfo::config;
353 }
354 text_tmap::const_iterator thisInfo = mapinfo.begin();
355 text_tmap::const_iterator endInfo = mapinfo.end();
356 while (thisInfo != endInfo) {
357 if (thisInfo->first == "longname") arginfo->longname = thisInfo->second;
358 else if (thisInfo->first == "multiplechar") arginfo->multiplechar = (thisInfo->second == "true");
359 else if (thisInfo->first == "defaultstatus") {
360 if (thisInfo->second == "none") arginfo->defaultstatus = cgiarginfo::none;
361 else if (thisInfo->second == "weak") arginfo->defaultstatus = cgiarginfo::weak;
362 else if (thisInfo->second == "good") arginfo->defaultstatus = cgiarginfo::good;
363 else if (thisInfo->second == "config") arginfo->defaultstatus = cgiarginfo::config;
364 else if (thisInfo->second == "imperative") arginfo->defaultstatus = cgiarginfo::imperative;
365 }
366 else if (thisInfo->first == "argdefault") {
367 arginfo->argdefault = thisInfo->second;
368 }
369 else if (thisInfo->first == "savedarginfo") {
370 if (thisInfo->second == "mustnot") arginfo->savedarginfo = cgiarginfo::mustnot;
371 else if (thisInfo->second == "can") arginfo->savedarginfo = cgiarginfo::can;
372 else if (thisInfo->second == "must") arginfo->savedarginfo = cgiarginfo::must;
373 } else if (logout != NULL) {
374 (*logout) << ("Invalid argument for cgiarg for " + argshortname + " (" + thisInfo->first + ")\n");
375 }
376 ++thisInfo;
377 }
378 return true;
379}
380
381bool cgiargsinfoclass::addarginfo (ostream *logout, confcgiarg_tmap& info)
382{
383 confcgiarg_tmap::const_iterator thisArg = info.begin();
384 confcgiarg_tmap::const_iterator endArg = info.end();
385 while (thisArg != endArg) {
386 if (!addarginfo(logout, thisArg->first, thisArg->second)) return false;
387 ++thisArg;
388 }
389 return true;
390}
391
392cgiarginfo *cgiargsinfoclass::getarginfo (const text_t &key) {
393 iterator here = argsinfo.find (key);
394 if (here == argsinfo.end()) return NULL;
395
396 return &((*here).second);
397}
398
399const cgiarginfo *cgiargsinfoclass::getarginfo (const text_t &key) const {
400 const_iterator here = argsinfo.find (key);
401 if (here == argsinfo.end()) return NULL;
402
403 return &((*here).second);
404}
405
406// stream operators to print cgiarginfo for debugging purposes
407ostream &operator<<(ostream &outs, const cgiargsinfoclass &argsinfo) {
408 utf8outconvertclass text_t2utf8;
409 cgiargsinfoclass::const_iterator here = argsinfo.begin ();
410 cgiargsinfoclass::const_iterator end = argsinfo.end ();
411
412 outs << "*** cgiargsinfoclass\n";
413
414 while (here != end) {
415 outs << text_t2utf8 << (*here).first << ", ";
416 ++here;
417 }
418 outs << "\n";
419
420 return outs;
421}
Note: See TracBrowser for help on using the repository browser.