summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Elements')
-rw-r--r--Swiften/Elements/Form.cpp8
-rw-r--r--Swiften/Elements/FormField.cpp33
-rw-r--r--Swiften/Elements/FormField.h126
-rw-r--r--Swiften/Elements/UnitTest/FormTest.cpp13
4 files changed, 118 insertions, 62 deletions
diff --git a/Swiften/Elements/Form.cpp b/Swiften/Elements/Form.cpp
index cf9ecf6..c4ae410 100644
--- a/Swiften/Elements/Form.cpp
+++ b/Swiften/Elements/Form.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -11,8 +11,10 @@ namespace Swift {
std::string Form::getFormType() const {
FormField::ref field = getField("FORM_TYPE");
- boost::shared_ptr<HiddenFormField> f = boost::dynamic_pointer_cast<HiddenFormField>(field);
- return (f ? f->getValue() : "");
+ if (field && field->getType() == FormField::HiddenType) {
+ return field->getValues().empty() ? "" : field->getValues()[0];
+ }
+ return "";
}
FormField::ref Form::getField(const std::string& name) const {
diff --git a/Swiften/Elements/FormField.cpp b/Swiften/Elements/FormField.cpp
new file mode 100644
index 0000000..27ced82
--- /dev/null
+++ b/Swiften/Elements/FormField.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2013 Remko Tronçon
+ * Licensed under the GNU General Public License.
+ * See the COPYING file for more information.
+ */
+
+#include <Swiften/Elements/FormField.h>
+
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/algorithm/string/classification.hpp>
+
+using namespace Swift;
+
+FormField::~FormField() {
+}
+
+std::string FormField::getTextMultiValue() const {
+ assert(type == TextMultiType || type == UnknownType);
+ return boost::algorithm::join(values, "\n");
+}
+
+void FormField::setTextMultiValue(const std::string& value) {
+ assert(type == TextMultiType || type == UnknownType);
+ values.clear();
+ boost::split(values, value, boost::is_any_of("\n"));
+}
+
+void FormField::setBoolValue(bool b) {
+ assert(type == BooleanType || type == UnknownType);
+ values.clear();
+ values.push_back(b ? "1" : "0");
+}
diff --git a/Swiften/Elements/FormField.h b/Swiften/Elements/FormField.h
index fbd1ebe..26e70bb 100644
--- a/Swiften/Elements/FormField.h
+++ b/Swiften/Elements/FormField.h
@@ -1,12 +1,9 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
-// FIXME: We currently keep 2 values: the raw values, and the actual value.
-// We should only store the raw values, and deduce the actual values from this
-
#pragma once
#include <vector>
@@ -20,7 +17,25 @@ namespace Swift {
public:
typedef boost::shared_ptr<FormField> ref;
- virtual ~FormField() {}
+ enum Type {
+ UnknownType,
+ BooleanType,
+ FixedType,
+ HiddenType,
+ ListSingleType,
+ TextMultiType,
+ TextPrivateType,
+ TextSingleType,
+ JIDSingleType,
+ JIDMultiType,
+ ListMultiType
+ };
+
+ FormField(Type type = UnknownType) : type(type), required(false) {}
+ FormField(Type type, const std::string& value) : type(type), required(false) {
+ addValue(value);
+ }
+ virtual ~FormField();
struct Option {
Option(const std::string& label, const std::string& value) : label(label), value(value) {}
@@ -48,67 +63,72 @@ namespace Swift {
return options;
}
- const std::vector<std::string>& getRawValues() const {
- return rawValues;
+ const std::vector<std::string>& getValues() const {
+ return values;
}
- void addRawValue(const std::string& value) {
- rawValues.push_back(value);
+ void addValue(const std::string& value) {
+ values.push_back(value);
}
- protected:
- FormField() : required(false) {}
+ Type getType() const {
+ return type;
+ }
- private:
- std::string name;
- std::string label;
- std::string description;
- bool required;
- std::vector<Option> options;
- std::vector<std::string> rawValues;
- };
+ void setType(Type type) {
+ this->type = type;
+ }
- template<typename T> class GenericFormField : public FormField {
- public:
- const T& getValue() const {
- return value;
+ // Type specific
+
+ bool getBoolValue() const {
+ assert(type == BooleanType || type == UnknownType);
+ if (values.empty()) {
+ return false;
+ }
+ return values[0] == "true" || values[0] == "1";
}
- void setValue(const T& value) {
- this->value = value;
+ void setBoolValue(bool b);
+
+ JID getJIDSingleValue() const {
+ assert(type == JIDSingleType || type == UnknownType);
+ return values.empty() ? JID() : JID(values[0]);
}
+ JID getJIDMultiValue(size_t index) const {
+ assert(type == JIDMultiType || type == UnknownType);
+ return values.empty() ? JID() : JID(values[index]);
+ }
+
+ std::string getTextPrivateValue() const {
+ assert(type == TextPrivateType || type == UnknownType);
+ return values.empty() ? "" : values[0];
+ }
+
+ std::string getFixedValue() const {
+ assert(type == FixedType || type == UnknownType);
+ return values.empty() ? "" : values[0];
+ }
+
+ std::string getTextSingleValue() const {
+ assert(type == TextSingleType || type == UnknownType);
+ return values.empty() ? "" : values[0];
+ }
+
+ std::string getTextMultiValue() const;
+ void setTextMultiValue(const std::string& value);
+
protected:
- GenericFormField() : value() {}
- GenericFormField(const T& value) : value(value) {}
private:
- T value;
- };
-
-#define SWIFTEN_DECLARE_FORM_FIELD(name, valueType) \
- class name##FormField : public GenericFormField< valueType > { \
- public: \
- typedef boost::shared_ptr<name##FormField> ref; \
- static ref create(const valueType& value) { \
- return ref(new name##FormField(value)); \
- } \
- static ref create() { \
- return ref(new name##FormField()); \
- } \
- private: \
- name##FormField(valueType value) : GenericFormField< valueType >(value) {} \
- name##FormField() : GenericFormField< valueType >() {} \
+ Type type;
+ std::string name;
+ std::string label;
+ std::string description;
+ bool required;
+ std::vector<Option> options;
+ std::vector<std::string> values;
};
- SWIFTEN_DECLARE_FORM_FIELD(Boolean, bool)
- SWIFTEN_DECLARE_FORM_FIELD(Fixed, std::string)
- SWIFTEN_DECLARE_FORM_FIELD(Hidden, std::string)
- SWIFTEN_DECLARE_FORM_FIELD(ListSingle, std::string)
- SWIFTEN_DECLARE_FORM_FIELD(TextMulti, std::string)
- SWIFTEN_DECLARE_FORM_FIELD(TextPrivate, std::string)
- SWIFTEN_DECLARE_FORM_FIELD(TextSingle, std::string)
- SWIFTEN_DECLARE_FORM_FIELD(JIDSingle, JID)
- SWIFTEN_DECLARE_FORM_FIELD(JIDMulti, std::vector<JID>)
- SWIFTEN_DECLARE_FORM_FIELD(ListMulti, std::vector<std::string>)
}
diff --git a/Swiften/Elements/UnitTest/FormTest.cpp b/Swiften/Elements/UnitTest/FormTest.cpp
index 1134182..3000c22 100644
--- a/Swiften/Elements/UnitTest/FormTest.cpp
+++ b/Swiften/Elements/UnitTest/FormTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010 Remko Tronçon
+ * Copyright (c) 2010-2013 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
@@ -7,6 +7,7 @@
#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <boost/shared_ptr.hpp>
+#include <boost/smart_ptr/make_shared.hpp>
#include <Swiften/Elements/Form.h>
@@ -23,13 +24,13 @@ class FormTest : public CppUnit::TestFixture {
void testGetFormType() {
Form form;
- form.addField(FixedFormField::create("Foo"));
+ form.addField(boost::make_shared<FormField>(FormField::FixedType, "Foo"));
- FormField::ref field = HiddenFormField::create("jabber:bot");
+ FormField::ref field = boost::make_shared<FormField>(FormField::HiddenType, "jabber:bot");
field->setName("FORM_TYPE");
form.addField(field);
- form.addField(FixedFormField::create("Bar"));
+ form.addField(boost::make_shared<FormField>(FormField::FixedType, "Bar"));
CPPUNIT_ASSERT_EQUAL(std::string("jabber:bot"), form.getFormType());
}
@@ -37,7 +38,7 @@ class FormTest : public CppUnit::TestFixture {
void testGetFormType_InvalidFormType() {
Form form;
- FormField::ref field = FixedFormField::create("jabber:bot");
+ FormField::ref field = boost::make_shared<FormField>(FormField::FixedType, "jabber:bot");
field->setName("FORM_TYPE");
form.addField(field);
@@ -47,7 +48,7 @@ class FormTest : public CppUnit::TestFixture {
void testGetFormType_NoFormType() {
Form form;
- form.addField(FixedFormField::create("Foo"));
+ form.addField(boost::make_shared<FormField>(FormField::FixedType, "Foo"));
CPPUNIT_ASSERT_EQUAL(std::string(""), form.getFormType());
}