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

# User Rev Content
1 douglas 362 // Represent
2     //
3     // Douglas Thrift
4     //
5     // $Id$
6    
7 douglas 371 #include "Hexadecimal.hpp"
8 douglas 380 #include "DataType.hpp"
9 douglas 387 #include "InputType.hpp"
10 douglas 362
11 douglas 386 #ifdef _WIN32
12 douglas 389 #pragma warning(disable:4267 4288)
13 douglas 386 #endif
14    
15 douglas 370 #include <menes-app/simple.hpp>
16 douglas 387 #include <menes-xml/document.hpp>
17     #include <menes-xml/nodeset.hpp>
18     #include <menes-xml/parse.hpp>
19 douglas 362
20 douglas 389 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 douglas 370 int Main(const app::Options& options)
34 douglas 362 {
35 douglas 370 Represent represent;
36 douglas 362
37 douglas 370 return 0;
38 douglas 362 }
39    
40 douglas 370 Represent::Represent()
41 douglas 362 {
42 douglas 387 api::Cout << "Content-Type: text/html; charset=UTF-8\r\n\r\n" << ios::Flush;
43    
44 douglas 388 xml::TextWriter xhtml(api::Cout);
45    
46 douglas 379 parse();
47 douglas 371
48 douglas 387 _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 douglas 371
52 douglas 388 api::Cout << ios::NewLine << before << ios::Flush;
53 douglas 387
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 douglas 379 }
64 douglas 373
65 douglas 379 void Represent::parse()
66     {
67     ext::String query(env.get("QUERY_STRING"));
68 douglas 373
69 douglas 379 if (env.get("REQUEST_METHOD") == "POST")
70     {
71     ext::Buffer content(lexical_cast<size_t>(env.get("CONTENT_LENGTH")));
72 douglas 373
73 douglas 379 api::Cin.ReadFully(content.Begin(), content.GetSize());
74 douglas 373
75 douglas 379 query = content;
76     }
77    
78 douglas 422 ext::Vector<ext::String> pairs(ext::SplitAll(query, ext::String("&")));
79 douglas 379
80 douglas 422 _foreach (const ext::Vector<ext::String>, pair, pairs)
81 douglas 379 {
82 douglas 422 ext::String::ConstIterator equal(ext::FindFirstAll(*pair, ext::String("=")));
83 douglas 379 ext::String name(pair->Begin(), equal), value(equal != pair->End() ? equal + 1 : equal, pair->End());
84    
85 douglas 393 cgi.insert(std::pair<std::string, std::string>(decode(name), decode(value)));
86     }
87     }
88 douglas 387
89 douglas 393 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 douglas 379 }
102 douglas 393
103     return decoded;
104 douglas 362 }
105 douglas 380
106     void Represent::headings(xml::TextWriter& xhtml)
107     {
108     xml::ScopeElement tr(xhtml, "tr");
109 douglas 387 ext::String headings[] = { "Data Type", "Data Representation", "Input Type", "Storage" };
110 douglas 380
111 douglas 422 _for (unsigned, index, 0, sizeof (headings) / sizeof (ext::String))
112 douglas 380 {
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 douglas 387 DataType type(cgi.find("type") != cgi.end() ? cgi.find("type")->second : std::string());
129 douglas 380
130 douglas 422 _foreach (const ext::Vector<DataType>, type_, DataType::enumerate())
131 douglas 380 {
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 douglas 387 xhtml.SetAttribute("name", "input");
156 douglas 380
157 douglas 387 InputType input(cgi.find("input") != cgi.end() ? cgi.find("input")->second : std::string());
158    
159 douglas 422 _foreach (const ext::Vector<InputType>, input_, InputType::enumerate())
160 douglas 380 {
161     xml::ScopeElement option(xhtml, "option");
162    
163 douglas 387 if (*input_ == input) xhtml.SetAttribute("selected", "selected");
164 douglas 380
165 douglas 387 xhtml.OutputText(*input_);
166 douglas 380 }
167     }
168    
169     xml::ScopeElement td(xhtml, "td"), input(xhtml, "input");
170    
171     xhtml.SetAttribute("type", "submit");
172     xhtml.SetAttribute("value", "Store");
173     }
174 douglas 385
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 douglas 422 _for (unsigned, index, 0, sizeof (names) / sizeof (ext::String)) count.insert(cgi.count(names[index]));
183 douglas 385
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 douglas 422 _for (unsigned, index, 0, *count.begin() < 128 ? *count.begin() : 128)
190 douglas 385 {
191 douglas 387 Item item(DataType(type != type_ ? type->second : std::string()), data != data_ ? data->second : std::string(), InputType(input != input_ ? input->second : std::string()));
192 douglas 385
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 douglas 395 if (!items.IsEmpty() && items.First().data.IsEmpty()) items.RemoveFirst();
203 douglas 394
204 douglas 387 size_t index(0);
205    
206 douglas 385 _foreach (ext::Vector<Item>, item, items) switch (item->type)
207     {
208     case DataType::TYPE_bool:
209 douglas 387 output<bool>(xhtml, *item, ++index);
210 douglas 385 break;
211     case DataType::TYPE_char:
212 douglas 387 output<char>(xhtml, *item, ++index);
213 douglas 385 break;
214 douglas 387 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 douglas 385 }
244     }
245 douglas 387
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 douglas 422 _for (unsigned, index, 0, sizeof (names) / sizeof (ext::String))
260 douglas 387 {
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 douglas 391 bool signed_(etl::Limits<Type>::IsSigned);
336 douglas 387
337 douglas 391 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 douglas 387 }
347    
348     template <>
349     char Represent::input(const Item& item)
350     {
351 douglas 391 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 douglas 392 return Hexadecimal(item.data, false).convert<char>(false);
359 douglas 391 }
360 douglas 387 }
361    
362     template <>
363     std::string Represent::input(const Item& item)
364     {
365 douglas 399 std::string string;
366    
367     switch (item.input)
368     {
369     default:
370     return item.data;
371     case InputType::INPUT_Binary:
372 douglas 422 _foreach (const _L<ext::String>, atom, ext::SplitAll(item.data, ext::String(" "))) string += Binary(*atom, false).convert<char>(false);
373 douglas 399 break;
374     case InputType::INPUT_Hexadecimal:
375 douglas 422 _foreach (const _L<ext::String>, atom, ext::SplitAll(item.data, ext::String(" "))) string += Hexadecimal(*atom, false).convert<char>(false);
376 douglas 399 }
377    
378     return string;
379 douglas 387 }
380    
381     template <>
382     ext::String Represent::input(const Item& item)
383     {
384 douglas 399 ext::String string;
385    
386     switch (item.input)
387     {
388     default:
389     return item.data;
390     case InputType::INPUT_Binary:
391 douglas 422 _foreach (const _L<ext::String>, atom, ext::SplitAll(item.data, ext::String(" "))) string.InsertLast(Binary(*atom, false).convert<uint32_t>(false));
392 douglas 399 break;
393     case InputType::INPUT_Hexadecimal:
394 douglas 422 _foreach (const _L<ext::String>, atom, ext::SplitAll(item.data, ext::String(" "))) string.InsertLast(Hexadecimal(*atom, false).convert<uint32_t>(false));
395 douglas 399 }
396    
397     return string;
398 douglas 387 }
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 douglas 393 xhtml.OutputText("'");
410     xhtml.OutputText(std::string(1, char_).c_str());
411     xhtml.OutputText("'");
412 douglas 387 }
413    
414     template <>
415     void Represent::normal(xml::TextWriter& xhtml, const std::string& string)
416     {
417 douglas 393 xhtml.OutputText("\"");
418 douglas 387 xhtml.OutputText(string);
419 douglas 393 xhtml.OutputText("\"");
420 douglas 387 }
421    
422     template <>
423     void Represent::normal(xml::TextWriter& xhtml, const ext::String& string)
424     {
425 douglas 393 xhtml.OutputText("\"");
426 douglas 387 xhtml.OutputText(string);
427 douglas 393 xhtml.OutputText("\"");
428 douglas 387 }
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 douglas 393 xhtml.OutputText(" = '");
449     xhtml.OutputText(ext::CodePoint(*atom));
450     xhtml.OutputText("'");
451 douglas 387 }
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 douglas 422 _foreach (const ext::String, atom, string)
462 douglas 387 {
463     xml::ScopeElement(xhtml, "br");
464    
465     xhtml.OutputText(Binary(*atom));
466 douglas 393 xhtml.OutputText(" = '");
467     xhtml.OutputText(ext::CodePoint(*atom));
468     xhtml.OutputText("'");
469 douglas 387 }
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 douglas 393 xhtml.OutputText(Hexadecimal(*atom));
490     xhtml.OutputText(" = '");
491     xhtml.OutputText(ext::CodePoint(*atom));
492     xhtml.OutputText("'");
493 douglas 387 }
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 douglas 422 _foreach (const ext::String, atom, string)
504 douglas 387 {
505     xml::ScopeElement(xhtml, "br");
506    
507 douglas 393 xhtml.OutputText(Hexadecimal(*atom));
508     xhtml.OutputText(" = '");
509     xhtml.OutputText(ext::CodePoint(*atom));
510     xhtml.OutputText("'");
511 douglas 387 }
512     }

Properties

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