libwreport  2.9
buffers.h
1 /*
2  * wreport/bulletin/buffers - Low-level I/O operations
3  *
4  * Copyright (C) 2005--2011 ARPA-SIM <urpsim@smr.arpa.emr.it>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  *
19  * Author: Enrico Zini <enrico@enricozini.com>
20  */
21 
22 #ifndef WREPORT_BULLETIN_BUFFERS_H
23 #define WREPORT_BULLETIN_BUFFERS_H
24 
25 #include <wreport/error.h>
26 #include <wreport/varinfo.h>
27 #include <string>
28 #include <stdint.h>
29 
30 namespace wreport {
31 struct Var;
32 
33 namespace bulletin {
34 
39 {
40  virtual ~CompressedVarSink() {}
41 
50  virtual void operator()(const Var& var, unsigned idx) = 0;
51 };
52 
56 class BufrInput
57 {
58 protected:
63  void scan_section_length(unsigned sec_no);
64 
65 public:
67  const unsigned char* data;
68 
70  size_t data_len;
71 
79  const char* fname;
80 
88  size_t start_offset;
89 
91  unsigned s4_cursor;
92 
94  unsigned char pbyte;
95 
97  int pbyte_len;
98 
100  unsigned sec[6];
101 
102 
109  BufrInput(const std::string& in);
110 
112  void reset(const std::string& in);
113 
121  void scan_lead_sections();
122 
134  void scan_other_sections(bool has_optional);
135 
137  int offset() const;
138 
140  int bits_left() const;
141 
145  inline unsigned read_byte(unsigned pos) const
146  {
147  return (unsigned)data[pos];
148  }
149 
153  inline unsigned read_byte(unsigned section, unsigned pos) const
154  {
155  return (unsigned)data[sec[section] + pos];
156  }
157 
161  unsigned read_number(unsigned pos, unsigned byte_len) const;
162 
167  inline unsigned read_number(unsigned section, unsigned pos, unsigned byte_len) const
168  {
169  return read_number(sec[section] + pos, byte_len);
170  }
171 
176  uint32_t get_bits(unsigned n);
177 
179  void debug_dump_next_bits(int count) const;
180 
182  void parse_error(const char* fmt, ...) const WREPORT_THROWF_ATTRS(2, 3);
183 
185  void parse_error(unsigned pos, const char* fmt, ...) const WREPORT_THROWF_ATTRS(3, 4);
186 
188  void parse_error(unsigned section, unsigned pos, const char* fmt, ...) const WREPORT_THROWF_ATTRS(4, 5);
189 
202  void check_available_data(unsigned pos, size_t datalen, const char* expected);
203 
218  void check_available_data(unsigned section, unsigned pos, size_t datalen, const char* expected);
219 
232  void decode_number(Var& dest, uint32_t base, unsigned diffbits);
233 
242  void decode_number(Var& dest);
243 
248  void decode_number(Varinfo info, unsigned subsets, CompressedVarSink& dest);
249 
261  void decode_number(Var& dest, unsigned subsets);
262 
279  bool decode_string(unsigned bit_len, char* str, size_t& len);
280 
292  void decode_string(Var& dest);
293 
305  void decode_string(Var& dest, unsigned subsets);
306 
311  void decode_string(Varinfo info, unsigned subsets, CompressedVarSink& dest);
312 
324  void decode_binary(Var& dest);
325 };
326 
331 {
333  std::string& out;
334 
336  uint8_t pbyte;
337 
340 
347  BufrOutput(std::string& out);
348 
352  void add_bits(uint32_t val, int n);
353 
358  void raw_append(const char* str, int len)
359  {
360  out.append(str, len);
361  }
362 
364  void append_short(unsigned short val)
365  {
366  add_bits(val, 16);
367  }
368 
370  void append_byte(unsigned char val)
371  {
372  add_bits(val, 8);
373  }
374 
376  void append_missing(unsigned len_bits)
377  {
378  add_bits(0xffffffff, len_bits);
379  }
380 
382  void append_string(const Var& var, unsigned len_bits);
383 
385  void append_string(const char* val, unsigned len_bits);
386 
388  void append_binary(const unsigned char* val, unsigned len_bits);
389 
391  void append_var(Varinfo info, const Var& var);
392 
394  void append_missing(Varinfo info);
395 
400  void flush();
401 };
402 
406 struct CrexInput
407 {
409  const char* data;
410 
412  size_t data_len;
413 
421  const char* fname;
422 
430  size_t offset;
431 
435  unsigned sec[5];
436 
438  const char* cur;
439 
442 
445 
446 
453  CrexInput(const std::string& in);
454 
456  bool eof() const;
457 
459  unsigned remaining() const;
460 
462  void parse_error(const char* fmt, ...) const WREPORT_THROWF_ATTRS(2, 3);
463 
472  void check_eof(const char* expected) const;
473 
484  void check_available_data(unsigned datalen, const char* expected) const;
485 
487  void skip_spaces();
488 
490  void skip_data_and_spaces(unsigned datalen);
491 
501  void mark_section_start(unsigned num);
502 
516  void read_word(char* buf, size_t len);
517 
530  void parse_value(int len, int is_signed, const char** d_start, const char** d_end);
531 
533  void debug_dump_next(const char* desc) const;
534 };
535 
540 {
542  std::string& buf;
543 
546 
549 
550 
557  CrexOutput(std::string& buf);
558 
560  void raw_append(const char* str, int len);
561 
563  void raw_appendf(const char* fmt, ...) __attribute__ ((format(printf, 2, 3)));
564 
566  void encode_check_digit();
567 
569  void append_missing(Varinfo info);
570 
572  void append_var(Varinfo info, const Var& var);
573 };
574 
575 }
576 }
577 
578 #endif