libwreport 2.1
varinfo.h
Go to the documentation of this file.
00001 /*
00002  * wreport/varinfo - Variable information
00003  *
00004  * Copyright (C) 2005--2011  ARPA-SIM <urpsim@smr.arpa.emr.it>
00005  *
00006  * This program is free software; you can redistribute it and/or modify
00007  * it under the terms of the GNU General Public License as published by
00008  * the Free Software Foundation; either version 2 of the License.
00009  *
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  * GNU General Public License for more details.
00014  *
00015  * You should have received a copy of the GNU General Public License
00016  * along with this program; if not, write to the Free Software
00017  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00018  *
00019  * Author: Enrico Zini <enrico@enricozini.com>
00020  */
00021 
00022 #ifndef WREPORT_VARINFO_H
00023 #define WREPORT_VARINFO_H
00024 
00025 #include <stdint.h>
00026 #include <string>
00027 
00028 namespace wreport {
00029 
00078 typedef short unsigned int Varcode;
00079 
00081 std::string varcode_format(Varcode code);
00082 
00086 #define WR_VAR(f, x, y) ((wreport::Varcode)( ((unsigned)(f)<<14) | ((unsigned)(x)<<8) | (unsigned)(y) ))
00087 
00094 #define WR_STRING_TO_VAR(str) ((wreport::Varcode)( \
00095         (( ((str)[0] - '0')*10 + ((str)[1] - '0') ) << 8) | \
00096         ( ((str)[2] - '0')*100 + ((str)[3] - '0')*10 + ((str)[4] - '0') ) \
00097 ))
00098 
00102 #define WR_VAR_F(code) (((code) >> 14) & 0x3)
00103 
00106 #define WR_VAR_X(code) ((code) >> 8 & 0x3f)
00107 
00110 #define WR_VAR_Y(code) ((code) & 0xff)
00111 
00122 Varcode descriptor_code(const char* desc);
00123 
00124 
00130 typedef short unsigned int Alteration;
00131 
00136 #define VARINFO_FLAG_STRING 0x01  ///< Mark string variables
00137 #define VARINFO_FLAG_BINARY 0x02  ///< Mark literal binary variables
00138 
00148 struct _Varinfo
00149 {
00151     Varcode var;
00153     char desc[64];
00155     char unit[24];
00158     int scale;
00161     int ref;
00164     unsigned len;
00167     int bit_ref;
00170     unsigned bit_len;
00172     unsigned flags;
00174     int imin;
00176     int imax;
00178     double dmin;
00180     double dmax;
00182     Alteration alteration;
00184     mutable struct _Varinfo* alterations;
00186     char bufr_unit[24];
00188     int bufr_scale;
00189 
00191     mutable int _ref;
00192 
00193     _Varinfo();
00194 
00196     void do_ref() const { ++_ref; }
00197 
00202     bool do_unref() const { return (--_ref) == 0; }
00203 
00205     bool is_string() const
00206     {
00207         return (flags & VARINFO_FLAG_STRING) != 0;
00208     }
00209 
00211     bool is_binary() const
00212     {
00213         return (flags & VARINFO_FLAG_BINARY) != 0;
00214     }
00215 
00225     int encode_int(double fval) const throw ();
00226 
00236     unsigned encode_bit_int(double fval) const;
00237 
00247     double decode_int(int val) const throw ();
00248 
00258     double bufr_decode_int(uint32_t val) const throw ();
00259 
00263     void reset();
00264 
00270     void set(Varcode var, const char* desc, const char* unit, int scale = 0, int ref = 0, int len = 0, int bit_ref = 0, int bit_len = 0, int flags = 0, const char* bufr_unit = 0, int bufr_scale = 0);
00271 
00279     void set_string(Varcode var, const char* desc, int len);
00280 
00285     void compute_range();
00286 };
00287 
00288 class Varinfo;
00289 
00291 class MutableVarinfo
00292 {
00293 protected:
00295     _Varinfo* m_impl;
00296 
00297 public:
00299 
00300     MutableVarinfo(_Varinfo* impl) : m_impl(impl) { m_impl->do_ref(); }
00301     MutableVarinfo(const MutableVarinfo& vi) : m_impl(vi.m_impl) { m_impl->do_ref(); }
00303     ~MutableVarinfo() { if (m_impl->do_unref()) delete m_impl; }
00304 
00306 
00307     MutableVarinfo& operator=(const MutableVarinfo& vi)
00308     {
00309         vi.m_impl->do_ref();
00310         if (m_impl->do_unref()) delete m_impl;
00311         m_impl = vi.m_impl;
00312         return *this;
00313     }
00314     _Varinfo* operator->() { return m_impl; }
00315     _Varinfo& operator*() { return *m_impl; }
00317 
00319     _Varinfo* impl() const { return m_impl; }
00320 
00330     static MutableVarinfo create_singleuse();
00331 
00332     friend class wreport::Varinfo;
00333 };
00334 
00336 class Varinfo
00337 {
00338 protected:
00340     const _Varinfo* m_impl;
00341 
00342 public:
00344 
00345     Varinfo(const _Varinfo* impl) : m_impl(impl) { m_impl->do_ref(); }
00346     Varinfo(const _Varinfo& impl) : m_impl(&impl) { m_impl->do_ref(); }
00347     Varinfo(const Varinfo& vi) : m_impl(vi.m_impl) { m_impl->do_ref(); }
00348     Varinfo(const MutableVarinfo& vi) : m_impl(vi.m_impl) { m_impl->do_ref(); }
00350     ~Varinfo() { if (m_impl->do_unref()) delete m_impl; }
00351 
00353 
00354     const Varinfo& operator=(const Varinfo& vi)
00355     {
00356         vi.m_impl->do_ref();
00357         if (m_impl->do_unref()) delete m_impl;
00358         m_impl = vi.m_impl;
00359         return *this;
00360     }
00361     const _Varinfo& operator*() const { return *m_impl; }
00362     const _Varinfo* operator->() const { return m_impl; }
00364 
00366     const _Varinfo* impl() const { return m_impl; }
00367 };
00368 
00369 }
00370 
00371 #endif
00372 /* vim:set ts=4 sw=4: */