libcluon  0.0.148
Envelope.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2017-2018 Christian Berger
3  *
4  * This Source Code Form is subject to the terms of the Mozilla Public
5  * License, v. 2.0. If a copy of the MPL was not distributed with this
6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7  */
8 
9 #ifndef CLUON_ENVELOPE_HPP
10 #define CLUON_ENVELOPE_HPP
11 
13 #include "cluon/ToProtoVisitor.hpp"
14 #include "cluon/cluonDataStructures.hpp"
15 
16 #include <cstring>
17 #include <istream>
18 #include <sstream>
19 #include <string>
20 #include <utility>
21 #include <vector>
22 
23 namespace cluon {
24 
32 inline std::string serializeEnvelope(cluon::data::Envelope &&envelope) noexcept {
33  std::string dataToSend;
34  {
35  std::stringstream sstr;
36 
37  cluon::ToProtoVisitor protoEncoder;
38  envelope.accept(protoEncoder);
39 
40  const std::string tmp{protoEncoder.encodedData()};
41  uint32_t length{static_cast<uint32_t>(tmp.size())};
42  length <<= 8;
43  length = htole32(length);
44 
45  // Add OD4 header.
46  constexpr unsigned char OD4_HEADER_BYTE0 = 0x0D;
47  constexpr unsigned char OD4_HEADER_BYTE1 = 0xA4;
48  sstr.put(static_cast<char>(OD4_HEADER_BYTE0));
49  auto posByte1 = sstr.tellp();
50  sstr.write(reinterpret_cast<char *>(&length), static_cast<std::streamsize>(sizeof(uint32_t)));
51  auto posByte5 = sstr.tellp();
52  sstr.seekp(posByte1);
53  sstr.put(static_cast<char>(OD4_HEADER_BYTE1));
54  sstr.seekp(posByte5);
55 
56  // Write payload.
57  sstr.write(tmp.data(), static_cast<std::streamsize>(tmp.size()));
58 
59  dataToSend = sstr.str();
60  }
61  return dataToSend;
62 }
63 
75 inline std::pair<bool, cluon::data::Envelope> extractEnvelope(std::istream &in) noexcept {
76  bool retVal{false};
77  cluon::data::Envelope env;
78  if (in.good()) {
79  constexpr uint8_t OD4_HEADER_SIZE{5};
80  std::vector<char> buffer;
81  buffer.reserve(OD4_HEADER_SIZE);
82 #ifdef WIN32 // LCOV_EXCL_LINE
83  buffer.clear(); // LCOV_EXCL_LINE
84  retVal = true; // LCOV_EXCL_LINE
85  for (uint8_t i{0}; i < OD4_HEADER_SIZE; i++) { // LCOV_EXCL_LINE
86  char c; // LCOV_EXCL_LINE
87  in.get(c); // LCOV_EXCL_LINE
88  retVal &= in.good(); // LCOV_EXCL_LINE
89  buffer.push_back(c); // LCOV_EXCL_LINE
90  }
91  if (retVal) { // LCOV_EXCL_LINE
92 #else // LCOV_EXCL_LINE
93  in.read(&buffer[0], OD4_HEADER_SIZE);
94  if (OD4_HEADER_SIZE == in.gcount()) {
95 #endif
96  if ((0x0D == static_cast<uint8_t>(buffer[0])) && (0xA4 == static_cast<uint8_t>(buffer[1]))) {
97  const uint32_t LENGTH{le32toh(*reinterpret_cast<uint32_t *>(&buffer[1])) >> 8};
98  buffer.reserve(LENGTH);
99 #ifdef WIN32 // LCOV_EXCL_LINE
100  buffer.clear(); // LCOV_EXCL_LINE
101  for (uint32_t i{0}; i < LENGTH; i++) { // LCOV_EXCL_LINE
102  char c; // LCOV_EXCL_LINE
103  in.get(c); // LCOV_EXCL_LINE
104  retVal &= in.good(); // LCOV_EXCL_LINE
105  buffer.push_back(c); // LCOV_EXCL_LINE
106  }
107 #else // LCOV_EXCL_LINE
108  in.read(&buffer[0], static_cast<std::streamsize>(LENGTH));
109  retVal = static_cast<int32_t>(LENGTH) == in.gcount();
110 #endif
111  if (retVal) {
112  std::stringstream sstr(std::string(buffer.begin(), buffer.begin() + static_cast<std::streamsize>(LENGTH)));
113  cluon::FromProtoVisitor protoDecoder;
114  protoDecoder.decodeFrom(sstr, env);
115  }
116  }
117  }
118  }
119  return std::make_pair(retVal, env);
120 }
121 
125 template <typename T>
126 inline T extractMessage(cluon::data::Envelope &&envelope) noexcept {
127  cluon::FromProtoVisitor decoder;
128 
129  std::stringstream sstr(envelope.serializedData());
130  decoder.decodeFrom(sstr);
131 
132  T msg;
133  msg.accept(decoder);
134 
135  return msg;
136 }
137 
138 } // namespace cluon
139 
140 #endif
Definition: cluon.hpp:65
Definition: FromProtoVisitor.hpp:28
std::string serializeEnvelope(cluon::data::Envelope &&envelope) noexcept
Definition: Envelope.hpp:32
void decodeFrom(std::istream &in) noexcept
Definition: FromProtoVisitor.cpp:35
std::pair< bool, cluon::data::Envelope > extractEnvelope(std::istream &in) noexcept
Definition: Envelope.hpp:75
std::string encodedData() const noexcept
Definition: ToProtoVisitor.cpp:15
T extractMessage(cluon::data::Envelope &&envelope) noexcept
Definition: Envelope.hpp:126
std::pair< std::vector< MetaMessage >, MessageParserErrorCodes > retVal
Definition: MessageParser.cpp:291
Definition: ToProtoVisitor.hpp:23