# Bulletin

`wreport::Bulletin` is the structure encoding a BUFR or CREX weather report message. It contains data organised in multiple subsets (`wreport::Subset`) that share a common structure.

Messages are encoded and decoded using the various read/write/create/decode functions in the format-specific subclasses of `wreport::Bulletin`: `wreport::BufrBulletin` and `wreport::CrexBulletin`.

class Bulletin

  Storage for the decoded data of a BUFR or CREX message.

  A Bulletin roughly reflects the structure of a BUFR or CREX message: it contains metadata, a sequence of wreport::Varcode with the contents of a Data Descriptor Section, and one or more wreport::Subset with the decoded values.

  Subsets are essentially sequences of wreport::Var objects, and therefore contain the values together with the full range of variable information, including type, measurement units and number of significant digits.

  Extra values like quality control statistics or replaced values are represented as ‘attributes’ to the wreport::Var objects.

  Subclassed by wreport::BufrBulletin, wreport::CrexBulletin

  Public Functions

  virtual void clear()

    Reset the bulletin.

  virtual const char *encoding_name() const = 0

    Type of source/target encoding.

  Subset &obtain_subset(unsigned subsection)

    Get a Subset from the message.

    The subset will be created if it does not exist, and it will be memory managed by the Bulletin.

    Parameters:

      subsection – The subsection index (starting from 0)

  const Subset &subset(unsigned subsection) const

    Get a Subset from the message.

    An exception will be thrown if the subset does not exist

    Parameters:

      subsection – The subsection index (starting from 0)

  virtual void load_tables() = 0

    Load a new set of tables to use for encoding this message.

  virtual std::string encode() const = 0

    Encode the message.

  void print(FILE *out) const

    Dump the contents of this bulletin.

  void print_structured(FILE *out) const

    Dump the contents of this bulletin, in a more structured way.

  virtual void print_details(FILE *out) const

    Print format-specific details.

  void print_datadesc(FILE *out, unsigned indent = 0) const

    Pretty-print the data descriptor section.

    Parameters:

      - out – Output stream to use

      - indent – Indent all output by this amount of spaces

  virtual unsigned diff(const Bulletin &msg) const

    Compute the differences between two bulletins.

    Details of the differences found will be formatted using the notes system (

    See also

    notes.h).

    Parameters:

      msg – The bulletin to compare with this one

    Returns:

      The number of differences found

  virtual unsigned diff_details(const Bulletin &msg) const

    Diff format-specific details.

  Public Members

  std::string fname

    Input file name (optional).

    If available, it will be used to generate better error messages.

    If not available, it is empty.

  off_t offset = 0

    File offset of the start of the message.

    If available, it will be used to generate better error messages.

    If not available, it is 0.

  uint8_t master_table_number = 0

    BUFR Master table number.

    A master table may be defined for a scientific discipline other than meteorology. The current list of master tables, along with their associated values in octet 4, is as follows:

    \l 0: Meteorology maintained by the World Meteorological Organization (WMO) \l 10: Oceanography maintained by the Intergovernmental Oceanographic Commission (IOC) of UNESCO

  uint8_t data_category = 0xff

    Data category (BUFR or CREX Table A).

  uint8_t data_subcategory = 0xff

    International data sub-category (see Common Code table C-13).

  uint8_t data_subcategory_local = 0xff

    Local data sub-category, defined locally by automatic data-processing (ADP) centres.

    Note: the local data sub-category is maintained for backwards compatibility with BUFR editions 0-3, since many ADP centres have made extensive use of such values in the past. The international data sub-category introduced with BUFR edition 4 is intended to provide a mechanism for better understanding of the overall nature and intent of messages exchanged between ADP centres. These two values (i.e. local sub-category and international sub-category) are intended to be supplementary to one another, so both may be used within a particular BUFR message.

  uint16_t originating_centre = 0xffff

    Identification of originating/generating centre (see Common Code table C-11).

  uint16_t originating_subcentre = 0xffff

    Identification of originating/generating sub-centre (allocated by originating/generating centre - see Common Code table C-12).

  uint8_t update_sequence_number = 0

    Update sequence number (zero for original messages and for messages containing only delayed reports; incremented for the other updates).

  uint16_t rep_year = 0

    Reference year in bulletin header.

  uint8_t rep_month = 0

    Reference month in bulletin header.

  uint8_t rep_day = 0

    Reference day in bulletin header.

  uint8_t rep_hour = 0

    Reference hour in bulletin header.

  uint8_t rep_minute = 0

    Reference minute in bulletin header.

  uint8_t rep_second = 0

    Reference second in bulletin header.

  Tables tables

    Varcode and opcode tables used for encoding or decoding.

  std::vector<Varcode> datadesc

    Parsed data descriptor section.

  std::vector<Subset> subsets

    Decoded variables.

