DCCL v3
ccl_compatibility.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 #include <ctime>
23 
24 #include <boost/date_time.hpp>
25 
26 #include "ccl_compatibility.h"
27 #include "WhoiUtil.h"
28 #include "dccl/codec.h"
29 
30 extern "C"
31 {
32  void dccl3_load(dccl::Codec* dccl)
33  {
34  using namespace dccl;
35  using namespace dccl::legacyccl;
36 
37  FieldCodecManager::add<dccl::legacyccl::IdentifierCodec>("dccl.ccl.id");
38  FieldCodecManager::add<LatLonCompressedCodec>("_ccl_latloncompressed");
39  FieldCodecManager::add<FixAgeCodec>("_ccl_fix_age");
40  FieldCodecManager::add<TimeDateCodec>("_ccl_time_date");
41  FieldCodecManager::add<HeadingCodec>("_ccl_heading");
42  FieldCodecManager::add<DepthCodec>("_ccl_depth");
43  FieldCodecManager::add<VelocityCodec>("_ccl_velocity");
44  FieldCodecManager::add<WattsCodec>("_ccl_watts");
45  FieldCodecManager::add<GFIPitchOilCodec>("_ccl_gfi_pitch_oil");
46  FieldCodecManager::add<SpeedCodec>("_ccl_speed");
47  FieldCodecManager::add<HiResAltitudeCodec>("_ccl_hires_altitude");
48  FieldCodecManager::add<TemperatureCodec>("_ccl_temperature");
49  FieldCodecManager::add<SalinityCodec>("_ccl_salinity");
50  FieldCodecManager::add<SoundSpeedCodec>("_ccl_sound_speed");
51 
55  dccl->load<protobuf::CCLMDATCTD>();
59  }
60 
61  void dccl3_unload(dccl::Codec* dccl)
62  {
63  using namespace dccl;
64  using namespace dccl::legacyccl;
65 
73 
74  FieldCodecManager::remove<dccl::legacyccl::IdentifierCodec>("dccl.ccl.id");
75  FieldCodecManager::remove<LatLonCompressedCodec>("_ccl_latloncompressed");
76  FieldCodecManager::remove<FixAgeCodec>("_ccl_fix_age");
77  FieldCodecManager::remove<TimeDateCodec>("_ccl_time_date");
78  FieldCodecManager::remove<HeadingCodec>("_ccl_heading");
79  FieldCodecManager::remove<DepthCodec>("_ccl_depth");
80  FieldCodecManager::remove<VelocityCodec>("_ccl_velocity");
81  FieldCodecManager::remove<WattsCodec>("_ccl_watts");
82  FieldCodecManager::remove<GFIPitchOilCodec>("_ccl_gfi_pitch_oil");
83  FieldCodecManager::remove<SpeedCodec>("_ccl_speed");
84  FieldCodecManager::remove<HiResAltitudeCodec>("_ccl_hires_altitude");
85  FieldCodecManager::remove<TemperatureCodec>("_ccl_temperature");
86  FieldCodecManager::remove<SalinityCodec>("_ccl_salinity");
87  FieldCodecManager::remove<SoundSpeedCodec>("_ccl_sound_speed");
88 
89  }
90 
91 }
92 
93 //
94 // LatLonCompressedCodec
95 //
96 
97 dccl::Bitset dccl::legacyccl::LatLonCompressedCodec::encode()
98 {
99  return encode(0);
100 }
101 
102 dccl::Bitset dccl::legacyccl::LatLonCompressedCodec::encode(const double& wire_value)
103 {
104  LONG_AND_COMP encoded;
105  encoded.as_long = 0;
106  encoded.as_compressed = Encode_latlon(wire_value);
107  return dccl::Bitset(size(), static_cast<unsigned long>(encoded.as_long));
108 }
109 
110 double dccl::legacyccl::LatLonCompressedCodec::decode(Bitset* bits)
111 {
112  LONG_AND_COMP decoded;
113  decoded.as_long = static_cast<long>(bits->to_ulong());
114  return Decode_latlon(decoded.as_compressed);
115 }
116 
117 unsigned dccl::legacyccl::LatLonCompressedCodec::size()
118 {
119  return LATLON_COMPRESSED_BYTE_SIZE * BITS_IN_BYTE;
120 }
121 
122 //
123 // TimeDateCodec
124 //
125 
126 dccl::Bitset dccl::legacyccl::TimeDateCodec::encode()
127 {
128  return encode(0);
129 }
130 
131 dccl::Bitset dccl::legacyccl::TimeDateCodec::encode(const dccl::uint64& wire_value)
132 {
133  TIME_DATE_LONG encoded;
134  encoded.as_long = 0;
135  encoded.as_time_date = Encode_time_date(wire_value / MICROSECONDS_IN_SECOND);
136  return dccl::Bitset(size(), static_cast<unsigned long>(encoded.as_long));
137 }
138 
139 dccl::uint64 dccl::legacyccl::TimeDateCodec::decode(Bitset* bits)
140 {
141  TIME_DATE_LONG decoded;
142  decoded.as_long = bits->to_ulong();
143  short mon, day, hour, min, sec;
144  Decode_time_date(decoded.as_time_date,
145  &mon, &day, &hour, &min, &sec);
146 
147  // \todo chrismurf FIX ME! with timegm
148  // assume current year
149  int year = boost::gregorian::day_clock::universal_day().year();
150 
151  boost::posix_time::ptime time_date(
152  boost::gregorian::date(year, mon, day),
153  boost::posix_time::time_duration(hour,min,sec));
154 
155  return to_uint64_time(time_date);
156 }
157 
158 dccl::uint64 dccl::legacyccl::TimeDateCodec::to_uint64_time(const boost::posix_time::ptime& time_date)
159 {
160 
161  using namespace boost::posix_time;
162  using namespace boost::gregorian;
163 
164  if (time_date == not_a_date_time)
165  return std::numeric_limits<uint64>::max();
166  else
167  {
168  const int MICROSEC_IN_SEC = 1000000;
169 
170  date_duration date_diff = time_date.date() - date(1970,1,1);
171  time_duration time_diff = time_date.time_of_day();
172 
173  return
174  static_cast<uint64>(date_diff.days())*24*3600*MICROSEC_IN_SEC +
175  static_cast<uint64>(time_diff.total_seconds())*MICROSEC_IN_SEC +
176  static_cast<uint64>(time_diff.fractional_seconds()) /
177  (time_duration::ticks_per_second() / MICROSEC_IN_SEC);
178  }
179 }
180 
181 
182 unsigned dccl::legacyccl::TimeDateCodec::size()
183 {
184  return TIME_DATE_COMPRESSED_BYTE_SIZE * BITS_IN_BYTE;
185 }
186 
187 
188 //
189 // HeadingCodec
190 //
191 dccl::Bitset dccl::legacyccl::HeadingCodec::encode(const float& wire_value)
192 { return dccl::Bitset(size(), Encode_heading(wire_value)); }
193 
194 float dccl::legacyccl::HeadingCodec::decode(Bitset* bits)
195 { return Decode_heading(bits->to_ulong()); }
196 
197 
198 //
199 // DepthCodec
200 //
201 dccl::Bitset dccl::legacyccl::DepthCodec::encode(const float& wire_value)
202 { return dccl::Bitset(size(), Encode_depth(wire_value)); }
203 
204 float dccl::legacyccl::DepthCodec::decode(Bitset* bits)
205 { return Decode_depth(bits->to_ulong()); }
206 
207 //
208 // VelocityCodec
209 //
210 dccl::Bitset dccl::legacyccl::VelocityCodec::encode(const float& wire_value)
211 {
212  return dccl::Bitset(size(), Encode_est_velocity(wire_value));
213 }
214 
215 float dccl::legacyccl::VelocityCodec::decode(Bitset* bits)
216 { return Decode_est_velocity(bits->to_ulong()); }
217 
218 
219 //
220 // SpeedCodec
221 //
222 dccl::Bitset dccl::legacyccl::SpeedCodec::encode(const float& wire_value)
223 {
224  const google::protobuf::Message* root = FieldCodecBase::root_message();
225  const google::protobuf::FieldDescriptor* thrust_mode_field_desc =
226  root->GetDescriptor()->FindFieldByNumber(
227  FieldCodecBase::dccl_field_options().GetExtension(ccl).thrust_mode_tag());
228 
229  switch(root->GetReflection()->GetEnum(*root, thrust_mode_field_desc)->number())
230  {
231  default:
232  case protobuf::CCLMDATRedirect::RPM:
233  return dccl::Bitset(size(), Encode_speed(SPEED_MODE_RPM, wire_value));
234 
235  case protobuf::CCLMDATRedirect::METERS_PER_SECOND:
236  return dccl::Bitset(size(), Encode_speed(SPEED_MODE_MSEC, wire_value));
237  }
238 }
239 
240 float dccl::legacyccl::SpeedCodec::decode(Bitset* bits)
241 {
242  const google::protobuf::Message* root = FieldCodecBase::root_message();
243  const google::protobuf::FieldDescriptor* thrust_mode_field_desc =
244  root->GetDescriptor()->FindFieldByNumber(
245  FieldCodecBase::dccl_field_options().GetExtension(ccl).thrust_mode_tag());
246 
247  switch(root->GetReflection()->GetEnum(*root, thrust_mode_field_desc)->number())
248  {
249  default:
250  case protobuf::CCLMDATRedirect::RPM:
251  return Decode_speed(SPEED_MODE_RPM, bits->to_ulong());
252 
253  case protobuf::CCLMDATRedirect::METERS_PER_SECOND:
254  return Decode_speed(SPEED_MODE_MSEC, bits->to_ulong());
255  }
256 }
257 
258 
259 
260 //
261 // WattsCodec
262 //
263 dccl::Bitset dccl::legacyccl::WattsCodec::encode(const float& wire_value)
264 { return dccl::Bitset(size(), Encode_watts(wire_value, 1)); }
265 
266 float dccl::legacyccl::WattsCodec::decode(Bitset* bits)
267 { return Decode_watts(bits->to_ulong()); }
268 
269 //
270 // GFIPitchOilCodec
271 //
272 dccl::Bitset dccl::legacyccl::GFIPitchOilCodec::encode(const protobuf::CCLMDATState::GFIPitchOil& wire_value)
273 {
274  return dccl::Bitset(size(), Encode_gfi_pitch_oil(wire_value.gfi(), wire_value.pitch(), wire_value.oil()));
275 }
276 
277 dccl::legacyccl::protobuf::CCLMDATState::GFIPitchOil dccl::legacyccl::GFIPitchOilCodec::decode(Bitset* bits)
278 {
279  float gfi, pitch, oil;
280  Decode_gfi_pitch_oil(bits->to_ulong(), &gfi, &pitch, &oil);
282  decoded.set_gfi(gfi);
283  decoded.set_pitch(pitch);
284  decoded.set_oil(oil);
285  return decoded;
286 }
287 
288 //
289 // HiResAltitudeCodec
290 //
291 dccl::Bitset dccl::legacyccl::HiResAltitudeCodec::encode(const float& wire_value)
292 { return dccl::Bitset(size(), Encode_hires_altitude(wire_value)); }
293 
294 float dccl::legacyccl::HiResAltitudeCodec::decode(Bitset* bits)
295 { return Decode_hires_altitude(bits->to_ulong()); }
296 
297 //
298 // SalinityCodec
299 //
300 dccl::Bitset dccl::legacyccl::SalinityCodec::encode(const float& wire_value)
301 { return dccl::Bitset(size(), Encode_salinity(wire_value)); }
302 
303 float dccl::legacyccl::SalinityCodec::decode(Bitset* bits)
304 { return Decode_salinity(bits->to_ulong()); }
305 
306 //
307 // TemperatureCodec
308 //
309 dccl::Bitset dccl::legacyccl::TemperatureCodec::encode(const float& wire_value)
310 { return dccl::Bitset(size(), Encode_temperature(wire_value)); }
311 
312 float dccl::legacyccl::TemperatureCodec::decode(Bitset* bits)
313 { return Decode_temperature(bits->to_ulong()); }
314 
315 //
316 // SoundSpeedCodec
317 //
318 dccl::Bitset dccl::legacyccl::SoundSpeedCodec::encode(const float& wire_value)
319 { return dccl::Bitset(size(), Encode_sound_speed(wire_value)); }
320 
321 float dccl::legacyccl::SoundSpeedCodec::decode(Bitset* bits)
322 { return Decode_sound_speed(bits->to_ulong()); }
The Dynamic CCL enCODer/DECoder. This is the main class you will use to load, encode and decode DCCL ...
Definition: codec.h:56
unsigned long to_ulong() const
Returns the value of the Bitset as an unsigned long integer. Equivalent to to<unsigned long>()...
Definition: bitset.h:284
dccl::DCCLFieldOptions dccl_field_options() const
Get the DCCL field option extension value for the current field.
Definition: field_codec.h:317
void load()
All messages must be explicited loaded and validated (size checks, option extensions checks...
Definition: codec.h:96
DCCL Implementation of the REMUS CCL Language Library namespace.
google::protobuf::uint64 uint64
an unsigned 64 bit integer
Definition: common.h:59
void unload()
Unload a given message.
Definition: codec.h:103
Dynamic Compact Control Language namespace.
A variable size container of bits (subclassed from std::deque<bool>) with an optional hierarchy...
Definition: bitset.h:38