ArrayVariant.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  * Copyright (C) 2014 by Ralf Kaestner                                        *
00003  * ralf.kaestner@gmail.com                                                    *
00004  *                                                                            *
00005  * This program is free software; you can redistribute it and/or modify       *
00006  * it under the terms of the Lesser GNU General Public License as published by*
00007  * the Free Software Foundation; either version 3 of the License, or          *
00008  * (at your option) any later version.                                        *
00009  *                                                                            *
00010  * This program is distributed in the hope that it will be useful,            *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               *
00013  * Lesser GNU General Public License for more details.                        *
00014  *                                                                            *
00015  * You should have received a copy of the Lesser GNU General Public License   *
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>.       *
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 /* Constructors and Destructor                                               */
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 /* Accessors                                                                 */
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 /* Methods                                                                   */
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 /* Operators                                                                 */
00243 /*****************************************************************************/
00244 
00245 ArrayVariant& ArrayVariant::operator+=(const Variant& member) {
00246   addMember(member);
00247   return *this;
00248 }
00249 
00250 }


variant_topic_tools
Author(s): Ralf Kaestner
autogenerated on Fri Aug 5 2016 06:06:26