1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
/*
* Copyright (c) 2010 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
#include <Swiften/Elements/Form.h>
#include <Swiften/Parser/GenericPayloadParser.h>
namespace Swift {
class FormParser : public GenericPayloadParser<Form> {
public:
FormParser();
virtual void handleStartElement(const std::string& element, const std::string&, const AttributeMap& attributes);
virtual void handleEndElement(const std::string& element, const std::string&);
virtual void handleCharacterData(const std::string& data);
private:
class FieldParseHelper {
public:
virtual ~FieldParseHelper() {}
virtual void addValue(const std::string&) = 0;
virtual boost::shared_ptr<FormField> getField() const {
return field;
}
protected:
boost::shared_ptr<FormField> field;
};
class BoolFieldParseHelper : public FieldParseHelper {
virtual void addValue(const std::string& s) {
boost::dynamic_pointer_cast< GenericFormField<bool> >(getField())->setValue(s == "1" || s == "true");
getField()->addRawValue(s);
}
};
class StringFieldParseHelper : public FieldParseHelper {
virtual void addValue(const std::string& s) {
boost::shared_ptr<GenericFormField<std::string> > field = boost::dynamic_pointer_cast< GenericFormField<std::string> >(getField());
if (field->getValue().empty()) {
field->setValue(s);
}
else {
field->setValue(field->getValue() + "\n" + s);
}
getField()->addRawValue(s);
}
};
class JIDFieldParseHelper : public FieldParseHelper {
virtual void addValue(const std::string& s) {
getField()->addRawValue(s);
boost::dynamic_pointer_cast< GenericFormField<JID> >(getField())->setValue(JID(s));
}
};
class StringListFieldParseHelper : public FieldParseHelper {
virtual void addValue(const std::string& s) {
// FIXME: Inefficient, but too much hassle to do efficiently
boost::shared_ptr<GenericFormField< std::vector<std::string> > > field = boost::dynamic_pointer_cast< GenericFormField<std::vector<std::string > > >(getField());
std::vector<std::string> l = field->getValue();
l.push_back(s);
field->setValue(l);
getField()->addRawValue(s);
}
};
class JIDListFieldParseHelper : public FieldParseHelper {
virtual void addValue(const std::string& s) {
// FIXME: Inefficient, but too much hassle to do efficiently
boost::shared_ptr< GenericFormField< std::vector<JID> > > field = boost::dynamic_pointer_cast< GenericFormField<std::vector<JID > > >(getField());
std::vector<JID> l = field->getValue();
l.push_back(JID(s));
field->setValue(l);
getField()->addRawValue(s);
}
};
#define SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(name, baseParser) \
class name##FormFieldParseHelper : public baseParser##FieldParseHelper { \
public: \
typedef boost::shared_ptr<name##FormFieldParseHelper> ref; \
static ref create() { \
return ref(new name##FormFieldParseHelper()); \
} \
private: \
name##FormFieldParseHelper() : baseParser##FieldParseHelper() { \
field = name##FormField::create(); \
} \
};
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(Boolean, Bool);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(Fixed, String);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(Hidden, String);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(ListSingle, String);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(TextMulti, String);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(TextPrivate, String);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(TextSingle, String);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(JIDSingle, JID);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(JIDMulti, JIDList);
SWIFTEN_DECLARE_FORM_FIELD_PARSE_HELPER(ListMulti, StringList);
enum Level {
TopLevel = 0,
PayloadLevel = 1,
FieldLevel = 2
};
int level_;
std::string currentText_;
std::string currentOptionLabel_;
boost::shared_ptr<FieldParseHelper> currentFieldParseHelper_;
bool parsingItem_;
bool parsingReported_;
std::vector<FormField::ref> currentFields_;
};
}
|