class BufrCodecOptions

  Options used to configure BUFR decoding.

  Public Members

  bool decode_adds_undef_attrs = false

    By default (false) undefined attributes are not added to variables, and there is no difference between an undefined or a missing attribute.

    If this is set to true, undefined attributes are added to variables, so that it is possible to tell between a variable with no attributes and a variable for which the bulletin provides attributes but they have an missing value.

  Public Static Functions

  static std::unique_ptr<BufrCodecOptions> create()

    Create a BufrCodecOptions.

    Options may be added at any time to future versions of the structure. To reduce the likelyhook of breaking ABI, construction on stack is discouraged in favour of an allocator function.

class BufrBulletin : public wreport::Bulletin

  BUFR bulletin implementation.

  Public Functions

  virtual void clear()

    Reset the bulletin.

  inline virtual const char *encoding_name() const override

    Type of source/target encoding.

  virtual void load_tables() override

    Load a new set of tables to use for encoding this message.

  virtual std::string encode() const override

    Encode the message.

  virtual void print_details(FILE *out) const override

    Print format-specific details.

  virtual unsigned diff_details(const Bulletin &msg) const override

    Diff format-specific details.

  Public Members

  uint8_t edition_number = 4

    BUFR edition number.

  uint8_t master_table_version_number = 19

    Version number of BUFR master table used.

    See WMO Manual on Codes, Binary codes, FM94-XIV BUFR, Section 1 Identification section, note 5, or FB95-XIV CREX, Specification of sections, note 3, for a list.

  uint8_t master_table_version_number_local = 0

    Version number of local table used to augment the master table.

    Local tables shall define those parts of the master table which are reserved for local use, thus version numbers of local tables may be changed at will by the originating centre. If no local table is used, the version number of the local table shall be encoded as 0.

  bool compression

    Whether the message is compressed.

  std::string optional_section

    Raw optional section of the message.

    It is empty if the message does not contain an optional section.

  unsigned section_end[6] = {0, 0, 0, 0, 0, 0}

    Offsets of the end of BUFR sections.

    This is only filled in during decoding.

  Public Static Functions

  static bool read(FILE *in, std::string &buf, const char *fname = 0, off_t *offset = 0)

    Read an encoded BUFR message from a stream.

    Parameters:

      - in – The stream to read from

      - buf – The buffer where the data will be written

      - fname – File name to use in error messages

    Return values:

      offset – The offset in the file of the beginning of the BUFR data

    Returns:

      true if a message was found, false on EOF

  static void write(const std::string &buf, FILE *out, const char *fname = 0)

    Write an encoded BUFR message to a stream.

    Parameters:

      - buf – The buffer with the data to write

      - out – The stream to write to

      - fname – File name to use in error messages

  static std::unique_ptr<BufrBulletin> create()

    To prevent breaking ABI if new members are added to bulletins, direct construction is discouraged in favour of an allocator function.

  static std::unique_ptr<BufrBulletin> decode_header(const std::string &raw, const char *fname = "(memory)", size_t offset = 0)

    Parse only the header of an encoded BUFR message.

    Parameters:

      - buf – The buffer to decode

      - fname – The file name to use for error messages

      - offset – The offset inside the file of the start of the bulletin, used for error messages

    Returns:

      The new bulletin with the decoded message

  static std::unique_ptr<BufrBulletin> decode_header(const std::string &raw, const BufrCodecOptions &opts, const char *fname = "(memory)", size_t offset = 0)

    Parse only the header of an encoded BUFR message.

    Parameters:

      - buf – The buffer to decode

      - opts – Options used to customise encoding or decoding.

      - fname – The file name to use for error messages

      - offset – The offset inside the file of the start of the bulletin, used for error messages

    Returns:

      The new bulletin with the decoded message

  static std::unique_ptr<BufrBulletin> decode(const std::string &raw, const char *fname = "(memory)", size_t offset = 0)

    Parse an encoded BUFR message.

    Parameters:

      - buf – The buffer to decode

      - fname – The file name to use for error messages

      - offset – The offset inside the file of the start of the bulletin, used for error messages

    Returns:

      The new bulletin with the decoded message

  static std::unique_ptr<BufrBulletin> decode_verbose(const std::string &raw, FILE *out, const char *fname = "(memory)", size_t offset = 0)

    Parse an encoded BUFR message, printing decoding information.

    Parameters:

      - buf – The buffer to decode

      - out – Where the decoder information should be printed

      - fname – The file name to use for error messages

      - offset – The offset inside the file of the start of the bulletin, used for error messages

    Returns:

      The new bulletin with the decoded message

  static std::unique_ptr<BufrBulletin> decode(const std::string &raw, const BufrCodecOptions &opts, const char *fname = "(memory)", size_t offset = 0)

    Parse an encoded BUFR message.

    Parameters:

      - buf – The buffer to decode

      - opts – Options used to customise encoding or decoding.

      - fname – The file name to use for error messages

      - offset – The offset inside the file of the start of the bulletin, used for error messages

    Returns:

      The new bulletin with the decoded message

