csv_printing.h
Go to the documentation of this file.
00001 /*
00002  * This file is part of the rc_dynamics_api package.
00003  *
00004  * Copyright (c) 2017 Roboception GmbH
00005  * All rights reserved
00006  *
00007  * Author: Christian Emmerich
00008  *
00009  * Redistribution and use in source and binary forms, with or without
00010  * modification, are permitted provided that the following conditions are met:
00011  *
00012  * 1. Redistributions of source code must retain the above copyright notice,
00013  * this list of conditions and the following disclaimer.
00014  *
00015  * 2. Redistributions in binary form must reproduce the above copyright notice,
00016  * this list of conditions and the following disclaimer in the documentation
00017  * and/or other materials provided with the distribution.
00018  *
00019  * 3. Neither the name of the copyright holder nor the names of its contributors
00020  * may be used to endorse or promote products derived from this software without
00021  * specific prior written permission.
00022  *
00023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00033  * POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 
00037 #ifndef RC_DYNAMICS_API_CSV_PRINTING_H_H
00038 #define RC_DYNAMICS_API_CSV_PRINTING_H_H
00039 
00040 #include <string>
00041 #include <sstream>
00042 #include <iostream>
00043 #include <vector>
00044 #include <memory>
00045 
00046 #include "rc_dynamics_api/msg_utils.h"
00047 
00048 #include "roboception/msgs/frame.pb.h"
00049 #include "roboception/msgs/dynamics.pb.h"
00050 #include "roboception/msgs/imu.pb.h"
00051 
00052 namespace csv {
00053 
00054 
00058 struct Header {
00059 
00060   std::vector<std::string> _fields;
00061   std::string _prefix;
00062 
00063   static Header
00064   prefixed(const std::string &p, const ::google::protobuf::Message &m)
00065   {
00066     Header header;
00067     header._prefix = p;
00068     return header << m;
00069   }
00070 
00071   Header& operator <<(const std::string &field)
00072   {
00073     _fields.insert(std::end(_fields), _prefix + field);
00074     return *this;
00075   }
00076 
00077   Header& operator <<(const Header &other)
00078   {
00079     for (auto&& f : other._fields)
00080       _fields.insert(std::end(_fields), _prefix + f);
00081     return *this;
00082   }
00083 
00084   Header& operator <<(const ::google::protobuf::Message &m)
00085   {
00086     using namespace ::google::protobuf;
00087 
00088     auto descr = m.GetDescriptor();
00089     auto refl = m.GetReflection();
00090     for (int i=0; i<descr->field_count(); ++i)
00091     {
00092       auto field = descr->field(i);
00093 
00094       if (field->is_repeated())
00095       {
00096         int size = refl->FieldSize(m, field);
00097         if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
00098         {
00099           for (int i=0; i<size; i++)
00100           {
00101             *this << prefixed(field->name() + '_' + std::to_string(i),
00102                               refl->GetMessage(m, field));
00103           }
00104         } else {
00105           for (int i=0; i<size; i++)
00106           {
00107             *this << field->name() + "_" + std::to_string(i);
00108           }
00109         }
00110       }
00111       else if (!field->is_optional() || refl->HasField(m, field))
00112       {
00113         if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
00114         {
00115           *this << prefixed(field->name() + '_', refl->GetMessage(m, field));
00116         } else {
00117           *this << field->name();
00118         }
00119       }
00120 
00121     }
00122 
00123     return *this;
00124   }
00125 
00126 };
00127 
00128 
00132 struct Line
00133 {
00134   std::vector<std::string> _entries;
00135 
00136 
00137   Line& operator <<(const std::string &t)
00138   {
00139     this->_entries.insert(std::end(this->_entries), t);
00140     return *this;
00141   }
00142 
00143   Line &operator<<(const ::google::protobuf::Message &m)
00144   {
00145     using namespace ::google::protobuf;
00146 
00147     auto descr = m.GetDescriptor();
00148     auto refl = m.GetReflection();
00149     for (int i=0; i<descr->field_count(); ++i)
00150     {
00151       auto field = descr->field(i);
00152 
00153       if (field->is_repeated())
00154       {
00155         int size = refl->FieldSize(m, field);
00156         switch (field->cpp_type()) {
00157           case FieldDescriptor::CPPTYPE_MESSAGE:
00158             for (int i=0; i<size;++i)
00159             {
00160               *this << refl->GetRepeatedMessage(m, field, i);
00161             }
00162             break;
00163           case FieldDescriptor::CPPTYPE_BOOL:
00164             for (int i=0; i<size;++i)
00165             {
00166               *this << std::to_string(refl->GetRepeatedBool(m, field, i));
00167             }
00168             break;
00169           case FieldDescriptor::CPPTYPE_ENUM:
00170             for (int i=0; i<size;++i)
00171             {
00172               *this << refl->GetRepeatedEnum(m, field, i)->name();
00173             }
00174             break;
00175           case FieldDescriptor::CPPTYPE_FLOAT:
00176             for (int i=0; i<size;++i)
00177             {
00178               *this << std::to_string(refl->GetRepeatedFloat(m, field, i));
00179             }
00180             break;
00181           case FieldDescriptor::CPPTYPE_DOUBLE:
00182             for (int i=0; i<size;++i)
00183             {
00184               *this << std::to_string(refl->GetRepeatedDouble(m, field, i));
00185             }
00186             break;
00187           case FieldDescriptor::CPPTYPE_UINT32:
00188             for (int i=0; i<size;++i)
00189             {
00190               *this << std::to_string(refl->GetRepeatedUInt32(m, field, i));
00191             }
00192             break;
00193           case FieldDescriptor::CPPTYPE_UINT64:
00194             for (int i=0; i<size;++i)
00195             {
00196               *this << std::to_string(refl->GetRepeatedUInt64(m, field, i));
00197             }
00198             break;
00199           case FieldDescriptor::CPPTYPE_INT32:
00200             for (int i=0; i<size;++i)
00201             {
00202               *this << std::to_string(refl->GetRepeatedInt32(m, field, i));
00203             }
00204             break;
00205           case FieldDescriptor::CPPTYPE_INT64:
00206             for (int i=0; i<size;++i)
00207             {
00208               *this << std::to_string(refl->GetRepeatedInt64(m, field, i));
00209             }
00210             break;
00211           case FieldDescriptor::CPPTYPE_STRING:
00212             for (int i=0; i<size;++i)
00213             {
00214               *this << refl->GetRepeatedString(m, field, i);
00215             }
00216             break;
00217         }
00218 
00219       } else if (!field->is_optional() || refl->HasField(m, field))
00220       {
00221         switch (field->cpp_type()) {
00222           case FieldDescriptor::CPPTYPE_MESSAGE:
00223             *this << refl->GetMessage(m, field);
00224             break;
00225           case FieldDescriptor::CPPTYPE_BOOL:
00226             *this << std::to_string(refl->GetBool(m, field));
00227             break;
00228           case FieldDescriptor::CPPTYPE_ENUM:
00229             *this << refl->GetEnum(m, field)->name();
00230             break;
00231           case FieldDescriptor::CPPTYPE_FLOAT:
00232             *this << std::to_string(refl->GetFloat(m, field));
00233             break;
00234           case FieldDescriptor::CPPTYPE_DOUBLE:
00235             *this << std::to_string(refl->GetDouble(m, field));
00236             break;
00237           case FieldDescriptor::CPPTYPE_UINT32:
00238             *this << std::to_string(refl->GetUInt32(m, field));
00239             break;
00240           case FieldDescriptor::CPPTYPE_UINT64:
00241             *this << std::to_string(refl->GetUInt64(m, field));
00242             break;
00243           case FieldDescriptor::CPPTYPE_INT32:
00244             *this << std::to_string(refl->GetInt32(m, field));
00245             break;
00246           case FieldDescriptor::CPPTYPE_INT64:
00247             *this << std::to_string(refl->GetInt64(m, field));
00248             break;
00249           case FieldDescriptor::CPPTYPE_STRING:
00250             *this << refl->GetString(m, field);
00251             break;
00252         }
00253       }
00254     }
00255 
00256     return *this;
00257   }
00258 };
00259 
00260 }
00261 
00262 
00263 
00264 std::ostream& operator <<(std::ostream& s, const csv::Header &header)
00265 {
00266   bool first = true;
00267   for (auto&& hf : header._fields)
00268   {
00269     if (first)
00270       s << hf;
00271     else
00272       s << "," << hf;
00273     first = false;
00274   }
00275   return s;
00276 }
00277 
00278 
00279 
00280 std::ostream& operator<<(std::ostream& s, const csv::Line &csv)
00281 {
00282   bool first = true;
00283   for (auto&& e : csv._entries)
00284   {
00285     if (first)
00286     {
00287       s << e;
00288     } else {
00289       s << "," << e;
00290     }
00291     first = false;
00292   }
00293 
00294   return s;
00295 }
00296 
00297 #endif //RC_DYNAMICS_API_CSV_PRINTING_H_H


rc_visard_driver
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Ruess
autogenerated on Thu Jun 6 2019 20:43:02