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