ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/repos/Represent/Represent.cpp
Revision: 395
Committed: 2004-12-24T22:48:09-08:00 (20 years, 5 months ago) by douglas
File size: 11367 byte(s)
Log Message:
Oops!

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     ext::Vector<ext::String> pairs(query.Split('&'));
79    
80     _foreach (ext::Vector<ext::String>, pair, pairs)
81     {
82     ext::String::ConstIterator equal(pair->FindFirst('='));
83     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     _foru (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 douglas 387 DataType type(cgi.find("type") != cgi.end() ? cgi.find("type")->second : std::string());
129 douglas 380
130     _foreach (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 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     _foreach (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     _foru (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 douglas 393 _foru (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     _foru (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 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 douglas 391 // XXX: constructing a string from Binary or Hexadecimal seems too dangerous
363 douglas 387 template <>
364     std::string Represent::input(const Item& item)
365     {
366     return item.data;
367     }
368    
369 douglas 391 // XXX: constructing a string from Binary or Hexadecimal seems too dangerous
370 douglas 387 template <>
371     ext::String Represent::input(const Item& item)
372     {
373     return item.data;
374     }
375    
376     template <typename Type>
377     void Represent::normal(xml::TextWriter& xhtml, const Type& type)
378     {
379     xhtml.OutputText(lexical_cast<ext::String>(type));
380     }
381    
382 douglas 393 // XXX: damn, this one is really quite screwy
383 douglas 387 template <>
384     void Represent::normal(xml::TextWriter& xhtml, const char& char_)
385     {
386 douglas 393 xhtml.OutputText("'");
387     xhtml.OutputText(std::string(1, char_).c_str());
388     xhtml.OutputText("'");
389 douglas 387 }
390    
391     template <>
392     void Represent::normal(xml::TextWriter& xhtml, const std::string& string)
393     {
394 douglas 393 xhtml.OutputText("\"");
395 douglas 387 xhtml.OutputText(string);
396 douglas 393 xhtml.OutputText("\"");
397 douglas 387 }
398    
399     template <>
400     void Represent::normal(xml::TextWriter& xhtml, const ext::String& string)
401     {
402 douglas 393 xhtml.OutputText("\"");
403 douglas 387 xhtml.OutputText(string);
404 douglas 393 xhtml.OutputText("\"");
405 douglas 387 }
406    
407     template <typename Type>
408     void Represent::binary(xml::TextWriter& xhtml, const Type& type)
409     {
410     xhtml.OutputText(Binary(type));
411     }
412    
413     template <>
414     void Represent::binary(xml::TextWriter& xhtml, const std::string& string)
415     {
416     xhtml.OutputText(Binary(string));
417    
418     xml::ScopeElement(xhtml, "br");
419    
420     _sforeach (std::string, atom, string)
421     {
422     xml::ScopeElement(xhtml, "br");
423    
424     xhtml.OutputText(Binary(*atom));
425 douglas 393 xhtml.OutputText(" = '");
426     xhtml.OutputText(ext::CodePoint(*atom));
427     xhtml.OutputText("'");
428 douglas 387 }
429     }
430    
431     template <>
432     void Represent::binary(xml::TextWriter& xhtml, const ext::String& string)
433     {
434     xhtml.OutputText(Binary(string));
435    
436     xml::ScopeElement(xhtml, "br");
437    
438     _foreach (ext::String, atom, string)
439     {
440     xml::ScopeElement(xhtml, "br");
441    
442     xhtml.OutputText(Binary(*atom));
443 douglas 393 xhtml.OutputText(" = '");
444     xhtml.OutputText(ext::CodePoint(*atom));
445     xhtml.OutputText("'");
446 douglas 387 }
447     }
448    
449     template <typename Type>
450     void Represent::hexadecimal(xml::TextWriter& xhtml, const Type& type)
451     {
452     xhtml.OutputText(Hexadecimal(type));
453     }
454    
455     template <>
456     void Represent::hexadecimal(xml::TextWriter& xhtml, const std::string& string)
457     {
458     xhtml.OutputText(Hexadecimal(string));
459    
460     xml::ScopeElement(xhtml, "br");
461    
462     _sforeach (std::string, atom, string)
463     {
464     xml::ScopeElement(xhtml, "br");
465    
466 douglas 393 xhtml.OutputText(Hexadecimal(*atom));
467     xhtml.OutputText(" = '");
468     xhtml.OutputText(ext::CodePoint(*atom));
469     xhtml.OutputText("'");
470 douglas 387 }
471     }
472    
473     template <>
474     void Represent::hexadecimal(xml::TextWriter& xhtml, const ext::String& string)
475     {
476     xhtml.OutputText(Hexadecimal(string));
477    
478     xml::ScopeElement(xhtml, "br");
479    
480     _foreach (ext::String, atom, string)
481     {
482     xml::ScopeElement(xhtml, "br");
483    
484 douglas 393 xhtml.OutputText(Hexadecimal(*atom));
485     xhtml.OutputText(" = '");
486     xhtml.OutputText(ext::CodePoint(*atom));
487     xhtml.OutputText("'");
488 douglas 387 }
489     }

Properties

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