libwreport 2.1
buffers.h
00001 /*
00002  * wreport/bulletin/buffers - Low-level I/O operations
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_BULLETIN_BUFFERS_H
00023 #define WREPORT_BULLETIN_BUFFERS_H
00024 
00025 #include <wreport/error.h>
00026 #include <wreport/varinfo.h>
00027 #include <string>
00028 #include <stdint.h>
00029 
00030 namespace wreport {
00031 struct Var;
00032 
00033 namespace bulletin {
00034 
00038 struct CompressedVarSink
00039 {
00040     virtual ~CompressedVarSink() {}
00041 
00050     virtual void operator()(const Var& var, unsigned idx) = 0;
00051 };
00052 
00056 class BufrInput
00057 {
00058 protected:
00063     void scan_section_length(unsigned sec_no);
00064 
00065 public:
00067     const unsigned char* data;
00068 
00070     size_t data_len;
00071 
00079     const char* fname;
00080 
00088     size_t start_offset;
00089 
00091     unsigned s4_cursor;
00092 
00094     unsigned char pbyte;
00095 
00097     int pbyte_len;
00098 
00100     unsigned sec[6];
00101 
00102  
00109     BufrInput(const std::string& in);
00110 
00112     void reset(const std::string& in);
00113 
00121     void scan_lead_sections();
00122 
00134     void scan_other_sections(bool has_optional);
00135 
00137     int offset() const;
00138 
00140     int bits_left() const;
00141 
00145     inline unsigned read_byte(unsigned pos) const
00146     {
00147         return (unsigned)data[pos];
00148     }
00149 
00153     inline unsigned read_byte(unsigned section, unsigned pos) const
00154     {
00155         return (unsigned)data[sec[section] + pos];
00156     }
00157 
00161     unsigned read_number(unsigned pos, unsigned byte_len) const;
00162 
00167     inline unsigned read_number(unsigned section, unsigned pos, unsigned byte_len) const
00168     {
00169         return read_number(sec[section] + pos, byte_len);
00170     }
00171 
00176     uint32_t get_bits(unsigned n);
00177 
00179     void debug_dump_next_bits(int count) const;
00180 
00182     void parse_error(const char* fmt, ...) const WREPORT_THROWF_ATTRS(2, 3);
00183 
00185     void parse_error(unsigned pos, const char* fmt, ...) const WREPORT_THROWF_ATTRS(3, 4);
00186 
00188     void parse_error(unsigned section, unsigned pos, const char* fmt, ...) const WREPORT_THROWF_ATTRS(4, 5);
00189 
00202     void check_available_data(unsigned pos, size_t datalen, const char* expected);
00203 
00218     void check_available_data(unsigned section, unsigned pos, size_t datalen, const char* expected);
00219 
00232     void decode_number(Var& dest, uint32_t base, unsigned diffbits);
00233 
00242     void decode_number(Var& dest);
00243 
00248     void decode_number(Varinfo info, unsigned subsets, CompressedVarSink& dest);
00249 
00261     void decode_number(Var& dest, unsigned subsets);
00262 
00279     bool decode_string(unsigned bit_len, char* str, size_t& len);
00280 
00292     void decode_string(Var& dest);
00293 
00305     void decode_string(Var& dest, unsigned subsets);
00306 
00311     void decode_string(Varinfo info, unsigned subsets, CompressedVarSink& dest);
00312 
00324     void decode_binary(Var& dest);
00325 };
00326 
00330 struct BufrOutput
00331 {
00333     std::string& out;
00334 
00336     uint8_t pbyte;
00337 
00339     int pbyte_len;
00340 
00347     BufrOutput(std::string& out);
00348 
00352     void add_bits(uint32_t val, int n);
00353 
00358     void raw_append(const char* str, int len)
00359     {
00360         out.append(str, len);
00361     }
00362 
00364     void append_short(unsigned short val)
00365     {
00366         add_bits(val, 16);
00367     }
00368 
00370     void append_byte(unsigned char val)
00371     {
00372         add_bits(val, 8);
00373     }
00374 
00376     void append_missing(unsigned len_bits)
00377     {
00378         add_bits(0xffffffff, len_bits);
00379     }
00380 
00382     void append_string(const Var& var, unsigned len_bits);
00383 
00385     void append_string(const char* val, unsigned len_bits);
00386 
00388     void append_binary(const unsigned char* val, unsigned len_bits);
00389 
00391     void append_var(Varinfo info, const Var& var);
00392 
00394     void append_missing(Varinfo info);
00395 
00400     void flush();
00401 };
00402 
00406 struct CrexInput
00407 {
00409     const char* data;
00410 
00412     size_t data_len;
00413 
00421     const char* fname;
00422 
00430     size_t offset;
00431 
00435     unsigned sec[5];
00436 
00438     const char* cur;
00439 
00441     int has_check_digit;
00442 
00444     int expected_check_digit;
00445 
00446 
00453     CrexInput(const std::string& in);
00454 
00456     bool eof() const;
00457 
00459     unsigned remaining() const;
00460 
00462     void parse_error(const char* fmt, ...) const WREPORT_THROWF_ATTRS(2, 3);
00463 
00472     void check_eof(const char* expected) const;
00473 
00484     void check_available_data(unsigned datalen, const char* expected) const;
00485 
00487     void skip_spaces();
00488 
00490     void skip_data_and_spaces(unsigned datalen);
00491 
00501     void mark_section_start(unsigned num);
00502 
00516     void read_word(char* buf, size_t len);
00517 
00530     void parse_value(int len, int is_signed, const char** d_start, const char** d_end);
00531 
00533     void debug_dump_next(const char* desc) const;
00534 };
00535 
00539 struct CrexOutput
00540 {
00542     std::string& buf;
00543 
00545     int has_check_digit;
00546 
00548     int expected_check_digit;
00549 
00550 
00557     CrexOutput(std::string& buf);
00558 
00560     void raw_append(const char* str, int len);
00561 
00563     void raw_appendf(const char* fmt, ...) __attribute__ ((format(printf, 2, 3)));
00564 
00566     void encode_check_digit();
00567 
00569     void append_missing(Varinfo info);
00570 
00572     void append_var(Varinfo info, const Var& var);
00573 };
00574 
00575 }
00576 }
00577 
00578 #endif