message.cpp
Go to the documentation of this file.
00001 //=================================================================================================
00002 // Copyright (c) 2013, Johannes Meyer, TU Darmstadt
00003 // All rights reserved.
00004 
00005 // Redistribution and use in source and binary forms, with or without
00006 // modification, are permitted provided that the following conditions are met:
00007 //     * Redistributions of source code must retain the above copyright
00008 //       notice, this list of conditions and the following disclaimer.
00009 //     * Redistributions in binary form must reproduce the above copyright
00010 //       notice, this list of conditions and the following disclaimer in the
00011 //       documentation and/or other materials provided with the distribution.
00012 //     * Neither the name of the Flight Systems and Automatic Control group,
00013 //       TU Darmstadt, nor the names of its contributors may be used to
00014 //       endorse or promote products derived from this software without
00015 //       specific prior written permission.
00016 
00017 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00018 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00019 // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00020 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
00021 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00022 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00023 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
00024 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00025 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00026 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00027 //=================================================================================================
00028 
00029 #include <rosmatlab/message.h>
00030 #include <rosmatlab/conversion.h>
00031 #include <rosmatlab/options.h>
00032 #include <rosmatlab/log.h>
00033 #include <rosmatlab/exception.h>
00034 
00035 #include <introspection/message.h>
00036 
00037 #include <mex.h>
00038 
00039 #include <boost/algorithm/string.hpp>
00040 
00041 namespace rosmatlab {
00042 
00043 mxArray *message_constructor(const MessagePtr& message, int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
00044 {
00045   mxArray *result = 0;
00046 
00047   // parse inputs
00048   if (nrhs > 0 && Options::isString(prhs[0])) {
00049     std::string option = Options::getString(prhs[0]);
00050     if (nrhs == 1 && boost::algorithm::iequals(option, "definition")) {
00051       result = mxCreateString(message->getDefinition());
00052       return result;
00053     }
00054     if (nrhs == 1 && boost::algorithm::iequals(option, "md5sum")) {
00055       result = mxCreateString(message->getMD5Sum());
00056       return result;
00057     }
00058     if (nrhs == 1 && boost::algorithm::iequals(option, "fields")) {
00059       result = mxCreateCellMatrix(1, message->getFieldNames().size());
00060       for(std::size_t i = 0; i < message->getFieldNames().size(); ++i) {
00061         mxSetCell(result, i, mxCreateString(message->getFieldNames().at(i)));
00062       }
00063       return result;
00064     }
00065     if ((nrhs == 1 || nrhs == 2) && boost::algorithm::iequals(option, "default")) {
00066       if (nrhs == 2) {
00067         const mxArray *default_options = prhs[1];
00068         Conversion::perMessageOptions(message).merge(ConversionOptions(1, &default_options));
00069       }
00070       return Conversion::perMessageOptions(message).toMatlab();
00071     }
00072   }
00073 
00074   // Check if a numeric argument (message count) has been given
00075   std::size_t count = 1;
00076   if (nrhs > 0 && (Options::isIntegerScalar(prhs[0]) || Options::isDoubleScalar(prhs[0]))) {
00077     count = Options::getIntegerScalar(prhs[0]);
00078     nrhs--; prhs++;
00079   }
00080 
00081   // Get conversion options
00082   ConversionOptions options;
00083   if (nrhs % 2 == 0) {
00084     options.init(nrhs, prhs);
00085   } else {
00086     options.init(nrhs - 1, prhs + 1);
00087   }
00088 
00089   // Is this a copy constructor?
00090   if (nrhs % 2 != 0) {
00091     Conversion conversion(message, options);
00092     V_Message copy(conversion.numberOfInstances(prhs[0]));
00093 
00094     for(std::size_t j = 0; j < copy.size(); j++) {
00095       copy[j] = conversion.fromMatlab(prhs[0], j);
00096       // std::cout << "Constructed a new " << copy[j]->getDataType() << " message: " << *boost::shared_static_cast<MessageType const>(copy[j]->getConstInstance()) << std::endl;
00097       result = Conversion(conversion, copy[j]).toMatlab(result, j, copy.size());
00098     }
00099 
00100   // otherwise construct a new message
00101   } else {
00102     MessagePtr m = message->introspect(message->createInstance());
00103     // std::cout << "Constructed a new " << m->getDataType() << " message: " << *boost::shared_static_cast<MessageType const>(m->getConstInstance()) << std::endl;
00104     Conversion conversion(m, options);
00105     result = conversion.toMatlab();
00106   }
00107 
00108   // copy the contents of result if count > 1
00109   if (count > 1) {
00110     // This seems to be a bit hacky. Is there a better solution?
00111     mxArray *repmatrhs[] = { result, mxCreateDoubleScalar(1), mxCreateDoubleScalar(count) };
00112     mxArray *repmatlhs[] = { 0 };
00113     mexCallMATLAB(1, repmatlhs, 3, repmatrhs, "repmat");
00114     mxDestroyArray(repmatrhs[0]);
00115     mxDestroyArray(repmatrhs[1]);
00116     mxDestroyArray(repmatrhs[2]);
00117     result = repmatlhs[0];
00118   }
00119 
00120   return result;
00121 }
00122 
00123 } // namespace rosmatlab


rosmatlab
Author(s): Johannes Meyer
autogenerated on Fri Jul 25 2014 06:48:12