This file is indexed.

/usr/include/dballe/msg/msg.h is in libdballe-dev 7.7-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
/*
 * dballe/msg - Hold an interpreted weather bulletin
 *
 * Copyright (C) 2005--2015  ARPA-SIM <urpsim@smr.arpa.emr.it>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
 *
 * Author: Enrico Zini <enrico@enricozini.com>
 */

#ifndef DBA_MSG_H
#define DBA_MSG_H

/** @file
 * @ingroup msg
 *
 * Abstraction for a weather report message which is independent from the
 * encoding, used to make sense of decoded information and to carry data between
 * the various import and export modules of DB-ALLe.
 * 
 * The internal representation is as connected as possible to physics rather than
 * to observations.  dba_msg is a container for related weather information,
 * stored in a nonambiguous way.
 *
 * To understand what is the difference betwee ::dba_msg and other ways of
 * representing weather data, it is important to keep in mind how a value is
 * usually defined in the various encodings:
 * 
 * \li by previous values and position, as in the AOF encoding
 * \li by previous values, data descriptor and sometimes position, as in the BUFR
 *     encoding
 * \li by measure type and physical coordinates, as in ::dba_msg and the DB-ALLe
 *     database
 * 
 * ::dba_msg contains values as tuples (variable, level layer, time range).
 * 
 * The variable is represented by a dba_var.  The dba_varcode of the dba_var
 * refers to a local B table which lists physical measurements unambiguously.
 * 
 * Level layer is a triple (level type, l1, l2) and time range is a triple
 * (pindicator, p1, p2).  The values of these two triples follow what is used in
 * the GRIB encoding plus some local extensions, and an explanation of their
 * possible value is found in the document "DB-ALLe Guide of the Fortran API".
 * 
 * Importers and exporters have to implement a mapping between their
 * representation and the unambiguous physical representation.  Luckily this is
 * necessarily possible, because the ultimate purpose of the various message
 * encodings is to correctly transmit those physical data.
 *
 * Since to work with the full physical coordinates one needs to specify a lot of
 * different parameters in order to identify a value (BLocal value, level layer,
 * time range), there is a var.h module available with shortcut functions to
 * the values that are used more commonly.
 */

#include <dballe/message.h>
#include <dballe/var.h>
#include <dballe/core/defs.h>
#include <dballe/core/matcher.h>
#include <dballe/msg/vars.h>
#include <stdio.h>
#include <vector>
#include <memory>
#include <iosfwd>

struct lua_State;

namespace dballe {

struct Record;
struct CSVReader;

namespace msg {
struct Context;

/**
 * Read data from a CSV input.
 *
 * Reading stops when Report changes.
 */
Messages messages_from_csv(CSVReader& in);

/**
 * Output in CSV format
 */
void messages_to_csv(const Messages& msgs, std::ostream& out);

}

/**
 * Source of the data
 */
enum MsgType {
    MSG_GENERIC,    /**< Data from unspecified source */
    MSG_SYNOP,      /**< Synop measured data */
    MSG_PILOT,      /**< Pilot sounding data */
    MSG_TEMP,       /**< Temp sounding data */
    MSG_TEMP_SHIP,  /**< Temp ship sounding data */
    MSG_AIREP,      /**< Airep airplane data */
    MSG_AMDAR,      /**< Amdar airplane data */
    MSG_ACARS,      /**< Acars airplane data */
    MSG_SHIP,       /**< Ship measured data */
    MSG_BUOY,       /**< Buoy measured data */
    MSG_METAR,      /**< Metar data */
    MSG_SAT,        /**< Satellite data */
    MSG_POLLUTION   /**< Pollution data */
};

/**
 * Return a string with the name of a dba_msg_type
 *
 * @param type
 *   The dba_msg_type value to name
 * @return
 *   The name, as a const string.  This function is thread safe.
 */
const char* msg_type_name(MsgType type);

/**
 * Storage for related physical data
 */
class Msg : public Message
{
protected:
    /**
     * Return the index of the given context, or -1 if it was not found
     */
    int find_index(const Level& lev, const Trange& tr) const;

    /// Sensor network of origin of the Msg contents
    std::string m_network;
    /// Reference coordinates for the Msg contents
    Coords m_coords;
    /// Identifier of the contents originator
    Ident m_ident;
    /// Reference time for the Msg contents
    Datetime m_datetime;

public:
    /// Source of the data
    MsgType type;

    /** Context in the message */
    std::vector<msg::Context*> data;

    /**
     * Create a new dba_msg
     *
     * By default, type is MSG_GENERIC
     */
    Msg();
    ~Msg();

    Msg(const Msg& m);
    Msg& operator=(const Msg& m);

    /**
     * Return a reference to \a o downcasted as a Msg.
     *
     * Throws an exception if \a o is not a Msg.
     */
    static const Msg& downcast(const Message& o);