class CrexBulletin : public wreport::Bulletin

  CREX bulletin implementation.

  Public Functions

  virtual void clear()

    Reset the bulletin.

  inline virtual const char *encoding_name() const override

    Type of source/target encoding.

  virtual void load_tables() override

    Load a new set of tables to use for encoding this message.

  virtual std::string encode() const override

    Encode the message.

  virtual void print_details(FILE *out) const override

    Print format-specific details.

  virtual unsigned diff_details(const Bulletin &msg) const override

    Diff format-specific details.

  Public Members

  uint8_t edition_number = 2

    CREX Edition number.

  uint8_t master_table_version_number = 19

    CREX master table version number.

    See WMO Manual on Codes, FB95-XIV CREX, Specification of sections, note 3, for a list.

  uint8_t master_table_version_number_bufr = 19

    BUFR master table version number.

    See WMO Manual on Codes, Binary codes, FM94-XIV BUFR, Section 1 Identification section, note 5, for a list.

    FIXME: I could not find any reference to why CREX edition 2 has a separate field for BUFR master table version number but not for BUFR master table version, or why it needs to reference BUFR master tables at all.

  uint8_t master_table_version_number_local = 0

    Version number of local table used to augment the master table.

    Local tables shall define those parts of the master table which are reserved for local use, thus version numbers of local tables may be changed at will by the originating centre. If no local table is used, the version number of the local table shall be encoded as 0.

  bool has_check_digit = false

    True if the CREX message uses the check digit feature.

  Public Static Functions

  static bool read(FILE *in, std::string &buf, const char *fname = 0, off_t *offset = 0)

    Read an encoded BUFR message from a stream.

    Parameters:

      - in – The stream to read from

      - buf – The buffer where the data will be written

      - fname – File name to use in error messages

    Return values:

      offset – The offset in the file of the beginning of the BUFR data

    Returns:

      true if a message was found, false on EOF

  static void write(const std::string &buf, FILE *out, const char *fname = 0)

    Write an encoded BUFR message to a stream.

    Parameters:

      - buf – The buffer with the data to write

      - out – The stream to write to

      - fname – File name to use in error messages

  static std::unique_ptr<CrexBulletin> create()

    To prevent breaking ABI if new members are added to bulletins, direct construction is discouraged in favour of an allocator function.

  static std::unique_ptr<CrexBulletin> decode_header(const std::string &raw, const char *fname = "(memory)", size_t offset = 0)

    Parse only the header of an encoded BUFR message.

    Parameters:

      - buf – The buffer to decode

      - fname – The file name to use for error messages

      - offset – The offset inside the file of the start of the bulletin, used for error messages

    Returns:

      The new bulletin with the decoded message

  static std::unique_ptr<CrexBulletin> decode(const std::string &raw, const char *fname = "(memory)", size_t offset = 0)

    Parse an encoded BUFR message.

    Parameters:

      - buf – The buffer to decode

      - fname – The file name to use for error messages

      - offset – The offset inside the file of the start of the bulletin, used for error messages

    Returns:

      The new bulletin with the decoded message

  static std::unique_ptr<CrexBulletin> decode_verbose(const std::string &raw, FILE *out, const char *fname = "(memory)", size_t offset = 0)

    Parse an encoded BUFR message, printing decoding information.

    Parameters:

      - buf – The buffer to decode

      - out – Where the decoder information should be printed

      - fname – The file name to use for error messages

      - offset – The offset inside the file of the start of the bulletin, used for error messages

    Returns:

      The new bulletin with the decoded message

