ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/Represent/Represent.cpp
Revision: 422
Committed: 2005-03-09T19:08:17-08:00 (20 years, 3 months ago) by douglas
File size: 12171 byte(s)
Log Message:
Gah! Menes is going crazy right now!

File Contents

# Content
1 // Represent
2 //
3 // Douglas Thrift
4 //
5 // $Id$
6
7 #include "Hexadecimal.hpp"
8 #include "DataType.hpp"
9 #include "InputType.hpp"
10
11 #ifdef _WIN32
12 #pragma warning(disable:4267 4288)
13 #endif
14
15 #include <menes-app/simple.hpp>
16 #include <menes-xml/document.hpp>
17 #include <menes-xml/nodeset.hpp>
18 #include <menes-xml/parse.hpp>
19
20 struct Environment
21 {
22 ext::String get(const ext::String& name) { try { return api::TheEnvironment.Get(name); } catch (ext::Exception) { return ext::String(); } }
23 } env;
24
25 struct Item
26 {
27 DataType type;
28 ext::String data;
29 InputType input;
30 Item(const DataType& type, const ext::String& data, const InputType& input_) : type(type), data(data), input(input_) {}
31 };
32
33 int Main(const app::Options& options)
34 {
35 Represent represent;
36
37 return 0;
38 }
39
40 Represent::Represent()
41 {
42 api::Cout << "Content-Type: text/html; charset=UTF-8\r\n\r\n" << ios::Flush;
43
44 xml::TextWriter xhtml(api::Cout);
45
46 parse();
47
48 _H<xml::Document> document(xml::Parse("represent.xml"));
49 _H<xml::Node> node(*document/"represent");
50 ext::String before(*node/"before"), after(*node/"after");
51
52 api::Cout << ios::NewLine << before << ios::Flush;
53
54 {
55 xml::ScopeElement table(xhtml, "table");
56
57 headings(xhtml);
58 form(xhtml);
59 output(xhtml);
60 }
61
62 api::Cout << after << ios::Flush;
63 }
64
65 void Represent::parse()
66 {
67 ext::String query(env.get("QUERY_STRING"));
68
69 if (env.get("REQUEST_METHOD") == "POST")
70 {
71 ext::Buffer content(lexical_cast<size_t>(env.get("CONTENT_LENGTH")));
72
73 api::Cin.ReadFully(content.Begin(), content.GetSize());
74
75 query = content;
76 }
77
78 ext::Vector<ext::String> pairs(ext::SplitAll(query, ext::String("&")));
79
80 _foreach (const ext::Vector<ext::String>, pair, pairs)
81 {
82 ext::String::ConstIterator equal(ext::FindFirstAll(*pair, ext::String("=")));
83 ext::String name(pair->Begin(), equal), value(equal != pair->End() ? equal + 1 : equal, pair->End());
84
85 cgi.insert(std::pair<std::string, std::string>(decode(name), decode(value)));
86 }
87 }
88
89 std::string Represent::decode(const ext::String& encoded)
90 {
91 std::string decoded(encoded);
92 std::string::size_type pos(0);
93
94 while ((pos = decoded.find_first_of("%+", pos)) != std::string::npos) switch (decoded[pos])
95 {
96 case '%':
97 decoded.replace(pos, 3, 1, Hexadecimal(decoded.substr(pos + 1, 2), false).convert<char>(false));
98 break;
99 case '+':
100 decoded[pos] = ' ';
101 }
102
103 return decoded;
104 }
105
106 void Represent::headings(xml::TextWriter& xhtml)
107 {
108 xml::ScopeElement tr(xhtml, "tr");
109 ext::String headings[] = { "Data Type", "Data Representation", "Input Type", "Storage" };
110
111 _for (unsigned, index, 0, sizeof (headings) / sizeof (ext::String))
112 {
113 xml::ScopeElement th(xhtml, "th");
114
115 xhtml.OutputText(headings[index]);
116 }
117 }
118
119 void Represent::form(xml::TextWriter& xhtml)
120 {
121 xml::ScopeElement tr(xhtml, "tr");
122
123 {
124 xml::ScopeElement td(xhtml, "td"), select(xhtml, "select");
125
126 xhtml.SetAttribute("name", "type");
127
128 DataType type(cgi.find("type") != cgi.end() ? cgi.find("type")->second : std::string());
129
130 _foreach (const ext::Vector<DataType>, type_, DataType::enumerate())
131 {
132 xml::ScopeElement option(xhtml, "option");
133
134 if (*type_ == type) xhtml.SetAttribute("selected", "selected");
135
136 xhtml.OutputText(*type_);
137 }
138 }
139
140 {
141 xml::ScopeElement td(xhtml, "td"), input(xhtml, "input");
142
143 xhtml.SetAttribute("name", "data");
144 xhtml.SetAttribute("size", "64");
145 xhtml.SetAttribute("type", "text");
146
147 ext::String data(cgi.find("data") != cgi.end() ? cgi.find("data")->second : std::string());
148
149 xhtml.SetAttribute("value", data);
150 }
151
152 {
153 xml::ScopeElement td(xhtml, "td"), select(xhtml, "select");
154
155 xhtml.SetAttribute("name", "input");
156
157 InputType input(cgi.find("input") != cgi.end() ? cgi.find("input")->second : std::string());
158
159 _foreach (const ext::Vector<InputType>, input_, InputType::enumerate())
160 {
161 xml::ScopeElement option(xhtml, "option");
162
163 if (*input_ == input) xhtml.SetAttribute("selected", "selected");
164
165 xhtml.OutputText(*input_);
166 }
167 }
168
169 xml::ScopeElement td(xhtml, "td"), input(xhtml, "input");
170
171 xhtml.SetAttribute("type", "submit");
172 xhtml.SetAttribute("value", "Store");
173 }
174
175 void Represent::output(xml::TextWriter& xhtml)
176 {
177 typedef std::multimap<std::string, std::string>::size_type MultiMapSize;
178
179 std::set<MultiMapSize, std::greater<MultiMapSize> > count;
180 ext::String names[] = { "type", "data", "input" };
181
182 _for (unsigned, index, 0, sizeof (names) / sizeof (ext::String)) count.insert(cgi.count(names[index]));
183
184 typedef std::multimap<std::string, std::string>::const_iterator MultiMapConstIterator;
185
186 MultiMapConstIterator type(cgi.lower_bound("type")), type_(cgi.upper_bound("type")), data(cgi.lower_bound("data")), data_(cgi.upper_bound("data")), input(cgi.lower_bound("input")), input_(cgi.upper_bound("input"));
187 ext::Vector<Item> items;
188
189 _for (unsigned, index, 0, *count.begin() < 128 ? *count.begin() : 128)
190 {
191 Item item(DataType(type != type_ ? type->second : std::string()), data != data_ ? data->second : std::string(), InputType(input != input_ ? input->second : std::string()));
192
193 items.InsertLast(item);
194
195 if (type != type_) ++type;
196 if (data != data_) ++data;
197 if (input != input_) ++input;
198 }
199
200 _rfor (MultiMapConstIterator, delete_, cgi.lower_bound("delete"), cgi.upper_bound("delete")) items.RemoveAt(lexical_cast<size_t>(delete_->second));
201
202 if (!items.IsEmpty() && items.First().data.IsEmpty()) items.RemoveFirst();
203
204 size_t index(0);
205
206 _foreach (ext::Vector<Item>, item, items) switch (item->type)
207 {
208 case DataType::TYPE_bool:
209 output<bool>(xhtml, *item, ++index);
210 break;
211 case DataType::TYPE_char:
212 output<char>(xhtml, *item, ++index);
213 break;
214 case DataType::TYPE_short:
215 output<short>(xhtml, *item, ++index);
216 break;
217 case DataType::TYPE_unsigned_short:
218 output<unsigned short>(xhtml, *item, ++index);
219 break;
220 case DataType::TYPE_int:
221 output<int>(xhtml, *item, ++index);
222 break;
223 case DataType::TYPE_unsigned_int:
224 output<unsigned int>(xhtml, *item, ++index);
225 break;
226 case DataType::TYPE_long:
227 output<long>(xhtml, *item, ++index);
228 break;
229 case DataType::TYPE_unsigned_long:
230 output<unsigned long>(xhtml, *item, ++index);
231 break;
232 case DataType::TYPE_float:
233 output<float>(xhtml, *item, ++index);
234 break;
235 case DataType::TYPE_double:
236 output<double>(xhtml, *item, ++index);
237 break;
238 case DataType::TYPE_std_string:
239 output<std::string>(xhtml, *item, ++index);
240 break;
241 case DataType::TYPE_ext_String:
242 output<ext::String>(xhtml, *item, ++index);
243 }
244 }
245
246 template <typename Type>
247 void Represent::output(xml::TextWriter& xhtml, const Item& item, size_t index)
248 {
249 xhtml.OpenElement("tr");
250
251 {
252 xml::ScopeElement td(xhtml, "td");
253
254 xhtml.SetAttribute("rowspan", "3");
255 xhtml.OutputText(item.type);
256
257 ext::String names[] = { "type", "data", "input" }, values[] = { item.type, item.data, item.input };
258
259 _for (unsigned, index, 0, sizeof (names) / sizeof (ext::String))
260 {
261 xml::ScopeElement input(xhtml, "input");
262
263 xhtml.SetAttribute("name", names[index]);
264 xhtml.SetAttribute("type", "hidden");
265 xhtml.SetAttribute("value", values[index]);
266 }
267 }
268
269 Type type(input<Type>(item));
270
271 {
272 xml::ScopeElement td(xhtml, "td");
273
274 normal(xhtml, type);
275 }
276
277 {
278 xml::ScopeElement th(xhtml, "th");
279
280 xhtml.OutputText("Normal");
281 }
282
283 {
284 xml::ScopeElement td(xhtml, "td");
285
286 xhtml.SetAttribute("rowspan", "3");
287
288 {
289 xml::ScopeElement input(xhtml, "input");
290
291 xhtml.SetAttribute("name", "delete");
292 xhtml.SetAttribute("type", "checkbox");
293 xhtml.SetAttribute("value", lexical_cast<ext::String>(index));
294 }
295
296 xhtml.OutputText("Delete");
297 }
298
299 xhtml.CloseElement();
300 xhtml.OpenElement("tr");
301
302 {
303 xml::ScopeElement td(xhtml, "td");
304
305 binary(xhtml, type);
306 }
307
308 {
309 xml::ScopeElement th(xhtml, "th");
310
311 xhtml.OutputText("Binary");
312 }
313
314 xhtml.CloseElement();
315 xhtml.OpenElement("tr");
316
317 {
318 xml::ScopeElement td(xhtml, "td");
319
320 hexadecimal(xhtml, type);
321 }
322
323 {
324 xml::ScopeElement th(xhtml, "th");
325
326 xhtml.OutputText("Hexadecimal");
327 }
328
329 xhtml.CloseElement();
330 }
331
332 template <typename Type>
333 Type Represent::input(const Item& item)
334 {
335 bool signed_(etl::Limits<Type>::IsSigned);
336
337 switch (item.input)
338 {
339 default:
340 try { return lexical_cast<Type>(item.data); } catch (ext::Exception) { return 0; }
341 case InputType::INPUT_Binary:
342 return Binary(item.data, signed_).convert<Type>(signed_);
343 case InputType::INPUT_Hexadecimal:
344 return Hexadecimal(item.data, signed_).convert<Type>(signed_);
345 }
346 }
347
348 template <>
349 char Represent::input(const Item& item)
350 {
351 switch (item.input)
352 {
353 default:
354 return item.data.First();
355 case InputType::INPUT_Binary:
356 return Binary(item.data, false).convert<char>(false);
357 case InputType::INPUT_Hexadecimal:
358 return Hexadecimal(item.data, false).convert<char>(false);
359 }
360 }
361
362 template <>
363 std::string Represent::input(const Item& item)
364 {
365 std::string string;
366
367 switch (item.input)
368 {
369 default:
370 return item.data;
371 case InputType::INPUT_Binary:
372 _foreach (const _L<ext::String>, atom, ext::SplitAll(item.data, ext::String(" "))) string += Binary(*atom, false).convert<char>(false);
373 break;
374 case InputType::INPUT_Hexadecimal:
375 _foreach (const _L<ext::String>, atom, ext::SplitAll(item.data, ext::String(" "))) string += Hexadecimal(*atom, false).convert<char>(false);
376 }
377
378 return string;
379 }
380
381 template <>
382 ext::String Represent::input(const Item& item)
383 {
384 ext::String string;
385
386 switch (item.input)
387 {
388 default:
389 return item.data;
390 case InputType::INPUT_Binary:
391 _foreach (const _L<ext::String>, atom, ext::SplitAll(item.data, ext::String(" "))) string.InsertLast(Binary(*atom, false).convert<uint32_t>(false));
392 break;
393 case InputType::INPUT_Hexadecimal:
394 _foreach (const _L<ext::String>, atom, ext::SplitAll(item.data, ext::String(" "))) string.InsertLast(Hexadecimal(*atom, false).convert<uint32_t>(false));
395 }
396
397 return string;
398 }
399
400 template <typename Type>
401 void Represent::normal(xml::TextWriter& xhtml, const Type& type)
402 {
403 xhtml.OutputText(lexical_cast<ext::String>(type));
404 }
405
406 template <>
407 void Represent::normal(xml::TextWriter& xhtml, const char& char_)
408 {
409 xhtml.OutputText("'");
410 xhtml.OutputText(std::string(1, char_).c_str());
411 xhtml.OutputText("'");
412 }
413
414 template <>
415 void Represent::normal(xml::TextWriter& xhtml, const std::string& string)
416 {
417 xhtml.OutputText("\"");
418 xhtml.OutputText(string);
419 xhtml.OutputText("\"");
420 }
421
422 template <>
423 void Represent::normal(xml::TextWriter& xhtml, const ext::String& string)
424 {
425 xhtml.OutputText("\"");
426 xhtml.OutputText(string);
427 xhtml.OutputText("\"");
428 }
429
430 template <typename Type>
431 void Represent::binary(xml::TextWriter& xhtml, const Type& type)
432 {
433 xhtml.OutputText(Binary(type));
434 }
435
436 template <>
437 void Represent::binary(xml::TextWriter& xhtml, const std::string& string)
438 {
439 xhtml.OutputText(Binary(string));
440
441 xml::ScopeElement(xhtml, "br");
442
443 _sforeach (std::string, atom, string)
444 {
445 xml::ScopeElement(xhtml, "br");
446
447 xhtml.OutputText(Binary(*atom));
448 xhtml.OutputText(" = '");
449 xhtml.OutputText(ext::CodePoint(*atom));
450 xhtml.OutputText("'");
451 }
452 }
453
454 template <>
455 void Represent::binary(xml::TextWriter& xhtml, const ext::String& string)
456 {
457 xhtml.OutputText(Binary(string));
458
459 xml::ScopeElement(xhtml, "br");
460
461 _foreach (const ext::String, atom, string)
462 {
463 xml::ScopeElement(xhtml, "br");
464
465 xhtml.OutputText(Binary(*atom));
466 xhtml.OutputText(" = '");
467 xhtml.OutputText(ext::CodePoint(*atom));
468 xhtml.OutputText("'");
469 }
470 }
471
472 template <typename Type>
473 void Represent::hexadecimal(xml::TextWriter& xhtml, const Type& type)
474 {
475 xhtml.OutputText(Hexadecimal(type));
476 }
477
478 template <>
479 void Represent::hexadecimal(xml::TextWriter& xhtml, const std::string& string)
480 {
481 xhtml.OutputText(Hexadecimal(string));
482
483 xml::ScopeElement(xhtml, "br");
484
485 _sforeach (std::string, atom, string)
486 {
487 xml::ScopeElement(xhtml, "br");
488
489 xhtml.OutputText(Hexadecimal(*atom));
490 xhtml.OutputText(" = '");
491 xhtml.OutputText(ext::CodePoint(*atom));
492 xhtml.OutputText("'");
493 }
494 }
495
496 template <>
497 void Represent::hexadecimal(xml::TextWriter& xhtml, const ext::String& string)
498 {
499 xhtml.OutputText(Hexadecimal(string));
500
501 xml::ScopeElement(xhtml, "br");
502
503 _foreach (const ext::String, atom, string)
504 {
505 xml::ScopeElement(xhtml, "br");
506
507 xhtml.OutputText(Hexadecimal(*atom));
508 xhtml.OutputText(" = '");
509 xhtml.OutputText(ext::CodePoint(*atom));
510 xhtml.OutputText("'");
511 }
512 }

Properties

Name Value
svn:eol-style native
svn:keywords Id