    /**
     * Return a reference to \a o downcasted as a Msg.
     *
     * Throws an exception if \a o is not a Msg.
     */
    static Msg& downcast(Message& o);


    std::unique_ptr<Message> clone() const override;
    Datetime get_datetime() const override { return m_datetime; }

    const wreport::Var* get(wreport::Varcode code, const Level& lev, const Trange& tr) const override;

    void print(FILE* out) const override;
    unsigned diff(const Message& msg) const override;

    void set_datetime(const Datetime& dt) { m_datetime = dt; }

    /// Remove all information from Msg
    void clear();

    /**
     * Add a missing context, taking care of its memory management
     *
     * Note: if the context already exists, an exception is thrown
     */
    void add_context(std::unique_ptr<msg::Context>&& ctx);

    /**
     * Remove a context from the message
     *
     * @return true if the context was removed, false if it did not exist
     */
    bool remove_context(const Level& lev, const Trange& tr);

    /**
     * Find a msg::Context given its description
     *
     * @param lev
     *   The Level to query
     * @param tr
     *   The Trange to query
     * @return
     *   The context found, or NULL if it was not found.
     */
    const msg::Context* find_context(const Level& lev, const Trange& tr) const;

    /**
     * Find the station info context
     *
     * @return
     *   The context found, or NULL if it was not found.
     */
    const msg::Context* find_station_context() const;

    /**
     * Find a msg::Context given its description
     *
     * @param lev
     *   The Level to query
     * @param tr
     *   The Trange to query
     * @return
     *   The context found, or NULL if it was not found.
     */
    msg::Context* edit_context(const Level& lev, const Trange& tr);

    /**
     * Find a msg::Context given its description, creating it if it does not
     * exist
     *
     * @param lev
     *   The Level to query
     * @param tr
     *   The Trange to query
     * @return
     *   The context found
     */
    msg::Context& obtain_context(const Level& lev, const Trange& tr);

    /// Shortcut to obtain_context(Level(), Trange());
    msg::Context& obtain_station_context();

    /**
     * Find a variable given its description
     *
     * @param code
     *   The ::dba_varcode of the variable to query. See @ref vartable.h
     * @param lev
     *   The Level to query
     * @param tr
     *   The Trange to query
     * @return
     *   The variable found, or NULL if it was not found.
     */
    wreport::Var* edit(wreport::Varcode code, const Level& lev, const Trange& tr);

    /**
     * Remove a variable given its description
     *
     * @param code
     *   The ::dba_varcode of the variable to query. See @ref vartable.h
     * @param lev
     *   The Level to query
     * @param tr
     *   The Trange to query
     * @returns
     *   True if the variable was removed, false if it was not found.
     */
    bool remove(wreport::Varcode code, const Level& lev, const Trange& tr);

    /** 
     * Find a datum given its shortcut ID
     *
     * @param msg
     *   The message to query
     * @param id
     *   Shortcut ID of the value to set (see @ref vars.h)
     * @return
     *   The value found, or NULL if it was not found.
     */
    const wreport::Var* find_by_id(int id) const;

    /** 
     * Find a contexts given level and timerange found in a shortcut ID
     *
     * @param msg
     *   The message to query
     * @param id
     *   Shortcut ID with the level information to use
     * @return
     *   The context found, or NULL if it was not found.
     */
    const msg::Context* find_context_by_id(int id) const;

    /** 
     * Find a datum given its shortcut ID
     *
     * @param msg
     *   The message to query
     * @param id
     *   Shortcut ID of the value to set (see @ref vars.h)
     * @return
     *   The value found, or NULL if it was not found.
     */
    wreport::Var* edit_by_id(int id);

    /**
     * Add or replace a value
     *
     * @param var
     *   The Var with the value to set
     * @param code
     *   The dba_varcode of the destination value.  If it is different than the
     *   varcode of var, a conversion will be attempted.
     * @param lev
     *   The Level of the value
     * @param tr
     *   The Trange of the value
     */
    void set(const wreport::Var& var, wreport::Varcode code, const Level& lev, const Trange& tr);

    /**
     * Add or replace a value
     *
     * @param var
     *   The Var with the value to set
     * @param shortcut
     *   Shortcut ID of the value to set
     */
    void set_by_id(const wreport::Var& var, int shortcut);

    /**
     * Add or replace a value, taking ownership of the source variable without
     * copying it.
     *
     * @param msg
     *   The Var with the value to set.  This Msg will take ownership of memory
     *   management.
     * @param lev
     *   The Level of the value
     * @param tr
     *   The Trange of the value
     */
    void set(std::unique_ptr<wreport::Var>&& var, const Level& lev, const Trange& tr);