class Subset : public std::vector<Var>

  Represent a BUFR/CREX data subset as a list of decoded variables.

  Public Functions

  Subset(const Tables &tables)

    Create a new BUFR/CREX subset.

    Parameters:

      btable – Reference to the B table to use to create variables.

  void store_variable(const Var &var)

    Store a decoded variable in the message, to be encoded later.

  void store_variable(Var &&var)

    Store a decoded variable in the message, to be encoded later.

  void store_variable(Varcode code, const Var &var)

    Store a new variable in the message, copying it from an already existing variable.

    Parameters:

      - code – The Varcode of the variable to add. See varinfo.h

      - var – The variable holding the value for the variable to add.

  void store_variable_i(Varcode code, int val)

    Store a new variable in the message, providing its value as an int.

    Parameters:

      - code – The Varcode of the variable to add. See vartable.h

      - val – The value for the variable

  void store_variable_d(Varcode code, double val)

    Store a new variable in the message, providing its value as a double.

    Parameters:

      - code – The Varcode of the variable to add. See vartable.h

      - val – The value for the variable

  void store_variable_c(Varcode code, const char *val)

    Store a new variable in the message, providing its value as a string.

    Parameters:

      - code – The Varcode of the variable to add. See vartable.h

      - val – The value for the variable

  void store_variable_undef(Varcode code)

    Store a new, undefined variable in the message.

  void store_variable_undef(Varinfo info)

    Store a new, undefined variable in the message.

  int append_dpb(Varcode ccode, unsigned size, Varcode attr)

    Compute and append a data present bitmap.

    Parameters:

      - ccode – The C code that uses this bitmap

      - size – The size of the bitmap

      - attr – The code of the attribute that the bitmap will represent. See vartable.h

    Returns:

      The number of attributes that will be encoded (for which the dpb has ‘+’)

  void append_fixed_dpb(Varcode ccode, int size)

    Append a fixed-size data present bitmap with all zeros.

    Parameters:

      - ccode – The C code that uses this bitmap

      - size – The size of the bitmap

  void print(FILE *out) const

    Dump the contents of this subset.

  unsigned diff(const Subset &s2) const

    Compute the differences between two wreport subsets.

    Details of the differences found will be formatted using the notes system (

    See also

    notes.h).

    Parameters:

      s2 – The subset to compare with this one

    Returns:

      The number of differences found

  Public Members

  const Tables *tables

    Tables used for creating variables in this subset.