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 #ifndef RC_DYNAMICS_API_CSV_PRINTING_H_H
00037 #define RC_DYNAMICS_API_CSV_PRINTING_H_H
00038 
00039 #include <string>
00040 #include <sstream>
00041 #include <iostream>
00042 #include <vector>
00043 #include <memory>
00044 
00045 #include "rc_dynamics_api/msg_utils.h"
00046 
00047 #include "roboception/msgs/frame.pb.h"
00048 #include "roboception/msgs/dynamics.pb.h"
00049 #include "roboception/msgs/imu.pb.h"
00050 
00051 #ifdef WIN32
00052 #ifdef GetMessage
00053 #undef GetMessage
00054 #endif
00055 #endif
00056 
00057 namespace csv
00058 {
00062 struct Header
00063 {
00064   std::vector<std::string> fields_;
00065   std::string prefix_;
00066 
00067   static Header prefixed(const std::string& p, const ::google::protobuf::Message& m)
00068   {
00069     Header header;
00070     header.prefix_ = p;
00071     return header << m;
00072   }
00073 
00074   Header& operator<<(const std::string& field)
00075   {
00076     fields_.insert(std::end(fields_), prefix_ + field);
00077     return *this;
00078   }
00079 
00080   Header& operator<<(const Header& other)
00081   {
00082     for (auto&& f : other.fields_)
00083       fields_.insert(std::end(fields_), prefix_ + f);
00084     return *this;
00085   }
00086 
00087   Header& operator<<(const ::google::protobuf::Message& m)
00088   {
00089     using namespace ::google::protobuf;
00090 
00091     auto descr = m.GetDescriptor();
00092     auto refl = m.GetReflection();
00093     for (int i = 0; i < descr->field_count(); ++i)
00094     {
00095       auto field = descr->field(i);
00096 
00097       if (field->is_repeated())
00098       {
00099         int size = refl->FieldSize(m, field);
00100         if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
00101         {
00102           for (int k = 0; k < size; k++)
00103           {
00104             *this << prefixed(field->name() + '_' + std::to_string(k), refl->GetMessage(m, field));
00105           }
00106         }
00107         else
00108         {
00109           for (int k = 0; k < size; k++)
00110           {
00111             *this << field->name() + "_" + std::to_string(k);
00112           }
00113         }
00114       }
00115       else if (!field->is_optional() || refl->HasField(m, field))
00116       {
00117         if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
00118         {
00119           *this << prefixed(field->name() + '_', refl->GetMessage(m, field));
00120         }
00121         else
00122         {
00123           *this << field->name();
00124         }
00125       }
00126     }
00127 
00128     return *this;
00129   }
00130 };
00131 
00135 struct Line
00136 {
00137   std::vector<std::string> entries_;
00138 
00139   Line& operator<<(const std::string& t)
00140   {
00141     this->entries_.insert(std::end(this->entries_), t);
00142     return *this;
00143   }
00144 
00145   Line& operator<<(const ::google::protobuf::Message& m)
00146   {
00147     using namespace ::google::protobuf;
00148 
00149     auto descr = m.GetDescriptor();
00150     auto refl = m.GetReflection();
00151     for (int i = 0; i < descr->field_count(); ++i)
00152     {
00153       auto field = descr->field(i);
00154 
00155       if (field->is_repeated())
00156       {
00157         int size = refl->FieldSize(m, field);
00158         switch (field->cpp_type())
00159         {
00160           case FieldDescriptor::CPPTYPE_MESSAGE:
00161             for (int k = 0; k < size; ++k)
00162             {
00163               *this << refl->GetRepeatedMessage(m, field, k);
00164             }
00165             break;
00166           case FieldDescriptor::CPPTYPE_BOOL:
00167             for (int k = 0; k < size; ++k)
00168             {
00169               *this << std::to_string(refl->GetRepeatedBool(m, field, k));
00170             }
00171             break;
00172           case FieldDescriptor::CPPTYPE_ENUM:
00173             for (int k = 0; k < size; ++k)
00174             {
00175               *this << refl->GetRepeatedEnum(m, field, k)->name();
00176             }
00177             break;
00178           case FieldDescriptor::CPPTYPE_FLOAT:
00179             for (int k = 0; k < size; ++k)
00180             {
00181               *this << std::to_string(refl->GetRepeatedFloat(m, field, k));
00182             }
00183             break;
00184           case FieldDescriptor::CPPTYPE_DOUBLE:
00185             for (int k = 0; k < size; ++k)
00186             {
00187               *this << std::to_string(refl->GetRepeatedDouble(m, field, k));
00188             }
00189             break;
00190           case FieldDescriptor::CPPTYPE_UINT32:
00191             for (int k = 0; k < size; ++k)
00192             {
00193               *this << std::to_string(refl->GetRepeatedUInt32(m, field, k));
00194             }
00195             break;
00196           case FieldDescriptor::CPPTYPE_UINT64:
00197             for (int k = 0; k < size; ++k)
00198             {
00199               *this << std::to_string(refl->GetRepeatedUInt64(m, field, k));
00200             }
00201             break;
00202           case FieldDescriptor::CPPTYPE_INT32:
00203             for (int k = 0; k < size; ++k)
00204             {
00205               *this << std::to_string(refl->GetRepeatedInt32(m, field, k));
00206             }
00207             break;
00208           case FieldDescriptor::CPPTYPE_INT64:
00209             for (int k = 0; k < size; ++k)
00210             {
00211               *this << std::to_string(refl->GetRepeatedInt64(m, field, k));
00212             }
00213             break;
00214           case FieldDescriptor::CPPTYPE_STRING:
00215             for (int k = 0; k < size; ++k)
00216             {
00217               *this << refl->GetRepeatedString(m, field, k);
00218             }
00219             break;
00220         }
00221       }
00222       else if (!field->is_optional() || refl->HasField(m, field))
00223       {
00224         switch (field->cpp_type())
00225         {
00226           case FieldDescriptor::CPPTYPE_MESSAGE:
00227             *this << refl->GetMessage(m, field);
00228             break;
00229           case FieldDescriptor::CPPTYPE_BOOL:
00230             *this << std::to_string(refl->GetBool(m, field));
00231             break;
00232           case FieldDescriptor::CPPTYPE_ENUM:
00233             *this << refl->GetEnum(m, field)->name();
00234             break;
00235           case FieldDescriptor::CPPTYPE_FLOAT:
00236             *this << std::to_string(refl->GetFloat(m, field));
00237             break;
00238           case FieldDescriptor::CPPTYPE_DOUBLE:
00239             *this << std::to_string(refl->GetDouble(m, field));
00240             break;
00241           case FieldDescriptor::CPPTYPE_UINT32:
00242             *this << std::to_string(refl->GetUInt32(m, field));
00243             break;
00244           case FieldDescriptor::CPPTYPE_UINT64:
00245             *this << std::to_string(refl->GetUInt64(m, field));
00246             break;
00247           case FieldDescriptor::CPPTYPE_INT32:
00248             *this << std::to_string(refl->GetInt32(m, field));
00249             break;
00250           case FieldDescriptor::CPPTYPE_INT64:
00251             *this << std::to_string(refl->GetInt64(m, field));
00252             break;
00253           case FieldDescriptor::CPPTYPE_STRING:
00254             *this << refl->GetString(m, field);
00255             break;
00256         }
00257       }
00258     }
00259 
00260     return *this;
00261   }
00262 };
00263 }
00264 
00265 std::ostream& operator<<(std::ostream& s, const csv::Header& header)
00266 {
00267   bool first = true;
00268   for (auto&& hf : header.fields_)
00269   {
00270     if (first)
00271       s << hf;
00272     else
00273       s << "," << hf;
00274     first = false;
00275   }
00276   return s;
00277 }
00278 
00279 std::ostream& operator<<(std::ostream& s, const csv::Line& csv)
00280 {
00281   bool first = true;
00282   for (auto&& e : csv.entries_)
00283   {
00284     if (first)
00285     {
00286       s << e;
00287     }
00288     else
00289     {
00290       s << "," << e;
00291     }
00292     first = false;
00293   }
00294 
00295   return s;
00296 }
00297 
00298 #endif  // RC_DYNAMICS_API_CSV_PRINTING_H_H


rc_dynamics_api
Author(s): Heiko Hirschmueller , Christian Emmerich , Felix Endres
autogenerated on Thu May 9 2019 02:13:50