DCCL v3
test.cpp
1 // Copyright 2009-2017 Toby Schneider (http://gobysoft.org/index.wt/people/toby)
2 // GobySoft, LLC (for 2013-)
3 // Massachusetts Institute of Technology (for 2007-2014)
4 // Community contributors (see AUTHORS file)
5 //
6 //
7 // This file is part of the Dynamic Compact Control Language Library
8 // ("DCCL").
9 //
10 // DCCL is free software: you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as published by
12 // the Free Software Foundation, either version 2.1 of the License, or
13 // (at your option) any later version.
14 //
15 // DCCL is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public License
21 // along with DCCL. If not, see <http://www.gnu.org/licenses/>.
22 // tests usage of Legacy CCL
23 
24 #include <boost/date_time.hpp>
25 
26 #include "dccl/codec.h"
27 #include "dccl/field_codec.h"
28 #include "dccl/ccl/ccl_compatibility.h"
29 #include "test.pb.h"
30 
31 using namespace dccl::test;
32 
33 using dccl::operator<<;
34 
35 bool double_cmp(double a, double b, int precision)
36 {
37  int a_whole = a;
38  int b_whole = b;
39 
40  int a_part = (a-a_whole)*pow(10.0, precision);
41  int b_part = (b-b_whole)*pow(10.0, precision);
42 
43  return (a_whole == b_whole) && (a_part == b_part);
44 }
45 
46 template<typename N>
47 void check_normal_dccl(dccl::Codec& codec)
48 {
49  codec.load<N>();
50  codec.info<N>(&dccl::dlog);
51  N normal_msg, normal_msg_out;
52  normal_msg.set_a(123);
53  normal_msg.set_b(321);
54 
55  std::string encoded;
56  codec.encode(&encoded, normal_msg);
57  std::cout << dccl::hex_encode(encoded) << std::endl;
58  assert(dccl::hex_encode(encoded).substr(0, 2) == "20");
59  codec.decode(encoded, &normal_msg_out);
60 
61  assert(normal_msg.SerializeAsString() == normal_msg_out.SerializeAsString());
62 }
63 
64 
65 int main(int argc, char* argv[])
66 {
67  dccl::dlog.connect(dccl::logger::ALL, &std::cerr);
68 
69  dccl::Codec codec("dccl.ccl.id", DCCL_CCL_COMPAT_NAME);
70 
71  check_normal_dccl<NormalDCCL1Byte>(codec);
72  check_normal_dccl<NormalDCCL2Byte>(codec);
73 
74  codec.info<dccl::legacyccl::protobuf::CCLMDATState>(&dccl::dlog);
75 
76  dccl::legacyccl::protobuf::CCLMDATState state_in, state_out;
77  std::string test_state_encoded = "0e86fa11ad20c9011b4432bf47d10000002401042f0e7d87fa111620c95a200a";
78  codec.decode(dccl::hex_decode(test_state_encoded), &state_out);
79  state_in.set_latitude(25.282416667);
80  state_in.set_longitude(-77.164266667);
81  state_in.set_fix_age(4);
82 
83  boost::gregorian::date today = boost::gregorian::day_clock::universal_day();
84  boost::posix_time::ptime time_date(
85  boost::gregorian::date(today.year(), boost::date_time::Mar, 4),
86  boost::posix_time::time_duration(17,1,44));
87 
88  state_in.set_time_date(dccl::legacyccl::TimeDateCodec::to_uint64_time(time_date));
89  state_in.set_heading(270);
90  state_in.set_depth(2323);
91  state_in.set_mission_mode(dccl::legacyccl::protobuf::CCLMDATState::NORMAL);
92  state_in.set_faults(dccl::hex_decode("00000024"));
93  state_in.set_faults_2(dccl::hex_decode("01"));
94  state_in.set_mission_leg(4);
95  state_in.set_est_velocity(1.88);
96  state_in.set_objective_index(dccl::hex_decode("0E"));
97  state_in.set_watts(500);
98  state_in.set_lat_goal(25.282440815262891);
99  state_in.set_lon_goal(-77.167505880296929);
100  state_in.set_battery_percent(90);
101  state_in.mutable_gfi_pitch_oil()->set_gfi(0);
102  state_in.mutable_gfi_pitch_oil()->set_pitch(6);
103  state_in.mutable_gfi_pitch_oil()->set_oil(55);
104 
105 
106  assert(double_cmp(state_in.latitude(), state_out.latitude(), 4));
107  assert(double_cmp(state_in.longitude(), state_out.longitude(), 4));
108  assert(state_in.fix_age() == state_out.fix_age());
109  assert(state_in.time_date() == state_out.time_date());
110  assert(dccl::round(state_in.heading(),0) ==
111  dccl::round(state_out.heading(),0));
112  assert(double_cmp(state_in.depth(), state_out.depth(), 1));
113  assert(state_in.mission_mode() == state_out.mission_mode());
114 
115 
116  // test the dynamically generated message
117  boost::shared_ptr<google::protobuf::Message> state_in_2 = dccl::DynamicProtobufManager::new_protobuf_message(dccl::legacyccl::protobuf::CCLMDATState::descriptor());
118  state_in_2->CopyFrom(state_in);
119 
120  std::string state_encoded;
121  codec.encode(&state_encoded, *state_in_2);
122 
123  dccl::legacyccl::protobuf::CCLMDATState state_out_2;
124  codec.decode(state_encoded, &state_out_2);
125 
126  std::cout << "in:" << state_in << std::endl;
127  std::cout << test_state_encoded << std::endl;
128  std::cout << dccl::hex_encode(state_encoded) << std::endl;
129  std::cout << std::setprecision(16) << state_out.lon_goal() << std::endl;
130  std::cout << "out:" << state_out << std::endl;
131  std::cout << "out2: " << state_out_2 << std::endl;
132 
133  assert(state_out.SerializeAsString() == state_out_2.SerializeAsString());
134  assert(test_state_encoded == dccl::hex_encode(state_encoded));
135 
136  std::cout << dccl::hex_encode(state_out.faults()) << std::endl;
137  std::cout << dccl::hex_encode(state_out.faults_2()) << std::endl;
138 
139 
140  codec.info<dccl::legacyccl::protobuf::CCLMDATRedirect>(&dccl::dlog);
141 
142  dccl::legacyccl::protobuf::CCLMDATRedirect redirect_in, redirect_out;
143  std::string test_redirect_encoded = "07522cf9113d20c99964003d6464003d640be60014142035f911ef21c9000000";
144  codec.decode(dccl::hex_decode(test_redirect_encoded), &redirect_out);
145  redirect_in.set_message_number(82);
146  redirect_in.set_latitude(25.274995002149939);
147  redirect_in.set_longitude(-77.166669030984522);
148  redirect_in.set_transit_vertical_mode(dccl::legacyccl::protobuf::CCLMDATRedirect::ALTITUDE);
149  redirect_in.set_transit_thrust_mode(dccl::legacyccl::protobuf::CCLMDATRedirect::METERS_PER_SECOND);
150  redirect_in.set_survey_vertical_mode(dccl::legacyccl::protobuf::CCLMDATRedirect::ALTITUDE);
151  redirect_in.set_survey_thrust_mode(dccl::legacyccl::protobuf::CCLMDATRedirect::METERS_PER_SECOND);
152 
153  redirect_in.set_depth_goal_transit(10.0);
154  redirect_in.set_speed_transit(2.0333333);
155  redirect_in.set_device_cmd_transit(100);
156 
157  redirect_in.set_depth_goal_survey(10.0);
158  redirect_in.set_speed_survey(2.0333333);
159  redirect_in.set_device_cmd_survey(100);
160 
161  redirect_in.set_num_rows(11);
162  redirect_in.set_row_length(230);
163  redirect_in.set_spacing_0(20);
164  redirect_in.set_spacing_1(20);
165  redirect_in.set_heading(45.176472);
166 
167  redirect_in.set_lat_start(25.275183333);
168  redirect_in.set_lon_start(-77.15735);
169 
170  redirect_in.set_spare(std::string(3, '\0'));
171 
172  std::string redirect_encoded;
173  codec.encode(&redirect_encoded, redirect_in);
174 
175  dccl::legacyccl::protobuf::CCLMDATRedirect redirect_out_2;
176  codec.decode(redirect_encoded, &redirect_out_2);
177 
178  std::cout << "in:" << redirect_in << std::endl;
179  std::cout << test_redirect_encoded << std::endl;
180  std::cout << dccl::hex_encode(redirect_encoded) << std::endl;
181  std::cout << "out:" << redirect_out << std::endl;
182  std::cout << "out2: " << redirect_out_2 << std::endl;
183 
184  assert(redirect_out.SerializeAsString() == redirect_out_2.SerializeAsString());
185  assert(test_redirect_encoded == dccl::hex_encode(redirect_encoded));
186 
187 
188  codec.info<dccl::legacyccl::protobuf::CCLMDATEmpty>(&dccl::dlog);
189  codec.info<dccl::legacyccl::protobuf::CCLMDATBathy>(&dccl::dlog);
190  codec.info<dccl::legacyccl::protobuf::CCLMDATCTD>(&dccl::dlog);
191  codec.info<dccl::legacyccl::protobuf::CCLMDATError>(&dccl::dlog);
192  codec.info<dccl::legacyccl::protobuf::CCLMDATCommand>(&dccl::dlog);
193 
194 
195  std::cout << "all tests passed" << std::endl;
196 }
197 
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition: codec.h:56
void hex_decode(const std::string &in, std::string *out)
Decodes a (little-endian) hexadecimal string to a byte string. Index 0 and 1 (first byte) of in are w...
Definition: binary.h:49
static GoogleProtobufMessagePointer new_protobuf_message(const std::string &protobuf_type_name)
Create a new (empty) Google Protobuf message of a given type by name.
void info(std::ostream *os=0, int user_id=-1) const
Writes a human readable summary (including field sizes) of the provided DCCL type to the stream provi...
Definition: codec.h:155
void load()
All messages must be explicited loaded and validated (size checks, option extensions checks...
Definition: codec.h:96
void encode(std::string *bytes, const google::protobuf::Message &msg, bool header_only=false, int user_id=-1)
Encodes a DCCL message.
Definition: codec.cpp:273
void connect(int verbosity_mask, Slot slot)
Connect the output of one or more given verbosities to a slot (function pointer or similar) ...
Definition: logger.h:161
void hex_encode(CharIterator begin, CharIterator end, std::string *out, bool upper_case=false)
Encodes a (little-endian) hexadecimal string from a byte string. Index 0 of begin is written to index...
Definition: binary.h:100
Unit test namespace.
Definition: test.cpp:44
CharIterator decode(CharIterator begin, CharIterator end, google::protobuf::Message *msg, bool header_only=false)
Decode a DCCL message when the type is known at compile time.
Definition: codec.h:439