Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "variant_topic_tools/ArrayDataType.h"
00020 #include "variant_topic_tools/ArraySerializer.h"
00021 #include "variant_topic_tools/ArrayVariant.h"
00022 #include "variant_topic_tools/Exceptions.h"
00023
00024 namespace variant_topic_tools {
00025
00026
00027
00028
00029
00030 ArrayVariant::ArrayVariant() {
00031 }
00032
00033 ArrayVariant::ArrayVariant(const DataType& type, const DataType& memberType,
00034 size_t numMembers) :
00035 CollectionVariant(type) {
00036 if (type.isValid())
00037 value.reset(new ValueImplV(memberType, numMembers));
00038 }
00039
00040 ArrayVariant::ArrayVariant(const ArrayVariant& src) :
00041 CollectionVariant(src) {
00042 }
00043
00044 ArrayVariant::ArrayVariant(const Variant& src) :
00045 CollectionVariant(src) {
00046 if (value)
00047 BOOST_ASSERT(boost::dynamic_pointer_cast<Value>(value));
00048 }
00049
00050 ArrayVariant::~ArrayVariant() {
00051 }
00052
00053 ArrayVariant::Value::Value() {
00054 }
00055
00056 ArrayVariant::Value::~Value() {
00057 }
00058
00059 ArrayVariant::ValueImplV::ValueImplV(const DataType& memberType, size_t
00060 numMembers) :
00061 memberType(memberType),
00062 numMembers(numMembers),
00063 members(numMembers) {
00064 for (size_t i = 0; i < numMembers; ++i)
00065 members[i] = memberType.createVariant();
00066 }
00067
00068 ArrayVariant::ValueImplV::ValueImplV(const ValueImplV& src) :
00069 memberType(src.memberType),
00070 numMembers(src.numMembers),
00071 members(src.members) {
00072 }
00073
00074 ArrayVariant::ValueImplV::~ValueImplV() {
00075 }
00076
00077
00078
00079
00080
00081 void ArrayVariant::Value::setValue(const Variant::Value& value) {
00082 const Value& arrayValue = dynamic_cast<const Value&>(value);
00083
00084 resize(arrayValue.getNumMembers());
00085
00086 for (size_t i = 0; i < getNumMembers(); ++i)
00087 setMember(i, arrayValue.getMember(i));
00088 }
00089
00090 void ArrayVariant::Value::setMember(const std::string& name, const Variant&
00091 member) {
00092 int index;
00093
00094 try {
00095 index = boost::lexical_cast<int>(name);
00096 }
00097 catch (...) {
00098 throw NoSuchMemberException(name);
00099 }
00100
00101 return setMember(index, member);
00102 }
00103
00104 Variant ArrayVariant::Value::getMember(const std::string& name) const {
00105 int index;
00106
00107 try {
00108 index = boost::lexical_cast<int>(name);
00109 }
00110 catch (...) {
00111 throw NoSuchMemberException(name);
00112 }
00113
00114 return getMember(index);
00115 }
00116
00117 bool ArrayVariant::Value::hasMember(const std::string& name) const {
00118 int index;
00119
00120 try {
00121 index = boost::lexical_cast<int>(name);
00122 }
00123 catch (...) {
00124 return false;
00125 }
00126
00127 return (index < getNumMembers());
00128 }
00129
00130
00131 size_t ArrayVariant::ValueImplV::getNumMembers() const {
00132 return members.size();
00133 }
00134
00135 void ArrayVariant::ValueImplV::setMember(int index, const Variant&
00136 member) {
00137 if (index < members.size())
00138 members[index] = member;
00139 else
00140 throw NoSuchMemberException(index);
00141 }
00142
00143 Variant ArrayVariant::ValueImplV::getMember(int index) const {
00144 if (index < members.size())
00145 return members[index];
00146 else
00147 throw NoSuchMemberException(index);
00148 }
00149
00150
00151
00152
00153
00154 void ArrayVariant::addMember(const Variant& member) {
00155 if (value) {
00156 if (member.getType().isValid())
00157 boost::dynamic_pointer_cast<Value>(value)->addMember(member);
00158 else
00159 throw InvalidDataTypeException();
00160 }
00161 else
00162 throw InvalidOperationException("Adding a member to an invalid array");
00163 }
00164
00165 void ArrayVariant::resize(size_t numMembers) {
00166 if (value)
00167 boost::dynamic_pointer_cast<Value>(value)->resize(numMembers);
00168 else if (numMembers)
00169 throw InvalidOperationException("Resizing an invalid array");
00170 }
00171
00172 void ArrayVariant::clear() {
00173 if (value)
00174 boost::dynamic_pointer_cast<Value>(value)->clear();
00175 }
00176
00177 void ArrayVariant::Value::writeMember(std::ostream& stream, int index)
00178 const {
00179 if (!getMember(index).getType().isBuiltin()) {
00180 stream << boost::lexical_cast<std::string>(index) << ":";
00181
00182 std::stringstream memberStream;
00183 std::string line;
00184
00185 memberStream << getMember(index);
00186
00187 while (std::getline(memberStream, line))
00188 stream << "\n " << line;
00189 }
00190 else
00191 stream << boost::lexical_cast<std::string>(index) << ": " <<
00192 getMember(index);
00193 }
00194
00195 void ArrayVariant::ValueImplV::addMember(const Variant& member) {
00196 if (!numMembers) {
00197 if (member.getType() == memberType)
00198 members.push_back(member);
00199 else
00200 throw DataTypeMismatchException(memberType.getIdentifier(),
00201 member.getType().getIdentifier());
00202 }
00203 else
00204 throw InvalidOperationException("Adding a member to a non-dynamic array");
00205 }
00206
00207 void ArrayVariant::ValueImplV::resize(size_t numMembers) {
00208 if (!this->numMembers || (numMembers == this->numMembers)) {
00209 if (numMembers != members.size()) {
00210 size_t i = members.size();
00211
00212 members.resize(numMembers);
00213
00214 for ( ; i < members.size(); ++i)
00215 members[i] = memberType.createVariant();
00216 }
00217 }
00218 else
00219 throw InvalidOperationException("Resizing a non-dynamic array");
00220 }
00221
00222 void ArrayVariant::ValueImplV::clear() {
00223 if (!numMembers)
00224 members.clear();
00225 else
00226 throw InvalidOperationException("Clearing a non-dynamic array");
00227 }
00228
00229 Variant::ValuePtr ArrayVariant::ValueImplV::clone() const {
00230 return Variant::ValuePtr(new ValueImplV(*this));
00231 }
00232
00233 Serializer ArrayVariant::ValueImplV::createSerializer(const DataType& type)
00234 const {
00235 if (!members.empty())
00236 return ArraySerializer(members.front().createSerializer(), numMembers);
00237 else
00238 return ArraySerializer(Serializer(), 0);
00239 }
00240
00241
00242
00243
00244
00245 ArrayVariant& ArrayVariant::operator+=(const Variant& member) {
00246 addMember(member);
00247 return *this;
00248 }
00249
00250 }