IODA Bundle
IntegerMissing.h
Go to the documentation of this file.
1 /*
2  * (C) Copyright 1996-2012 ECMWF.
3  *
4  * This software is licensed under the terms of the Apache Licence Version 2.0
5  * which can be obtained at http://www.apache.org/licenses/LICENSE-2.0.
6  * In applying this licence, ECMWF does not waive the privileges and immunities
7  * granted to it by virtue of its status as an intergovernmental organisation nor
8  * does it submit to any jurisdiction.
9  */
10 
11 #ifndef odc_core_codec_IntegerMissing_H
12 #define odc_core_codec_IntegerMissing_H
13 
14 #include "odc/codec/Integer.h"
15 
16 namespace odc {
17 namespace codec {
18 
19 //----------------------------------------------------------------------------------------------------------------------
20 
21 template <typename ByteOrder,
22  typename ValueType,
23  typename InternalValueType,
24  class DerivedCodec> // codec_nam passed through CRTP as char* is odd to deal with in template
25 class BaseCodecMissing : public BaseCodecInteger<ByteOrder, ValueType> {
26 
27 public: // methods
28 
29  // n.b. We should be able to call name=DerivedCodec::codec_name() directly, but
30  // this causes a compilation error with Cray C++ 8.6
32  const std::string& name=codec_name_str(),
33  double minmaxmissing=odc::MDI::integerMDI()) :
34  BaseCodecInteger<ByteOrder, ValueType>(type, name, minmaxmissing) {}
36 
37 private: // methods
38 
39  static std::string codec_name_str() { return DerivedCodec::codec_name(); }
40 
41  unsigned char* encode(unsigned char* p, const double& d) override {
42  static_assert(sizeof(ValueType) == sizeof(d), "unsafe casting check");
43 
44  const ValueType& val(reinterpret_cast<const ValueType&>(d));
45  InternalValueType s;
46  if (val == this->missingValue_) {
47  s = DerivedCodec::missingMarker;
48  } else {
49  s = val - this->min_;
50  ASSERT(s != DerivedCodec::missingMarker);
51  }
52  ByteOrder::swap(s);
53  ::memcpy(p, &s, sizeof(s));
54  return p + sizeof(s);
55  }
56 
57  void decode(double* out) override {
58  static_assert(sizeof(ValueType) == sizeof(out), "unsafe casting check");
59 
60  ValueType* val_out = reinterpret_cast<ValueType*>(out);
61  InternalValueType s;
62  this->ds().read(s);
63  (*val_out) = (s == DerivedCodec::missingMarker ? this->missingValue_ : (s + this->min_));
64  }
65 
66  void skip() override {
67  this->ds().advance(sizeof(InternalValueType));
68  }
69 };
70 
71 
72 //----------------------------------------------------------------------------------------------------------------------
73 
74 template <typename ByteOrder, typename ValueType>
75 struct CodecInt8Missing : public BaseCodecMissing<ByteOrder, ValueType, uint8_t, CodecInt8Missing<ByteOrder, ValueType>> {
76  constexpr static const char* codec_name() { return "int8_missing"; }
77  constexpr static uint8_t missingMarker = 0xff;
79 };
80 
81 //----------------------------------------------------------------------------------------------------------------------
82 
83 template<typename ByteOrder, typename ValueType>
84 struct CodecInt16Missing : public BaseCodecMissing<ByteOrder, ValueType, uint16_t, CodecInt16Missing<ByteOrder, ValueType>> {
85  constexpr static const char* codec_name() { return "int16_missing"; }
86  constexpr static uint16_t missingMarker = 0xffff;
88 };
89 
90 //----------------------------------------------------------------------------------------------------------------------
91 
92 
93 template <typename ByteOrder, typename ValueType>
94 struct CodecConstantOrMissing : public BaseCodecMissing<ByteOrder, ValueType, uint8_t, CodecConstantOrMissing<ByteOrder, ValueType>> {
95 
96  static_assert(sizeof(ValueType) == sizeof(double), "unsafe casting check");
97 
98  constexpr static const char* codec_name() { return "constant_or_missing"; }
99  constexpr static uint8_t missingMarker = 0xff;
100 
102 
103 private: // methods
104 
105  void print(std::ostream &s) const {
106  s << this->name_ << ", value=";
107 
108  if (this->min_ == this->missingValue_) {
109  s << "NULL";
110  } else {
111  s << std::fixed << this->min_;
112  }
113 
114  if (this->hasMissing_) {
115  s << ", missingValue=" << this->missingValue_;
116  }
117  }
118 };
119 
120 //----------------------------------------------------------------------------------------------------------------------
121 
122 template <typename ByteOrder>
123 class CodecRealConstantOrMissing : public CodecConstantOrMissing<ByteOrder, double> {
124 
125 public: // definitions
126 
127  constexpr static const char* codec_name() { return "real_constant_or_missing"; }
128 
129 public: // methods
130 
132  CodecConstantOrMissing<ByteOrder, double>(type, codec_name(), odc::MDI::realMDI()) {}
133 
135 };
136 
137 //----------------------------------------------------------------------------------------------------------------------
138 
139 } // namespace codec
140 } // namespace odc
141 
142 #endif
143 
Definition: MDI.h:19
static double integerMDI()
Definition: MDI.h:22
static std::string codec_name_str()
void decode(double *out) override
unsigned char * encode(unsigned char *p, const double &d) override
BaseCodecMissing(api::ColumnType type, const std::string &name=codec_name_str(), double minmaxmissing=odc::MDI::integerMDI())
constexpr static const char * codec_name()
CodecRealConstantOrMissing(api::ColumnType type)
std::string name_
Definition: Codec.h:96
const std::string & name() const
Definition: Codec.h:40
double missingValue_
Definition: Codec.h:99
double min_
Definition: Codec.h:100
int32_t hasMissing_
Definition: Codec.h:98
DataStream< ByteOrder > & ds()
Definition: Codec.h:157
Definition: ColumnInfo.h:23
constexpr static const char * codec_name()
constexpr static uint8_t missingMarker
void print(std::ostream &s) const
constexpr static uint16_t missingMarker
constexpr static const char * codec_name()
constexpr static uint8_t missingMarker
constexpr static const char * codec_name()