    /**
     * Add or replace an integer value in the dba_msg
     *
     * @param code
     *   The dba_varcode of the destination value..  See @ref vartable.h
     * @param val
     *   The integer value of the data
     * @param conf
     *   The confidence interval of the data, as the value of a B33007 WMO B (per
     *   cent confidence) table entry, that is, a number between 0 and 100
     *   inclusive.  -1 means no confidence interval attribute.
     * @param lev
     *   The Level of the value
     * @param tr
     *   The Trange of the value
     */
    void seti(wreport::Varcode code, int val, int conf, const Level& lev, const Trange& tr);

    /**
     * Add or replace a double value in the dba_msg
     *
     * @param code
     *   The dba_varcode of the destination value.  See @ref vartable.h
     * @param val
     *   The double value of the data
     * @param conf
     *   The confidence interval of the data, as the value of a B33007 WMO B (per
     *   cent confidence) table entry, that is, a number between 0 and 100
     *   inclusive.  -1 means no confidence interval attribute.
     * @param lev
     *   The Level of the value
     * @param tr
     *   The Trange of the value
     */
    void setd(wreport::Varcode code, double val, int conf, const Level& lev, const Trange& tr);

    /**
     * Add or replace a string value in the dba_msg
     *
     * @param code
     *   The dba_varcode of the destination value.  See @ref vartable.h
     * @param val
     *   The string value of the data
     * @param conf
     *   The confidence interval of the data, as the value of a B33007 WMO B (per
     *   cent confidence) table entry, that is, a number between 0 and 100
     *   inclusive.  -1 means no confidence interval attribute.
     * @param lev
     *   The Level of the value
     * @param tr
     *   The Trange of the value
     */
    void setc(wreport::Varcode code, const char* val, int conf, const Level& lev, const Trange& tr);

    /**
     * Copy to dest all the variable in this message that match \a filter
     * TODO: to be implemented
     */
    //void filter(const Record& filter, Msg& dest) const;

    /**
     * Copy a Msg, removing the sounding significance from the level
     * descriptions and packing together the data at the same pressure level.
     *
     * This is used to postprocess data after decoding, where the l2 field of the
     * level description is temporarily used to store the vertical sounding
     * significance, to simplify decoding.
     */
    void sounding_pack_levels(Msg& dst) const;

#if 0
    /**
     * Copy a Msg, adding the sounding significance from the level descriptions
     * and moving the data at the same pressure level to the resulting
     * pseudolevels.
     *
     * This is used to preprocess data before encoding, where the l2 field of the
     * level description is temporarily used to store the vertical sounding
     * significance, to simplify encoding.
     */
    void sounding_unpack_levels(Msg& dst) const;
#endif

    /**
     * Read data from a CSV input.
     *
     * Reading stops when one of Longitude, Latitude, Report or Date changes.
     *
     * @return true if some CSV data has been found, false on EOF
     */
    bool from_csv(CSVReader& in);

    /**
     * Output in CSV format
     */
    void to_csv(std::ostream& out) const;

    /// Output the CSV header
    static void csv_header(std::ostream& out);

    /**
     * Get the message source type corresponding to the given report code
     */
    static MsgType type_from_repmemo(const char* repmemo);

    /**
     * Get the report code corresponding to the given message source type
     */
    static const char* repmemo_from_type(MsgType type);

#include <dballe/msg/msg-extravars.h>


    /**
     * Push the variable as an object in the lua stack
     */
    void lua_push(struct lua_State* L);

    /**
     * Check that the element at \a idx is a dba_msg
     *
     * @return the dba_msg element, or NULL if the check failed
     */
    static Msg* lua_check(struct lua_State* L, int idx);
};

/**
 * Match adapter for Msg
 */
struct MatchedMsg : public Matched
{
    const Msg& m;

    MatchedMsg(const Msg& r);
    ~MatchedMsg();

    matcher::Result match_var_id(int val) const override;
    matcher::Result match_station_id(int val) const override;
    matcher::Result match_station_wmo(int block, int station=-1) const override;
    matcher::Result match_datetime(const DatetimeRange& range) const override;
    matcher::Result match_coords(const LatRange& latrange, const LonRange& lonrange) const override;
    matcher::Result match_rep_memo(const char* memo) const override;
};

/**
 * Match adapter for Messages
 */
struct MatchedMessages : public Matched
{
    const Messages& m;

    MatchedMessages(const Messages& m);
    ~MatchedMessages();

    matcher::Result match_var_id(int val) const override;
    matcher::Result match_station_id(int val) const override;
    matcher::Result match_station_wmo(int block, int station=-1) const override;
    matcher::Result match_datetime(const DatetimeRange& range) const override;
    matcher::Result match_coords(const LatRange& latrange, const LonRange& lonrange) const override;
    matcher::Result match_rep_memo(const char* memo) const override;
};

}
#endif