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
std::string & out
Output buffer to which we append encoded data.
Definition: buffers.h:333
BufrInput(const std::string &in)
Wrap a string iinto a BufrInput.
int pbyte_len
Number of bits already encoded in pbyte.
Definition: buffers.h:339
unsigned read_byte(unsigned pos) const
Read a byte value at offset pos.
Definition: buffers.h:145
bool decode_string(unsigned bit_len, char *str, size_t &len)
Read a string from the data section.
size_t offset
File offset of the start of the message.
Definition: buffers.h:430
unsigned read_byte(unsigned section, unsigned pos) const
Read a byte value at offset pos inside section section.
Definition: buffers.h:153
void reset(const std::string &in)
Start decoding a different buffer.
Binary buffer with bit-level read operations.
Definition: buffers.h:56
Destination for decoded variables from compressed BUFRs.
Definition: buffers.h:38
void scan_section_length(unsigned sec_no)
Scan length of section sec_no, filling in the start of the next section in sec[sec_no + 1]...
unsigned s4_cursor
Offset of the byte we are currently decoding.
Definition: buffers.h:91
Binary buffer with bit-level append operations.
Definition: buffers.h:330
void decode_number(Var &dest, uint32_t base, unsigned diffbits)
Decode a compressed number as described by dest.info(), ad set it as value for dest.
Holds a wreport variable.
Definition: var.h:50
void raw_append(const char *str, int len)
Append a string len bits long to the output buffer as it is, ignoring partially encoded bits...
Definition: buffers.h:358
uint32_t get_bits(unsigned n)
Get the integer value of the next 'n' bits from the decode input n must be <= 32. ...
virtual void operator()(const Var &var, unsigned idx)=0
Send a variable to a subset.
void append_short(unsigned short val)
Append a 16 bits integer.
Definition: buffers.h:364
int bits_left() const
Return the number of bits left in the message to be decoded.
unsigned read_number(unsigned pos, unsigned byte_len) const
Read a big endian integer value byte_len bytes long, at offset pos.
size_t start_offset
File offset of the start of the message.
Definition: buffers.h:88
Text input buffer.
Definition: buffers.h:406
size_t data_len
Input buffer size.
Definition: buffers.h:412
void decode_binary(Var &dest)
Decode a generic binary value as-is, as described by dest.info(), ad set it as value for dest...
unsigned read_number(unsigned section, unsigned pos, unsigned byte_len) const
Read a big endian integer value byte_len bytes long, at offset pos inside section section...
Definition: buffers.h:167
wreport exceptions
void parse_error(const char *fmt,...) const WREPORT_THROWF_ATTRS(2
Throw an error_parse at the current decoding location.
Text output buffer.
Definition: buffers.h:539
unsigned sec[6]
Offsets of the start of BUFR sections.
Definition: buffers.h:100
const char * data
Input buffer.
Definition: buffers.h:409
uint8_t pbyte
Byte to which we are appending bits to encode.
Definition: buffers.h:336
void void void void check_available_data(unsigned pos, size_t datalen, const char *expected)
Check that the input buffer contains at least datalen characters after offset pos; throw error_parse ...
void debug_dump_next_bits(int count) const
Dump to stderr 'count' bits of 'buf', starting at the 'ofs-th' bit.
int expected_check_digit
Value of the next expected check digit.
Definition: buffers.h:444
int expected_check_digit
Value of the next expected check digit.
Definition: buffers.h:548
int pbyte_len
Bits left in pbyte to decode.
Definition: buffers.h:97
const char * cur
Cursor inside in.data() used for decoding.
Definition: buffers.h:438
int offset() const
Return the current decoding byte offset.
void scan_other_sections(bool has_optional)
Scan the message filling in the sec[] array of section start offsets of all sections from 2 on...
void scan_lead_sections()
Scan the message filling in the sec[] array of start offsets of sections 0 and 1. ...
Implement fast access to information about WMO variables.
Smart pointer to handle/use varinfos.
Definition: varinfo.h:336
#define WREPORT_THROWF_ATTRS(a, b)
Tell the compiler that a function always throws and expects printf-style arguments.
Definition: error.h:78
void append_missing(unsigned len_bits)
Append a missing value len_bits long.
Definition: buffers.h:376
const unsigned char * data
Input buffer.
Definition: buffers.h:67
const char * fname
Input file name (optional).
Definition: buffers.h:79
int has_check_digit
True if the CREX message uses the check digit feature.
Definition: buffers.h:545
size_t data_len
Input buffer size.
Definition: buffers.h:70
const char * fname
Input file name (optional).
Definition: buffers.h:421
int has_check_digit
True if the CREX message uses the check digit feature.
Definition: buffers.h:441
std::string & buf
String we append to.
Definition: buffers.h:542
void append_byte(unsigned char val)
Append an 8 bits integer.
Definition: buffers.h:370
unsigned char pbyte
Byte we are currently decoding.
Definition: buffers.h:94