LLVMFuzzerTestOneInput:
   27|  2.72k|{//gpsd/tests//test_json.c
   28|       |
   29|  2.72k|    if (Size < kMinInputLength || Size > kMaxInputLength){
  ------------------
  |  |   21|  5.45k|#define kMinInputLength 10
  ------------------
                  if (Size < kMinInputLength || Size > kMaxInputLength){
  ------------------
  |  |   22|  2.72k|#define kMaxInputLength 5120
  ------------------
  |  Branch (29:9): [True: 6, False: 2.72k]
  |  Branch (29:35): [True: 19, False: 2.70k]
  ------------------
   30|     25|        return 0;
   31|     25|    }
   32|       |
   33|  2.70k|    uint8_t *DataFx;
   34|  2.70k|    size_t SizeFx = Size+1;
   35|  2.70k|    DataFx = (uint8_t *)calloc(SizeFx,sizeof(uint8_t));
   36|       |
   37|  2.70k|    memcpy((void *)DataFx,(void *)Data,Size);
   38|       |
   39|  2.70k|    char AddCB[] ={0x7b}; //{
   40|  2.70k|    memcpy((void *)DataFx,(void *)AddCB,sizeof(AddCB));
   41|       |//calloc already added 0x00 at the end of DataFx.
   42|       |
   43|  2.70k|    int status;
   44|  2.70k|    {
   45|  2.70k|        memset((void *)&gpsdata, 0, sizeof(gpsdata));
   46|  2.70k|        status = libgps_json_unpack((char *)DataFx, &gpsdata, NULL);
   47|  2.70k|    }
   48|  2.70k|    {
   49|  2.70k|        memset((void *)&gpsdata, 0, sizeof(gpsdata));
   50|  2.70k|        status = json_toff_read((char *)DataFx, &gpsdata, NULL);
   51|  2.70k|    }
   52|       |
   53|  2.70k|    free(DataFx);
   54|       |
   55|  2.70k|    return status;
   56|  2.72k|}

libgps_json.c:str_starts_with:
   18|  19.1k|{
   19|  19.1k|    return 0 == strncmp(str, prefix, strlen(prefix));
   20|  19.1k|}

json_ais_read:
   43|    343|{
   44|       |    // collected but not actually used yet
   45|    343|    bool scaled;
   46|       |
   47|    343|#define AIS_HEADER \
   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
   50|    343|        {"device",         t_string,   .addr.string = path, \
   51|    343|                                          .len = pathlen}, \
   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
   54|    343|                                          .dflt.boolean = false}, \
   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
   56|       |
   57|    343|#define AIS_TYPE6 \
   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
   59|    343|                                       .dflt.uinteger = 0},\
   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
   61|    343|                                       .dflt.uinteger = 0},\
   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
   63|    343|                                       .dflt.boolean = false},\
   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
   65|    343|                                       .dflt.uinteger = 0},\
   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
   67|    343|                                       .dflt.uinteger = 0},
   68|    343|#define AIS_TYPE8 \
   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
   70|    343|                                       .dflt.uinteger = 0},\
   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
   72|    343|                                       .dflt.uinteger = 0},
   73|       |
   74|    343|    int status;
   75|       |
   76|    343|#include "ais_json.i"           // JSON parser template structures
  ------------------
  |  |    1|       |/*
  |  |    2|       | * This is code generated by jsongen.py. Do not hand-hack it!
  |  |    3|       | */
  |  |    4|    343| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |    5|       |
  |  |    6|       |
  |  |    7|    343|    const struct json_attr_t json_ais1[] = {
  |  |    8|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |    9|    343|	{"status",        t_uinteger,  .addr.uinteger = &ais->type1.status,
  |  |   10|    343|                                       .dflt.uinteger = 0},
  |  |   11|    343|	{"status_text",   t_ignore},
  |  |   12|    343|	{"turn",          t_integer,   .addr.integer = &ais->type1.turn,
  |  |   13|    343|                                       .dflt.integer = AIS_TURN_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1478|    343|#define AIS_TURN_NOT_AVAILABLE  128
  |  |  ------------------
  |  |   14|    343|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type1.speed,
  |  |   15|    343|                                       .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1480|    343|#define AIS_SPEED_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |   16|    343|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type1.accuracy,
  |  |   17|    343|                                       .dflt.boolean = false},
  |  |   18|    343|	{"lon",           t_integer,   .addr.integer = &ais->type1.lon,
  |  |   19|    343|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1485|    343|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |   20|    343|	{"lat",           t_integer,   .addr.integer = &ais->type1.lat,
  |  |   21|    343|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1487|    343|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |   22|    343|	{"course",        t_uinteger,  .addr.uinteger = &ais->type1.course,
  |  |   23|    343|                                       .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1489|    343|#define AIS_COURSE_NOT_AVAILABLE        3600
  |  |  ------------------
  |  |   24|    343|	{"heading",       t_uinteger,  .addr.uinteger = &ais->type1.heading,
  |  |   25|    343|                                       .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1491|    343|#define AIS_HEADING_NOT_AVAILABLE       511
  |  |  ------------------
  |  |   26|    343|	{"second",        t_uinteger,  .addr.uinteger = &ais->type1.second,
  |  |   27|    343|                                       .dflt.uinteger = AIS_SEC_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1496|    343|#define AIS_SEC_NOT_AVAILABLE   60
  |  |  ------------------
  |  |   28|    343|	{"maneuver",      t_uinteger,  .addr.uinteger = &ais->type1.maneuver,
  |  |   29|    343|                                       .dflt.uinteger = AIS_SEC_INOPERATIVE},
  |  |  ------------------
  |  |  |  | 1499|    343|#define AIS_SEC_INOPERATIVE     63
  |  |  ------------------
  |  |   30|    343|	{"raim",          t_boolean,   .addr.boolean = &ais->type1.raim,
  |  |   31|    343|                                       .dflt.boolean = false},
  |  |   32|    343|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type1.radio,
  |  |   33|    343|                                       .dflt.uinteger = 0},
  |  |   34|    343|        {NULL}
  |  |   35|    343|    };
  |  |   36|       |
  |  |   37|    343|    char timestamp[JSON_VAL_MAX+1];
  |  |   38|    343|    const struct json_attr_t json_ais4[] = {
  |  |   39|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |   40|    343|	{"timestamp",     t_string,    .addr.string = timestamp,
  |  |   41|    343|                                       .len = sizeof(timestamp)},
  |  |   42|    343|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type4.accuracy,
  |  |   43|    343|                                       .dflt.boolean = true},
  |  |   44|    343|	{"lon",           t_integer,   .addr.integer = &ais->type4.lon,
  |  |   45|    343|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1485|    343|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |   46|    343|	{"lat",           t_integer,   .addr.integer = &ais->type4.lat,
  |  |   47|    343|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1487|    343|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |   48|    343|	{"epfd",          t_uinteger,  .addr.uinteger = &ais->type4.epfd,
  |  |   49|    343|                                       .dflt.uinteger = 0},
  |  |   50|    343|	{"epfd_text",   t_ignore},
  |  |   51|    343|	{"raim",          t_boolean,   .addr.boolean = &ais->type4.raim,
  |  |   52|    343|                                       .dflt.boolean = false},
  |  |   53|    343|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type4.radio,
  |  |   54|    343|                                       .dflt.uinteger = 0},
  |  |   55|    343|        {NULL}
  |  |   56|    343|    };
  |  |   57|       |
  |  |   58|    343|    char eta[JSON_VAL_MAX+1];
  |  |   59|    343|    const struct json_attr_t json_ais5[] = {
  |  |   60|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |   61|    343|	{"imo",           t_uinteger,  .addr.uinteger = &ais->type5.imo,
  |  |   62|    343|                                       .dflt.uinteger = 0},
  |  |   63|    343|	{"ais_version",   t_uinteger,  .addr.uinteger = &ais->type5.ais_version,
  |  |   64|    343|                                       .dflt.uinteger = 0},
  |  |   65|    343|	{"callsign",      t_string,    .addr.string = ais->type5.callsign,
  |  |   66|    343|                                       .len = sizeof(ais->type5.callsign)},
  |  |   67|    343|	{"shipname",      t_string,    .addr.string = ais->type5.shipname,
  |  |   68|    343|                                       .len = sizeof(ais->type5.shipname)},
  |  |   69|    343|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type5.shiptype,
  |  |   70|    343|                                       .dflt.uinteger = 0},
  |  |   71|    343|	{"shiptype_text",   t_ignore},
  |  |   72|    343|	{"to_bow",        t_uinteger,  .addr.uinteger = &ais->type5.to_bow,
  |  |   73|    343|                                       .dflt.uinteger = 0},
  |  |   74|    343|	{"to_stern",      t_uinteger,  .addr.uinteger = &ais->type5.to_stern,
  |  |   75|    343|                                       .dflt.uinteger = 0},
  |  |   76|    343|	{"to_port",       t_uinteger,  .addr.uinteger = &ais->type5.to_port,
  |  |   77|    343|                                       .dflt.uinteger = 0},
  |  |   78|    343|	{"to_starboard",  t_uinteger,  .addr.uinteger = &ais->type5.to_starboard,
  |  |   79|    343|                                       .dflt.uinteger = 0},
  |  |   80|    343|	{"epfd",          t_uinteger,  .addr.uinteger = &ais->type5.epfd,
  |  |   81|    343|                                       .dflt.uinteger = 0},
  |  |   82|    343|	{"epfd_text",   t_ignore},
  |  |   83|    343|	{"eta",           t_string,    .addr.string = eta,
  |  |   84|    343|                                       .len = sizeof(eta)},
  |  |   85|    343|	{"draught",       t_uinteger,  .addr.uinteger = &ais->type5.draught,
  |  |   86|    343|                                       .dflt.uinteger = 0},
  |  |   87|    343|	{"destination",   t_string,    .addr.string = ais->type5.destination,
  |  |   88|    343|                                       .len = sizeof(ais->type5.destination)},
  |  |   89|    343|	{"dte",           t_uinteger,  .addr.uinteger = &ais->type5.dte,
  |  |   90|    343|                                       .dflt.uinteger = 1},
  |  |   91|    343|        {NULL}
  |  |   92|    343|    };
  |  |   93|       |
  |  |   94|    343|    char data[JSON_VAL_MAX+1];
  |  |   95|    343|    const struct json_attr_t json_ais6[] = {
  |  |   96|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |   97|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |   98|    343|	{"data",          t_string,    .addr.string = data,
  |  |   99|    343|                                       .len = sizeof(data)},
  |  |  100|    343|        {NULL}
  |  |  101|    343|    };
  |  |  102|       |
  |  |  103|    343|    const struct json_attr_t json_ais6_fid10[] = {
  |  |  104|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  105|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  106|    343|	{"ana_int",       t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.ana_int,
  |  |  107|    343|                                       .dflt.uinteger = 0},
  |  |  108|    343|	{"ana_ext1",      t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.ana_ext1,
  |  |  109|    343|                                       .dflt.uinteger = 0},
  |  |  110|    343|	{"ana_ext2",      t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.ana_ext2,
  |  |  111|    343|                                       .dflt.uinteger = 0},
  |  |  112|    343|	{"racon",         t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.racon,
  |  |  113|    343|                                       .dflt.uinteger = 0},
  |  |  114|    343|	{"racon_text",   t_ignore},
  |  |  115|    343|	{"light",         t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.light,
  |  |  116|    343|                                       .dflt.uinteger = 0},
  |  |  117|    343|	{"light_text",   t_ignore},
  |  |  118|    343|	{"alarm",         t_boolean,   .addr.boolean = &ais->type6.dac235fid10.alarm,
  |  |  119|    343|                                       .dflt.boolean = false},
  |  |  120|    343|	{"stat_ext",      t_uinteger,  .addr.uinteger = &ais->type6.dac235fid10.stat_ext,
  |  |  121|    343|                                       .dflt.uinteger = 0},
  |  |  122|    343|	{"off_pos",       t_boolean,   .addr.boolean = &ais->type6.dac235fid10.off_pos,
  |  |  123|    343|                                       .dflt.boolean = false},
  |  |  124|    343|        {NULL}
  |  |  125|    343|    };
  |  |  126|       |
  |  |  127|    343|    char departure[JSON_VAL_MAX+1];
  |  |  128|    343|    const struct json_attr_t json_ais6_fid12[] = {
  |  |  129|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  130|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  131|    343|	{"lastport",      t_string,    .addr.string = ais->type6.dac1fid12.lastport,
  |  |  132|    343|                                       .len = sizeof(ais->type6.dac1fid12.lastport)},
  |  |  133|    343|	{"departure",     t_string,    .addr.string = departure,
  |  |  134|    343|                                       .len = sizeof(departure)},
  |  |  135|    343|	{"nextport",      t_string,    .addr.string = ais->type6.dac1fid12.nextport,
  |  |  136|    343|                                       .len = sizeof(ais->type6.dac1fid12.nextport)},
  |  |  137|    343|	{"eta",           t_string,    .addr.string = eta,
  |  |  138|    343|                                       .len = sizeof(eta)},
  |  |  139|    343|	{"dangerous",     t_string,    .addr.string = ais->type6.dac1fid12.dangerous,
  |  |  140|    343|                                       .len = sizeof(ais->type6.dac1fid12.dangerous)},
  |  |  141|    343|	{"imdcat",        t_string,    .addr.string = ais->type6.dac1fid12.imdcat,
  |  |  142|    343|                                       .len = sizeof(ais->type6.dac1fid12.imdcat)},
  |  |  143|    343|	{"unid",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid12.unid,
  |  |  144|    343|                                       .dflt.uinteger = 0},
  |  |  145|    343|	{"amount",        t_uinteger,  .addr.uinteger = &ais->type6.dac1fid12.amount,
  |  |  146|    343|                                       .dflt.uinteger = 0},
  |  |  147|    343|	{"unit",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid12.unit,
  |  |  148|    343|                                       .dflt.uinteger = 0},
  |  |  149|    343|        {NULL}
  |  |  150|    343|    };
  |  |  151|       |
  |  |  152|    343|    const struct json_attr_t json_ais6_fid15[] = {
  |  |  153|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  154|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  155|    343|	{"airdraught",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid15.airdraught,
  |  |  156|    343|                                       .dflt.uinteger = 0},
  |  |  157|    343|        {NULL}
  |  |  158|    343|    };
  |  |  159|       |
  |  |  160|    343|    const struct json_attr_t json_ais6_fid16[] = {
  |  |  161|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  162|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  163|    343|	{"persons",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid16.persons,
  |  |  164|    343|                                       .dflt.uinteger = 0},
  |  |  165|    343|        {NULL}
  |  |  166|    343|    };
  |  |  167|       |
  |  |  168|    343|    char arrival[JSON_VAL_MAX+1];
  |  |  169|    343|    const struct json_attr_t json_ais6_fid18[] = {
  |  |  170|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  171|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  172|    343|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid18.linkage,
  |  |  173|    343|                                       .dflt.uinteger = 0},
  |  |  174|    343|	{"arrival",       t_string,    .addr.string = arrival,
  |  |  175|    343|                                       .len = sizeof(arrival)},
  |  |  176|    343|	{"portname",      t_string,    .addr.string = ais->type6.dac1fid18.portname,
  |  |  177|    343|                                       .len = sizeof(ais->type6.dac1fid18.portname)},
  |  |  178|    343|	{"destination",   t_string,    .addr.string = ais->type6.dac1fid18.destination,
  |  |  179|    343|                                       .len = sizeof(ais->type6.dac1fid18.destination)},
  |  |  180|    343|	{"lon",           t_integer,   .addr.integer = &ais->type6.dac1fid18.lon,
  |  |  181|    343|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1441|    343|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  182|    343|	{"lat",           t_integer,   .addr.integer = &ais->type6.dac1fid18.lat,
  |  |  183|    343|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1442|    343|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  184|    343|        {NULL}
  |  |  185|    343|    };
  |  |  186|       |
  |  |  187|    343|    char berth_name[JSON_VAL_MAX+1];
  |  |  188|    343|    const struct json_attr_t json_ais6_fid20[] = {
  |  |  189|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  190|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  191|    343|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.linkage,
  |  |  192|    343|                                       .dflt.uinteger = 0},
  |  |  193|    343|	{"berth_length",  t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.berth_length,
  |  |  194|    343|                                       .dflt.uinteger = 0},
  |  |  195|    343|	{"berth_depth",   t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.berth_depth,
  |  |  196|    343|                                       .dflt.uinteger = 0},
  |  |  197|    343|	{"position",      t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.position,
  |  |  198|    343|                                       .dflt.uinteger = 0},
  |  |  199|    343|	{"position_text",   t_ignore},
  |  |  200|    343|	{"arrival",       t_string,    .addr.string = arrival,
  |  |  201|    343|                                       .len = sizeof(arrival)},
  |  |  202|    343|	{"availability",  t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.availability,
  |  |  203|    343|                                       .dflt.uinteger = 0},
  |  |  204|    343|	{"agent",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.agent,
  |  |  205|    343|                                       .dflt.uinteger = 0},
  |  |  206|    343|	{"fuel",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.fuel,
  |  |  207|    343|                                       .dflt.uinteger = 0},
  |  |  208|    343|	{"chandler",      t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.chandler,
  |  |  209|    343|                                       .dflt.uinteger = 0},
  |  |  210|    343|	{"stevedore",     t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.stevedore,
  |  |  211|    343|                                       .dflt.uinteger = 0},
  |  |  212|    343|	{"electrical",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.electrical,
  |  |  213|    343|                                       .dflt.uinteger = 0},
  |  |  214|    343|	{"water",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.water,
  |  |  215|    343|                                       .dflt.uinteger = 0},
  |  |  216|    343|	{"customs",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.customs,
  |  |  217|    343|                                       .dflt.uinteger = 0},
  |  |  218|    343|	{"cartage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.cartage,
  |  |  219|    343|                                       .dflt.uinteger = 0},
  |  |  220|    343|	{"crane",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.crane,
  |  |  221|    343|                                       .dflt.uinteger = 0},
  |  |  222|    343|	{"lift",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.lift,
  |  |  223|    343|                                       .dflt.uinteger = 0},
  |  |  224|    343|	{"medical",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.medical,
  |  |  225|    343|                                       .dflt.uinteger = 0},
  |  |  226|    343|	{"navrepair",     t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.navrepair,
  |  |  227|    343|                                       .dflt.uinteger = 0},
  |  |  228|    343|	{"provisions",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.provisions,
  |  |  229|    343|                                       .dflt.uinteger = 0},
  |  |  230|    343|	{"shiprepair",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.shiprepair,
  |  |  231|    343|                                       .dflt.uinteger = 0},
  |  |  232|    343|	{"surveyor",      t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.surveyor,
  |  |  233|    343|                                       .dflt.uinteger = 0},
  |  |  234|    343|	{"steam",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.steam,
  |  |  235|    343|                                       .dflt.uinteger = 0},
  |  |  236|    343|	{"tugs",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.tugs,
  |  |  237|    343|                                       .dflt.uinteger = 0},
  |  |  238|    343|	{"solidwaste",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.solidwaste,
  |  |  239|    343|                                       .dflt.uinteger = 0},
  |  |  240|    343|	{"liquidwaste",   t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.liquidwaste,
  |  |  241|    343|                                       .dflt.uinteger = 0},
  |  |  242|    343|	{"hazardouswaste",t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.hazardouswaste,
  |  |  243|    343|                                       .dflt.uinteger = 0},
  |  |  244|    343|	{"ballast",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.ballast,
  |  |  245|    343|                                       .dflt.uinteger = 0},
  |  |  246|    343|	{"additional",    t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.additional,
  |  |  247|    343|                                       .dflt.uinteger = 0},
  |  |  248|    343|	{"regional1",     t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.regional1,
  |  |  249|    343|                                       .dflt.uinteger = 0},
  |  |  250|    343|	{"regional2",     t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.regional2,
  |  |  251|    343|                                       .dflt.uinteger = 0},
  |  |  252|    343|	{"future1",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.future1,
  |  |  253|    343|                                       .dflt.uinteger = 0},
  |  |  254|    343|	{"future2",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid20.future2,
  |  |  255|    343|                                       .dflt.uinteger = 0},
  |  |  256|    343|	{"berth_name",    t_string,    .addr.string = berth_name,
  |  |  257|    343|                                       .len = sizeof(berth_name)},
  |  |  258|    343|	{"berth_lon",     t_integer,   .addr.integer = &ais->type6.dac1fid20.berth_lon,
  |  |  259|    343|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1441|    343|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  260|    343|	{"berth_lat",     t_integer,   .addr.integer = &ais->type6.dac1fid20.berth_lat,
  |  |  261|    343|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1442|    343|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  262|    343|        {NULL}
  |  |  263|    343|    };
  |  |  264|       |
  |  |  265|    343|    const struct json_attr_t json_ais6_fid21[] = {
  |  |  266|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  267|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  268|    343|	{"country",       t_string,    .addr.string = ais->type6.dac200fid21.country,
  |  |  269|    343|                                       .len = sizeof(ais->type6.dac200fid21.country)},
  |  |  270|    343|	{"locode",        t_string,    .addr.string = ais->type6.dac200fid21.locode,
  |  |  271|    343|                                       .len = sizeof(ais->type6.dac200fid21.locode)},
  |  |  272|    343|	{"section",       t_string,    .addr.string = ais->type6.dac200fid21.section,
  |  |  273|    343|                                       .len = sizeof(ais->type6.dac200fid21.section)},
  |  |  274|    343|	{"terminal",      t_string,    .addr.string = ais->type6.dac200fid21.terminal,
  |  |  275|    343|                                       .len = sizeof(ais->type6.dac200fid21.terminal)},
  |  |  276|    343|	{"hectometre",    t_string,    .addr.string = ais->type6.dac200fid21.hectometre,
  |  |  277|    343|                                       .len = sizeof(ais->type6.dac200fid21.hectometre)},
  |  |  278|    343|	{"eta",           t_string,    .addr.string = eta,
  |  |  279|    343|                                       .len = sizeof(eta)},
  |  |  280|    343|	{"tugs",          t_uinteger,  .addr.uinteger = &ais->type6.dac200fid21.tugs,
  |  |  281|    343|                                       .dflt.uinteger = 0},
  |  |  282|    343|	{"airdraught",    t_uinteger,  .addr.uinteger = &ais->type6.dac200fid21.airdraught,
  |  |  283|    343|                                       .dflt.uinteger = 0},
  |  |  284|    343|        {NULL}
  |  |  285|    343|    };
  |  |  286|       |
  |  |  287|    343|    char rta[JSON_VAL_MAX+1];
  |  |  288|    343|    const struct json_attr_t json_ais6_fid22[] = {
  |  |  289|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  290|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  291|    343|	{"country",       t_string,    .addr.string = ais->type6.dac200fid22.country,
  |  |  292|    343|                                       .len = sizeof(ais->type6.dac200fid22.country)},
  |  |  293|    343|	{"locode",        t_string,    .addr.string = ais->type6.dac200fid22.locode,
  |  |  294|    343|                                       .len = sizeof(ais->type6.dac200fid22.locode)},
  |  |  295|    343|	{"section",       t_string,    .addr.string = ais->type6.dac200fid22.section,
  |  |  296|    343|                                       .len = sizeof(ais->type6.dac200fid22.section)},
  |  |  297|    343|	{"terminal",      t_string,    .addr.string = ais->type6.dac200fid22.terminal,
  |  |  298|    343|                                       .len = sizeof(ais->type6.dac200fid22.terminal)},
  |  |  299|    343|	{"hectometre",    t_string,    .addr.string = ais->type6.dac200fid22.hectometre,
  |  |  300|    343|                                       .len = sizeof(ais->type6.dac200fid22.hectometre)},
  |  |  301|    343|	{"rta",           t_string,    .addr.string = rta,
  |  |  302|    343|                                       .len = sizeof(rta)},
  |  |  303|    343|	{"status",        t_uinteger,  .addr.uinteger = &ais->type6.dac200fid22.status,
  |  |  304|    343|                                       .dflt.uinteger = DAC200FID22_STATUS_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1594|    343|#define DAC200FID22_STATUS_NOT_AVAILABLE        0
  |  |  ------------------
  |  |  305|    343|        {NULL}
  |  |  306|    343|    };
  |  |  307|       |
  |  |  308|    343|    const struct json_attr_t json_ais6_fid25_cargos_subtype[] = {
  |  |  309|    343|	{"code",          t_uinteger,STRUCTOBJECT(struct cargo_t, code),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  310|    343|                                       .dflt.uinteger = 0},
  |  |  311|    343|	{"subtype",       t_uinteger,STRUCTOBJECT(struct cargo_t, subtype),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  312|    343|                                       .dflt.uinteger = 0},
  |  |  313|    343|        {NULL}
  |  |  314|    343|    };
  |  |  315|    343|    const struct json_attr_t json_ais6_fid25[] = {
  |  |  316|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  317|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  318|    343|	{"unit",          t_uinteger,  .addr.uinteger = &ais->type6.dac1fid25.unit,
  |  |  319|    343|                                       .dflt.uinteger = 0},
  |  |  320|    343|	{"amount",        t_uinteger,  .addr.uinteger = &ais->type6.dac1fid25.amount,
  |  |  321|    343|                                       .dflt.uinteger = 0},
  |  |  322|    343|	{"cargos",        t_array,     STRUCTARRAY(ais->type6.dac1fid25.cargos, json_ais6_fid25_cargos_subtype, &ais->type6.dac1fid25.ncargos)},
  |  |  ------------------
  |  |  |  |  190|    343|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    343|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    343|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    343|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    343|        .addr.array.count = n, \
  |  |  |  |  195|    343|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    343| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  323|    343|        {NULL}
  |  |  324|    343|    };
  |  |  325|       |
  |  |  326|    343|    char start[JSON_VAL_MAX+1];
  |  |  327|    343|    const struct json_attr_t json_ais6_fid28_waypoints_subtype[] = {
  |  |  328|    343|	{"lon",           t_integer, STRUCTOBJECT(struct waypoint_t, lon),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  329|    343|                                       .dflt.integer = AIS_LON4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1446|    343|#define AIS_LON4_NOT_AVAILABLE  1810000
  |  |  ------------------
  |  |  330|    343|	{"lat",           t_integer, STRUCTOBJECT(struct waypoint_t, lat),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  331|    343|                                       .dflt.integer = AIS_LAT4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1447|    343|#define AIS_LAT4_NOT_AVAILABLE  910000
  |  |  ------------------
  |  |  332|    343|        {NULL}
  |  |  333|    343|    };
  |  |  334|    343|    const struct json_attr_t json_ais6_fid28[] = {
  |  |  335|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  336|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  337|    343|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid28.linkage,
  |  |  338|    343|                                       .dflt.uinteger = 0},
  |  |  339|    343|	{"sender",        t_uinteger,  .addr.uinteger = &ais->type6.dac1fid28.sender,
  |  |  340|    343|                                       .dflt.uinteger = 0},
  |  |  341|    343|	{"rtype",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid28.rtype,
  |  |  342|    343|                                       .dflt.uinteger = 0},
  |  |  343|    343|	{"rtype_text",   t_ignore},
  |  |  344|    343|	{"start",         t_string,    .addr.string = start,
  |  |  345|    343|                                       .len = sizeof(start)},
  |  |  346|    343|	{"duration",      t_uinteger,  .addr.uinteger = &ais->type6.dac1fid28.duration,
  |  |  347|    343|                                       .dflt.uinteger = 0},
  |  |  348|    343|	{"waypoints",     t_array,     STRUCTARRAY(ais->type6.dac1fid28.waypoints, json_ais6_fid28_waypoints_subtype, &ais->type6.dac1fid28.waycount)},
  |  |  ------------------
  |  |  |  |  190|    343|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    343|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    343|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    343|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    343|        .addr.array.count = n, \
  |  |  |  |  195|    343|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    343| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  349|    343|        {NULL}
  |  |  350|    343|    };
  |  |  351|       |
  |  |  352|    343|    const struct json_attr_t json_ais6_fid30[] = {
  |  |  353|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  354|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  355|    343|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type6.dac1fid30.linkage,
  |  |  356|    343|                                       .dflt.uinteger = 0},
  |  |  357|    343|	{"text",          t_string,    .addr.string = ais->type6.dac1fid30.text,
  |  |  358|    343|                                       .len = sizeof(ais->type6.dac1fid30.text)},
  |  |  359|    343|        {NULL}
  |  |  360|    343|    };
  |  |  361|       |
  |  |  362|    343|    const struct json_attr_t json_ais6_fid32_tidals_subtype[] = {
  |  |  363|    343|	{"lon",           t_integer, STRUCTOBJECT(struct tidal_t, lon),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  364|    343|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1441|    343|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  365|    343|	{"lat",           t_integer, STRUCTOBJECT(struct tidal_t, lat),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  366|    343|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1442|    343|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  367|    343|	{"from_hour",     t_uinteger,STRUCTOBJECT(struct tidal_t, from_hour),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  368|    343|                                       .dflt.uinteger = AIS_MONTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1510|    343|#define AIS_MONTH_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  369|    343|	{"from_min",      t_uinteger,STRUCTOBJECT(struct tidal_t, from_min),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  370|    343|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    343|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  371|    343|	{"to_hour",       t_uinteger,STRUCTOBJECT(struct tidal_t, to_hour),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  372|    343|                                       .dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1514|    343|#define AIS_HOUR_NOT_AVAILABLE  24
  |  |  ------------------
  |  |  373|    343|	{"to_min",        t_uinteger,STRUCTOBJECT(struct tidal_t, to_min),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  374|    343|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    343|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  375|    343|	{"cdir",          t_uinteger,STRUCTOBJECT(struct tidal_t, cdir),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  376|    343|                                       .dflt.uinteger = DAC1FID32_CDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1810|    343|#define DAC1FID32_CDIR_NOT_AVAILABLE     360
  |  |  ------------------
  |  |  377|    343|	{"cspeed",        t_uinteger,STRUCTOBJECT(struct tidal_t, cspeed),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  378|    343|                                       .dflt.uinteger = DAC1FID32_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1812|    343|#define DAC1FID32_CSPEED_NOT_AVAILABLE   127
  |  |  ------------------
  |  |  379|    343|        {NULL}
  |  |  380|    343|    };
  |  |  381|    343|    const struct json_attr_t json_ais6_fid32[] = {
  |  |  382|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  383|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  384|    343|	{"month",         t_uinteger,  .addr.uinteger = &ais->type6.dac1fid32.month,
  |  |  385|    343|                                       .dflt.uinteger = AIS_MONTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1510|    343|#define AIS_MONTH_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  386|    343|	{"day",           t_uinteger,  .addr.uinteger = &ais->type6.dac1fid32.day,
  |  |  387|    343|                                       .dflt.uinteger = AIS_DAY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1512|    343|#define AIS_DAY_NOT_AVAILABLE   0
  |  |  ------------------
  |  |  388|    343|	{"tidals",        t_array,     STRUCTARRAY(ais->type6.dac1fid32.tidals, json_ais6_fid32_tidals_subtype, &ais->type6.dac1fid32.ntidals)},
  |  |  ------------------
  |  |  |  |  190|    343|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    343|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    343|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    343|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    343|        .addr.array.count = n, \
  |  |  |  |  195|    343|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    343| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  389|    343|        {NULL}
  |  |  390|    343|    };
  |  |  391|       |
  |  |  392|    343|    const struct json_attr_t json_ais6_fid55[] = {
  |  |  393|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  394|    343|	AIS_TYPE6
  |  |  ------------------
  |  |  |  |   58|    343|        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
  |  |  |  |   59|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   60|    343|        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
  |  |  |  |   61|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   62|    343|        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
  |  |  |  |   63|    343|                                       .dflt.boolean = false},\
  |  |  |  |   64|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
  |  |  |  |   65|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   66|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
  |  |  |  |   67|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  395|    343|	{"crew",          t_uinteger,  .addr.uinteger = &ais->type6.dac200fid55.crew,
  |  |  396|    343|                                       .dflt.uinteger = DAC200FID55_COUNT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1601|    343|#define DAC200FID55_COUNT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  397|    343|	{"passengers",    t_uinteger,  .addr.uinteger = &ais->type6.dac200fid55.passengers,
  |  |  398|    343|                                       .dflt.uinteger = DAC200FID55_COUNT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1601|    343|#define DAC200FID55_COUNT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  399|    343|	{"personnel",     t_uinteger,  .addr.uinteger = &ais->type6.dac200fid55.personnel,
  |  |  400|    343|                                       .dflt.uinteger = DAC200FID55_COUNT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1601|    343|#define DAC200FID55_COUNT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  401|    343|        {NULL}
  |  |  402|    343|    };
  |  |  403|       |
  |  |  404|    343|    const struct json_attr_t json_ais7[] = {
  |  |  405|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  406|    343|	{"mmsi1",         t_uinteger,  .addr.uinteger = &ais->type7.mmsi1,
  |  |  407|    343|                                       .dflt.uinteger = 0},
  |  |  408|    343|	{"mmsi2",         t_uinteger,  .addr.uinteger = &ais->type7.mmsi2,
  |  |  409|    343|                                       .dflt.uinteger = 0},
  |  |  410|    343|	{"mmsi3",         t_uinteger,  .addr.uinteger = &ais->type7.mmsi3,
  |  |  411|    343|                                       .dflt.uinteger = 0},
  |  |  412|    343|	{"mmsi4",         t_uinteger,  .addr.uinteger = &ais->type7.mmsi4,
  |  |  413|    343|                                       .dflt.uinteger = 0},
  |  |  414|    343|	{"seqno1",        t_uinteger,  .addr.uinteger = &ais->type7.seqno1,
  |  |  415|    343|                                       .dflt.uinteger = 0},
  |  |  416|    343|	{"seqno2",        t_uinteger,  .addr.uinteger = &ais->type7.seqno2,
  |  |  417|    343|                                       .dflt.uinteger = 0},
  |  |  418|    343|	{"seqno3",        t_uinteger,  .addr.uinteger = &ais->type7.seqno3,
  |  |  419|    343|                                       .dflt.uinteger = 0},
  |  |  420|    343|	{"seqno4",        t_uinteger,  .addr.uinteger = &ais->type7.seqno4,
  |  |  421|    343|                                       .dflt.uinteger = 0},
  |  |  422|    343|        {NULL}
  |  |  423|    343|    };
  |  |  424|       |
  |  |  425|    343|    const struct json_attr_t json_ais8[] = {
  |  |  426|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  427|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  428|    343|	{"data",          t_string,    .addr.string = data,
  |  |  429|    343|                                       .len = sizeof(data)},
  |  |  430|    343|        {NULL}
  |  |  431|    343|    };
  |  |  432|       |
  |  |  433|    343|    const struct json_attr_t json_ais8_fid10[] = {
  |  |  434|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  435|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  436|    343|	{"vin",           t_string,    .addr.string = ais->type8.dac200fid10.vin,
  |  |  437|    343|                                       .len = sizeof(ais->type8.dac200fid10.vin)},
  |  |  438|    343|	{"length",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.length,
  |  |  439|    343|                                       .dflt.uinteger = 0},
  |  |  440|    343|	{"beam",          t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.beam,
  |  |  441|    343|                                       .dflt.uinteger = 0},
  |  |  442|    343|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.shiptype,
  |  |  443|    343|                                       .dflt.uinteger = 0},
  |  |  444|    343|	{"shiptype_text",   t_ignore},
  |  |  445|    343|	{"hazard",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.hazard,
  |  |  446|    343|                                       .dflt.uinteger = 0},
  |  |  447|    343|	{"hazard_text",   t_ignore},
  |  |  448|    343|	{"draught",       t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.draught,
  |  |  449|    343|                                       .dflt.uinteger = 0},
  |  |  450|    343|	{"loaded",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid10.loaded,
  |  |  451|    343|                                       .dflt.uinteger = 0},
  |  |  452|    343|	{"loaded_text",   t_ignore},
  |  |  453|    343|	{"speed_q",       t_boolean,   .addr.boolean = &ais->type8.dac200fid10.speed_q,
  |  |  454|    343|                                       .dflt.boolean = false},
  |  |  455|    343|	{"course_q",      t_boolean,   .addr.boolean = &ais->type8.dac200fid10.course_q,
  |  |  456|    343|                                       .dflt.boolean = false},
  |  |  457|    343|	{"heading_q",     t_boolean,   .addr.boolean = &ais->type8.dac200fid10.heading_q,
  |  |  458|    343|                                       .dflt.boolean = false},
  |  |  459|    343|        {NULL}
  |  |  460|    343|    };
  |  |  461|       |
  |  |  462|    343|    const struct json_attr_t json_ais8_fid11[] = {
  |  |  463|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  464|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  465|    343|	{"lat",           t_integer,   .addr.integer = &ais->type8.dac1fid11.lat,
  |  |  466|    343|                                       .dflt.integer = DAC1FID11_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1912|    343|#define DAC1FID11_LAT_NOT_AVAILABLE     0x7FFFFF
  |  |  ------------------
  |  |  467|    343|	{"lon",           t_integer,   .addr.integer = &ais->type8.dac1fid11.lon,
  |  |  468|    343|                                       .dflt.integer = DAC1FID11_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1910|    343|#define DAC1FID11_LON_NOT_AVAILABLE     0xFFFFFF
  |  |  ------------------
  |  |  469|    343|	{"timestamp",     t_string,    .addr.string = timestamp,
  |  |  470|    343|                                       .len = sizeof(timestamp)},
  |  |  471|    343|	{"wspeed",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wspeed,
  |  |  472|    343|                                       .dflt.uinteger = DAC1FID11_WSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1918|    343|#define DAC1FID11_WSPEED_NOT_AVAILABLE  127
  |  |  ------------------
  |  |  473|    343|	{"wgust",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wgust,
  |  |  474|    343|                                       .dflt.uinteger = DAC1FID11_WSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1918|    343|#define DAC1FID11_WSPEED_NOT_AVAILABLE  127
  |  |  ------------------
  |  |  475|    343|	{"wdir",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wdir,
  |  |  476|    343|                                       .dflt.uinteger = DAC1FID11_WDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1921|    343|#define DAC1FID11_WDIR_NOT_AVAILABLE    511
  |  |  ------------------
  |  |  477|    343|	{"wgustdir",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wgustdir,
  |  |  478|    343|                                       .dflt.uinteger = DAC1FID11_WDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1921|    343|#define DAC1FID11_WDIR_NOT_AVAILABLE    511
  |  |  ------------------
  |  |  479|    343|	{"airtemp",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.airtemp,
  |  |  480|    343|                                       .dflt.uinteger = DAC1FID11_AIRTEMP_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1923|    343|#define DAC1FID11_AIRTEMP_NOT_AVAILABLE 2047
  |  |  ------------------
  |  |  481|    343|	{"humidity",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.humidity,
  |  |  482|    343|                                       .dflt.uinteger = DAC1FID11_HUMIDITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1927|    343|#define DAC1FID11_HUMIDITY_NOT_AVAILABLE 127
  |  |  ------------------
  |  |  483|    343|	{"dewpoint",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.dewpoint,
  |  |  484|    343|                                       .dflt.uinteger = DAC1FID11_DEWPOINT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1929|    343|#define DAC1FID11_DEWPOINT_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |  485|    343|	{"pressure",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.pressure,
  |  |  486|    343|                                       .dflt.uinteger = DAC1FID11_PRESSURE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1933|    343|#define DAC1FID11_PRESSURE_NOT_AVAILABLE 511
  |  |  ------------------
  |  |  487|    343|	{"pressuretend",  t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.pressuretend,
  |  |  488|    343|                                       .dflt.uinteger = DAC1FID11_PRESSURETREND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1936|    343|#define DAC1FID11_PRESSURETREND_NOT_AVAILABLE 3
  |  |  ------------------
  |  |  489|    343|	{"visibility",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.visibility,
  |  |  490|    343|                                       .dflt.uinteger = DAC1FID11_VISIBILITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1938|    343|#define DAC1FID11_VISIBILITY_NOT_AVAILABLE  255
  |  |  ------------------
  |  |  491|    343|	{"waterlevel",    t_integer,   .addr.integer = &ais->type8.dac1fid11.waterlevel,
  |  |  492|    343|                                       .dflt.integer = DAC1FID11_WATERLEVEL_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1941|    343|#define DAC1FID11_WATERLEVEL_NOT_AVAILABLE  511
  |  |  ------------------
  |  |  493|    343|	{"leveltrend",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.leveltrend,
  |  |  494|    343|                                       .dflt.uinteger = DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1945|    343|#define DAC1FID11_WATERLEVELTREND_NOT_AVAILABLE 3
  |  |  ------------------
  |  |  495|    343|	{"cspeed",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cspeed,
  |  |  496|    343|                                       .dflt.uinteger = DAC1FID11_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1947|    343|#define DAC1FID11_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  497|    343|	{"cdir",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdir,
  |  |  498|    343|                                       .dflt.uinteger = DAC1FID11_CDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1950|    343|#define DAC1FID11_CDIR_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  499|    343|	{"cspeed2",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cspeed2,
  |  |  500|    343|                                       .dflt.uinteger = DAC1FID11_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1947|    343|#define DAC1FID11_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  501|    343|	{"cdir2",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdir2,
  |  |  502|    343|                                       .dflt.uinteger = DAC1FID11_CDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1950|    343|#define DAC1FID11_CDIR_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  503|    343|	{"cdepth2",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdepth2,
  |  |  504|    343|                                       .dflt.uinteger = DAC1FID11_CDEPTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1954|    343|#define DAC1FID11_CDEPTH_NOT_AVAILABLE     31
  |  |  ------------------
  |  |  505|    343|	{"cspeed3",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cspeed3,
  |  |  506|    343|                                       .dflt.uinteger = DAC1FID11_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1947|    343|#define DAC1FID11_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  507|    343|	{"cdir3",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdir3,
  |  |  508|    343|                                       .dflt.uinteger = DAC1FID11_CDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1950|    343|#define DAC1FID11_CDIR_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  509|    343|	{"cdepth3",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.cdepth3,
  |  |  510|    343|                                       .dflt.uinteger = DAC1FID11_CDEPTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1954|    343|#define DAC1FID11_CDEPTH_NOT_AVAILABLE     31
  |  |  ------------------
  |  |  511|    343|	{"waveheight",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.waveheight,
  |  |  512|    343|                                       .dflt.uinteger = DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1959|    343|#define DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  513|    343|	{"waveperiod",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.waveperiod,
  |  |  514|    343|                                       .dflt.uinteger = DAC1FID11_WAVEPERIOD_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1962|    343|#define DAC1FID11_WAVEPERIOD_NOT_AVAILABLE 63
  |  |  ------------------
  |  |  515|    343|	{"wavedir",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.wavedir,
  |  |  516|    343|                                       .dflt.uinteger = DAC1FID11_WAVEDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1964|    343|#define DAC1FID11_WAVEDIR_NOT_AVAILABLE    511
  |  |  ------------------
  |  |  517|    343|	{"swellheight",   t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.swellheight,
  |  |  518|    343|                                       .dflt.uinteger = DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1959|    343|#define DAC1FID11_WAVEHEIGHT_NOT_AVAILABLE 255
  |  |  ------------------
  |  |  519|    343|	{"swellperiod",   t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.swellperiod,
  |  |  520|    343|                                       .dflt.uinteger = DAC1FID11_WAVEPERIOD_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1962|    343|#define DAC1FID11_WAVEPERIOD_NOT_AVAILABLE 63
  |  |  ------------------
  |  |  521|    343|	{"swelldir",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.swelldir,
  |  |  522|    343|                                       .dflt.uinteger = DAC1FID11_WAVEDIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1964|    343|#define DAC1FID11_WAVEDIR_NOT_AVAILABLE    511
  |  |  ------------------
  |  |  523|    343|	{"seastate",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.seastate,
  |  |  524|    343|                                       .dflt.uinteger = DAC1FID11_SEASTATE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1969|    343|#define DAC1FID11_SEASTATE_NOT_AVAILABLE   15
  |  |  ------------------
  |  |  525|    343|	{"watertemp",     t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.watertemp,
  |  |  526|    343|                                       .dflt.uinteger = DAC1FID11_WATERTEMP_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1971|    343|#define DAC1FID11_WATERTEMP_NOT_AVAILABLE  1023
  |  |  ------------------
  |  |  527|    343|	{"preciptype",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.preciptype,
  |  |  528|    343|                                       .dflt.uinteger = DAC1FID11_PRECIPTYPE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1975|    343|#define DAC1FID11_PRECIPTYPE_NOT_AVAILABLE  7
  |  |  ------------------
  |  |  529|    343|	{"preciptype_text",   t_ignore},
  |  |  530|    343|	{"salinity",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.salinity,
  |  |  531|    343|                                       .dflt.uinteger = DAC1FID11_SALINITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1977|    343|#define DAC1FID11_SALINITY_NOT_AVAILABLE   511
  |  |  ------------------
  |  |  532|    343|	{"ice",           t_uinteger,  .addr.uinteger = &ais->type8.dac1fid11.ice,
  |  |  533|    343|                                       .dflt.uinteger = DAC1FID11_ICE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1980|    343|#define DAC1FID11_ICE_NOT_AVAILABLE        3
  |  |  ------------------
  |  |  534|    343|	{"ice_text",   t_ignore},
  |  |  535|    343|        {NULL}
  |  |  536|    343|    };
  |  |  537|       |
  |  |  538|    343|    char closefrom[JSON_VAL_MAX+1];
  |  |  539|    343|    char closeto[JSON_VAL_MAX+1];
  |  |  540|    343|    const struct json_attr_t json_ais8_fid13[] = {
  |  |  541|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  542|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  543|    343|	{"reason",        t_string,    .addr.string = ais->type8.dac1fid13.reason,
  |  |  544|    343|                                       .len = sizeof(ais->type8.dac1fid13.reason)},
  |  |  545|    343|	{"closefrom",     t_string,    .addr.string = closefrom,
  |  |  546|    343|                                       .len = sizeof(closefrom)},
  |  |  547|    343|	{"closeto",       t_string,    .addr.string = closeto,
  |  |  548|    343|                                       .len = sizeof(closeto)},
  |  |  549|    343|	{"radius",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.radius,
  |  |  550|    343|                                       .dflt.uinteger = AIS_DAC1FID13_RADIUS_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1988|    343|#define AIS_DAC1FID13_RADIUS_NOT_AVAILABLE 10001
  |  |  ------------------
  |  |  551|    343|	{"extunit",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.extunit,
  |  |  552|    343|                                       .dflt.uinteger = AIS_DAC1FID13_EXTUNIT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1990|    343|#define AIS_DAC1FID13_EXTUNIT_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  553|    343|	{"fday",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.fday,
  |  |  554|    343|                                       .dflt.uinteger = AIS_DAY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1512|    343|#define AIS_DAY_NOT_AVAILABLE   0
  |  |  ------------------
  |  |  555|    343|	{"fmonth",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.fmonth,
  |  |  556|    343|                                       .dflt.uinteger = AIS_MONTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1510|    343|#define AIS_MONTH_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  557|    343|	{"fhour",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.fhour,
  |  |  558|    343|                                       .dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1514|    343|#define AIS_HOUR_NOT_AVAILABLE  24
  |  |  ------------------
  |  |  559|    343|	{"fminute",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.fminute,
  |  |  560|    343|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    343|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  561|    343|	{"tday",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.tday,
  |  |  562|    343|                                       .dflt.uinteger = AIS_DAY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1512|    343|#define AIS_DAY_NOT_AVAILABLE   0
  |  |  ------------------
  |  |  563|    343|	{"tmonth",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.tmonth,
  |  |  564|    343|                                       .dflt.uinteger = AIS_MONTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1510|    343|#define AIS_MONTH_NOT_AVAILABLE 0
  |  |  ------------------
  |  |  565|    343|	{"thour",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.thour,
  |  |  566|    343|                                       .dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1514|    343|#define AIS_HOUR_NOT_AVAILABLE  24
  |  |  ------------------
  |  |  567|    343|	{"tminute",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid13.tminute,
  |  |  568|    343|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    343|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  569|    343|        {NULL}
  |  |  570|    343|    };
  |  |  571|       |
  |  |  572|    343|    const struct json_attr_t json_ais8_fid15[] = {
  |  |  573|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  574|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  575|    343|	{"airdraught",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid15.airdraught,
  |  |  576|    343|                                       .dflt.uinteger = 0},
  |  |  577|    343|        {NULL}
  |  |  578|    343|    };
  |  |  579|       |
  |  |  580|    343|    const struct json_attr_t json_ais8_fid16[] = {
  |  |  581|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  582|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  583|    343|	{"persons",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid16.persons,
  |  |  584|    343|                                       .dflt.uinteger = 0},
  |  |  585|    343|        {NULL}
  |  |  586|    343|    };
  |  |  587|       |
  |  |  588|    343|    const struct json_attr_t json_ais8_fid17_targets_subtype[] = {
  |  |  589|    343|	{"idtype",        t_uinteger,STRUCTOBJECT(struct target_t, idtype),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  590|    343|                                       .dflt.uinteger = DAC1FID17_IDTYPE_OTHER},
  |  |  ------------------
  |  |  |  | 2015|    343|#define DAC1FID17_IDTYPE_OTHER          3
  |  |  ------------------
  |  |  591|    343|	{"id.mmsi",       t_uinteger,STRUCTOBJECT(struct target_t, id.mmsi),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  592|    343|                                       .dflt.uinteger = 0},
  |  |  593|    343|	{"id.imo",        t_uinteger,STRUCTOBJECT(struct target_t, id.imo),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  594|    343|                                       .dflt.uinteger = 0},
  |  |  595|    343|	{"id.callsign",   t_string,  STRUCTOBJECT(struct target_t, id.callsign),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  596|    343|                                       .len = DAC1FID17_ID_LENGTH},
  |  |  ------------------
  |  |  |  | 2020|    343|#define DAC1FID17_ID_LENGTH             7
  |  |  ------------------
  |  |  597|    343|	{"id.other",      t_string,  STRUCTOBJECT(struct target_t, id.other),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  598|    343|                                       .len = DAC1FID17_ID_LENGTH},
  |  |  ------------------
  |  |  |  | 2020|    343|#define DAC1FID17_ID_LENGTH             7
  |  |  ------------------
  |  |  599|    343|	{"lat",           t_integer, STRUCTOBJECT(struct target_t, lat),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  600|    343|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1442|    343|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  601|    343|	{"lon",           t_integer, STRUCTOBJECT(struct target_t, lon),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  602|    343|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1441|    343|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  603|    343|	{"course",        t_uinteger,STRUCTOBJECT(struct target_t, course),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  604|    343|                                       .dflt.uinteger = DAC1FID17_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2027|    343|#define DAC1FID17_COURSE_NOT_AVAILABLE  360
  |  |  ------------------
  |  |  605|    343|	{"second",        t_uinteger,STRUCTOBJECT(struct target_t, second),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  606|    343|                                       .dflt.uinteger = AIS_SECOND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1518|    343|#define AIS_SECOND_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  607|    343|	{"speed",         t_uinteger,STRUCTOBJECT(struct target_t, speed),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  608|    343|                                       .dflt.uinteger = DAC1FID17_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2030|    343|#define DAC1FID17_SPEED_NOT_AVAILABLE   255
  |  |  ------------------
  |  |  609|    343|        {NULL}
  |  |  610|    343|    };
  |  |  611|    343|    const struct json_attr_t json_ais8_fid17[] = {
  |  |  612|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  613|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  614|    343|	{"targets",       t_array,     STRUCTARRAY(ais->type8.dac1fid17.targets, json_ais8_fid17_targets_subtype, &ais->type8.dac1fid17.ntargets)},
  |  |  ------------------
  |  |  |  |  190|    343|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    343|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    343|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    343|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    343|        .addr.array.count = n, \
  |  |  |  |  195|    343|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    343| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  615|    343|        {NULL}
  |  |  616|    343|    };
  |  |  617|       |
  |  |  618|    343|    const struct json_attr_t json_ais8_fid19[] = {
  |  |  619|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  620|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  621|    343|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.linkage,
  |  |  622|    343|                                       .dflt.uinteger = 0},
  |  |  623|    343|	{"station",       t_string,    .addr.string = ais->type8.dac1fid19.station,
  |  |  624|    343|                                       .len = sizeof(ais->type8.dac1fid19.station)},
  |  |  625|    343|	{"lon",           t_integer,   .addr.integer = &ais->type8.dac1fid19.lon,
  |  |  626|    343|                                       .dflt.integer = AIS_LON3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1441|    343|#define AIS_LON3_NOT_AVAILABLE  181000
  |  |  ------------------
  |  |  627|    343|	{"lat",           t_integer,   .addr.integer = &ais->type8.dac1fid19.lat,
  |  |  628|    343|                                       .dflt.integer = AIS_LAT3_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1442|    343|#define AIS_LAT3_NOT_AVAILABLE  91000
  |  |  ------------------
  |  |  629|    343|	{"status",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.status,
  |  |  630|    343|                                       .dflt.uinteger = 0},
  |  |  631|    343|	{"signal",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.signal,
  |  |  632|    343|                                       .dflt.uinteger = 0},
  |  |  633|    343|	{"signal_text",   t_ignore},
  |  |  634|    343|	{"hour",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.hour,
  |  |  635|    343|                                       .dflt.uinteger = AIS_HOUR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1514|    343|#define AIS_HOUR_NOT_AVAILABLE  24
  |  |  ------------------
  |  |  636|    343|	{"minute",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.minute,
  |  |  637|    343|                                       .dflt.uinteger = AIS_MINUTE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1516|    343|#define AIS_MINUTE_NOT_AVAILABLE        60
  |  |  ------------------
  |  |  638|    343|	{"nextsignal",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid19.nextsignal,
  |  |  639|    343|                                       .dflt.uinteger = 0},
  |  |  640|    343|	{"nextsignal_type",   t_ignore},
  |  |  641|    343|        {NULL}
  |  |  642|    343|    };
  |  |  643|       |
  |  |  644|    343|    char end[JSON_VAL_MAX+1];
  |  |  645|    343|    const struct json_attr_t json_ais8_fid23[] = {
  |  |  646|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  647|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  648|    343|	{"start",         t_string,    .addr.string = start,
  |  |  649|    343|                                       .len = sizeof(start)},
  |  |  650|    343|	{"end",           t_string,    .addr.string = end,
  |  |  651|    343|                                       .len = sizeof(end)},
  |  |  652|    343|	{"start_lon",     t_integer,   .addr.integer = &ais->type8.dac200fid23.start_lon,
  |  |  653|    343|                                       .dflt.integer = AIS_LON4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1446|    343|#define AIS_LON4_NOT_AVAILABLE  1810000
  |  |  ------------------
  |  |  654|    343|	{"start_lat",     t_integer,   .addr.integer = &ais->type8.dac200fid23.start_lat,
  |  |  655|    343|                                       .dflt.integer = AIS_LAT4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1447|    343|#define AIS_LAT4_NOT_AVAILABLE  910000
  |  |  ------------------
  |  |  656|    343|	{"end_lon",       t_integer,   .addr.integer = &ais->type8.dac200fid23.end_lon,
  |  |  657|    343|                                       .dflt.integer = AIS_LON4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1446|    343|#define AIS_LON4_NOT_AVAILABLE  1810000
  |  |  ------------------
  |  |  658|    343|	{"end_lat",       t_integer,   .addr.integer = &ais->type8.dac200fid23.end_lat,
  |  |  659|    343|                                       .dflt.integer = AIS_LAT4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1447|    343|#define AIS_LAT4_NOT_AVAILABLE  910000
  |  |  ------------------
  |  |  660|    343|	{"type",          t_uinteger,  .addr.uinteger = &ais->type8.dac200fid23.type,
  |  |  661|    343|                                       .dflt.uinteger = DAC200FID23_TYPE_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1871|    343|#define DAC200FID23_TYPE_UNKNOWN        0
  |  |  ------------------
  |  |  662|    343|	{"type_text",   t_ignore},
  |  |  663|    343|	{"min",           t_integer,   .addr.integer = &ais->type8.dac200fid23.min,
  |  |  664|    343|                                       .dflt.integer = DAC200FID23_MIN_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1873|    343|#define DAC200FID23_MIN_UNKNOWN         255
  |  |  ------------------
  |  |  665|    343|	{"max",           t_integer,   .addr.integer = &ais->type8.dac200fid23.max,
  |  |  666|    343|                                       .dflt.integer = DAC200FID23_MAX_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1875|    343|#define DAC200FID23_MAX_UNKNOWN         255
  |  |  ------------------
  |  |  667|    343|	{"intensity",     t_uinteger,  .addr.uinteger = &ais->type8.dac200fid23.intensity,
  |  |  668|    343|                                       .dflt.uinteger = DAC200FID23_CLASS_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1877|    343|#define DAC200FID23_CLASS_UNKNOWN       0
  |  |  ------------------
  |  |  669|    343|	{"intensity_text",   t_ignore},
  |  |  670|    343|	{"wind",          t_uinteger,  .addr.uinteger = &ais->type8.dac200fid23.wind,
  |  |  671|    343|                                       .dflt.uinteger = DAC200FID23_WIND_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1879|    343|#define DAC200FID23_WIND_UNKNOWN        0
  |  |  ------------------
  |  |  672|    343|	{"wind_text",   t_ignore},
  |  |  673|    343|        {NULL}
  |  |  674|    343|    };
  |  |  675|       |
  |  |  676|    343|    const struct json_attr_t json_ais8_fid24_gauges_subtype[] = {
  |  |  677|    343|	{"id",            t_uinteger,STRUCTOBJECT(struct gauge_t, id),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  678|    343|                                       .dflt.uinteger = DAC200FID24_GAUGE_ID_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1886|    343|#define DAC200FID24_GAUGE_ID_UNKNOWN    0
  |  |  ------------------
  |  |  679|    343|	{"level",         t_integer, STRUCTOBJECT(struct gauge_t, level),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  680|    343|                                       .dflt.integer = DAC200FID24_GAUGE_LEVEL_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1888|    343|#define DAC200FID24_GAUGE_LEVEL_UNKNOWN 0
  |  |  ------------------
  |  |  681|    343|        {NULL}
  |  |  682|    343|    };
  |  |  683|    343|    const struct json_attr_t json_ais8_fid24[] = {
  |  |  684|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  685|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  686|    343|	{"country",       t_string,    .addr.string = ais->type8.dac200fid24.country,
  |  |  687|    343|                                       .len = sizeof(ais->type8.dac200fid24.country)},
  |  |  688|    343|	{"gauges",        t_array,     STRUCTARRAY(ais->type8.dac200fid24.gauges, json_ais8_fid24_gauges_subtype, &ais->type8.dac200fid24.ngauges)},
  |  |  ------------------
  |  |  |  |  190|    343|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    343|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    343|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    343|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    343|        .addr.array.count = n, \
  |  |  |  |  195|    343|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    343| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  689|    343|        {NULL}
  |  |  690|    343|    };
  |  |  691|       |
  |  |  692|    343|    const struct json_attr_t json_ais8_fid27_waypoints_subtype[] = {
  |  |  693|    343|	{"lon",           t_integer, STRUCTOBJECT(struct waypoint_t, lon),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  694|    343|                                       .dflt.integer = AIS_LON4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1446|    343|#define AIS_LON4_NOT_AVAILABLE  1810000
  |  |  ------------------
  |  |  695|    343|	{"lat",           t_integer, STRUCTOBJECT(struct waypoint_t, lat),
  |  |  ------------------
  |  |  |  |  188|    343|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  |  |  696|    343|                                       .dflt.integer = AIS_LAT4_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1447|    343|#define AIS_LAT4_NOT_AVAILABLE  910000
  |  |  ------------------
  |  |  697|    343|        {NULL}
  |  |  698|    343|    };
  |  |  699|    343|    const struct json_attr_t json_ais8_fid27[] = {
  |  |  700|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  701|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  702|    343|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid27.linkage,
  |  |  703|    343|                                       .dflt.uinteger = 0},
  |  |  704|    343|	{"sender",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid27.sender,
  |  |  705|    343|                                       .dflt.uinteger = 0},
  |  |  706|    343|	{"rtype",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid27.rtype,
  |  |  707|    343|                                       .dflt.uinteger = 0},
  |  |  708|    343|	{"rtype_text",   t_ignore},
  |  |  709|    343|	{"start",         t_string,    .addr.string = start,
  |  |  710|    343|                                       .len = sizeof(start)},
  |  |  711|    343|	{"duration",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid27.duration,
  |  |  712|    343|                                       .dflt.uinteger = 0},
  |  |  713|    343|	{"waypoints",     t_array,     STRUCTARRAY(ais->type8.dac1fid27.waypoints, json_ais8_fid27_waypoints_subtype, &ais->type8.dac1fid27.waycount)},
  |  |  ------------------
  |  |  |  |  190|    343|        .addr.array.element_type = t_structobject, \
  |  |  |  |  191|    343|        .addr.array.arr.objects.subtype = e, \
  |  |  |  |  192|    343|        .addr.array.arr.objects.base = (char*)a, \
  |  |  |  |  193|    343|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  |  |  194|    343|        .addr.array.count = n, \
  |  |  |  |  195|    343|        .addr.array.maxlen = NITEMS(a)
  |  |  |  |  ------------------
  |  |  |  |  |  |    4|    343| #define NITEMS(x) (int)(sizeof(x)/sizeof(x[0]))
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  714|    343|        {NULL}
  |  |  715|    343|    };
  |  |  716|       |
  |  |  717|    343|    const struct json_attr_t json_ais8_fid29[] = {
  |  |  718|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  719|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  720|    343|	{"linkage",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid29.linkage,
  |  |  721|    343|                                       .dflt.uinteger = 0},
  |  |  722|    343|	{"text",          t_string,    .addr.string = ais->type8.dac1fid29.text,
  |  |  723|    343|                                       .len = sizeof(ais->type8.dac1fid29.text)},
  |  |  724|    343|        {NULL}
  |  |  725|    343|    };
  |  |  726|       |
  |  |  727|    343|    const struct json_attr_t json_ais8_fid31[] = {
  |  |  728|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  729|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  730|    343|	{"lon",           t_integer,   .addr.integer = &ais->type8.dac1fid31.lon,
  |  |  731|    343|                                       .dflt.integer = DAC1FID31_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2059|    343|#define DAC1FID31_LON_NOT_AVAILABLE     (181*60*DAC1FID31_LATLON_SCALE)
  |  |  |  |  ------------------
  |  |  |  |  |  | 2057|    343|#define DAC1FID31_LATLON_SCALE  1000
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  732|    343|	{"lat",           t_integer,   .addr.integer = &ais->type8.dac1fid31.lat,
  |  |  733|    343|                                       .dflt.integer = DAC1FID31_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2061|    343|#define DAC1FID31_LAT_NOT_AVAILABLE     (91*60*DAC1FID31_LATLON_SCALE)
  |  |  |  |  ------------------
  |  |  |  |  |  | 2057|    343|#define DAC1FID31_LATLON_SCALE  1000
  |  |  |  |  ------------------
  |  |  ------------------
  |  |  734|    343|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type8.dac1fid31.accuracy,
  |  |  735|    343|                                       .dflt.boolean = false},
  |  |  736|    343|	{"timestamp",     t_string,    .addr.string = timestamp,
  |  |  737|    343|                                       .len = sizeof(timestamp)},
  |  |  738|    343|	{"wspeed",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wspeed,
  |  |  739|    343|                                       .dflt.uinteger = DAC1FID31_WIND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2068|    343|#define DAC1FID31_WIND_NOT_AVAILABLE     127
  |  |  ------------------
  |  |  740|    343|	{"wgust",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wgust,
  |  |  741|    343|                                       .dflt.uinteger = DAC1FID31_WIND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2068|    343|#define DAC1FID31_WIND_NOT_AVAILABLE     127
  |  |  ------------------
  |  |  742|    343|	{"wdir",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wdir,
  |  |  743|    343|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2071|    343|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  744|    343|	{"wgustdir",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wgustdir,
  |  |  745|    343|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2071|    343|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  746|    343|	{"airtemp",       t_integer,   .addr.integer = &ais->type8.dac1fid31.airtemp,
  |  |  747|    343|                                       .dflt.integer = DAC1FID31_AIRTEMP_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2073|    343|#define DAC1FID31_AIRTEMP_NOT_AVAILABLE  -1024
  |  |  ------------------
  |  |  748|    343|	{"humidity",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.humidity,
  |  |  749|    343|                                       .dflt.uinteger = DAC1FID31_HUMIDITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2076|    343|#define DAC1FID31_HUMIDITY_NOT_AVAILABLE 101
  |  |  ------------------
  |  |  750|    343|	{"dewpoint",      t_integer,   .addr.integer = &ais->type8.dac1fid31.dewpoint,
  |  |  751|    343|                                       .dflt.integer = DAC1FID31_DEWPOINT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2078|    343|#define DAC1FID31_DEWPOINT_NOT_AVAILABLE 501
  |  |  ------------------
  |  |  752|    343|	{"pressure",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.pressure,
  |  |  753|    343|                                       .dflt.uinteger = DAC1FID31_PRESSURE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2081|    343|#define DAC1FID31_PRESSURE_NOT_AVAILABLE 511
  |  |  ------------------
  |  |  754|    343|	{"pressuretend",  t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.pressuretend,
  |  |  755|    343|                                       .dflt.uinteger = DAC1FID31_PRESSURETEND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2085|    343|#define DAC1FID31_PRESSURETEND_NOT_AVAILABLE  3
  |  |  ------------------
  |  |  756|    343|	{"visgreater",    t_boolean,   .addr.boolean = &ais->type8.dac1fid31.visgreater,
  |  |  757|    343|                                       .dflt.boolean = false},
  |  |  758|    343|	{"visibility",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.visibility,
  |  |  759|    343|                                       .dflt.uinteger = DAC1FID31_VISIBILITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2088|    343|#define DAC1FID31_VISIBILITY_NOT_AVAILABLE  127
  |  |  ------------------
  |  |  760|    343|	{"waterlevel",    t_integer,   .addr.integer = &ais->type8.dac1fid31.waterlevel,
  |  |  761|    343|                                       .dflt.integer = DAC1FID31_WATERLEVEL_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2091|    343|#define DAC1FID31_WATERLEVEL_NOT_AVAILABLE 4001
  |  |  ------------------
  |  |  762|    343|	{"leveltrend",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.leveltrend,
  |  |  763|    343|                                       .dflt.uinteger = DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2095|    343|#define DAC1FID31_WATERLEVELTREND_NOT_AVAILABLE 3
  |  |  ------------------
  |  |  764|    343|	{"cspeed",        t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cspeed,
  |  |  765|    343|                                       .dflt.uinteger = DAC1FID31_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2097|    343|#define DAC1FID31_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  766|    343|	{"cdir",          t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdir,
  |  |  767|    343|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2071|    343|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  768|    343|	{"cspeed2",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cspeed2,
  |  |  769|    343|                                       .dflt.uinteger = DAC1FID31_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2097|    343|#define DAC1FID31_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  770|    343|	{"cdir2",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdir2,
  |  |  771|    343|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2071|    343|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  772|    343|	{"cdepth2",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdepth2,
  |  |  773|    343|                                       .dflt.uinteger = DAC1FID31_CDEPTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2103|    343|#define DAC1FID31_CDEPTH_NOT_AVAILABLE     301
  |  |  ------------------
  |  |  774|    343|	{"cspeed3",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cspeed3,
  |  |  775|    343|                                       .dflt.uinteger = DAC1FID31_CSPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2097|    343|#define DAC1FID31_CSPEED_NOT_AVAILABLE     255
  |  |  ------------------
  |  |  776|    343|	{"cdir3",         t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdir3,
  |  |  777|    343|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2071|    343|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  778|    343|	{"cdepth3",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.cdepth3,
  |  |  779|    343|                                       .dflt.uinteger = DAC1FID31_CDEPTH_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2103|    343|#define DAC1FID31_CDEPTH_NOT_AVAILABLE     301
  |  |  ------------------
  |  |  780|    343|	{"waveheight",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.waveheight,
  |  |  781|    343|                                       .dflt.uinteger = DAC1FID31_HEIGHT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2109|    343|#define DAC1FID31_HEIGHT_NOT_AVAILABLE     31
  |  |  ------------------
  |  |  782|    343|	{"waveperiod",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.waveperiod,
  |  |  783|    343|                                       .dflt.uinteger = DAC1FID31_PERIOD_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2112|    343|#define DAC1FID31_PERIOD_NOT_AVAILABLE     63
  |  |  ------------------
  |  |  784|    343|	{"wavedir",       t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.wavedir,
  |  |  785|    343|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2071|    343|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  786|    343|	{"swellheight",   t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.swellheight,
  |  |  787|    343|                                       .dflt.uinteger = DAC1FID31_HEIGHT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2109|    343|#define DAC1FID31_HEIGHT_NOT_AVAILABLE     31
  |  |  ------------------
  |  |  788|    343|	{"swellperiod",   t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.swellperiod,
  |  |  789|    343|                                       .dflt.uinteger = DAC1FID31_PERIOD_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2112|    343|#define DAC1FID31_PERIOD_NOT_AVAILABLE     63
  |  |  ------------------
  |  |  790|    343|	{"swelldir",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.swelldir,
  |  |  791|    343|                                       .dflt.uinteger = DAC1FID31_DIR_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2071|    343|#define DAC1FID31_DIR_NOT_AVAILABLE      360
  |  |  ------------------
  |  |  792|    343|	{"seastate",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.seastate,
  |  |  793|    343|                                       .dflt.uinteger = DAC1FID31_SEASTATE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2118|    343|#define DAC1FID31_SEASTATE_NOT_AVAILABLE   15
  |  |  ------------------
  |  |  794|    343|	{"watertemp",     t_integer,   .addr.integer = &ais->type8.dac1fid31.watertemp,
  |  |  795|    343|                                       .dflt.integer = DAC1FID31_WATERTEMP_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2120|    343|#define DAC1FID31_WATERTEMP_NOT_AVAILABLE  601
  |  |  ------------------
  |  |  796|    343|	{"preciptype",    t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.preciptype,
  |  |  797|    343|                                       .dflt.uinteger = DAC1FID31_PRECIPTYPE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2123|    343|#define DAC1FID31_PRECIPTYPE_NOT_AVAILABLE 7
  |  |  ------------------
  |  |  798|    343|	{"preciptype_text",   t_ignore},
  |  |  799|    343|	{"salinity",      t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.salinity,
  |  |  800|    343|                                       .dflt.uinteger = DAC1FID31_SALINITY_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2125|    343|#define DAC1FID31_SALINITY_NOT_AVAILABLE   510
  |  |  ------------------
  |  |  801|    343|	{"ice",           t_uinteger,  .addr.uinteger = &ais->type8.dac1fid31.ice,
  |  |  802|    343|                                       .dflt.uinteger = DAC1FID31_ICE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2128|    343|#define DAC1FID31_ICE_NOT_AVAILABLE       3
  |  |  ------------------
  |  |  803|    343|        {NULL}
  |  |  804|    343|    };
  |  |  805|       |
  |  |  806|    343|    const struct json_attr_t json_ais8_fid40[] = {
  |  |  807|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  808|    343|	AIS_TYPE8
  |  |  ------------------
  |  |  |  |   69|    343|        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
  |  |  |  |   70|    343|                                       .dflt.uinteger = 0},\
  |  |  |  |   71|    343|        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
  |  |  |  |   72|    343|                                       .dflt.uinteger = 0},
  |  |  ------------------
  |  |  809|    343|	{"form",          t_uinteger,  .addr.uinteger = &ais->type8.dac200fid40.form,
  |  |  810|    343|                                       .dflt.uinteger = DAC200FID40_FORM_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1895|    343|#define DAC200FID40_FORM_UNKNOWN        0
  |  |  ------------------
  |  |  811|    343|	{"facing",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid40.facing,
  |  |  812|    343|                                       .dflt.uinteger = DAC200FID40_FACING_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1897|    343|#define DAC200FID40_FACING_UNKNOWN      0
  |  |  ------------------
  |  |  813|    343|	{"direction",     t_uinteger,  .addr.uinteger = &ais->type8.dac200fid40.direction,
  |  |  814|    343|                                       .dflt.uinteger = DAC200FID40_DIRECTION_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1899|    343|#define DAC200FID40_DIRECTION_UNKNOWN   0
  |  |  ------------------
  |  |  815|    343|	{"direction_text",   t_ignore},
  |  |  816|    343|	{"status",        t_uinteger,  .addr.uinteger = &ais->type8.dac200fid40.status,
  |  |  817|    343|                                       .dflt.uinteger = DAC200FID40_STATUS_UNKNOWN},
  |  |  ------------------
  |  |  |  | 1901|    343|#define DAC200FID40_STATUS_UNKNOWN      0
  |  |  ------------------
  |  |  818|    343|	{"status_text",   t_ignore},
  |  |  819|    343|        {NULL}
  |  |  820|    343|    };
  |  |  821|       |
  |  |  822|    343|    const struct json_attr_t json_ais9[] = {
  |  |  823|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  824|    343|	{"alt",           t_uinteger,  .addr.uinteger = &ais->type9.alt,
  |  |  825|    343|                                       .dflt.uinteger = AIS_ALT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2135|    343|#define AIS_ALT_NOT_AVAILABLE   4095
  |  |  ------------------
  |  |  826|    343|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type9.speed,
  |  |  827|    343|                                       .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1480|    343|#define AIS_SPEED_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |  828|    343|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type9.accuracy,
  |  |  829|    343|                                       .dflt.boolean = false},
  |  |  830|    343|	{"lon",           t_integer,   .addr.integer = &ais->type9.lon,
  |  |  831|    343|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1485|    343|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |  832|    343|	{"lat",           t_integer,   .addr.integer = &ais->type9.lat,
  |  |  833|    343|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1487|    343|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |  834|    343|	{"course",        t_uinteger,  .addr.uinteger = &ais->type9.course,
  |  |  835|    343|                                       .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1489|    343|#define AIS_COURSE_NOT_AVAILABLE        3600
  |  |  ------------------
  |  |  836|    343|	{"second",        t_uinteger,  .addr.uinteger = &ais->type9.second,
  |  |  837|    343|                                       .dflt.uinteger = AIS_SEC_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1496|    343|#define AIS_SEC_NOT_AVAILABLE   60
  |  |  ------------------
  |  |  838|    343|	{"regional",      t_uinteger,  .addr.uinteger = &ais->type9.regional,
  |  |  839|    343|                                       .dflt.uinteger = 0},
  |  |  840|    343|	{"dte",           t_uinteger,  .addr.uinteger = &ais->type9.dte,
  |  |  841|    343|                                       .dflt.uinteger = 1},
  |  |  842|    343|	{"raim",          t_boolean,   .addr.boolean = &ais->type9.raim,
  |  |  843|    343|                                       .dflt.boolean = false},
  |  |  844|    343|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type9.radio,
  |  |  845|    343|                                       .dflt.uinteger = 0},
  |  |  846|    343|        {NULL}
  |  |  847|    343|    };
  |  |  848|       |
  |  |  849|    343|    const struct json_attr_t json_ais10[] = {
  |  |  850|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  851|    343|	{"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type10.dest_mmsi,
  |  |  852|    343|                                       .dflt.uinteger = 0},
  |  |  853|    343|        {NULL}
  |  |  854|    343|    };
  |  |  855|       |
  |  |  856|    343|    const struct json_attr_t json_ais12[] = {
  |  |  857|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  858|    343|	{"seqno",         t_uinteger,  .addr.uinteger = &ais->type12.seqno,
  |  |  859|    343|                                       .dflt.uinteger = 0},
  |  |  860|    343|	{"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type12.dest_mmsi,
  |  |  861|    343|                                       .dflt.uinteger = 0},
  |  |  862|    343|	{"retransmit",    t_boolean,   .addr.boolean = &ais->type12.retransmit,
  |  |  863|    343|                                       .dflt.boolean = 0},
  |  |  864|    343|	{"text",          t_string,    .addr.string = ais->type12.text,
  |  |  865|    343|                                       .len = sizeof(ais->type12.text)},
  |  |  866|    343|        {NULL}
  |  |  867|    343|    };
  |  |  868|       |
  |  |  869|    343|    const struct json_attr_t json_ais14[] = {
  |  |  870|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  871|    343|	{"text",          t_string,    .addr.string = ais->type14.text,
  |  |  872|    343|                                       .len = sizeof(ais->type14.text)},
  |  |  873|    343|        {NULL}
  |  |  874|    343|    };
  |  |  875|       |
  |  |  876|    343|    const struct json_attr_t json_ais15[] = {
  |  |  877|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  878|    343|	{"mmsi1",         t_uinteger,  .addr.uinteger = &ais->type15.mmsi1,
  |  |  879|    343|                                       .dflt.uinteger = 0},
  |  |  880|    343|	{"type1_1",       t_uinteger,  .addr.uinteger = &ais->type15.type1_1,
  |  |  881|    343|                                       .dflt.uinteger = 0},
  |  |  882|    343|	{"offset1_1",     t_uinteger,  .addr.uinteger = &ais->type15.offset1_1,
  |  |  883|    343|                                       .dflt.uinteger = 0},
  |  |  884|    343|	{"type1_2",       t_uinteger,  .addr.uinteger = &ais->type15.type1_2,
  |  |  885|    343|                                       .dflt.uinteger = 0},
  |  |  886|    343|	{"offset1_2",     t_uinteger,  .addr.uinteger = &ais->type15.offset1_2,
  |  |  887|    343|                                       .dflt.uinteger = 0},
  |  |  888|    343|	{"mmsi2",         t_uinteger,  .addr.uinteger = &ais->type15.mmsi2,
  |  |  889|    343|                                       .dflt.uinteger = 0},
  |  |  890|    343|	{"type2_1",       t_uinteger,  .addr.uinteger = &ais->type15.type2_1,
  |  |  891|    343|                                       .dflt.uinteger = 0},
  |  |  892|    343|	{"offset2_1",     t_uinteger,  .addr.uinteger = &ais->type15.offset2_1,
  |  |  893|    343|                                       .dflt.uinteger = 0},
  |  |  894|    343|        {NULL}
  |  |  895|    343|    };
  |  |  896|       |
  |  |  897|    343|    const struct json_attr_t json_ais16[] = {
  |  |  898|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  899|    343|	{"mmsi1",         t_uinteger,  .addr.uinteger = &ais->type16.mmsi1,
  |  |  900|    343|                                       .dflt.uinteger = 0},
  |  |  901|    343|	{"offset1",       t_uinteger,  .addr.uinteger = &ais->type16.offset1,
  |  |  902|    343|                                       .dflt.uinteger = 0},
  |  |  903|    343|	{"increment1",    t_uinteger,  .addr.uinteger = &ais->type16.increment1,
  |  |  904|    343|                                       .dflt.uinteger = 0},
  |  |  905|    343|	{"mmsi2",         t_uinteger,  .addr.uinteger = &ais->type16.mmsi2,
  |  |  906|    343|                                       .dflt.uinteger = 0},
  |  |  907|    343|	{"offset2",       t_uinteger,  .addr.uinteger = &ais->type16.offset2,
  |  |  908|    343|                                       .dflt.uinteger = 0},
  |  |  909|    343|	{"increment2",    t_uinteger,  .addr.uinteger = &ais->type16.increment2,
  |  |  910|    343|                                       .dflt.uinteger = 0},
  |  |  911|    343|        {NULL}
  |  |  912|    343|    };
  |  |  913|       |
  |  |  914|    343|    const struct json_attr_t json_ais17[] = {
  |  |  915|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  916|    343|	{"lon",           t_integer,   .addr.integer = &ais->type17.lon,
  |  |  917|    343|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2218|    343|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  |  918|    343|	{"lat",           t_integer,   .addr.integer = &ais->type17.lat,
  |  |  919|    343|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2220|    343|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  |  920|    343|	{"data",          t_string,    .addr.string = data,
  |  |  921|    343|                                       .len = sizeof(data)},
  |  |  922|    343|        {NULL}
  |  |  923|    343|    };
  |  |  924|       |
  |  |  925|    343|    const struct json_attr_t json_ais18[] = {
  |  |  926|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  927|    343|	{"reserved",      t_uinteger,  .addr.uinteger = &ais->type18.reserved,
  |  |  928|    343|                                       .dflt.uinteger = 0},
  |  |  929|    343|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type18.speed,
  |  |  930|    343|                                       .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1480|    343|#define AIS_SPEED_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |  931|    343|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type18.accuracy,
  |  |  932|    343|                                       .dflt.boolean = false},
  |  |  933|    343|	{"lon",           t_integer,   .addr.integer = &ais->type18.lon,
  |  |  934|    343|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1485|    343|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |  935|    343|	{"lat",           t_integer,   .addr.integer = &ais->type18.lat,
  |  |  936|    343|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1487|    343|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |  937|    343|	{"course",        t_uinteger,  .addr.uinteger = &ais->type18.course,
  |  |  938|    343|                                       .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1489|    343|#define AIS_COURSE_NOT_AVAILABLE        3600
  |  |  ------------------
  |  |  939|    343|	{"heading",       t_uinteger,  .addr.uinteger = &ais->type18.heading,
  |  |  940|    343|                                       .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1491|    343|#define AIS_HEADING_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  941|    343|	{"second",        t_uinteger,  .addr.uinteger = &ais->type18.second,
  |  |  942|    343|                                       .dflt.uinteger = AIS_SEC_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1496|    343|#define AIS_SEC_NOT_AVAILABLE   60
  |  |  ------------------
  |  |  943|    343|	{"regional",      t_uinteger,  .addr.uinteger = &ais->type18.regional,
  |  |  944|    343|                                       .dflt.uinteger = 0},
  |  |  945|    343|	{"cs",            t_boolean,   .addr.boolean = &ais->type18.cs,
  |  |  946|    343|                                       .dflt.boolean = false},
  |  |  947|    343|	{"display",       t_boolean,   .addr.boolean = &ais->type18.display,
  |  |  948|    343|                                       .dflt.boolean = false},
  |  |  949|    343|	{"dsc",           t_boolean,   .addr.boolean = &ais->type18.dsc,
  |  |  950|    343|                                       .dflt.boolean = false},
  |  |  951|    343|	{"band",          t_boolean,   .addr.boolean = &ais->type18.band,
  |  |  952|    343|                                       .dflt.boolean = false},
  |  |  953|    343|	{"msg22",         t_boolean,   .addr.boolean = &ais->type18.msg22,
  |  |  954|    343|                                       .dflt.boolean = false},
  |  |  955|    343|	{"raim",          t_boolean,   .addr.boolean = &ais->type18.raim,
  |  |  956|    343|                                       .dflt.boolean = false},
  |  |  957|    343|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type18.radio,
  |  |  958|    343|                                       .dflt.uinteger = 0},
  |  |  959|    343|        {NULL}
  |  |  960|    343|    };
  |  |  961|       |
  |  |  962|    343|    const struct json_attr_t json_ais19[] = {
  |  |  963|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  |  964|    343|	{"reserved",      t_uinteger,  .addr.uinteger = &ais->type19.reserved,
  |  |  965|    343|                                       .dflt.uinteger = 0},
  |  |  966|    343|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type19.speed,
  |  |  967|    343|                                       .dflt.uinteger = AIS_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1480|    343|#define AIS_SPEED_NOT_AVAILABLE 1023
  |  |  ------------------
  |  |  968|    343|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type19.accuracy,
  |  |  969|    343|                                       .dflt.boolean = false},
  |  |  970|    343|	{"lon",           t_integer,   .addr.integer = &ais->type19.lon,
  |  |  971|    343|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1485|    343|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  |  972|    343|	{"lat",           t_integer,   .addr.integer = &ais->type19.lat,
  |  |  973|    343|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1487|    343|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  |  974|    343|	{"course",        t_uinteger,  .addr.uinteger = &ais->type19.course,
  |  |  975|    343|                                       .dflt.uinteger = AIS_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1489|    343|#define AIS_COURSE_NOT_AVAILABLE        3600
  |  |  ------------------
  |  |  976|    343|	{"heading",       t_uinteger,  .addr.uinteger = &ais->type19.heading,
  |  |  977|    343|                                       .dflt.uinteger = AIS_HEADING_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1491|    343|#define AIS_HEADING_NOT_AVAILABLE       511
  |  |  ------------------
  |  |  978|    343|	{"second",        t_uinteger,  .addr.uinteger = &ais->type19.second,
  |  |  979|    343|                                       .dflt.uinteger = AIS_SEC_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1496|    343|#define AIS_SEC_NOT_AVAILABLE   60
  |  |  ------------------
  |  |  980|    343|	{"regional",      t_uinteger,  .addr.uinteger = &ais->type19.regional,
  |  |  981|    343|                                       .dflt.uinteger = 0},
  |  |  982|    343|	{"shipname",      t_string,    .addr.string = ais->type19.shipname,
  |  |  983|    343|                                       .len = sizeof(ais->type19.shipname)},
  |  |  984|    343|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type19.shiptype,
  |  |  985|    343|                                       .dflt.uinteger = 0},
  |  |  986|    343|	{"shiptype_text",   t_ignore},
  |  |  987|    343|	{"to_bow",        t_uinteger,  .addr.uinteger = &ais->type19.to_bow,
  |  |  988|    343|                                       .dflt.uinteger = 0},
  |  |  989|    343|	{"to_stern",      t_uinteger,  .addr.uinteger = &ais->type19.to_stern,
  |  |  990|    343|                                       .dflt.uinteger = 0},
  |  |  991|    343|	{"to_port",       t_uinteger,  .addr.uinteger = &ais->type19.to_port,
  |  |  992|    343|                                       .dflt.uinteger = 0},
  |  |  993|    343|	{"to_starboard",  t_uinteger,  .addr.uinteger = &ais->type19.to_starboard,
  |  |  994|    343|                                       .dflt.uinteger = 0},
  |  |  995|    343|	{"epfd",          t_uinteger,  .addr.uinteger = &ais->type19.epfd,
  |  |  996|    343|                                       .dflt.uinteger = 0},
  |  |  997|    343|	{"epfd_text",   t_ignore},
  |  |  998|    343|	{"raim",          t_boolean,   .addr.boolean = &ais->type19.raim,
  |  |  999|    343|                                       .dflt.boolean = false},
  |  | 1000|    343|	{"dte",           t_uinteger,  .addr.uinteger = &ais->type19.dte,
  |  | 1001|    343|                                       .dflt.uinteger = 1},
  |  | 1002|    343|	{"assigned",      t_boolean,   .addr.boolean = &ais->type19.assigned,
  |  | 1003|    343|                                       .dflt.boolean = false},
  |  | 1004|    343|        {NULL}
  |  | 1005|    343|    };
  |  | 1006|       |
  |  | 1007|    343|    const struct json_attr_t json_ais20[] = {
  |  | 1008|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1009|    343|	{"offset1",       t_uinteger,  .addr.uinteger = &ais->type20.offset1,
  |  | 1010|    343|                                       .dflt.uinteger = 0},
  |  | 1011|    343|	{"number1",       t_uinteger,  .addr.uinteger = &ais->type20.number1,
  |  | 1012|    343|                                       .dflt.uinteger = 0},
  |  | 1013|    343|	{"timeout1",      t_uinteger,  .addr.uinteger = &ais->type20.timeout1,
  |  | 1014|    343|                                       .dflt.uinteger = 0},
  |  | 1015|    343|	{"increment1",    t_uinteger,  .addr.uinteger = &ais->type20.increment1,
  |  | 1016|    343|                                       .dflt.uinteger = 0},
  |  | 1017|    343|	{"offset2",       t_uinteger,  .addr.uinteger = &ais->type20.offset2,
  |  | 1018|    343|                                       .dflt.uinteger = 0},
  |  | 1019|    343|	{"number2",       t_uinteger,  .addr.uinteger = &ais->type20.number2,
  |  | 1020|    343|                                       .dflt.uinteger = 0},
  |  | 1021|    343|	{"timeout2",      t_uinteger,  .addr.uinteger = &ais->type20.timeout2,
  |  | 1022|    343|                                       .dflt.uinteger = 0},
  |  | 1023|    343|	{"increment2",    t_uinteger,  .addr.uinteger = &ais->type20.increment2,
  |  | 1024|    343|                                       .dflt.uinteger = 0},
  |  | 1025|    343|	{"offset3",       t_uinteger,  .addr.uinteger = &ais->type20.offset3,
  |  | 1026|    343|                                       .dflt.uinteger = 0},
  |  | 1027|    343|	{"number3",       t_uinteger,  .addr.uinteger = &ais->type20.number3,
  |  | 1028|    343|                                       .dflt.uinteger = 0},
  |  | 1029|    343|	{"timeout3",      t_uinteger,  .addr.uinteger = &ais->type20.timeout3,
  |  | 1030|    343|                                       .dflt.uinteger = 0},
  |  | 1031|    343|	{"increment3",    t_uinteger,  .addr.uinteger = &ais->type20.increment3,
  |  | 1032|    343|                                       .dflt.uinteger = 0},
  |  | 1033|    343|	{"offset4",       t_uinteger,  .addr.uinteger = &ais->type20.offset4,
  |  | 1034|    343|                                       .dflt.uinteger = 0},
  |  | 1035|    343|	{"number4",       t_uinteger,  .addr.uinteger = &ais->type20.number4,
  |  | 1036|    343|                                       .dflt.uinteger = 0},
  |  | 1037|    343|	{"timeout4",      t_uinteger,  .addr.uinteger = &ais->type20.timeout4,
  |  | 1038|    343|                                       .dflt.uinteger = 0},
  |  | 1039|    343|	{"increment4",    t_uinteger,  .addr.uinteger = &ais->type20.increment4,
  |  | 1040|    343|                                       .dflt.uinteger = 0},
  |  | 1041|    343|        {NULL}
  |  | 1042|    343|    };
  |  | 1043|       |
  |  | 1044|    343|    const struct json_attr_t json_ais21[] = {
  |  | 1045|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1046|    343|	{"aid_type",      t_uinteger,  .addr.uinteger = &ais->type21.aid_type,
  |  | 1047|    343|                                       .dflt.uinteger = 0},
  |  | 1048|    343|	{"aid_type_text",   t_ignore},
  |  | 1049|    343|	{"name",          t_string,    .addr.string = ais->type21.name,
  |  | 1050|    343|                                       .len = sizeof(ais->type21.name)},
  |  | 1051|    343|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type21.accuracy,
  |  | 1052|    343|                                       .dflt.boolean = false},
  |  | 1053|    343|	{"lon",           t_integer,   .addr.integer = &ais->type21.lon,
  |  | 1054|    343|                                       .dflt.integer = AIS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1485|    343|#define AIS_LON_NOT_AVAILABLE   0x6791AC0
  |  |  ------------------
  |  | 1055|    343|	{"lat",           t_integer,   .addr.integer = &ais->type21.lat,
  |  | 1056|    343|                                       .dflt.integer = AIS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 1487|    343|#define AIS_LAT_NOT_AVAILABLE   0x3412140
  |  |  ------------------
  |  | 1057|    343|	{"to_bow",        t_uinteger,  .addr.uinteger = &ais->type21.to_bow,
  |  | 1058|    343|                                       .dflt.uinteger = 0},
  |  | 1059|    343|	{"to_stern",      t_uinteger,  .addr.uinteger = &ais->type21.to_stern,
  |  | 1060|    343|                                       .dflt.uinteger = 0},
  |  | 1061|    343|	{"to_port",       t_uinteger,  .addr.uinteger = &ais->type21.to_port,
  |  | 1062|    343|                                       .dflt.uinteger = 0},
  |  | 1063|    343|	{"to_starboard",  t_uinteger,  .addr.uinteger = &ais->type21.to_starboard,
  |  | 1064|    343|                                       .dflt.uinteger = 0},
  |  | 1065|    343|	{"epfd",          t_uinteger,  .addr.uinteger = &ais->type21.epfd,
  |  | 1066|    343|                                       .dflt.uinteger = 0},
  |  | 1067|    343|	{"epfd_text",   t_ignore},
  |  | 1068|    343|	{"second",        t_uinteger,  .addr.uinteger = &ais->type21.second,
  |  | 1069|    343|                                       .dflt.uinteger = 0},
  |  | 1070|    343|	{"regional",      t_uinteger,  .addr.uinteger = &ais->type21.regional,
  |  | 1071|    343|                                       .dflt.uinteger = 0},
  |  | 1072|    343|	{"off_position",  t_boolean,   .addr.boolean = &ais->type21.off_position,
  |  | 1073|    343|                                       .dflt.boolean = false},
  |  | 1074|    343|	{"raim",          t_boolean,   .addr.boolean = &ais->type21.raim,
  |  | 1075|    343|                                       .dflt.boolean = false},
  |  | 1076|    343|	{"virtual_aid",   t_boolean,   .addr.boolean = &ais->type21.virtual_aid,
  |  | 1077|    343|                                       .dflt.boolean = false},
  |  | 1078|    343|        {NULL}
  |  | 1079|    343|    };
  |  | 1080|       |
  |  | 1081|    343|    const struct json_attr_t json_ais22[] = {
  |  | 1082|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1083|    343|	{"channel_a",     t_uinteger,  .addr.uinteger = &ais->type22.channel_a,
  |  | 1084|    343|                                       .dflt.uinteger = 0},
  |  | 1085|    343|	{"channel_b",     t_uinteger,  .addr.uinteger = &ais->type22.channel_b,
  |  | 1086|    343|                                       .dflt.uinteger = 0},
  |  | 1087|    343|	{"txrx",          t_uinteger,  .addr.uinteger = &ais->type22.txrx,
  |  | 1088|    343|                                       .dflt.uinteger = 0},
  |  | 1089|    343|	{"power",         t_boolean,   .addr.boolean = &ais->type22.power,
  |  | 1090|    343|                                       .dflt.boolean = false},
  |  | 1091|    343|	{"ne_lon",        t_integer,   .addr.integer = &ais->type22.area.ne_lon,
  |  | 1092|    343|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2218|    343|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  | 1093|    343|	{"ne_lat",        t_integer,   .addr.integer = &ais->type22.area.ne_lat,
  |  | 1094|    343|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2220|    343|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  | 1095|    343|	{"sw_lon",        t_integer,   .addr.integer = &ais->type22.area.sw_lon,
  |  | 1096|    343|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2218|    343|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  | 1097|    343|	{"sw_lat",        t_integer,   .addr.integer = &ais->type22.area.sw_lat,
  |  | 1098|    343|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2220|    343|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  | 1099|    343|	{"dest1",         t_uinteger,  .addr.uinteger = &ais->type22.mmsi.dest1,
  |  | 1100|    343|                                       .dflt.uinteger = 0},
  |  | 1101|    343|	{"dest2",         t_uinteger,  .addr.uinteger = &ais->type22.mmsi.dest2,
  |  | 1102|    343|                                       .dflt.uinteger = 0},
  |  | 1103|    343|	{"addressed",     t_boolean,   .addr.boolean = &ais->type22.addressed,
  |  | 1104|    343|                                       .dflt.boolean = false},
  |  | 1105|    343|	{"band_a",        t_boolean,   .addr.boolean = &ais->type22.band_a,
  |  | 1106|    343|                                       .dflt.boolean = false},
  |  | 1107|    343|	{"band_b",        t_boolean,   .addr.boolean = &ais->type22.band_b,
  |  | 1108|    343|                                       .dflt.boolean = false},
  |  | 1109|    343|	{"zonesize",      t_uinteger,  .addr.uinteger = &ais->type22.zonesize,
  |  | 1110|    343|                                       .dflt.uinteger = 0},
  |  | 1111|    343|        {NULL}
  |  | 1112|    343|    };
  |  | 1113|       |
  |  | 1114|    343|    const struct json_attr_t json_ais23[] = {
  |  | 1115|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1116|    343|	{"ne_lon",        t_integer,   .addr.integer = &ais->type23.ne_lon,
  |  | 1117|    343|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2218|    343|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  | 1118|    343|	{"ne_lat",        t_integer,   .addr.integer = &ais->type23.ne_lat,
  |  | 1119|    343|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2220|    343|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  | 1120|    343|	{"sw_lon",        t_integer,   .addr.integer = &ais->type23.sw_lon,
  |  | 1121|    343|                                       .dflt.integer = AIS_GNS_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2218|    343|#define AIS_GNS_LON_NOT_AVAILABLE       0x1a838
  |  |  ------------------
  |  | 1122|    343|	{"sw_lat",        t_integer,   .addr.integer = &ais->type23.sw_lat,
  |  | 1123|    343|                                       .dflt.integer = AIS_GNS_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2220|    343|#define AIS_GNS_LAT_NOT_AVAILABLE       0xd548
  |  |  ------------------
  |  | 1124|    343|	{"stationtype",   t_uinteger,  .addr.uinteger = &ais->type23.stationtype,
  |  | 1125|    343|                                       .dflt.uinteger = 0},
  |  | 1126|    343|	{"stationtype_text",   t_ignore},
  |  | 1127|    343|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type23.shiptype,
  |  | 1128|    343|                                       .dflt.uinteger = 0},
  |  | 1129|    343|	{"shiptype_text",   t_ignore},
  |  | 1130|    343|	{"txrx",          t_uinteger,  .addr.uinteger = &ais->type23.txrx,
  |  | 1131|    343|                                       .dflt.uinteger = 0},
  |  | 1132|    343|	{"interval",      t_uinteger,  .addr.uinteger = &ais->type23.interval,
  |  | 1133|    343|                                       .dflt.uinteger = 0},
  |  | 1134|    343|	{"quiet",         t_uinteger,  .addr.uinteger = &ais->type23.quiet,
  |  | 1135|    343|                                       .dflt.uinteger = 0},
  |  | 1136|    343|        {NULL}
  |  | 1137|    343|    };
  |  | 1138|       |
  |  | 1139|    343|    const struct json_attr_t json_ais24[] = {
  |  | 1140|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1141|    343|	{"shipname",      t_string,    .addr.string = ais->type24.shipname,
  |  | 1142|    343|                                       .len = sizeof(ais->type24.shipname)},
  |  | 1143|    343|	{"shiptype",      t_uinteger,  .addr.uinteger = &ais->type24.shiptype,
  |  | 1144|    343|                                       .dflt.uinteger = 0},
  |  | 1145|    343|	{"shiptype_text",   t_ignore},
  |  | 1146|    343|	{"vendorid",      t_string,    .addr.string = ais->type24.vendorid,
  |  | 1147|    343|                                       .len = sizeof(ais->type24.vendorid)},
  |  | 1148|    343|	{"model",         t_uinteger,  .addr.uinteger = &ais->type24.model,
  |  | 1149|    343|                                       .dflt.uinteger = 0},
  |  | 1150|    343|	{"serial",        t_uinteger,  .addr.uinteger = &ais->type24.serial,
  |  | 1151|    343|                                       .dflt.uinteger = 0},
  |  | 1152|    343|	{"callsign",      t_string,    .addr.string = ais->type24.callsign,
  |  | 1153|    343|                                       .len = sizeof(ais->type24.callsign)},
  |  | 1154|    343|	{"mothership_mmsi",t_uinteger,  .addr.uinteger = &ais->type24.mothership_mmsi,
  |  | 1155|    343|                                       .dflt.uinteger = 0},
  |  | 1156|    343|	{"to_bow",        t_uinteger,  .addr.uinteger = &ais->type24.dim.to_bow,
  |  | 1157|    343|                                       .dflt.uinteger = 0},
  |  | 1158|    343|	{"to_stern",      t_uinteger,  .addr.uinteger = &ais->type24.dim.to_stern,
  |  | 1159|    343|                                       .dflt.uinteger = 0},
  |  | 1160|    343|	{"to_port",       t_uinteger,  .addr.uinteger = &ais->type24.dim.to_port,
  |  | 1161|    343|                                       .dflt.uinteger = 0},
  |  | 1162|    343|	{"to_starboard",  t_uinteger,  .addr.uinteger = &ais->type24.dim.to_starboard,
  |  | 1163|    343|                                       .dflt.uinteger = 0},
  |  | 1164|    343|        {NULL}
  |  | 1165|    343|    };
  |  | 1166|       |
  |  | 1167|    343|    const struct json_attr_t json_ais25[] = {
  |  | 1168|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1169|    343|	{"addressed",     t_boolean,   .addr.boolean = &ais->type25.addressed,
  |  | 1170|    343|                                       .dflt.boolean = false},
  |  | 1171|    343|	{"structured",    t_boolean,   .addr.boolean = &ais->type25.structured,
  |  | 1172|    343|                                       .dflt.boolean = false},
  |  | 1173|    343|	{"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type25.dest_mmsi,
  |  | 1174|    343|                                       .dflt.uinteger = 0},
  |  | 1175|    343|	{"app_id",        t_uinteger,  .addr.uinteger = &ais->type25.app_id,
  |  | 1176|    343|                                       .dflt.uinteger = 0},
  |  | 1177|    343|	{"data",          t_string,    .addr.string = data,
  |  | 1178|    343|                                       .len = sizeof(data)},
  |  | 1179|    343|        {NULL}
  |  | 1180|    343|    };
  |  | 1181|       |
  |  | 1182|    343|    const struct json_attr_t json_ais26[] = {
  |  | 1183|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1184|    343|	{"addressed",     t_boolean,   .addr.boolean = &ais->type26.addressed,
  |  | 1185|    343|                                       .dflt.boolean = false},
  |  | 1186|    343|	{"structured",    t_boolean,   .addr.boolean = &ais->type26.structured,
  |  | 1187|    343|                                       .dflt.boolean = false},
  |  | 1188|    343|	{"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type26.dest_mmsi,
  |  | 1189|    343|                                       .dflt.uinteger = 0},
  |  | 1190|    343|	{"app_id",        t_uinteger,  .addr.uinteger = &ais->type26.app_id,
  |  | 1191|    343|                                       .dflt.uinteger = 0},
  |  | 1192|    343|	{"data",          t_string,    .addr.string = data,
  |  | 1193|    343|                                       .len = sizeof(data)},
  |  | 1194|    343|	{"radio",         t_uinteger,  .addr.uinteger = &ais->type26.radio,
  |  | 1195|    343|                                       .dflt.uinteger = 0},
  |  | 1196|    343|        {NULL}
  |  | 1197|    343|    };
  |  | 1198|       |
  |  | 1199|    343|    const struct json_attr_t json_ais27[] = {
  |  | 1200|    343|	AIS_HEADER
  |  |  ------------------
  |  |  |  |   48|    343|        {"class",          t_check,    .dflt.check = "AIS"}, \
  |  |  |  |   49|    343|        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
  |  |  |  |   50|    343|        {"device",         t_string,   .addr.string = path, \
  |  |  |  |   51|    343|                                          .len = pathlen}, \
  |  |  |  |   52|    343|        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
  |  |  |  |   53|    343|        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
  |  |  |  |   54|    343|                                          .dflt.boolean = false}, \
  |  |  |  |   55|    343|        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
  |  |  ------------------
  |  | 1201|    343|	{"status",        t_uinteger,  .addr.uinteger = &ais->type27.status,
  |  | 1202|    343|                                       .dflt.uinteger = 0},
  |  | 1203|    343|	{"speed",         t_uinteger,  .addr.uinteger = &ais->type27.speed,
  |  | 1204|    343|                                       .dflt.uinteger = AIS_LONGRANGE_SPEED_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2402|    343|#define AIS_LONGRANGE_SPEED_NOT_AVAILABLE 63
  |  |  ------------------
  |  | 1205|    343|	{"accuracy",      t_boolean,   .addr.boolean = &ais->type27.accuracy,
  |  | 1206|    343|                                       .dflt.boolean = false},
  |  | 1207|    343|	{"lon",           t_integer,   .addr.integer = &ais->type27.lon,
  |  | 1208|    343|                                       .dflt.integer = AIS_LONGRANGE_LON_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2398|    343|#define AIS_LONGRANGE_LON_NOT_AVAILABLE 0x1a838
  |  |  ------------------
  |  | 1209|    343|	{"lat",           t_integer,   .addr.integer = &ais->type27.lat,
  |  | 1210|    343|                                       .dflt.integer = AIS_LONGRANGE_LAT_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2400|    343|#define AIS_LONGRANGE_LAT_NOT_AVAILABLE 0xd548
  |  |  ------------------
  |  | 1211|    343|	{"course",        t_uinteger,  .addr.uinteger = &ais->type27.course,
  |  | 1212|    343|                                       .dflt.uinteger = AIS_LONGRANGE_COURSE_NOT_AVAILABLE},
  |  |  ------------------
  |  |  |  | 2404|    343|#define AIS_LONGRANGE_COURSE_NOT_AVAILABLE 511
  |  |  ------------------
  |  | 1213|    343|	{"raim",          t_boolean,   .addr.boolean = &ais->type27.raim,
  |  | 1214|    343|                                       .dflt.boolean = false},
  |  | 1215|    343|	{"gnss",          t_boolean,   .addr.boolean = &ais->type27.gnss,
  |  | 1216|    343|                                       .dflt.boolean = true},
  |  | 1217|    343|        {NULL}
  |  | 1218|    343|    };
  |  | 1219|       |
  |  | 1220|       |
  |  | 1221|       |
  |  | 1222|       |/* Generated code ends. */
  |  | 1223|       |
  ------------------
   77|       |
   78|    343|#undef AIS_HEADER
   79|       |
   80|    343|    memset(ais, '\0', sizeof(struct ais_t));
   81|       |
   82|    343|    if (NULL != strstr(buf, "\"type\":1,") ||
  ------------------
  |  Branch (82:9): [True: 3, False: 340]
  ------------------
   83|    343|        NULL != strstr(buf, "\"type\":2,") ||
  ------------------
  |  Branch (83:9): [True: 1, False: 339]
  ------------------
   84|    343|        NULL != strstr(buf, "\"type\":3,")) {
  ------------------
  |  Branch (84:9): [True: 2, False: 337]
  ------------------
   85|      6|        status = json_read_object(buf, json_ais1, endptr);
   86|    337|    } else if (NULL != strstr(buf, "\"type\":4,") ||
  ------------------
  |  Branch (86:16): [True: 5, False: 332]
  ------------------
   87|    337|               NULL != strstr(buf, "\"type\":11,")) {
  ------------------
  |  Branch (87:16): [True: 1, False: 331]
  ------------------
   88|      6|        status = json_read_object(buf, json_ais4, endptr);
   89|      6|        if (0 == status) {
  ------------------
  |  Branch (89:13): [True: 1, False: 5]
  ------------------
   90|      1|            ais->type4.year = AIS_YEAR_NOT_AVAILABLE;
  ------------------
  |  | 1508|      1|#define AIS_YEAR_NOT_AVAILABLE  0
  ------------------
   91|      1|            ais->type4.month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
   92|      1|            ais->type4.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
   93|      1|            ais->type4.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
   94|      1|            ais->type4.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
   95|      1|            ais->type4.second = AIS_SECOND_NOT_AVAILABLE;
  ------------------
  |  | 1518|      1|#define AIS_SECOND_NOT_AVAILABLE        60
  ------------------
   96|       |            /* We use %09u for the date to allow for dodgy years (>9999)
   97|       |             * to go through. */
   98|      1|            (void)sscanf(timestamp, "%09u-%02u-%02uT%02u:%02u:%02uZ",
   99|      1|                         &ais->type4.year,
  100|      1|                         &ais->type4.month,
  101|      1|                         &ais->type4.day,
  102|      1|                         &ais->type4.hour,
  103|      1|                         &ais->type4.minute,
  104|      1|                         &ais->type4.second);
  105|      1|        }
  106|    331|    } else if (strstr(buf, "\"type\":5,") != NULL) {
  ------------------
  |  Branch (106:16): [True: 15, False: 316]
  ------------------
  107|     15|        status = json_read_object(buf, json_ais5, endptr);
  108|     15|        if (status == 0) {
  ------------------
  |  Branch (108:13): [True: 2, False: 13]
  ------------------
  109|      2|            ais->type5.month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      2|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  110|      2|            ais->type5.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      2|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  111|      2|            ais->type5.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      2|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  112|      2|            ais->type5.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      2|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  113|      2|            (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
  114|      2|                         &ais->type5.month,
  115|      2|                         &ais->type5.day,
  116|      2|                         &ais->type5.hour,
  117|      2|                         &ais->type5.minute);
  118|      2|        }
  119|    316|    } else if (strstr(buf, "\"type\":6,") != NULL) {
  ------------------
  |  Branch (119:16): [True: 132, False: 184]
  ------------------
  120|    132|        bool structured = false;
  121|    132|        if (strstr(buf, "\"dac\":1,") != NULL) {
  ------------------
  |  Branch (121:13): [True: 23, False: 109]
  ------------------
  122|     23|            if (strstr(buf, "\"fid\":12,") != NULL) {
  ------------------
  |  Branch (122:17): [True: 2, False: 21]
  ------------------
  123|      2|                status = json_read_object(buf, json_ais6_fid12, endptr);
  124|      2|                if (status == 0) {
  ------------------
  |  Branch (124:21): [True: 1, False: 1]
  ------------------
  125|      1|                    ais->type6.dac1fid12.lmonth = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  126|      1|                    ais->type6.dac1fid12.lday = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  127|      1|                    ais->type6.dac1fid12.lhour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  128|      1|                    ais->type6.dac1fid12.lminute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  129|      1|                    (void)sscanf(departure, "%02u-%02uT%02u:%02uZ",
  130|      1|                                 &ais->type6.dac1fid12.lmonth,
  131|      1|                                 &ais->type6.dac1fid12.lday,
  132|      1|                                 &ais->type6.dac1fid12.lhour,
  133|      1|                                 &ais->type6.dac1fid12.lminute);
  134|      1|                    ais->type6.dac1fid12.nmonth = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  135|      1|                    ais->type6.dac1fid12.nday = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  136|      1|                    ais->type6.dac1fid12.nhour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  137|      1|                    ais->type6.dac1fid12.nminute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  138|      1|                    (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
  139|      1|                                 &ais->type6.dac1fid12.nmonth,
  140|      1|                                 &ais->type6.dac1fid12.nday,
  141|      1|                                 &ais->type6.dac1fid12.nhour,
  142|      1|                                 &ais->type6.dac1fid12.nminute);
  143|      1|                }
  144|      2|                structured = true;
  145|      2|            }
  146|     21|            else if (strstr(buf, "\"fid\":15,") != NULL) {
  ------------------
  |  Branch (146:22): [True: 1, False: 20]
  ------------------
  147|      1|                status = json_read_object(buf, json_ais6_fid15, endptr);
  148|      1|                structured = true;
  149|      1|            }
  150|     20|            else if (strstr(buf, "\"fid\":16,") != NULL) {
  ------------------
  |  Branch (150:22): [True: 1, False: 19]
  ------------------
  151|      1|                status = json_read_object(buf, json_ais6_fid16, endptr);
  152|      1|                structured = true;
  153|      1|            }
  154|     19|            else if (strstr(buf, "\"fid\":18,") != NULL) {
  ------------------
  |  Branch (154:22): [True: 5, False: 14]
  ------------------
  155|      5|                status = json_read_object(buf, json_ais6_fid18, endptr);
  156|      5|                if (status == 0) {
  ------------------
  |  Branch (156:21): [True: 1, False: 4]
  ------------------
  157|      1|                    ais->type6.dac1fid18.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  158|      1|                    ais->type6.dac1fid18.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  159|      1|                    ais->type6.dac1fid18.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  160|      1|                    (void)sscanf(arrival, "%02u-%02uT%02u:%02uZ",
  161|      1|                                 &ais->type6.dac1fid18.month,
  162|      1|                                 &ais->type6.dac1fid18.day,
  163|      1|                                 &ais->type6.dac1fid18.hour,
  164|      1|                                 &ais->type6.dac1fid18.minute);
  165|      1|                }
  166|      5|                structured = true;
  167|      5|            }
  168|     14|            else if (strstr(buf, "\"fid\":20,") != NULL) {
  ------------------
  |  Branch (168:22): [True: 7, False: 7]
  ------------------
  169|      7|                status = json_read_object(buf, json_ais6_fid20, endptr);
  170|      7|                if (status == 0) {
  ------------------
  |  Branch (170:21): [True: 2, False: 5]
  ------------------
  171|      2|                    ais->type6.dac1fid20.month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      2|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  172|      2|                    ais->type6.dac1fid20.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      2|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  173|      2|                    ais->type6.dac1fid20.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      2|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  174|      2|                    ais->type6.dac1fid20.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      2|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  175|      2|                    (void)sscanf(arrival, "%02u-%02uT%02u:%02uZ",
  176|      2|                                 &ais->type6.dac1fid20.month,
  177|      2|                                 &ais->type6.dac1fid20.day,
  178|      2|                                 &ais->type6.dac1fid20.hour,
  179|      2|                                 &ais->type6.dac1fid20.minute);
  180|      2|                }
  181|      7|                structured = true;
  182|      7|            }
  183|      7|            else if (strstr(buf, "\"fid\":25,") != NULL) {
  ------------------
  |  Branch (183:22): [True: 1, False: 6]
  ------------------
  184|      1|                status = json_read_object(buf, json_ais6_fid25, endptr);
  185|      1|                structured = true;
  186|      1|            }
  187|      6|            else if (strstr(buf, "\"fid\":28,") != NULL) {
  ------------------
  |  Branch (187:22): [True: 2, False: 4]
  ------------------
  188|      2|                status = json_read_object(buf, json_ais6_fid28, endptr);
  189|      2|                if (status == 0) {
  ------------------
  |  Branch (189:21): [True: 1, False: 1]
  ------------------
  190|      1|                    ais->type6.dac1fid28.month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  191|      1|                    ais->type6.dac1fid28.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  192|      1|                    ais->type6.dac1fid28.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  193|      1|                    ais->type6.dac1fid28.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  194|      1|                    (void)sscanf(start, "%02u-%02uT%02u:%02uZ",
  195|      1|                                 &ais->type6.dac1fid28.month,
  196|      1|                                 &ais->type6.dac1fid28.day,
  197|      1|                                 &ais->type6.dac1fid28.hour,
  198|      1|                                 &ais->type6.dac1fid28.minute);
  199|      1|                }
  200|      2|                structured = true;
  201|      2|            }
  202|      4|            else if (strstr(buf, "\"fid\":30,") != NULL) {
  ------------------
  |  Branch (202:22): [True: 1, False: 3]
  ------------------
  203|      1|                status = json_read_object(buf, json_ais6_fid30, endptr);
  204|      1|                structured = true;
  205|      1|            }
  206|      3|            else if (strstr(buf, "\"fid\":32,") != NULL ||
  ------------------
  |  Branch (206:22): [True: 1, False: 2]
  ------------------
  207|      3|                     strstr(buf, "\"fid\":14,") != NULL) {
  ------------------
  |  Branch (207:22): [True: 1, False: 1]
  ------------------
  208|      2|                status = json_read_object(buf, json_ais6_fid32, endptr);
  209|      2|                structured = true;
  210|      2|            }
  211|     23|        }
  212|    109|        else if (strstr(buf, "\"dac\":235,") != NULL ||
  ------------------
  |  Branch (212:18): [True: 1, False: 108]
  ------------------
  213|    109|                 strstr(buf, "\"dac\":250,") != NULL) {
  ------------------
  |  Branch (213:18): [True: 3, False: 105]
  ------------------
  214|      4|            if (strstr(buf, "\"fid\":10,") != NULL) {
  ------------------
  |  Branch (214:17): [True: 2, False: 2]
  ------------------
  215|      2|                status = json_read_object(buf, json_ais6_fid10, endptr);
  216|      2|                structured = true;
  217|      2|            }
  218|      4|        }
  219|    105|        else if (strstr(buf, "\"dac\":200,") != NULL) {
  ------------------
  |  Branch (219:18): [True: 12, False: 93]
  ------------------
  220|     12|            if (strstr(buf, "\"fid\":21,") != NULL) {
  ------------------
  |  Branch (220:17): [True: 5, False: 7]
  ------------------
  221|      5|                status = json_read_object(buf, json_ais6_fid21, endptr);
  222|      5|                structured = true;
  223|      5|                if (status == 0) {
  ------------------
  |  Branch (223:21): [True: 1, False: 4]
  ------------------
  224|      1|                    ais->type6.dac200fid21.month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  225|      1|                    ais->type6.dac200fid21.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  226|      1|                    ais->type6.dac200fid21.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  227|      1|                    ais->type6.dac200fid21.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  228|      1|                    (void)sscanf(eta, "%02u-%02uT%02u:%02u",
  229|      1|                                 &ais->type6.dac200fid21.month,
  230|      1|                                 &ais->type6.dac200fid21.day,
  231|      1|                                 &ais->type6.dac200fid21.hour,
  232|      1|                                 &ais->type6.dac200fid21.minute);
  233|      1|                }
  234|      5|            }
  235|      7|            else if (strstr(buf, "\"fid\":22,") != NULL) {
  ------------------
  |  Branch (235:22): [True: 5, False: 2]
  ------------------
  236|      5|                status = json_read_object(buf, json_ais6_fid22, endptr);
  237|      5|                structured = true;
  238|      5|                if (status == 0) {
  ------------------
  |  Branch (238:21): [True: 1, False: 4]
  ------------------
  239|      1|                    ais->type6.dac200fid22.month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  240|      1|                    ais->type6.dac200fid22.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  241|      1|                    ais->type6.dac200fid22.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  242|      1|                    ais->type6.dac200fid22.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  243|      1|                    (void)sscanf(rta, "%02u-%02uT%02u:%02u",
  244|      1|                                 &ais->type6.dac200fid22.month,
  245|      1|                                 &ais->type6.dac200fid22.day,
  246|      1|                                 &ais->type6.dac200fid22.hour,
  247|      1|                                 &ais->type6.dac200fid22.minute);
  248|      1|                }
  249|      5|            }
  250|      2|            else if (strstr(buf, "\"fid\":55,") != NULL) {
  ------------------
  |  Branch (250:22): [True: 1, False: 1]
  ------------------
  251|      1|                status = json_read_object(buf, json_ais6_fid55, endptr);
  252|      1|                structured = true;
  253|      1|            }
  254|     12|        }
  255|    132|        if (!structured) {
  ------------------
  |  Branch (255:13): [True: 97, False: 35]
  ------------------
  256|     97|            status = json_read_object(buf, json_ais6, endptr);
  257|     97|            if (status == 0)
  ------------------
  |  Branch (257:17): [True: 86, False: 11]
  ------------------
  258|     86|                lenhex_unpack(data, &ais->type6.bitcount,
  259|     86|                              ais->type6.bitdata, sizeof(ais->type6.bitdata));
  260|     97|        }
  261|    132|        ais->type6.structured = structured;
  262|    184|    } else if (strstr(buf, "\"type\":7,") != NULL
  ------------------
  |  Branch (262:16): [True: 2, False: 182]
  ------------------
  263|    184|               || strstr(buf, "\"type\":13,") != NULL) {
  ------------------
  |  Branch (263:19): [True: 1, False: 181]
  ------------------
  264|      3|        status = json_read_object(buf, json_ais7, endptr);
  265|    181|    } else if (strstr(buf, "\"type\":8,") != NULL) {
  ------------------
  |  Branch (265:16): [True: 116, False: 65]
  ------------------
  266|    116|        bool structured = false;
  267|    116|        if (strstr(buf, "\"dac\":1,") != NULL) {
  ------------------
  |  Branch (267:13): [True: 79, False: 37]
  ------------------
  268|     79|            if (strstr(buf, "\"fid\":11,") != NULL) {
  ------------------
  |  Branch (268:17): [True: 5, False: 74]
  ------------------
  269|      5|                status = json_read_object(buf, json_ais8_fid11, endptr);
  270|      5|                if (status == 0) {
  ------------------
  |  Branch (270:21): [True: 1, False: 4]
  ------------------
  271|      1|                    ais->type8.dac1fid11.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  272|      1|                    ais->type8.dac1fid11.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  273|      1|                    ais->type8.dac1fid11.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  274|      1|                    (void)sscanf(timestamp, "%02uT%02u:%02uZ",
  275|      1|                                 &ais->type8.dac1fid11.day,
  276|      1|                                 &ais->type8.dac1fid11.hour,
  277|      1|                                 &ais->type8.dac1fid11.minute);
  278|      1|                }
  279|      5|                structured = true;
  280|      5|            }
  281|     74|            else if (strstr(buf, "\"fid\":13,") != NULL) {
  ------------------
  |  Branch (281:22): [True: 5, False: 69]
  ------------------
  282|      5|                status = json_read_object(buf, json_ais8_fid13, endptr);
  283|      5|                if (status == 0) {
  ------------------
  |  Branch (283:21): [True: 1, False: 4]
  ------------------
  284|      1|                    ais->type8.dac1fid13.fmonth = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  285|      1|                    ais->type8.dac1fid13.fday = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  286|      1|                    ais->type8.dac1fid13.fhour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  287|      1|                    ais->type8.dac1fid13.fminute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  288|      1|                    (void)sscanf(departure, "%02u-%02uT%02u:%02uZ",
  289|      1|                                 &ais->type8.dac1fid13.fmonth,
  290|      1|                                 &ais->type8.dac1fid13.fday,
  291|      1|                                 &ais->type8.dac1fid13.fhour,
  292|      1|                                 &ais->type8.dac1fid13.fminute);
  293|      1|                    ais->type8.dac1fid13.tmonth = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  294|      1|                    ais->type8.dac1fid13.tday = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  295|      1|                    ais->type8.dac1fid13.thour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  296|      1|                    ais->type8.dac1fid13.tminute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  297|      1|                    (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
  298|      1|                                 &ais->type8.dac1fid13.tmonth,
  299|      1|                                 &ais->type8.dac1fid13.tday,
  300|      1|                                 &ais->type8.dac1fid13.thour,
  301|      1|                                 &ais->type8.dac1fid13.tminute);
  302|      1|                }
  303|      5|                structured = true;
  304|      5|            }
  305|     69|            else if (strstr(buf, "\"fid\":15,") != NULL) {
  ------------------
  |  Branch (305:22): [True: 1, False: 68]
  ------------------
  306|      1|                status = json_read_object(buf, json_ais8_fid15, endptr);
  307|      1|                structured = true;
  308|      1|            }
  309|     68|            else if (strstr(buf, "\"fid\":16,") != NULL) {
  ------------------
  |  Branch (309:22): [True: 48, False: 20]
  ------------------
  310|     48|                status = json_read_object(buf, json_ais8_fid16, endptr);
  311|     48|                if (status == 0) {
  ------------------
  |  Branch (311:21): [True: 1, False: 47]
  ------------------
  312|      1|                        structured = true;
  313|      1|                }
  314|     48|            }
  315|     20|            else if (strstr(buf, "\"fid\":17,") != NULL) {
  ------------------
  |  Branch (315:22): [True: 1, False: 19]
  ------------------
  316|      1|                status = json_read_object(buf, json_ais8_fid17, endptr);
  317|      1|                structured = true;
  318|      1|            }
  319|     19|            else if (strstr(buf, "\"fid\":19,") != NULL) {
  ------------------
  |  Branch (319:22): [True: 2, False: 17]
  ------------------
  320|      2|                status = json_read_object(buf, json_ais8_fid19, endptr);
  321|      2|                structured = true;
  322|      2|            }
  323|     17|            else if (strstr(buf, "\"fid\":23,") != NULL) {
  ------------------
  |  Branch (323:22): [True: 3, False: 14]
  ------------------
  324|      3|                status = json_read_object(buf, json_ais8_fid23, endptr);
  325|      3|                ais->type8.dac200fid23.start_year = AIS_YEAR_NOT_AVAILABLE;
  ------------------
  |  | 1508|      3|#define AIS_YEAR_NOT_AVAILABLE  0
  ------------------
  326|      3|                ais->type8.dac200fid23.start_month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      3|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  327|      3|                ais->type8.dac200fid23.start_day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      3|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  328|      3|                ais->type8.dac200fid23.start_hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      3|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  329|      3|                ais->type8.dac200fid23.start_minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      3|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  330|      3|                ais->type8.dac200fid23.end_year = AIS_YEAR_NOT_AVAILABLE;
  ------------------
  |  | 1508|      3|#define AIS_YEAR_NOT_AVAILABLE  0
  ------------------
  331|      3|                ais->type8.dac200fid23.end_month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      3|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  332|      3|                ais->type8.dac200fid23.end_day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      3|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  333|      3|                ais->type8.dac200fid23.end_hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      3|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  334|      3|                ais->type8.dac200fid23.end_minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      3|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  335|      3|                (void)sscanf(start, "%09u-%02u-%02uT%02u:%02u",
  336|      3|                         &ais->type8.dac200fid23.start_year,
  337|      3|                         &ais->type8.dac200fid23.start_month,
  338|      3|                         &ais->type8.dac200fid23.start_day,
  339|      3|                         &ais->type8.dac200fid23.start_hour,
  340|      3|                         &ais->type8.dac200fid23.start_minute);
  341|      3|                (void)sscanf(end, "%09u-%02u-%02uT%02u:%02u",
  342|      3|                         &ais->type8.dac200fid23.end_year,
  343|      3|                         &ais->type8.dac200fid23.end_month,
  344|      3|                         &ais->type8.dac200fid23.end_day,
  345|      3|                         &ais->type8.dac200fid23.end_hour,
  346|      3|                         &ais->type8.dac200fid23.end_minute);
  347|      3|                structured = true;
  348|      3|            }
  349|     14|            else if (strstr(buf, "\"fid\":24,") != NULL) {
  ------------------
  |  Branch (349:22): [True: 1, False: 13]
  ------------------
  350|      1|                status = json_read_object(buf, json_ais8_fid24, endptr);
  351|      1|                structured = true;
  352|      1|            }
  353|     13|            else if (strstr(buf, "\"fid\":27,") != NULL) {
  ------------------
  |  Branch (353:22): [True: 5, False: 8]
  ------------------
  354|      5|                status = json_read_object(buf, json_ais8_fid27, endptr);
  355|      5|                if (status == 0) {
  ------------------
  |  Branch (355:21): [True: 1, False: 4]
  ------------------
  356|      1|                    ais->type8.dac1fid27.month = AIS_MONTH_NOT_AVAILABLE;
  ------------------
  |  | 1510|      1|#define AIS_MONTH_NOT_AVAILABLE 0
  ------------------
  357|      1|                    ais->type8.dac1fid27.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  358|      1|                    ais->type8.dac1fid27.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  359|      1|                    ais->type8.dac1fid27.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  360|      1|                    (void)sscanf(start, "%02u-%02uT%02u:%02uZ",
  361|      1|                                 &ais->type8.dac1fid27.month,
  362|      1|                                 &ais->type8.dac1fid27.day,
  363|      1|                                 &ais->type8.dac1fid27.hour,
  364|      1|                                 &ais->type8.dac1fid27.minute);
  365|      1|                }
  366|      5|                structured = true;
  367|      5|            }
  368|      8|            else if (strstr(buf, "\"fid\":29,") != NULL) {
  ------------------
  |  Branch (368:22): [True: 1, False: 7]
  ------------------
  369|      1|                status = json_read_object(buf, json_ais8_fid29, endptr);
  370|      1|                structured = true;
  371|      1|            }
  372|      7|            else if (strstr(buf, "\"fid\":31,") != NULL) {
  ------------------
  |  Branch (372:22): [True: 6, False: 1]
  ------------------
  373|      6|                status = json_read_object(buf, json_ais8_fid31, endptr);
  374|      6|                if (status == 0) {
  ------------------
  |  Branch (374:21): [True: 1, False: 5]
  ------------------
  375|      1|                    ais->type8.dac1fid31.day = AIS_DAY_NOT_AVAILABLE;
  ------------------
  |  | 1512|      1|#define AIS_DAY_NOT_AVAILABLE   0
  ------------------
  376|      1|                    ais->type8.dac1fid31.hour = AIS_HOUR_NOT_AVAILABLE;
  ------------------
  |  | 1514|      1|#define AIS_HOUR_NOT_AVAILABLE  24
  ------------------
  377|      1|                    ais->type8.dac1fid31.minute = AIS_MINUTE_NOT_AVAILABLE;
  ------------------
  |  | 1516|      1|#define AIS_MINUTE_NOT_AVAILABLE        60
  ------------------
  378|      1|                    (void)sscanf(timestamp, "%02uT%02u:%02uZ",
  379|      1|                                 &ais->type8.dac1fid31.day,
  380|      1|                                 &ais->type8.dac1fid31.hour,
  381|      1|                                 &ais->type8.dac1fid31.minute);
  382|      1|                }
  383|      6|                structured = true;
  384|      6|            }
  385|     79|        }
  386|     37|        else if (strstr(buf, "\"dac\":200,") != NULL &&
  ------------------
  |  Branch (386:18): [True: 7, False: 30]
  ------------------
  387|     37|                 strstr(buf,"data")==NULL) {
  ------------------
  |  Branch (387:18): [True: 6, False: 1]
  ------------------
  388|      6|            if (strstr(buf, "\"fid\":10,") != NULL) {
  ------------------
  |  Branch (388:17): [True: 4, False: 2]
  ------------------
  389|      4|                status = json_read_object(buf, json_ais8_fid10, endptr);
  390|      4|                structured = true;
  391|      4|            }
  392|      6|            if (strstr(buf, "\"fid\":40,") != NULL) {
  ------------------
  |  Branch (392:17): [True: 4, False: 2]
  ------------------
  393|      4|                status = json_read_object(buf, json_ais8_fid40, endptr);
  394|      4|                structured = true;
  395|      4|            }
  396|      6|        }
  397|    116|        if (!structured) {
  ------------------
  |  Branch (397:13): [True: 80, False: 36]
  ------------------
  398|     80|            status = json_read_object(buf, json_ais8, endptr);
  399|     80|            if (status == 0)
  ------------------
  |  Branch (399:17): [True: 26, False: 54]
  ------------------
  400|     26|                lenhex_unpack(data, &ais->type8.bitcount,
  401|     26|                              ais->type8.bitdata, sizeof(ais->type8.bitdata));
  402|     80|        }
  403|    116|        ais->type8.structured = structured;
  404|    116|    } else if (strstr(buf, "\"type\":9,") != NULL) {
  ------------------
  |  Branch (404:16): [True: 1, False: 64]
  ------------------
  405|      1|        status = json_read_object(buf, json_ais9, endptr);
  406|     64|    } else if (strstr(buf, "\"type\":10,") != NULL) {
  ------------------
  |  Branch (406:16): [True: 1, False: 63]
  ------------------
  407|      1|        status = json_read_object(buf, json_ais10, endptr);
  408|     63|    } else if (strstr(buf, "\"type\":12,") != NULL) {
  ------------------
  |  Branch (408:16): [True: 2, False: 61]
  ------------------
  409|      2|        status = json_read_object(buf, json_ais12, endptr);
  410|     61|    } else if (strstr(buf, "\"type\":14,") != NULL) {
  ------------------
  |  Branch (410:16): [True: 2, False: 59]
  ------------------
  411|      2|        status = json_read_object(buf, json_ais14, endptr);
  412|     59|    } else if (strstr(buf, "\"type\":15,") != NULL) {
  ------------------
  |  Branch (412:16): [True: 1, False: 58]
  ------------------
  413|      1|        status = json_read_object(buf, json_ais15, endptr);
  414|     58|    } else if (strstr(buf, "\"type\":16,") != NULL) {
  ------------------
  |  Branch (414:16): [True: 1, False: 57]
  ------------------
  415|      1|        status = json_read_object(buf, json_ais16, endptr);
  416|     57|    } else if (strstr(buf, "\"type\":17,") != NULL) {
  ------------------
  |  Branch (416:16): [True: 4, False: 53]
  ------------------
  417|      4|        status = json_read_object(buf, json_ais17, endptr);
  418|      4|        if (status == 0)
  ------------------
  |  Branch (418:13): [True: 1, False: 3]
  ------------------
  419|      1|            lenhex_unpack(data, &ais->type17.bitcount,
  420|      1|                          ais->type17.bitdata, sizeof(ais->type17.bitdata));
  421|     53|    } else if (strstr(buf, "\"type\":18,") != NULL) {
  ------------------
  |  Branch (421:16): [True: 3, False: 50]
  ------------------
  422|      3|        status = json_read_object(buf, json_ais18, endptr);
  423|     50|    } else if (strstr(buf, "\"type\":19,") != NULL) {
  ------------------
  |  Branch (423:16): [True: 1, False: 49]
  ------------------
  424|      1|        status = json_read_object(buf, json_ais19, endptr);
  425|     49|    } else if (strstr(buf, "\"type\":20,") != NULL) {
  ------------------
  |  Branch (425:16): [True: 1, False: 48]
  ------------------
  426|      1|        status = json_read_object(buf, json_ais20, endptr);
  427|     48|    } else if (strstr(buf, "\"type\":21,") != NULL) {
  ------------------
  |  Branch (427:16): [True: 1, False: 47]
  ------------------
  428|      1|        status = json_read_object(buf, json_ais21, endptr);
  429|     47|    } else if (strstr(buf, "\"type\":22,") != NULL) {
  ------------------
  |  Branch (429:16): [True: 2, False: 45]
  ------------------
  430|      2|        status = json_read_object(buf, json_ais22, endptr);
  431|     45|    } else if (strstr(buf, "\"type\":23,") != NULL) {
  ------------------
  |  Branch (431:16): [True: 18, False: 27]
  ------------------
  432|     18|        status = json_read_object(buf, json_ais23, endptr);
  433|     27|    } else if (strstr(buf, "\"type\":24,") != NULL) {
  ------------------
  |  Branch (433:16): [True: 3, False: 24]
  ------------------
  434|      3|        status = json_read_object(buf, json_ais24, endptr);
  435|     24|    } else if (strstr(buf, "\"type\":25,") != NULL) {
  ------------------
  |  Branch (435:16): [True: 14, False: 10]
  ------------------
  436|     14|        status = json_read_object(buf, json_ais25, endptr);
  437|     14|        if (status == 0)
  ------------------
  |  Branch (437:13): [True: 10, False: 4]
  ------------------
  438|     10|            lenhex_unpack(data, &ais->type25.bitcount,
  439|     10|                          ais->type25.bitdata, sizeof(ais->type25.bitdata));
  440|     14|    } else if (strstr(buf, "\"type\":26,") != NULL) {
  ------------------
  |  Branch (440:16): [True: 8, False: 2]
  ------------------
  441|      8|        status = json_read_object(buf, json_ais26, endptr);
  442|      8|        if (status == 0)
  ------------------
  |  Branch (442:13): [True: 4, False: 4]
  ------------------
  443|      4|            lenhex_unpack(data, &ais->type26.bitcount,
  444|      4|                          ais->type26.bitdata, sizeof(ais->type26.bitdata));
  445|      8|    } else if (strstr(buf, "\"type\":27,") != NULL) {
  ------------------
  |  Branch (445:16): [True: 1, False: 1]
  ------------------
  446|      1|        status = json_read_object(buf, json_ais27, endptr);
  447|      1|    } else {
  448|      1|        if (NULL != endptr) {
  ------------------
  |  Branch (448:13): [True: 0, False: 1]
  ------------------
  449|      0|            *endptr = NULL;
  450|      0|        }
  451|      1|        return JSON_ERR_MISC;
  ------------------
  |  |  172|      1|#define JSON_ERR_MISC           21      // other data conversion error
  ------------------
  452|      1|    }
  453|    342|    return status;
  454|    343|}
ais_json.c:lenhex_unpack:
   30|    127|{
   31|    127|    char *colon = strchr(from, ':');
   32|       |
   33|    127|    *plen = (size_t)atoi(from);
   34|    127|    if (NULL != colon) {
  ------------------
  |  Branch (34:9): [True: 118, False: 9]
  ------------------
   35|    118|        (void)gps_hexpack(colon + 1, (unsigned char *)to, maxlen);
   36|    118|    }
   37|    127|}

safe_atof:
  122|  5.07k|{
  123|  5.07k|    static int maxExponent = 511;   /* Largest possible base 10 exponent.  Any
  124|       |                                     * exponent larger than this will already
  125|       |                                     * produce underflow or overflow, so there's
  126|       |                                     * no need to worry about additional digits.
  127|       |                                     */
  128|       |    /* Table giving binary powers of 10.  Entry is 10^2^i.
  129|       |     * Used to convert decimal exponents into floating-point numbers. */
  130|  5.07k|    static double powersOf10[] = {
  131|  5.07k|        10.,
  132|  5.07k|        100.,
  133|  5.07k|        1.0e4,
  134|  5.07k|        1.0e8,
  135|  5.07k|        1.0e16,
  136|  5.07k|        1.0e32,
  137|  5.07k|        1.0e64,
  138|  5.07k|        1.0e128,
  139|  5.07k|        1.0e256
  140|  5.07k|    };
  141|       |
  142|  5.07k|    bool sign = false, expSign = false;
  143|  5.07k|    double fraction, dblExp, *d;
  144|  5.07k|    const char *p;
  145|  5.07k|    int c;
  146|  5.07k|    int exp = 0;                // Exponent read from "EX" field.
  147|  5.07k|    int fracExp = 0;            /* Exponent that derives from the fractional
  148|       |                                 * part.  Under normal circumstatnces, it is
  149|       |                                 * the negative of the number of digits in F.
  150|       |                                 * However, if I is very long, the last digits
  151|       |                                 * of I get dropped (otherwise a long I with a
  152|       |                                 * large negative exponent could cause an
  153|       |                                 * unnecessary overflow on I alone).  In this
  154|       |                                 * case, fracExp is incremented one for each
  155|       |                                 * dropped digit. */
  156|  5.07k|    int mantSize;               // Number of digits in mantissa.
  157|  5.07k|    int decPt;                  /* Number of mantissa digits BEFORE decimal
  158|       |                                 * point. */
  159|  5.07k|    const char *pExp;           /* Temporarily holds location of exponent
  160|       |                                 * in string. */
  161|       |
  162|       |    /*
  163|       |     * Strip off leading blanks and check for a sign.
  164|       |     */
  165|       |
  166|  5.07k|    p = string;
  167|  5.07k|    while (isspace((int)*p)) {
  168|      0|        p += 1;
  169|      0|    }
  170|  5.07k|    if (isdigit((int)*p)) {
  171|       |        // ignore
  172|  3.01k|    } else if ('-' == *p) {
  ------------------
  |  Branch (172:16): [True: 407, False: 1.65k]
  ------------------
  173|    407|        sign = true;
  174|    407|        p += 1;
  175|  1.65k|    } else if ('+' == *p) {
  ------------------
  |  Branch (175:16): [True: 199, False: 1.45k]
  ------------------
  176|    199|        p += 1;
  177|  1.45k|    } else if ('.' == *p) {
  ------------------
  |  Branch (177:16): [True: 800, False: 652]
  ------------------
  178|       |        // ignore
  179|    800|    } else {
  180|    652|        return NAN;
  181|    652|    }
  182|       |
  183|       |    /*
  184|       |     * Count the number of digits in the mantissa (including the decimal
  185|       |     * point), and also locate the decimal point.
  186|       |     */
  187|       |
  188|  4.41k|    decPt = -1;
  189|  19.9k|    for (mantSize = 0; ; mantSize += 1) {
  190|  19.9k|        c = *p;
  191|  19.9k|        if (!isdigit((int)c)) {
  ------------------
  |  Branch (191:13): [True: 5.51k, False: 14.4k]
  ------------------
  192|  5.51k|            if ((c != '.') || (decPt >= 0)) {
  ------------------
  |  Branch (192:17): [True: 4.21k, False: 1.29k]
  |  Branch (192:31): [True: 205, False: 1.09k]
  ------------------
  193|  4.41k|                break;
  194|  4.41k|            }
  195|  1.09k|            decPt = mantSize;
  196|  1.09k|        }
  197|  15.5k|        p += 1;
  198|  15.5k|    }
  199|       |
  200|       |    /*
  201|       |     * Now suck up the digits in the mantissa.  Use two integers to
  202|       |     * collect 9 digits each (this is faster than using floating-point).
  203|       |     * If the mantissa has more than 18 digits, ignore the extras, since
  204|       |     * they can't affect the value anyway.
  205|       |     */
  206|       |
  207|  4.41k|    pExp  = p;
  208|  4.41k|    p -= mantSize;
  209|  4.41k|    if (decPt < 0) {
  ------------------
  |  Branch (209:9): [True: 3.32k, False: 1.09k]
  ------------------
  210|  3.32k|        decPt = mantSize;
  211|  3.32k|    } else {
  212|  1.09k|        mantSize -= 1;                  // One of the digits was the point.
  213|  1.09k|    }
  214|  4.41k|    if (mantSize > 18) {
  ------------------
  |  Branch (214:9): [True: 209, False: 4.21k]
  ------------------
  215|    209|        fracExp = decPt - 18;
  216|    209|        mantSize = 18;
  217|  4.21k|    } else {
  218|  4.21k|        fracExp = decPt - mantSize;
  219|  4.21k|    }
  220|  4.41k|    if (mantSize == 0) {
  ------------------
  |  Branch (220:9): [True: 996, False: 3.42k]
  ------------------
  221|    996|        fraction = 0.0;
  222|       |        // p = string;
  223|    996|        goto done;
  224|  3.42k|    } else {
  225|  3.42k|        int frac1, frac2;
  226|       |
  227|  3.42k|        frac1 = 0;
  228|  6.46k|        for ( ; mantSize > 9; mantSize -= 1) {
  ------------------
  |  Branch (228:17): [True: 3.03k, False: 3.42k]
  ------------------
  229|  3.03k|            c = *p;
  230|  3.03k|            p += 1;
  231|  3.03k|            if ('.' == c) {
  ------------------
  |  Branch (231:17): [True: 274, False: 2.76k]
  ------------------
  232|    274|                c = *p;
  233|    274|                p += 1;
  234|    274|            }
  235|  3.03k|            frac1 = 10*frac1 + (c - '0');
  236|  3.03k|        }
  237|  3.42k|        frac2 = 0;
  238|  13.1k|        for (; mantSize > 0; mantSize -= 1) {
  ------------------
  |  Branch (238:16): [True: 9.77k, False: 3.42k]
  ------------------
  239|  9.77k|            c = *p;
  240|  9.77k|            p += 1;
  241|  9.77k|            if ('.' == c) {
  ------------------
  |  Branch (241:17): [True: 220, False: 9.55k]
  ------------------
  242|    220|                c = *p;
  243|    220|                p += 1;
  244|    220|            }
  245|  9.77k|            frac2 = 10*frac2 + (c - '0');
  246|  9.77k|        }
  247|  3.42k|        fraction = (1.0e9 * frac1) + frac2;
  248|  3.42k|    }
  249|       |
  250|       |    /*
  251|       |     * Skim off the exponent.
  252|       |     */
  253|       |
  254|  3.42k|    p = pExp;
  255|  3.42k|    if (('E' == *p) ||
  ------------------
  |  Branch (255:9): [True: 697, False: 2.72k]
  ------------------
  256|  3.42k|        ('e' == *p)) {
  ------------------
  |  Branch (256:9): [True: 1.19k, False: 1.53k]
  ------------------
  257|  1.89k|        p += 1;
  258|  1.89k|        if ('-' == *p) {
  ------------------
  |  Branch (258:13): [True: 540, False: 1.35k]
  ------------------
  259|    540|            expSign = true;
  260|    540|            p += 1;
  261|  1.35k|        } else {
  262|  1.35k|            if ('+' == *p) {
  ------------------
  |  Branch (262:17): [True: 194, False: 1.15k]
  ------------------
  263|    194|                p += 1;
  264|    194|            }
  265|  1.35k|            expSign = false;
  266|  1.35k|        }
  267|  3.18k|        while (isdigit((int) *p)) {
  268|  3.18k|            exp = exp * 10 + (*p - '0');
  269|  3.18k|            if (1024 < exp) {
  ------------------
  |  Branch (269:17): [True: 408, False: 2.77k]
  ------------------
  270|    408|                if (true == expSign) {
  ------------------
  |  Branch (270:21): [True: 210, False: 198]
  ------------------
  271|       |                    // exponent underflow!
  272|    210|                    return 0.0;
  273|    210|                } // else  exponent overflow!
  274|    198|                return INFINITY;
  275|    408|            }
  276|  2.77k|            p += 1;
  277|  2.77k|        }
  278|  1.89k|    }
  279|  3.01k|    if (expSign) {
  ------------------
  |  Branch (279:9): [True: 330, False: 2.68k]
  ------------------
  280|    330|        exp = fracExp - exp;
  281|  2.68k|    } else {
  282|  2.68k|        exp = fracExp + exp;
  283|  2.68k|    }
  284|       |
  285|       |    /*
  286|       |     * Generate a floating-point number that represents the exponent.
  287|       |     * Do this by processing the exponent one bit at a time to combine
  288|       |     * many powers of 2 of 10. Then combine the exponent with the
  289|       |     * fraction.
  290|       |     */
  291|       |
  292|  3.01k|    if (0 > exp) {
  ------------------
  |  Branch (292:9): [True: 630, False: 2.38k]
  ------------------
  293|    630|        expSign = true;
  294|    630|        exp = -exp;
  295|  2.38k|    } else {
  296|  2.38k|        expSign = false;
  297|  2.38k|    }
  298|  3.01k|    if (exp > maxExponent) {
  ------------------
  |  Branch (298:9): [True: 340, False: 2.67k]
  ------------------
  299|    340|        exp = maxExponent;
  300|    340|        errno = ERANGE;
  301|    340|    }
  302|  3.01k|    dblExp = 1.0;
  303|  8.43k|    for (d = powersOf10; exp != 0; exp >>= 1, d += 1) {
  ------------------
  |  Branch (303:26): [True: 5.42k, False: 3.01k]
  ------------------
  304|  5.42k|        if (exp & 01) {
  ------------------
  |  Branch (304:13): [True: 4.47k, False: 948]
  ------------------
  305|  4.47k|            dblExp *= *d;
  306|  4.47k|        }
  307|  5.42k|    }
  308|  3.01k|    if (expSign) {
  ------------------
  |  Branch (308:9): [True: 630, False: 2.38k]
  ------------------
  309|    630|        fraction /= dblExp;
  310|  2.38k|    } else {
  311|  2.38k|        fraction *= dblExp;
  312|  2.38k|    }
  313|       |
  314|  4.01k|done:
  315|  4.01k|    if (sign) {
  ------------------
  |  Branch (315:9): [True: 407, False: 3.60k]
  ------------------
  316|    407|        return -fraction;
  317|    407|    }
  318|  3.60k|    return fraction;
  319|  4.01k|}
mkgmtime:
  608|  1.93k|{
  609|  1.93k|    int year;
  610|  1.93k|    time_t result;
  611|  1.93k|    static const int cumdays[MONTHSPERYEAR] =
  612|  1.93k|        { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
  613|       |
  614|  1.93k|    year = 1900 + t->tm_year + t->tm_mon / MONTHSPERYEAR;
  ------------------
  |  |  321|  1.93k|#define MONTHSPERYEAR   12      // months per calendar year
  ------------------
  615|  1.93k|    result = (year - 1970) * 365 + cumdays[t->tm_mon % MONTHSPERYEAR];
  ------------------
  |  |  321|  1.93k|#define MONTHSPERYEAR   12      // months per calendar year
  ------------------
  616|  1.93k|    result += (year - 1968) / 4;
  617|  1.93k|    result -= (year - 1900) / 100;
  618|  1.93k|    result += (year - 1600) / 400;
  619|  1.93k|    if (0 == (year % 4) &&
  ------------------
  |  Branch (619:9): [True: 1.28k, False: 652]
  ------------------
  620|  1.93k|        (0 != (year % 100) ||
  ------------------
  |  Branch (620:10): [True: 291, False: 992]
  ------------------
  621|  1.28k|         0 == (year % 400)) &&
  ------------------
  |  Branch (621:10): [True: 590, False: 402]
  ------------------
  622|  1.93k|        (2 > (t->tm_mon % MONTHSPERYEAR))) {
  ------------------
  |  |  321|    881|#define MONTHSPERYEAR   12      // months per calendar year
  ------------------
  |  Branch (622:9): [True: 485, False: 396]
  ------------------
  623|    485|        result--;
  624|    485|    }
  625|  1.93k|    result += t->tm_mday - 1;
  626|  1.93k|    result *= 24;
  627|  1.93k|    result += t->tm_hour;
  628|  1.93k|    result *= 60;
  629|  1.93k|    result += t->tm_min;
  630|  1.93k|    result *= 60;
  631|  1.93k|    result += t->tm_sec;
  632|       |    /* this is UTC, no DST
  633|       |     * if (t->tm_isdst == 1)
  634|       |     * result -= 3600;
  635|       |     */
  636|  1.93k|    return (result);
  637|  1.93k|}
iso8601_to_timespec:
  641|  1.93k|{
  642|  1.93k|    timespec_t ret;
  643|       |
  644|  1.93k|#ifndef __clang_analyzer__
  645|       |#ifdef USE_QT
  646|       |    double usec = 0;
  647|       |
  648|       |    QString t(isotime);
  649|       |    QDateTime d = QDateTime::fromString(isotime, Qt::ISODate);
  650|       |    QStringList sl = t.split(".");
  651|       |    if (1 < sl.size()) {
  652|       |        usec = sl[1].toInt() / pow(10., (double)sl[1].size());
  653|       |    }
  654|       |    ret.tv_sec = d.toTime_t();
  655|       |    ret.tv_nsec = usec * 1e9;
  656|       |#else  // USE_QT
  657|  1.93k|    double usec = 0;
  658|  1.93k|    struct tm tm;
  659|       |
  660|  1.93k|    memset(&tm,0,sizeof(tm));
  661|       |
  662|  1.93k|#ifdef HAVE_STRPTIME
  663|  1.93k|    {
  664|  1.93k|        char *dp = NULL;
  665|  1.93k|        dp = strptime(isotime, "%Y-%m-%dT%H:%M:%S", &tm);
  666|  1.93k|        if (NULL != dp &&
  ------------------
  |  Branch (666:13): [True: 606, False: 1.32k]
  ------------------
  667|  1.93k|            '.' == *dp) {
  ------------------
  |  Branch (667:13): [True: 194, False: 412]
  ------------------
  668|    194|            usec = strtod(dp, NULL);
  669|    194|        }
  670|  1.93k|    }
  671|       |#else
  672|       |    /* Fallback for systems without strptime (i.e. Windows)
  673|       |     * This is a simplistic conversion for iso8601 strings only,
  674|       |     * rather than embedding a full copy of strptime() that handles
  675|       |     * all formats.
  676|       |     * Thus avoiding needing to test for (broken) negative date/time
  677|       |     * numbers in token reading - only need to check the upper range */
  678|       |    bool failed = false;
  679|       |    char *isotime_tokenizer = strdup(isotime);
  680|       |    if (isotime_tokenizer) {
  681|       |        char *tmpbuf;
  682|       |        char *pch = strtok_r(isotime_tokenizer, "-T:", &tmpbuf);
  683|       |        int token_number = 0;
  684|       |
  685|       |        while (NULL != pch) {
  686|       |            double sec;
  687|       |            unsigned int tmp;
  688|       |
  689|       |            token_number++;
  690|       |            // Give up if encountered way too many tokens.
  691|       |            if (10 < token_number) {
  692|       |                failed = true;
  693|       |                break;
  694|       |            }
  695|       |            switch (token_number) {
  696|       |            case 1:  // Year token
  697|       |                tmp = atoi(pch);
  698|       |                if (9999 > tmp) {
  699|       |                    tm.tm_year = tmp - 1900; // Adjust to tm year
  700|       |                } else {
  701|       |                    failed = true;
  702|       |                }
  703|       |                break;
  704|       |            case 2: // Month token
  705|       |                tmp = atoi(pch);
  706|       |                if (13 > tmp) {
  707|       |                    tm.tm_mon = tmp - 1;  // Month indexing starts from zero
  708|       |                } else {
  709|       |                    failed = true;
  710|       |                }
  711|       |                break;
  712|       |            case 3: // Day token
  713|       |                tmp = atoi(pch);
  714|       |                if (32 > tmp) {
  715|       |                    tm.tm_mday = tmp;
  716|       |                } else {
  717|       |                    failed = true;
  718|       |                }
  719|       |                break;
  720|       |            case 4:  // Hour token
  721|       |                tmp = atoi(pch);
  722|       |                if (24 > tmp) {
  723|       |                    tm.tm_hour = tmp;
  724|       |                } else {
  725|       |                    failed = true;
  726|       |                }
  727|       |                break;
  728|       |            case 5:  // Minute token
  729|       |                tmp = atoi(pch);
  730|       |                if (60 > tmp) {
  731|       |                    tm.tm_min = tmp;
  732|       |                } else {
  733|       |                    failed = true;
  734|       |                }
  735|       |                break;
  736|       |            case 6:  // Seconds token
  737|       |                sec = safe_atof(pch);
  738|       |                // NB To handle timestamps with leap seconds
  739|       |                if (0 == isfinite(sec) &&
  740|       |                    0.0 <= sec &&
  741|       |                    61.5 > sec) {
  742|       |                    // Truncate to get integer value
  743|       |                    tm.tm_sec = (unsigned int)sec;
  744|       |                    // Get the fractional part (if any)
  745|       |                    usec = sec - (unsigned int)sec;
  746|       |                } else {
  747|       |                    failed = true;
  748|       |                }
  749|       |                break;
  750|       |            default:
  751|       |                break;
  752|       |            }
  753|       |            pch = strtok_r(NULL, "-T:", &tmpbuf);
  754|       |        }
  755|       |        free(isotime_tokenizer);
  756|       |        /* Split may result in more than 6 tokens if the TZ has any t's
  757|       |         * in it.  So check that we've seen enough tokens rather than
  758|       |         * an exact number */
  759|       |        if (6 > token_number) {
  760|       |              failed = true;
  761|       |        }
  762|       |    }
  763|       |    if (failed) {
  764|       |        memset(&tm,0,sizeof(tm));
  765|       |    } else {
  766|       |        /* When successful this normalizes tm so that tm_yday is set
  767|       |         * and thus tm is valid for use with other functions */
  768|       |        if ((time_t)-1 == mktime(&tm)) {
  769|       |            // Failed mktime - so reset the timestamp
  770|       |            memset(&tm,0,sizeof(tm));
  771|       |        }
  772|       |    }
  773|       |#endif
  774|       |    /*
  775|       |     * It would be nice if we could say mktime(&tm) - timezone + usec instead,
  776|       |     * but timezone is not available at all on some BSDs. Besides, when working
  777|       |     * with historical dates the value of timezone after an ordinary tzset(3)
  778|       |     * can be wrong; you have to do a redirect through the IANA historical
  779|       |     * timezone database to get it right.
  780|       |     */
  781|  1.93k|    ret.tv_sec = mkgmtime(&tm);
  782|  1.93k|    ret.tv_nsec = usec * 1e9;
  783|  1.93k|#endif  // USE_QT
  784|  1.93k|#endif  // __clang_analyzer__
  785|       |
  786|  1.93k|#if 4 < SIZEOF_TIME_T
  787|  1.93k|    if (253402300799LL < ret.tv_sec) {
  ------------------
  |  Branch (787:9): [True: 194, False: 1.74k]
  ------------------
  788|       |        // enforce max "9999-12-31T23:59:59.999Z"
  789|    194|        ret.tv_sec = 253402300799LL;
  790|    194|    }
  791|  1.93k|#endif
  792|  1.93k|    return ret;
  793|  1.93k|}

gps_hexpack:
  119|    118|{
  120|    118|    ssize_t i, j;
  121|       |
  122|    118|    j = strnlen(src, BUFSIZ) / 2;
  123|    118|    if ((1 > j) ||
  ------------------
  |  Branch (123:9): [True: 2, False: 116]
  ------------------
  124|    118|        ((size_t)j > len)) {
  ------------------
  |  Branch (124:9): [True: 11, False: 105]
  ------------------
  125|     13|        return -2;
  126|     13|    }
  127|       |
  128|    416|    for (i = 0; i < j; i++) {
  ------------------
  |  Branch (128:17): [True: 376, False: 40]
  ------------------
  129|    376|        int k;
  130|    376|        if (-1 == (k = hex2bin(src + i * 2))) {
  ------------------
  |  Branch (130:13): [True: 65, False: 311]
  ------------------
  131|     65|            return -1;
  132|     65|        }
  133|    311|        dst[i] = (char)(k & 0xff);
  134|    311|    }
  135|     40|    (void)memset(dst + i, '\0', (size_t)(len - i));
  136|     40|    return j;
  137|    105|}
hex.c:hex2bin:
   82|    376|{
   83|    376|    int a, b;
   84|       |
   85|    376|    a = s[0] & 0xff;
   86|    376|    b = s[1] & 0xff;
   87|       |
   88|    376|    if ((a >= 'a') &&
  ------------------
  |  Branch (88:9): [True: 108, False: 268]
  ------------------
   89|    376|        (a <= 'f')) {
  ------------------
  |  Branch (89:9): [True: 97, False: 11]
  ------------------
   90|     97|        a = a + 10 - 'a';
   91|    279|    } else if ((a >= 'A') &&
  ------------------
  |  Branch (91:16): [True: 95, False: 184]
  ------------------
   92|    279|               (a <= 'F')) {
  ------------------
  |  Branch (92:16): [True: 77, False: 18]
  ------------------
   93|     77|        a = a + 10 - 'A';
   94|    202|    } else if ((a >= '0') &&
  ------------------
  |  Branch (94:16): [True: 191, False: 11]
  ------------------
   95|    202|               (a <= '9')) {
  ------------------
  |  Branch (95:16): [True: 167, False: 24]
  ------------------
   96|    167|        a -= '0';
   97|    167|    } else {
   98|     35|        return -1;
   99|     35|    }
  100|       |
  101|    341|    if ((b >= 'a') &&
  ------------------
  |  Branch (101:9): [True: 96, False: 245]
  ------------------
  102|    341|        (b <= 'f')) {
  ------------------
  |  Branch (102:9): [True: 86, False: 10]
  ------------------
  103|     86|        b = b + 10 - 'a';
  104|    255|    } else if ((b >= 'A') &&
  ------------------
  |  Branch (104:16): [True: 88, False: 167]
  ------------------
  105|    255|               (b <= 'F')) {
  ------------------
  |  Branch (105:16): [True: 71, False: 17]
  ------------------
  106|     71|        b = b + 10 - 'A';
  107|    184|    } else if ((b >= '0') &&
  ------------------
  |  Branch (107:16): [True: 179, False: 5]
  ------------------
  108|    184|               (b <= '9')) {
  ------------------
  |  Branch (108:16): [True: 154, False: 25]
  ------------------
  109|    154|        b -= '0';
  110|    154|    } else {
  111|     30|        return -1;
  112|     30|    }
  113|       |
  114|    311|    return ((a << 4) + b);
  115|    341|}

json_read_array:
  746|  1.28k|{
  747|  1.28k|    int substatus, offset, arrcount;
  748|  1.28k|    char *tp;
  749|       |
  750|  1.28k|    if (NULL != end)
  ------------------
  |  Branch (750:9): [True: 1.28k, False: 0]
  ------------------
  751|  1.28k|        *end = NULL;    // give it a well-defined value on parse failure
  752|       |
  753|  1.28k|    json_debug_trace((1, "Entered json_read_array()\n"));
  ------------------
  |  |  110|  1.28k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  754|       |
  755|  1.28k|    while (isspace((unsigned char)*cp)) {
  756|      0|        cp++;
  757|      0|    }
  758|  1.28k|    if (*cp != '[') {
  ------------------
  |  Branch (758:9): [True: 0, False: 1.28k]
  ------------------
  759|      0|        json_debug_trace((1, "Didn't find expected array start\n"));
  ------------------
  |  |  110|      0|#define json_debug_trace(args) (void) json_trace args
  ------------------
  760|      0|        return JSON_ERR_ARRAYSTART;
  ------------------
  |  |  161|      0|#define JSON_ERR_ARRAYSTART     10      // didn't find expected array start
  ------------------
  761|      0|    }
  762|  1.28k|    cp++;
  763|       |
  764|  1.28k|    tp = arr->arr.strings.store;
  765|  1.28k|    arrcount = 0;
  766|       |
  767|       |    // Check for empty array
  768|  1.28k|    while (isspace((unsigned char)*cp)) {
  769|    410|        cp++;
  770|    410|    }
  771|  1.28k|    if (*cp == ']') {
  ------------------
  |  Branch (771:9): [True: 504, False: 785]
  ------------------
  772|    504|        goto breakout;
  773|    504|    }
  774|       |
  775|  7.44k|    for (offset = 0; offset < arr->maxlen; offset++) {
  ------------------
  |  Branch (775:22): [True: 7.44k, False: 1]
  ------------------
  776|  7.44k|        char *ep = NULL;
  777|       |
  778|  7.44k|        json_debug_trace((1, "Looking at %s\n", cp));
  ------------------
  |  |  110|  7.44k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  779|  7.44k|        switch (arr->element_type) {
  ------------------
  |  Branch (779:17): [True: 0, False: 7.44k]
  ------------------
  780|  3.06k|        case t_string:
  ------------------
  |  Branch (780:9): [True: 3.06k, False: 4.38k]
  ------------------
  781|  3.06k|            if (isspace((unsigned char) *cp)) {
  782|    194|                cp++;
  783|    194|            }
  784|  3.06k|            if (*cp != '"') {
  ------------------
  |  Branch (784:17): [True: 17, False: 3.04k]
  ------------------
  785|     17|                return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|     17|#define JSON_ERR_BADSTRING      15      // error while string parsing
  ------------------
  786|  3.04k|            } else {
  787|  3.04k|                ++cp;
  788|  3.04k|            }
  789|  3.04k|            arr->arr.strings.ptrs[offset] = tp;
  790|  13.9k|            for (; tp - arr->arr.strings.store < arr->arr.strings.storelen;
  ------------------
  |  Branch (790:20): [True: 13.9k, False: 3]
  ------------------
  791|  10.8k|                 tp++)
  792|  13.9k|                if (*cp == '"') {
  ------------------
  |  Branch (792:21): [True: 3.04k, False: 10.8k]
  ------------------
  793|  3.04k|                    ++cp;
  794|  3.04k|                    *tp++ = '\0';
  795|  3.04k|                    goto stringend;
  796|  10.8k|                } else if (*cp == '\0') {
  ------------------
  |  Branch (796:28): [True: 1, False: 10.8k]
  ------------------
  797|      1|                    json_debug_trace((1,
  ------------------
  |  |  110|      1|#define json_debug_trace(args) (void) json_trace args
  ------------------
  798|      1|                                      "Bad string syntax in string list.\n"));
  799|      1|                    return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|      1|#define JSON_ERR_BADSTRING      15      // error while string parsing
  ------------------
  800|  10.8k|                } else {
  801|  10.8k|                    *tp = *cp++;
  802|  10.8k|                }
  803|      3|            json_debug_trace((1, "Bad string syntax in string list.\n"));
  ------------------
  |  |  110|      3|#define json_debug_trace(args) (void) json_trace args
  ------------------
  804|      3|            return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|      3|#define JSON_ERR_BADSTRING      15      // error while string parsing
  ------------------
  805|  3.04k|          stringend:
  806|  3.04k|            break;
  807|      0|        case t_object:
  ------------------
  |  Branch (807:9): [True: 0, False: 7.44k]
  ------------------
  808|      0|            FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  809|  4.38k|        case t_structobject:
  ------------------
  |  Branch (809:9): [True: 4.38k, False: 3.06k]
  ------------------
  810|  4.38k|            substatus =
  811|  4.38k|                json_internal_read_object(cp, arr->arr.objects.subtype, arr,
  812|  4.38k|                                          offset, &cp);
  813|  4.38k|            if (substatus != 0) {
  ------------------
  |  Branch (813:17): [True: 110, False: 4.27k]
  ------------------
  814|    110|                if (NULL != end) {
  ------------------
  |  Branch (814:21): [True: 110, False: 0]
  ------------------
  815|    110|                    *end = cp;
  816|    110|                }
  817|    110|                return substatus;
  818|    110|            }
  819|  4.27k|            break;
  820|  4.27k|        case t_integer:
  ------------------
  |  Branch (820:9): [True: 0, False: 7.44k]
  ------------------
  821|      0|            arr->arr.integers.store[offset] = (int)strtol(cp, &ep, 0);
  822|      0|            if (ep == cp) {
  ------------------
  |  Branch (822:17): [True: 0, False: 0]
  ------------------
  823|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  824|      0|            }
  825|      0|            cp = ep;
  826|      0|            break;
  827|      0|        case t_uinteger:
  ------------------
  |  Branch (827:9): [True: 0, False: 7.44k]
  ------------------
  828|      0|            arr->arr.uintegers.store[offset] = (unsigned int)strtoul(cp,
  829|      0|                                                                     &ep, 0);
  830|      0|            if (ep == cp) {
  ------------------
  |  Branch (830:17): [True: 0, False: 0]
  ------------------
  831|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  832|      0|            }
  833|      0|            cp = ep;
  834|      0|            break;
  835|      0|        case t_longint:
  ------------------
  |  Branch (835:9): [True: 0, False: 7.44k]
  ------------------
  836|      0|            arr->arr.longint.store[offset] = strtol(cp, &ep, 0);
  837|      0|            if (ep == cp) {
  ------------------
  |  Branch (837:17): [True: 0, False: 0]
  ------------------
  838|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  839|      0|            }
  840|      0|            cp = ep;
  841|      0|            break;
  842|      0|        case t_ulongint:
  ------------------
  |  Branch (842:9): [True: 0, False: 7.44k]
  ------------------
  843|      0|            arr->arr.ulongint.store[offset] = strtoul(cp, &ep, 0);
  844|      0|            if (ep == cp) {
  ------------------
  |  Branch (844:17): [True: 0, False: 0]
  ------------------
  845|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  846|      0|            }
  847|      0|            cp = ep;
  848|      0|            break;
  849|      0|        case t_byte:
  ------------------
  |  Branch (849:9): [True: 0, False: 7.44k]
  ------------------
  850|      0|            arr->arr.bytes.store[offset] = (char)strtol(cp, &ep, 0);
  851|      0|            if (ep == cp) {
  ------------------
  |  Branch (851:17): [True: 0, False: 0]
  ------------------
  852|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  853|      0|            }
  854|      0|            cp = ep;
  855|      0|            break;
  856|      0|        case t_ubyte:
  ------------------
  |  Branch (856:9): [True: 0, False: 7.44k]
  ------------------
  857|      0|            arr->arr.ubytes.store[offset] = (unsigned char)strtoul(cp,
  858|      0|                                                                   &ep, 0);
  859|      0|            if (ep == cp) {
  ------------------
  |  Branch (859:17): [True: 0, False: 0]
  ------------------
  860|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  861|      0|            }
  862|      0|            cp = ep;
  863|      0|            break;
  864|      0|        case t_short:
  ------------------
  |  Branch (864:9): [True: 0, False: 7.44k]
  ------------------
  865|      0|            arr->arr.shorts.store[offset] = (short)strtol(cp, &ep, 0);
  866|      0|            if (ep == cp) {
  ------------------
  |  Branch (866:17): [True: 0, False: 0]
  ------------------
  867|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  868|      0|            }
  869|      0|            cp = ep;
  870|      0|            break;
  871|      0|        case t_ushort:
  ------------------
  |  Branch (871:9): [True: 0, False: 7.44k]
  ------------------
  872|      0|            arr->arr.ushorts.store[offset] = (unsigned short)strtoul(cp,
  873|      0|                                                                     &ep, 0);
  874|      0|            if (ep == cp) {
  ------------------
  |  Branch (874:17): [True: 0, False: 0]
  ------------------
  875|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  876|      0|            }
  877|      0|            cp = ep;
  878|      0|            break;
  879|      0|        case t_time:
  ------------------
  |  Branch (879:9): [True: 0, False: 7.44k]
  ------------------
  880|      0|            {
  881|      0|                timespec_t ts_tmp;
  882|      0|                if (*cp != '"') {
  ------------------
  |  Branch (882:21): [True: 0, False: 0]
  ------------------
  883|      0|                    return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|      0|#define JSON_ERR_BADSTRING      15      // error while string parsing
  ------------------
  884|      0|                } else {
  885|      0|                    ++cp;
  886|      0|                }
  887|      0|                ts_tmp = iso8601_to_timespec(cp);
  888|      0|                arr->arr.timespecs.store[offset] = ts_tmp;
  889|      0|                while (*cp &&
  ------------------
  |  Branch (889:24): [True: 0, False: 0]
  ------------------
  890|      0|                       *cp != '"') {
  ------------------
  |  Branch (890:24): [True: 0, False: 0]
  ------------------
  891|      0|                    cp++;
  892|      0|                }
  893|      0|                if (*cp != '"') {
  ------------------
  |  Branch (893:21): [True: 0, False: 0]
  ------------------
  894|      0|                    return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|      0|#define JSON_ERR_BADSTRING      15      // error while string parsing
  ------------------
  895|      0|                }
  896|      0|                ++cp;
  897|      0|            }
  898|      0|            break;
  899|      0|        case t_timespec:
  ------------------
  |  Branch (899:9): [True: 0, False: 7.44k]
  ------------------
  900|       |            // TODO not sure how to implement this
  901|      0|            return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  902|      0|            break;
  903|      0|        case t_real:
  ------------------
  |  Branch (903:9): [True: 0, False: 7.44k]
  ------------------
  904|      0|            arr->arr.reals.store[offset] = strtod(cp, &ep);
  905|      0|            if (ep == cp) {
  ------------------
  |  Branch (905:17): [True: 0, False: 0]
  ------------------
  906|      0|                return JSON_ERR_BADNUM;
  ------------------
  |  |  173|      0|#define JSON_ERR_BADNUM         22      // error while parsing a numerical argument
  ------------------
  907|      0|            }
  908|      0|            cp = ep;
  909|      0|            break;
  910|      0|        case t_boolean:
  ------------------
  |  Branch (910:9): [True: 0, False: 7.44k]
  ------------------
  911|      0|            if (str_starts_with(cp, "true")) {
  ------------------
  |  Branch (911:17): [True: 0, False: 0]
  ------------------
  912|      0|                arr->arr.booleans.store[offset] = true;
  913|      0|                cp += 4;
  914|      0|            } else if (str_starts_with(cp, "false")) {
  ------------------
  |  Branch (914:24): [True: 0, False: 0]
  ------------------
  915|      0|                arr->arr.booleans.store[offset] = false;
  916|      0|                cp += 5;
  917|      0|            }
  918|      0|            break;
  919|      0|        case t_character:
  ------------------
  |  Branch (919:9): [True: 0, False: 7.44k]
  ------------------
  920|      0|            FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  921|      0|        case t_array:
  ------------------
  |  Branch (921:9): [True: 0, False: 7.44k]
  ------------------
  922|      0|            FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  923|      0|        case t_check:
  ------------------
  |  Branch (923:9): [True: 0, False: 7.44k]
  ------------------
  924|      0|            FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  925|      0|        case t_ignore:
  ------------------
  |  Branch (925:9): [True: 0, False: 7.44k]
  ------------------
  926|      0|            json_debug_trace((1, "Invalid array subtype.\n"));
  ------------------
  |  |  110|      0|#define json_debug_trace(args) (void) json_trace args
  ------------------
  927|      0|            return JSON_ERR_SUBTYPE;
  ------------------
  |  |  165|      0|#define JSON_ERR_SUBTYPE        14      // unsupported array element type
  ------------------
  928|  7.44k|        }
  929|  7.31k|        arrcount++;
  930|  7.31k|        if (isspace((unsigned char)*cp)) {
  931|    194|            cp++;
  932|    194|        }
  933|  7.31k|        if (*cp == ']') {
  ------------------
  |  Branch (933:13): [True: 483, False: 6.83k]
  ------------------
  934|    483|            json_debug_trace((1, "End of array found.\n"));
  ------------------
  |  |  110|    483|#define json_debug_trace(args) (void) json_trace args
  ------------------
  935|    483|            goto breakout;
  936|    483|        }
  937|  6.83k|        if (*cp == ',') {
  ------------------
  |  Branch (937:13): [True: 6.66k, False: 170]
  ------------------
  938|  6.66k|            cp++;
  939|  6.66k|        } else {
  940|    170|            json_debug_trace((1, "Bad trailing syntax on array.\n"));
  ------------------
  |  |  110|    170|#define json_debug_trace(args) (void) json_trace args
  ------------------
  941|    170|            return JSON_ERR_BADSUBTRAIL;
  ------------------
  |  |  164|    170|#define JSON_ERR_BADSUBTRAIL    13      // garbage while expecting array comma
  ------------------
  942|    170|        }
  943|  6.83k|    }
  944|      1|    json_debug_trace((1, "Too many elements in array.\n"));
  ------------------
  |  |  110|      1|#define json_debug_trace(args) (void) json_trace args
  ------------------
  945|      1|    if (NULL != end) {
  ------------------
  |  Branch (945:9): [True: 1, False: 0]
  ------------------
  946|      1|        *end = cp;
  947|      1|    }
  948|      1|    return JSON_ERR_SUBTOOLONG;
  ------------------
  |  |  163|      1|#define JSON_ERR_SUBTOOLONG     12      // too many array elements
  ------------------
  949|    987|  breakout:
  950|    987|    if (NULL != arr->count) {
  ------------------
  |  Branch (950:9): [True: 987, False: 0]
  ------------------
  951|    987|        *(arr->count) = arrcount;
  952|    987|    }
  953|    987|    if (NULL != end) {
  ------------------
  |  Branch (953:9): [True: 987, False: 0]
  ------------------
  954|    987|        *end = cp;
  955|    987|    }
  956|    987|    json_debug_trace((1, "leaving json_read_array() with %d elements\n",
  ------------------
  |  |  110|    987|#define json_debug_trace(args) (void) json_trace args
  ------------------
  957|    987|                      arrcount));
  958|    987|    return 0;
  959|    785|}
json_read_object:
  963|  4.85k|{
  964|  4.85k|    int st;
  965|       |
  966|  4.85k|    json_debug_trace((1, "json_read_object() sees '%s'\n", cp));
  ------------------
  |  |  110|  4.85k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  967|  4.85k|    st = json_internal_read_object(cp, attrs, NULL, 0, end);
  968|  4.85k|    return st;
  969|  4.85k|}
json.c:json_trace:
   95|  1.07M|{
   96|  1.07M|    if (errlevel <= debuglevel &&
  ------------------
  |  Branch (96:9): [True: 0, False: 1.07M]
  ------------------
   97|  1.07M|        NULL != debugfp) {
  ------------------
  |  Branch (97:9): [True: 0, False: 0]
  ------------------
   98|      0|        char buf[BUFSIZ] = {0};
   99|      0|        va_list ap;
  100|       |
  101|      0|        (void)strlcpy(buf, "json: ", sizeof(buf));
  102|      0|        va_start(ap, fmt);
  103|      0|        str_vappendf(buf, sizeof(buf), fmt, ap);
  104|      0|        va_end(ap);
  105|       |
  106|      0|        (void)fputs(buf, debugfp);
  107|      0|    }
  108|  1.07M|}
json.c:json_internal_read_object:
  187|  9.23k|{
  188|  9.23k|    enum
  189|  9.23k|    { init, await_attr, in_attr, await_value, in_val_string,
  190|  9.23k|        in_escape, in_val_token, post_val, post_element
  191|  9.23k|    } state = 0;
  192|  9.23k|    char *statenames[] = {
  193|  9.23k|        "init", "await_attr", "in_attr", "await_value", "in_val_string",
  194|  9.23k|        "in_escape", "in_val_token", "post_val", "post_element",
  195|  9.23k|    };
  196|  9.23k|    char attrbuf[JSON_ATTR_MAX + 1], *pattr = NULL;
  197|  9.23k|    char valbuf[JSON_VAL_MAX + 1], *pval = NULL;
  198|  9.23k|    bool value_quoted = false;
  199|  9.23k|    char uescape[5];            // enough space for 4 hex digits and a NUL
  200|  9.23k|    const struct json_attr_t *cursor;
  201|  9.23k|    int substatus, maxlen = 0;
  202|  9.23k|    unsigned int u;
  203|  9.23k|    const struct json_enum_t *mp;
  204|  9.23k|    char *lptr;
  205|       |
  206|  9.23k|    if (NULL != end) {
  ------------------
  |  Branch (206:9): [True: 4.38k, False: 4.85k]
  ------------------
  207|  4.38k|        *end = NULL;    // give it a well-defined value on parse failure
  208|  4.38k|    }
  209|       |
  210|       |    // stuff fields with defaults in case they're omitted in the JSON input
  211|   137k|    for (cursor = attrs; cursor->attribute != NULL; cursor++)
  ------------------
  |  Branch (211:26): [True: 128k, False: 9.23k]
  ------------------
  212|   128k|        if (!cursor->nodefault) {
  ------------------
  |  Branch (212:13): [True: 128k, False: 156]
  ------------------
  213|   128k|            lptr = json_target_address(cursor, parent, offset);
  214|   128k|            if (NULL != lptr)
  ------------------
  |  Branch (214:17): [True: 118k, False: 9.69k]
  ------------------
  215|   118k|                switch (cursor->type) {
  ------------------
  |  Branch (215:25): [True: 0, False: 118k]
  ------------------
  216|  2.34k|                case t_byte:
  ------------------
  |  Branch (216:17): [True: 2.34k, False: 116k]
  ------------------
  217|  2.34k|                    lptr[0] = cursor->dflt.byte;
  218|  2.34k|                    break;
  219|  18.4k|                case t_ubyte:
  ------------------
  |  Branch (219:17): [True: 18.4k, False: 100k]
  ------------------
  220|  18.4k|                    lptr[0] = cursor->dflt.ubyte;
  221|  18.4k|                    break;
  222|  16.4k|                case t_integer:
  ------------------
  |  Branch (222:17): [True: 16.4k, False: 102k]
  ------------------
  223|  16.4k|                    memcpy(lptr, &cursor->dflt.integer, sizeof(int));
  224|  16.4k|                    break;
  225|  7.92k|                case t_uinteger:
  ------------------
  |  Branch (225:17): [True: 7.92k, False: 110k]
  ------------------
  226|  7.92k|                    memcpy(lptr, &cursor->dflt.uinteger, sizeof(unsigned int));
  227|  7.92k|                    break;
  228|      0|                case t_longint:
  ------------------
  |  Branch (228:17): [True: 0, False: 118k]
  ------------------
  229|      0|                    memcpy(lptr, &cursor->dflt.longint, sizeof(long));
  230|      0|                    break;
  231|    122|                case t_ulongint:
  ------------------
  |  Branch (231:17): [True: 122, False: 118k]
  ------------------
  232|    122|                    memcpy(lptr, &cursor->dflt.ulongint,
  233|    122|                           sizeof(unsigned long));
  234|    122|                    break;
  235|  2.34k|                case t_short:
  ------------------
  |  Branch (235:17): [True: 2.34k, False: 116k]
  ------------------
  236|  2.34k|                    memcpy(lptr, &cursor->dflt.shortint, sizeof(short));
  237|  2.34k|                    break;
  238|      0|                case t_ushort:
  ------------------
  |  Branch (238:17): [True: 0, False: 118k]
  ------------------
  239|      0|                    memcpy(lptr, &cursor->dflt.ushortint,
  240|      0|                           sizeof(unsigned short));
  241|      0|                    break;
  242|  1.47k|                case t_time:
  ------------------
  |  Branch (242:17): [True: 1.47k, False: 117k]
  ------------------
  243|  1.47k|                    memcpy(lptr, &cursor->dflt.ts, sizeof(timespec_t));
  244|  1.47k|                    break;
  245|  1.04k|                case t_timespec:
  ------------------
  |  Branch (245:17): [True: 1.04k, False: 117k]
  ------------------
  246|  1.04k|                    memcpy(lptr, &cursor->dflt.ts, sizeof(timespec_t));
  247|  1.04k|                    break;
  248|  48.1k|                case t_real:
  ------------------
  |  Branch (248:17): [True: 48.1k, False: 70.3k]
  ------------------
  249|  48.1k|                    memcpy(lptr, &cursor->dflt.real, sizeof(double));
  250|  48.1k|                    break;
  251|  10.8k|                case t_string:
  ------------------
  |  Branch (251:17): [True: 10.8k, False: 107k]
  ------------------
  252|  10.8k|                    if (parent != NULL
  ------------------
  |  Branch (252:25): [True: 4.62k, False: 6.17k]
  ------------------
  253|  10.8k|                        && parent->element_type != t_structobject
  ------------------
  |  Branch (253:28): [True: 0, False: 4.62k]
  ------------------
  254|  10.8k|                        && offset > 0)
  ------------------
  |  Branch (254:28): [True: 0, False: 0]
  ------------------
  255|      0|                        return JSON_ERR_NOPARSTR;
  ------------------
  |  |  168|      0|#define JSON_ERR_NOPARSTR       17      // can't support strings in parallel arrays
  ------------------
  256|  10.8k|                    lptr[0] = '\0';
  257|  10.8k|                    break;
  258|  3.47k|                case t_boolean:
  ------------------
  |  Branch (258:17): [True: 3.47k, False: 115k]
  ------------------
  259|  3.47k|                    memcpy(lptr, &cursor->dflt.boolean, sizeof(bool));
  260|  3.47k|                    break;
  261|  1.03k|                case t_character:
  ------------------
  |  Branch (261:17): [True: 1.03k, False: 117k]
  ------------------
  262|  1.03k|                    lptr[0] = cursor->dflt.character;
  263|  1.03k|                    break;
  264|      0|                case t_object:  // silences a compiler warning
  ------------------
  |  Branch (264:17): [True: 0, False: 118k]
  ------------------
  265|      0|                    FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  266|      0|                case t_structobject:
  ------------------
  |  Branch (266:17): [True: 0, False: 118k]
  ------------------
  267|      0|                    FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  268|      0|                case t_array:
  ------------------
  |  Branch (268:17): [True: 0, False: 118k]
  ------------------
  269|      0|                    FALLTHROUGH
  ------------------
  |  |   55|      0|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  270|    520|                case t_check:
  ------------------
  |  Branch (270:17): [True: 520, False: 117k]
  ------------------
  271|    520|                    FALLTHROUGH
  ------------------
  |  |   55|    520|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  272|  4.89k|                case t_ignore:
  ------------------
  |  Branch (272:17): [True: 4.37k, False: 114k]
  ------------------
  273|  4.89k|                    break;
  274|   118k|                }
  275|   128k|        }
  276|       |
  277|  9.23k|    json_debug_trace((1, "JSON parse of '%s' begins.\n", cp));
  ------------------
  |  |  110|  9.23k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  278|       |
  279|       |    // parse input JSON
  280|   422k|    for (; *cp != '\0'; cp++) {
  ------------------
  |  Branch (280:12): [True: 421k, False: 1.92k]
  ------------------
  281|   421k|        json_debug_trace((2, "State %-14s, looking at '%c' (%p)\n",
  ------------------
  |  |  110|   421k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  282|   421k|                          statenames[state], *cp, cp));
  283|   421k|        switch (state) {
  ------------------
  |  Branch (283:17): [True: 0, False: 421k]
  ------------------
  284|  9.38k|        case init:
  ------------------
  |  Branch (284:9): [True: 9.38k, False: 411k]
  ------------------
  285|  9.38k|            if (isspace((unsigned char) *cp)) {
  286|    194|                continue;
  287|    194|            }
  288|  9.18k|            if (*cp == '{') {
  ------------------
  |  Branch (288:17): [True: 9.16k, False: 24]
  ------------------
  289|  9.16k|                state = await_attr;
  290|  9.16k|            } else {
  291|     24|                json_debug_trace((1,
  ------------------
  |  |  110|     24|#define json_debug_trace(args) (void) json_trace args
  ------------------
  292|     24|                                  "Non-WS when expecting object start.\n"));
  293|     24|                if (NULL != end) {
  ------------------
  |  Branch (293:21): [True: 24, False: 0]
  ------------------
  294|     24|                    *end = cp;
  295|     24|                }
  296|     24|                return JSON_ERR_OBSTART;
  ------------------
  |  |  152|     24|#define JSON_ERR_OBSTART         1      // non-WS when expecting object start
  ------------------
  297|     24|            }
  298|  9.16k|            break;
  299|  37.2k|        case await_attr:
  ------------------
  |  Branch (299:9): [True: 37.2k, False: 383k]
  ------------------
  300|  37.2k|            if (isspace((unsigned char) *cp)) {
  301|    196|                continue;
  302|    196|            }
  303|  37.0k|            if (*cp == '"') {
  ------------------
  |  Branch (303:17): [True: 36.7k, False: 356]
  ------------------
  304|  36.7k|                state = in_attr;
  305|  36.7k|                pattr = attrbuf;
  306|  36.7k|                if (NULL != end) {
  ------------------
  |  Branch (306:21): [True: 5.96k, False: 30.7k]
  ------------------
  307|  5.96k|                    *end = cp;
  308|  5.96k|                }
  309|  36.7k|            } else if (*cp == '}') {
  ------------------
  |  Branch (309:24): [True: 201, False: 155]
  ------------------
  310|    201|                break;
  311|    201|            } else {
  312|    155|                json_debug_trace((1, "Non-WS when expecting attribute.\n"));
  ------------------
  |  |  110|    155|#define json_debug_trace(args) (void) json_trace args
  ------------------
  313|    155|                if (NULL != end) {
  ------------------
  |  Branch (313:21): [True: 1, False: 154]
  ------------------
  314|      1|                    *end = cp;
  315|      1|                }
  316|    155|                return JSON_ERR_ATTRSTART;
  ------------------
  |  |  153|    155|#define JSON_ERR_ATTRSTART       2      // non-WS when expecting attrib start
  ------------------
  317|    155|            }
  318|  36.7k|            break;
  319|   148k|        case in_attr:
  ------------------
  |  Branch (319:9): [True: 148k, False: 272k]
  ------------------
  320|   148k|            if (NULL == pattr) {
  ------------------
  |  Branch (320:17): [True: 0, False: 148k]
  ------------------
  321|       |                // don't update end here, leave at attribute start
  322|      0|                return JSON_ERR_NULLPTR;
  ------------------
  |  |  174|      0|#define JSON_ERR_NULLPTR        23      // unexpected null value or attribute pointer
  ------------------
  323|      0|            }
  324|   148k|            if (*cp == '"') {
  ------------------
  |  Branch (324:17): [True: 36.7k, False: 111k]
  ------------------
  325|  36.7k|                *pattr++ = '\0';
  326|  36.7k|                json_debug_trace((1, "Collected attribute name %s\n",
  ------------------
  |  |  110|  36.7k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  327|  36.7k|                                  attrbuf));
  328|   390k|                for (cursor = attrs; cursor->attribute != NULL; cursor++) {
  ------------------
  |  Branch (328:38): [True: 390k, False: 60]
  ------------------
  329|   390k|                    json_debug_trace((2, "Checking against %s\n",
  ------------------
  |  |  110|   390k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  330|   390k|                                      cursor->attribute));
  331|   390k|                    if (strcmp(cursor->attribute, attrbuf) == 0) {
  ------------------
  |  Branch (331:25): [True: 24.8k, False: 365k]
  ------------------
  332|  24.8k|                        break;
  333|  24.8k|                    }
  334|   365k|                    if (cursor->type == t_ignore &&
  ------------------
  |  Branch (334:25): [True: 12.0k, False: 353k]
  ------------------
  335|   365k|                        strncmp(cursor->attribute, "", 1) == 0) {
  ------------------
  |  Branch (335:25): [True: 11.8k, False: 240]
  ------------------
  336|  11.8k|                        break;
  337|  11.8k|                    }
  338|   365k|                }
  339|  36.7k|                if (NULL == cursor->attribute) {
  ------------------
  |  Branch (339:21): [True: 60, False: 36.6k]
  ------------------
  340|     60|                    json_debug_trace((1,
  ------------------
  |  |  110|     60|#define json_debug_trace(args) (void) json_trace args
  ------------------
  341|     60|                                      "Unknown attribute name '%s'"
  342|     60|                                      " (attributes begin with '%s').\n",
  343|     60|                                      attrbuf, attrs->attribute));
  344|       |                    // don't update end here, leave at attribute start
  345|     60|                    return JSON_ERR_BADATTR;
  ------------------
  |  |  154|     60|#define JSON_ERR_BADATTR         3      // unknown attribute name
  ------------------
  346|     60|                }
  347|  36.6k|                state = await_value;
  348|  36.6k|                if (cursor->type == t_string) {
  ------------------
  |  Branch (348:21): [True: 975, False: 35.6k]
  ------------------
  349|    975|                    maxlen = (int)cursor->len - 1;
  350|  35.6k|                } else if (cursor->type == t_check) {
  ------------------
  |  Branch (350:28): [True: 1.54k, False: 34.1k]
  ------------------
  351|  1.54k|                    maxlen = (int)strnlen(cursor->dflt.check, JSON_VAL_MAX);
  ------------------
  |  |  135|  1.54k|#define JSON_VAL_MAX    512     /* max chars in JSON value part */
  ------------------
  352|  34.1k|                } else if (cursor->type == t_time ||
  ------------------
  |  Branch (352:28): [True: 2.14k, False: 31.9k]
  ------------------
  353|  34.1k|                           cursor->type == t_ignore) {
  ------------------
  |  Branch (353:28): [True: 17.7k, False: 14.2k]
  ------------------
  354|  19.9k|                    maxlen = JSON_VAL_MAX;
  ------------------
  |  |  135|  19.9k|#define JSON_VAL_MAX    512     /* max chars in JSON value part */
  ------------------
  355|  19.9k|                } else if (NULL != cursor->map) {
  ------------------
  |  Branch (355:28): [True: 450, False: 13.7k]
  ------------------
  356|    450|                    maxlen = (int)sizeof(valbuf) - 1;
  357|    450|                }
  358|  36.6k|                pval = valbuf;
  359|   111k|            } else if (pattr >= attrbuf + JSON_ATTR_MAX - 1) {
  ------------------
  |  |  134|   111k|#define JSON_ATTR_MAX   31      /* max chars in JSON attribute name */
  ------------------
  |  Branch (359:24): [True: 11, False: 111k]
  ------------------
  360|     11|                json_debug_trace((1, "Attribute name too long.\n"));
  ------------------
  |  |  110|     11|#define json_debug_trace(args) (void) json_trace args
  ------------------
  361|       |                // don't update end here, leave at attribute start
  362|     11|                return JSON_ERR_ATTRLEN;
  ------------------
  |  |  155|     11|#define JSON_ERR_ATTRLEN         4      // attribute name too long
  ------------------
  363|   111k|            } else {
  364|   111k|                *pattr++ = *cp;
  365|   111k|            }
  366|   148k|            break;
  367|   148k|        case await_value:
  ------------------
  |  Branch (367:9): [True: 38.5k, False: 382k]
  ------------------
  368|  38.5k|            if (isspace((unsigned char) *cp) ||
  369|  38.5k|                *cp == ':') {
  ------------------
  |  Branch (369:17): [True: 1.82k, False: 36.5k]
  ------------------
  370|  2.02k|                continue;
  371|  2.02k|            }
  372|  36.5k|            if (*cp == '[') {
  ------------------
  |  Branch (372:17): [True: 1.72k, False: 34.8k]
  ------------------
  373|  1.72k|                if (cursor->type != t_array) {
  ------------------
  |  Branch (373:21): [True: 437, False: 1.28k]
  ------------------
  374|    437|                    json_debug_trace((1,
  ------------------
  |  |  110|    437|#define json_debug_trace(args) (void) json_trace args
  ------------------
  375|    437|                                      "Saw [ when not expecting array.\n"));
  376|    437|                    if (NULL != end) {
  ------------------
  |  Branch (376:25): [True: 1, False: 436]
  ------------------
  377|      1|                        *end = cp;
  378|      1|                    }
  379|    437|                    return JSON_ERR_NOARRAY;
  ------------------
  |  |  156|    437|#define JSON_ERR_NOARRAY         5      // saw [ when not expecting array
  ------------------
  380|    437|                }
  381|  1.28k|                substatus = json_read_array(cp, &cursor->addr.array, &cp);
  382|  1.28k|                if (substatus != 0) {
  ------------------
  |  Branch (382:21): [True: 302, False: 987]
  ------------------
  383|    302|                    return substatus;
  384|    302|                }
  385|    987|                state = post_element;
  386|  34.8k|            } else if (cursor->type == t_array) {
  ------------------
  |  Branch (386:24): [True: 1, False: 34.8k]
  ------------------
  387|      1|                json_debug_trace((1,
  ------------------
  |  |  110|      1|#define json_debug_trace(args) (void) json_trace args
  ------------------
  388|      1|                                  "Array element was specified, but no [.\n"));
  389|      1|                if (NULL != end) {
  ------------------
  |  Branch (389:21): [True: 0, False: 1]
  ------------------
  390|      0|                    *end = cp;
  391|      0|                }
  392|      1|                return JSON_ERR_NOBRAK;
  ------------------
  |  |  157|      1|#define JSON_ERR_NOBRAK          6      // array element specified, but no [
  ------------------
  393|  34.8k|            } else if (*cp == '"') {
  ------------------
  |  Branch (393:24): [True: 8.50k, False: 26.3k]
  ------------------
  394|  8.50k|                value_quoted = true;
  395|  8.50k|                state = in_val_string;
  396|  8.50k|                pval = valbuf;
  397|  26.3k|            } else {
  398|  26.3k|                value_quoted = false;
  399|  26.3k|                state = in_val_token;
  400|  26.3k|                pval = valbuf;
  401|  26.3k|                *pval++ = *cp;
  402|  26.3k|            }
  403|  35.7k|            break;
  404|  53.1k|        case in_val_string:
  ------------------
  |  Branch (404:9): [True: 53.1k, False: 367k]
  ------------------
  405|  53.1k|            if (NULL == pval) {
  ------------------
  |  Branch (405:17): [True: 0, False: 53.1k]
  ------------------
  406|       |                // don't update end here, leave at value start
  407|      0|                return JSON_ERR_NULLPTR;
  ------------------
  |  |  174|      0|#define JSON_ERR_NULLPTR        23      // unexpected null value or attribute pointer
  ------------------
  408|      0|            }
  409|  53.1k|            if (*cp == '\\') {
  ------------------
  |  Branch (409:17): [True: 1.70k, False: 51.4k]
  ------------------
  410|  1.70k|                state = in_escape;
  411|  51.4k|            } else if (*cp == '"') {
  ------------------
  |  Branch (411:24): [True: 8.00k, False: 43.4k]
  ------------------
  412|  8.00k|                *pval++ = '\0';
  413|  8.00k|                json_debug_trace((1, "Collected string value %s\n", valbuf));
  ------------------
  |  |  110|  8.00k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  414|  8.00k|                state = post_val;
  415|  43.4k|            } else if (pval > valbuf + JSON_VAL_MAX - 1 ||
  ------------------
  |  |  135|  43.4k|#define JSON_VAL_MAX    512     /* max chars in JSON value part */
  ------------------
  |  Branch (415:24): [True: 3, False: 43.4k]
  ------------------
  416|  43.4k|                       pval > valbuf + maxlen - 1) {
  ------------------
  |  Branch (416:24): [True: 180, False: 43.2k]
  ------------------
  417|    183|                json_debug_trace((1, "String value too long.\n"));
  ------------------
  |  |  110|    183|#define json_debug_trace(args) (void) json_trace args
  ------------------
  418|       |                // don't update end here, leave at value start
  419|    183|                return JSON_ERR_STRLONG;
  ------------------
  |  |  158|    183|#define JSON_ERR_STRLONG         7      // string value too long
  ------------------
  420|  43.2k|            } else {
  421|  43.2k|                *pval++ = *cp;
  422|  43.2k|            }
  423|  53.0k|            break;
  424|  53.0k|        case in_escape:
  ------------------
  |  Branch (424:9): [True: 1.70k, False: 419k]
  ------------------
  425|  1.70k|            if (NULL == pval) {
  ------------------
  |  Branch (425:17): [True: 0, False: 1.70k]
  ------------------
  426|       |                /* don't update end here, leave at value start */
  427|      0|                return JSON_ERR_NULLPTR;
  ------------------
  |  |  174|      0|#define JSON_ERR_NULLPTR        23      // unexpected null value or attribute pointer
  ------------------
  428|      0|            }
  429|  1.70k|            if (pval > valbuf + JSON_VAL_MAX - 1 ||
  ------------------
  |  |  135|  1.70k|#define JSON_VAL_MAX    512     /* max chars in JSON value part */
  ------------------
  |  Branch (429:17): [True: 3, False: 1.70k]
  ------------------
  430|  1.70k|                pval > valbuf + maxlen) {
  ------------------
  |  Branch (430:17): [True: 6, False: 1.69k]
  ------------------
  431|      9|                json_debug_trace((1, "String value too long.\n"));
  ------------------
  |  |  110|      9|#define json_debug_trace(args) (void) json_trace args
  ------------------
  432|       |                // don't update end here, leave at value start
  433|      9|                return JSON_ERR_STRLONG;
  ------------------
  |  |  158|      9|#define JSON_ERR_STRLONG         7      // string value too long
  ------------------
  434|      9|            }
  435|  1.69k|            switch (*cp) {
  436|    195|            case 'b':
  ------------------
  |  Branch (436:13): [True: 195, False: 1.49k]
  ------------------
  437|    195|                *pval++ = '\b';
  438|    195|                break;
  439|    196|            case 'f':
  ------------------
  |  Branch (439:13): [True: 196, False: 1.49k]
  ------------------
  440|    196|                *pval++ = '\f';
  441|    196|                break;
  442|    195|            case 'n':
  ------------------
  |  Branch (442:13): [True: 195, False: 1.49k]
  ------------------
  443|    195|                *pval++ = '\n';
  444|    195|                break;
  445|    200|            case 'r':
  ------------------
  |  Branch (445:13): [True: 200, False: 1.49k]
  ------------------
  446|    200|                *pval++ = '\r';
  447|    200|                break;
  448|    360|            case 't':
  ------------------
  |  Branch (448:13): [True: 360, False: 1.33k]
  ------------------
  449|    360|                *pval++ = '\t';
  450|    360|                break;
  451|    286|            case 'u':
  ------------------
  |  Branch (451:13): [True: 286, False: 1.40k]
  ------------------
  452|    286|                {
  453|    286|                    unsigned n;
  454|       |
  455|    286|                    cp++;                   // skip the 'u'
  456|       |                    // NetBSD 6 wants the cast
  457|  1.10k|                    for (n = 0; n < 4 && isxdigit((int)*cp); n++) {
  ------------------
  |  Branch (457:33): [True: 913, False: 196]
  ------------------
  458|    823|                        uescape[n] = *cp++;
  459|    823|                    }
  460|    286|                    uescape[n] = '\0';      // terminate
  461|    286|                    --cp;
  462|       |                    // ECMA-404 says JSON \u must have 4 hex digits
  463|    286|                    if ((4 != n) ||
  ------------------
  |  Branch (463:25): [True: 90, False: 196]
  ------------------
  464|    286|                        (1 != sscanf(uescape, "%4x", &u))) {
  ------------------
  |  Branch (464:25): [True: 0, False: 196]
  ------------------
  465|     90|                        return JSON_ERR_BADSTRING;
  ------------------
  |  |  166|     90|#define JSON_ERR_BADSTRING      15      // error while string parsing
  ------------------
  466|     90|                    }
  467|       |                    // truncate values above 0xff
  468|    196|                    *pval++ = (unsigned char)u;
  469|    196|                }
  470|      0|                break;
  471|    262|            default:            // handles double quote and solidus
  ------------------
  |  Branch (471:13): [True: 262, False: 1.43k]
  ------------------
  472|    262|                *pval++ = *cp;
  473|    262|                break;
  474|  1.69k|            }
  475|  1.60k|            state = in_val_string;
  476|  1.60k|            break;
  477|  97.6k|        case in_val_token:
  ------------------
  |  Branch (477:9): [True: 97.6k, False: 323k]
  ------------------
  478|  97.6k|            if (NULL == pval) {
  ------------------
  |  Branch (478:17): [True: 0, False: 97.6k]
  ------------------
  479|       |                // don't update end here, leave at value start
  480|      0|                return JSON_ERR_NULLPTR;
  ------------------
  |  |  174|      0|#define JSON_ERR_NULLPTR        23      // unexpected null value or attribute pointer
  ------------------
  481|      0|            }
  482|  97.6k|            if (isspace((unsigned char) *cp) ||
  483|  97.6k|                *cp == ',' ||
  ------------------
  |  Branch (483:17): [True: 21.4k, False: 75.6k]
  ------------------
  484|  97.6k|                *cp == '}') {
  ------------------
  |  Branch (484:17): [True: 4.20k, False: 71.4k]
  ------------------
  485|  26.1k|                *pval = '\0';
  486|  26.1k|                json_debug_trace((1, "Collected token value %s.\n", valbuf));
  ------------------
  |  |  110|  26.1k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  487|  26.1k|                state = post_val;
  488|  26.1k|                if (*cp == '}' ||
  ------------------
  |  Branch (488:21): [True: 4.20k, False: 21.9k]
  ------------------
  489|  26.1k|                    *cp == ',') {
  ------------------
  |  Branch (489:21): [True: 21.4k, False: 474]
  ------------------
  490|  25.6k|                    --cp;
  491|  25.6k|                }
  492|  71.4k|            } else if (pval > valbuf + JSON_VAL_MAX - 1) {
  ------------------
  |  |  135|  71.4k|#define JSON_VAL_MAX    512     /* max chars in JSON value part */
  ------------------
  |  Branch (492:24): [True: 6, False: 71.4k]
  ------------------
  493|      6|                json_debug_trace((1, "Token value too long.\n"));
  ------------------
  |  |  110|      6|#define json_debug_trace(args) (void) json_trace args
  ------------------
  494|       |                // don't update end here, leave at value start
  495|      6|                return JSON_ERR_TOKLONG;
  ------------------
  |  |  159|      6|#define JSON_ERR_TOKLONG         8      // token value too long
  ------------------
  496|  71.4k|            } else {
  497|  71.4k|                *pval++ = *cp;
  498|  71.4k|            }
  499|  97.6k|            break;
  500|       |            // coverity[unterminated_case]
  501|  97.6k|        case post_val:
  ------------------
  |  Branch (501:9): [True: 33.6k, False: 387k]
  ------------------
  502|       |            // Ignore whitespace after either string or token values.
  503|  33.6k|            if (isspace(*cp)) {
  504|    634|                while (*cp != '\0' && isspace((unsigned char) *cp)) {
  ------------------
  |  Branch (504:24): [True: 615, False: 19]
  ------------------
  505|    413|                    ++cp;
  506|    413|                }
  507|    221|                json_debug_trace((1,
  ------------------
  |  |  110|    221|#define json_debug_trace(args) (void) json_trace args
  ------------------
  508|    221|                    "Skipped trailing whitespace: value \"%s\"\n", valbuf));
  509|    221|            }
  510|       |            /*
  511|       |             * We know that cursor points at the first spec matching
  512|       |             * the current attribute.  We don't know that it's *the*
  513|       |             * correct spec; our dialect allows there to be any number
  514|       |             * of adjacent ones with the same attrname but different
  515|       |             * types.  Here's where we try to seek forward for a
  516|       |             * matching type/attr pair if we're not looking at one.
  517|       |             */
  518|  33.8k|            for (;;) {
  519|  33.8k|                int seeking = cursor->type;
  520|       |
  521|  33.8k|                if (value_quoted &&
  ------------------
  |  Branch (521:21): [True: 7.45k, False: 26.3k]
  ------------------
  522|  33.8k|                    (cursor->type == t_string ||
  ------------------
  |  Branch (522:22): [True: 945, False: 6.50k]
  ------------------
  523|  7.45k|                     cursor->type == t_time)) {
  ------------------
  |  Branch (523:22): [True: 1.93k, False: 4.57k]
  ------------------
  524|  2.88k|                    break;
  525|  2.88k|                }
  526|  30.9k|                if ((strcmp(valbuf, "true") == 0 ||
  ------------------
  |  Branch (526:22): [True: 1.48k, False: 29.4k]
  ------------------
  527|  30.9k|                     strcmp(valbuf, "false") == 0) &&
  ------------------
  |  Branch (527:22): [True: 194, False: 29.2k]
  ------------------
  528|  30.9k|                    seeking == t_boolean) {
  ------------------
  |  Branch (528:21): [True: 1.18k, False: 496]
  ------------------
  529|  1.18k|                    break;
  530|  1.18k|                }
  531|  29.7k|                if (isdigit((unsigned char) valbuf[0])) {
  532|  15.8k|                    bool decimal = strchr(valbuf, '.') != NULL;
  533|       |
  534|  15.8k|                    if (decimal &&
  ------------------
  |  Branch (534:25): [True: 1.00k, False: 14.8k]
  ------------------
  535|  15.8k|                        seeking == t_real) {
  ------------------
  |  Branch (535:25): [True: 298, False: 703]
  ------------------
  536|    298|                        break;
  537|    298|                    }
  538|  15.5k|                    if (!decimal && (seeking == t_byte ||
  ------------------
  |  Branch (538:25): [True: 14.8k, False: 703]
  |  Branch (538:38): [True: 196, False: 14.6k]
  ------------------
  539|  14.8k|                                     seeking == t_ubyte ||
  ------------------
  |  Branch (539:38): [True: 625, False: 14.0k]
  ------------------
  540|  14.8k|                                     seeking == t_integer ||
  ------------------
  |  Branch (540:38): [True: 1.10k, False: 12.9k]
  ------------------
  541|  14.8k|                                     seeking == t_uinteger ||
  ------------------
  |  Branch (541:38): [True: 521, False: 12.4k]
  ------------------
  542|  14.8k|                                     seeking == t_longint ||
  ------------------
  |  Branch (542:38): [True: 0, False: 12.4k]
  ------------------
  543|  14.8k|                                     seeking == t_ulongint ||
  ------------------
  |  Branch (543:38): [True: 405, False: 12.0k]
  ------------------
  544|  14.8k|                                     seeking == t_short ||
  ------------------
  |  Branch (544:38): [True: 1.24k, False: 10.7k]
  ------------------
  545|  14.8k|                                     seeking == t_ushort))
  ------------------
  |  Branch (545:38): [True: 0, False: 10.7k]
  ------------------
  546|  4.09k|                        break;
  547|  15.5k|                }
  548|  25.3k|                if (NULL == cursor[1].attribute) {  // out of possibilities
  ------------------
  |  Branch (548:21): [True: 17.1k, False: 8.24k]
  ------------------
  549|  17.1k|                    break;
  550|  17.1k|                }
  551|  8.24k|                if (0 != strcmp(cursor[1].attribute, attrbuf)) {
  ------------------
  |  Branch (551:21): [True: 8.04k, False: 194]
  ------------------
  552|  8.04k|                    break;
  553|  8.04k|                }
  554|    194|                ++cursor;
  555|    194|            }
  556|  33.6k|            if (value_quoted &&
  ------------------
  |  Branch (556:17): [True: 7.45k, False: 26.1k]
  ------------------
  557|  33.6k|                (cursor->type != t_string &&
  ------------------
  |  Branch (557:18): [True: 6.50k, False: 945]
  ------------------
  558|  7.45k|                 cursor->type != t_character &&
  ------------------
  |  Branch (558:18): [True: 6.30k, False: 202]
  ------------------
  559|  7.45k|                 cursor->type != t_check &&
  ------------------
  |  Branch (559:18): [True: 5.65k, False: 647]
  ------------------
  560|  7.45k|                 cursor->type != t_time &&
  ------------------
  |  Branch (560:18): [True: 3.72k, False: 1.93k]
  ------------------
  561|  7.45k|                 cursor->type != t_ignore &&
  ------------------
  |  Branch (561:18): [True: 455, False: 3.26k]
  ------------------
  562|  7.45k|                 cursor->map == 0)) {
  ------------------
  |  Branch (562:18): [True: 12, False: 443]
  ------------------
  563|     12|                json_debug_trace((1, "Saw quoted value when expecting"
  ------------------
  |  |  110|     12|#define json_debug_trace(args) (void) json_trace args
  ------------------
  564|     12|                                  " non-string.\n"));
  565|     12|                return JSON_ERR_QNONSTRING;
  ------------------
  |  |  170|     12|#define JSON_ERR_QNONSTRING     19      // saw quoted value when expecting nonstring
  ------------------
  566|     12|            }
  567|  33.6k|            if (!value_quoted &&
  ------------------
  |  Branch (567:17): [True: 26.1k, False: 7.44k]
  ------------------
  568|  33.6k|                (cursor->type == t_string ||
  ------------------
  |  Branch (568:18): [True: 18, False: 26.1k]
  ------------------
  569|  26.1k|                 cursor->type == t_check ||
  ------------------
  |  Branch (569:18): [True: 26, False: 26.1k]
  ------------------
  570|  26.1k|                 cursor->type == t_time ||
  ------------------
  |  Branch (570:18): [True: 6, False: 26.1k]
  ------------------
  571|  26.1k|                 cursor->map != 0)) {
  ------------------
  |  Branch (571:18): [True: 7, False: 26.1k]
  ------------------
  572|     57|                json_debug_trace((1, "Didn't see quoted value when expecting"
  ------------------
  |  |  110|     57|#define json_debug_trace(args) (void) json_trace args
  ------------------
  573|     57|                                  " string.\n"));
  574|     57|                return JSON_ERR_NONQSTRING;
  ------------------
  |  |  171|     57|#define JSON_ERR_NONQSTRING     20      // didn't see quoted value when expecting string
  ------------------
  575|     57|            }
  576|  33.5k|            if (cursor->map != 0) {
  ------------------
  |  Branch (576:17): [True: 443, False: 33.1k]
  ------------------
  577|    902|                for (mp = cursor->map; mp->name != NULL; mp++)
  ------------------
  |  Branch (577:40): [True: 833, False: 69]
  ------------------
  578|    833|                    if (strcmp(mp->name, valbuf) == 0) {
  ------------------
  |  Branch (578:25): [True: 374, False: 459]
  ------------------
  579|    374|                        goto foundit;
  580|    374|                    }
  581|     69|                json_debug_trace((1, "Invalid enumerated value string %s.\n",
  ------------------
  |  |  110|     69|#define json_debug_trace(args) (void) json_trace args
  ------------------
  582|     69|                                  valbuf));
  583|     69|                return JSON_ERR_BADENUM;
  ------------------
  |  |  169|     69|#define JSON_ERR_BADENUM        18      // invalid enumerated value
  ------------------
  584|    374|              foundit:
  585|    374|                (void)snprintf(valbuf, sizeof(valbuf), "%d", mp->value);
  586|    374|            }
  587|  33.4k|            if (cursor->type == t_check) {
  ------------------
  |  Branch (587:17): [True: 647, False: 32.8k]
  ------------------
  588|    647|                lptr = cursor->dflt.check;
  589|  32.8k|            } else {
  590|  32.8k|                lptr = json_target_address(cursor, parent, offset);
  591|  32.8k|            }
  592|  33.4k|            if (NULL != lptr) {
  ------------------
  |  Branch (592:17): [True: 18.9k, False: 14.5k]
  ------------------
  593|  18.9k|                switch (cursor->type) {
  ------------------
  |  Branch (593:25): [True: 0, False: 18.9k]
  ------------------
  594|    228|                case t_byte:
  ------------------
  |  Branch (594:17): [True: 228, False: 18.7k]
  ------------------
  595|    228|                    {
  596|    228|                        int tmp = atoi(valbuf);
  597|    228|                        lptr[0] = (char)tmp;
  598|    228|                    }
  599|    228|                    break;
  600|  1.06k|                case t_ubyte:
  ------------------
  |  Branch (600:17): [True: 1.06k, False: 17.8k]
  ------------------
  601|  1.06k|                    {
  602|  1.06k|                        int tmp = atoi(valbuf);
  603|  1.06k|                        lptr[0] = (unsigned char)tmp;
  604|  1.06k|                    }
  605|  1.06k|                    break;
  606|  1.70k|                case t_integer:
  ------------------
  |  Branch (606:17): [True: 1.70k, False: 17.2k]
  ------------------
  607|  1.70k|                    {
  608|  1.70k|                        int tmp = atoi(valbuf);
  609|  1.70k|                        memcpy(lptr, &tmp, sizeof(int));
  610|  1.70k|                    }
  611|  1.70k|                    break;
  612|  1.05k|                case t_uinteger:
  ------------------
  |  Branch (612:17): [True: 1.05k, False: 17.8k]
  ------------------
  613|  1.05k|                    {
  614|  1.05k|                        unsigned int tmp = (unsigned int)atol(valbuf);
  615|  1.05k|                        memcpy(lptr, &tmp, sizeof(unsigned int));
  616|  1.05k|                    }
  617|  1.05k|                    break;
  618|      0|                case t_longint:
  ------------------
  |  Branch (618:17): [True: 0, False: 18.9k]
  ------------------
  619|      0|                    {
  620|      0|                        long tmp = atol(valbuf);
  621|      0|                        memcpy(lptr, &tmp, sizeof(long));
  622|      0|                    }
  623|      0|                    break;
  624|    440|                case t_ulongint:
  ------------------
  |  Branch (624:17): [True: 440, False: 18.5k]
  ------------------
  625|    440|                    {
  626|    440|                        unsigned long tmp = (unsigned long)atoll(valbuf);
  627|    440|                        memcpy(lptr, &tmp, sizeof(unsigned long));
  628|    440|                    }
  629|    440|                    break;
  630|  1.26k|                case t_short:
  ------------------
  |  Branch (630:17): [True: 1.26k, False: 17.6k]
  ------------------
  631|  1.26k|                    {
  632|  1.26k|                        short tmp = atoi(valbuf);
  633|  1.26k|                        memcpy(lptr, &tmp, sizeof(short));
  634|  1.26k|                    }
  635|  1.26k|                    break;
  636|      0|                case t_ushort:
  ------------------
  |  Branch (636:17): [True: 0, False: 18.9k]
  ------------------
  637|      0|                    {
  638|      0|                        unsigned short tmp = (unsigned int)atoi(valbuf);
  639|      0|                        memcpy(lptr, &tmp, sizeof(unsigned short));
  640|      0|                    }
  641|      0|                    break;
  642|  1.93k|                case t_time:
  ------------------
  |  Branch (642:17): [True: 1.93k, False: 17.0k]
  ------------------
  643|  1.93k|                    {
  644|  1.93k|                        timespec_t ts_tmp = iso8601_to_timespec(valbuf);
  645|  1.93k|                        memcpy(lptr, &ts_tmp, sizeof(timespec_t));
  646|  1.93k|                    }
  647|  1.93k|                    break;
  648|    390|                case t_timespec:
  ------------------
  |  Branch (648:17): [True: 390, False: 18.5k]
  ------------------
  649|    390|                    {
  650|    390|                        double sec_tmp = safe_atof(valbuf);
  651|    390|                        timespec_t ts_tmp;
  652|    390|                        if (0 != isfinite(sec_tmp)) {
  ------------------
  |  Branch (652:29): [True: 195, False: 195]
  ------------------
  653|    195|                            DTOTS(&ts_tmp, sec_tmp);
  ------------------
  |  |  143|    195|    do { \
  |  |  144|    195|        double int_part; \
  |  |  145|    195|        (ts)->tv_nsec = (long)(modf(d, &int_part) * 1e9); \
  |  |  146|    195|        (ts)->tv_sec = (time_t)int_part; \
  |  |  147|    195|    } while (0)
  |  |  ------------------
  |  |  |  Branch (147:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
  654|    195|                            memcpy(lptr, &ts_tmp, sizeof(timespec_t));
  655|    195|                        } // else leave at .dflt
  656|    390|                    }
  657|    390|                    break;
  658|  4.68k|                case t_real:
  ------------------
  |  Branch (658:17): [True: 4.68k, False: 14.2k]
  ------------------
  659|  4.68k|                    {
  660|  4.68k|                        double tmp = safe_atof(valbuf);
  661|  4.68k|                        if (0 != isfinite(tmp)) {
  ------------------
  |  Branch (661:29): [True: 3.79k, False: 886]
  ------------------
  662|  3.79k|                            memcpy(lptr, &tmp, sizeof(double));
  663|  3.79k|                        } // else leave at .dflt
  664|  4.68k|                    }
  665|  4.68k|                    break;
  666|    945|                case t_string:
  ------------------
  |  Branch (666:17): [True: 945, False: 17.9k]
  ------------------
  667|    945|                    if (NULL != parent &&
  ------------------
  |  Branch (667:25): [True: 388, False: 557]
  ------------------
  668|    945|                        parent->element_type != t_structobject &&
  ------------------
  |  Branch (668:25): [True: 0, False: 388]
  ------------------
  669|    945|                        offset > 0) {
  ------------------
  |  Branch (669:25): [True: 0, False: 0]
  ------------------
  670|      0|                        return JSON_ERR_NOPARSTR;
  ------------------
  |  |  168|      0|#define JSON_ERR_NOPARSTR       17      // can't support strings in parallel arrays
  ------------------
  671|      0|                    }
  672|    945|                    (void)strlcpy(lptr, valbuf, cursor->len);
  673|    945|                    break;
  674|  1.56k|                case t_boolean:
  ------------------
  |  Branch (674:17): [True: 1.56k, False: 17.3k]
  ------------------
  675|  1.56k|                    {
  676|  1.56k|                        bool tmp = (strcmp(valbuf, "true") == 0);
  677|  1.56k|                        memcpy(lptr, &tmp, sizeof(bool));
  678|  1.56k|                    }
  679|  1.56k|                    break;
  680|    561|                case t_character:
  ------------------
  |  Branch (680:17): [True: 561, False: 18.3k]
  ------------------
  681|    561|                    if (strnlen(valbuf, 2) > 1) {
  ------------------
  |  Branch (681:25): [True: 7, False: 554]
  ------------------
  682|       |                        // don't update end here, leave at value start
  683|      7|                        return JSON_ERR_STRLONG;
  ------------------
  |  |  158|      7|#define JSON_ERR_STRLONG         7      // string value too long
  ------------------
  684|    554|                    } else {
  685|    554|                        lptr[0] = valbuf[0];
  686|    554|                    }
  687|    554|                    break;
  688|  2.47k|                case t_ignore:  // silences a compiler warning
  ------------------
  |  Branch (688:17): [True: 2.47k, False: 16.4k]
  ------------------
  689|  2.47k|                    FALLTHROUGH
  ------------------
  |  |   55|  2.47k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  690|  2.47k|                case t_object:  // silences a compiler warning
  ------------------
  |  Branch (690:17): [True: 0, False: 18.9k]
  ------------------
  691|  2.47k|                    FALLTHROUGH
  ------------------
  |  |   55|  2.47k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  692|  2.47k|                case t_structobject:
  ------------------
  |  Branch (692:17): [True: 0, False: 18.9k]
  ------------------
  693|  2.47k|                    FALLTHROUGH
  ------------------
  |  |   55|  2.47k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  694|  2.47k|                case t_array:
  ------------------
  |  Branch (694:17): [True: 0, False: 18.9k]
  ------------------
  695|  2.47k|                    break;
  696|    647|                case t_check:
  ------------------
  |  Branch (696:17): [True: 647, False: 18.2k]
  ------------------
  697|    647|                    if (strcmp(cursor->dflt.check, valbuf) != 0) {
  ------------------
  |  Branch (697:25): [True: 201, False: 446]
  ------------------
  698|    201|                        json_debug_trace((1, "Required attribute value %s"
  ------------------
  |  |  110|    201|#define json_debug_trace(args) (void) json_trace args
  ------------------
  699|    201|                                          " not present.\n",
  700|    201|                                          cursor->dflt.check));
  701|       |                        // don't update end here, leave at start of attribute
  702|    201|                        return JSON_ERR_CHECKFAIL;
  ------------------
  |  |  167|    201|#define JSON_ERR_CHECKFAIL      16      // check attribute not matched
  ------------------
  703|    201|                    }
  704|    446|                    break;
  705|  18.9k|                }
  706|  18.9k|            }
  707|  33.4k|            FALLTHROUGH
  ------------------
  |  |   55|  33.2k|        #define FALLTHROUGH __attribute__((fallthrough));
  ------------------
  708|  34.5k|        case post_element:
  ------------------
  |  Branch (708:9): [True: 1.31k, False: 419k]
  ------------------
  709|  34.5k|            if (isspace((unsigned char) *cp)) {
  710|    374|                continue;
  711|    374|            }
  712|  34.2k|            if (*cp == ',') {
  ------------------
  |  Branch (712:17): [True: 28.5k, False: 5.69k]
  ------------------
  713|  28.5k|                state = await_attr;
  714|  28.5k|            } else if (*cp == '}') {
  ------------------
  |  Branch (714:24): [True: 4.50k, False: 1.18k]
  ------------------
  715|  4.50k|                ++cp;
  716|  4.50k|                goto good_parse;
  717|  4.50k|            } else {
  718|  1.18k|                json_debug_trace((1, "Garbage while expecting comma or }\n"));
  ------------------
  |  |  110|  1.18k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  719|  1.18k|                if (NULL != end) {
  ------------------
  |  Branch (719:21): [True: 17, False: 1.16k]
  ------------------
  720|     17|                    *end = cp;
  721|     17|                }
  722|  1.18k|                return JSON_ERR_BADTRAIL;
  ------------------
  |  |  160|  1.18k|#define JSON_ERR_BADTRAIL        9      // garbage while expecting comma or } or ]
  ------------------
  723|  1.18k|            }
  724|  28.5k|            break;
  725|   421k|        }
  726|   421k|    }
  727|  1.92k|    if (state == init) {
  ------------------
  |  Branch (727:9): [True: 50, False: 1.87k]
  ------------------
  728|     50|        json_debug_trace((1, "Input was empty or white-space only\n"));
  ------------------
  |  |  110|     50|#define json_debug_trace(args) (void) json_trace args
  ------------------
  729|     50|        return JSON_ERR_EMPTY;
  ------------------
  |  |  176|     50|#define JSON_ERR_EMPTY          25      // input was empty or white-space only
  ------------------
  730|     50|    }
  731|       |
  732|  6.38k|  good_parse:
  733|       |    // in case there's another object following, consume trailing WS
  734|  6.38k|    while (isspace((unsigned char)*cp)) {
  735|    403|        ++cp;
  736|    403|    }
  737|  6.38k|    if (NULL != end) {
  ------------------
  |  Branch (737:9): [True: 4.27k, False: 2.10k]
  ------------------
  738|  4.27k|        *end = cp;
  739|  4.27k|    }
  740|  6.38k|    json_debug_trace((1, "JSON parse ends.\n"));
  ------------------
  |  |  110|  6.38k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  741|  6.38k|    return 0;
  742|  1.92k|}
json.c:json_target_address:
  115|   161k|{
  116|   161k|    char *targetaddr = NULL;
  117|   161k|    if (NULL == parent ||
  ------------------
  |  Branch (117:9): [True: 99.2k, False: 61.7k]
  ------------------
  118|   161k|        parent->element_type != t_structobject) {
  ------------------
  |  Branch (118:9): [True: 0, False: 61.7k]
  ------------------
  119|       |        // ordinary case - use the address in the cursor structure
  120|  99.2k|        switch (cursor->type) {
  121|      0|        case t_byte:
  ------------------
  |  Branch (121:9): [True: 0, False: 99.2k]
  ------------------
  122|      0|            targetaddr = (char *)&cursor->addr.byte[offset];
  123|      0|            break;
  124|  1.10k|        case t_ubyte:
  ------------------
  |  Branch (124:9): [True: 1.10k, False: 98.1k]
  ------------------
  125|  1.10k|            targetaddr = (char *)&cursor->addr.ubyte[offset];
  126|  1.10k|            break;
  127|  18.6k|        case t_ignore:
  ------------------
  |  Branch (127:9): [True: 18.6k, False: 80.5k]
  ------------------
  128|  18.6k|            targetaddr = NULL;
  129|  18.6k|            break;
  130|  17.1k|        case t_integer:
  ------------------
  |  Branch (130:9): [True: 17.1k, False: 82.1k]
  ------------------
  131|  17.1k|            targetaddr = (char *)&cursor->addr.integer[offset];
  132|  17.1k|            break;
  133|  6.38k|        case t_uinteger:
  ------------------
  |  Branch (133:9): [True: 6.38k, False: 92.8k]
  ------------------
  134|  6.38k|            targetaddr = (char *)&cursor->addr.uinteger[offset];
  135|  6.38k|            break;
  136|      0|        case t_longint:
  ------------------
  |  Branch (136:9): [True: 0, False: 99.2k]
  ------------------
  137|      0|            targetaddr = (char *)&cursor->addr.longint[offset];
  138|      0|            break;
  139|    562|        case t_ulongint:
  ------------------
  |  Branch (139:9): [True: 562, False: 98.7k]
  ------------------
  140|    562|            targetaddr = (char *)&cursor->addr.ulongint[offset];
  141|    562|            break;
  142|      0|        case t_short:
  ------------------
  |  Branch (142:9): [True: 0, False: 99.2k]
  ------------------
  143|      0|            targetaddr = (char *)&cursor->addr.shortint[offset];
  144|      0|            break;
  145|      0|        case t_ushort:
  ------------------
  |  Branch (145:9): [True: 0, False: 99.2k]
  ------------------
  146|      0|            targetaddr = (char *)&cursor->addr.ushortint[offset];
  147|      0|            break;
  148|  2.88k|        case t_time:
  ------------------
  |  Branch (148:9): [True: 2.88k, False: 96.3k]
  ------------------
  149|  2.88k|            targetaddr = (char *)&cursor->addr.ts[offset];
  150|  2.88k|            break;
  151|      0|        case t_timespec:
  ------------------
  |  Branch (151:9): [True: 0, False: 99.2k]
  ------------------
  152|      0|            targetaddr = (char *)&cursor->addr.ts[offset];
  153|      0|            break;
  154|  37.5k|        case t_real:
  ------------------
  |  Branch (154:9): [True: 37.5k, False: 61.7k]
  ------------------
  155|  37.5k|            targetaddr = (char *)&cursor->addr.real[offset];
  156|  37.5k|            break;
  157|  6.72k|        case t_string:
  ------------------
  |  Branch (157:9): [True: 6.72k, False: 92.5k]
  ------------------
  158|  6.72k|            targetaddr = cursor->addr.string;
  159|  6.72k|            break;
  160|  1.65k|        case t_boolean:
  ------------------
  |  Branch (160:9): [True: 1.65k, False: 97.6k]
  ------------------
  161|  1.65k|            targetaddr = (char *)&cursor->addr.boolean[offset];
  162|  1.65k|            break;
  163|  1.07k|        case t_character:
  ------------------
  |  Branch (163:9): [True: 1.07k, False: 98.1k]
  ------------------
  164|  1.07k|            targetaddr = (char *)&cursor->addr.character[offset];
  165|  1.07k|            break;
  166|  5.55k|        default:
  ------------------
  |  Branch (166:9): [True: 5.55k, False: 93.7k]
  ------------------
  167|  5.55k|            targetaddr = NULL;
  168|  5.55k|            break;
  169|  99.2k|        }
  170|  99.2k|    } else {
  171|       |        // tricky case - hacking a member in an array of structures
  172|  61.7k|        targetaddr =
  173|  61.7k|            parent->arr.objects.base + (offset * parent->arr.objects.stride) +
  174|  61.7k|            cursor->addr.offset;
  175|  61.7k|    }
  176|   161k|    json_debug_trace((1, "Target address for %s (offset %d) is %p\n",
  ------------------
  |  |  110|   161k|#define json_debug_trace(args) (void) json_trace args
  ------------------
  177|   161k|                      cursor->attribute, offset, targetaddr));
  178|   161k|    return targetaddr;
  179|   161k|}

json_toff_read:
  656|  2.72k|{
  657|  2.72k|    int real_sec = 0, real_nsec = 0, clock_sec = 0, clock_nsec = 0;
  658|  2.72k|    const struct json_attr_t json_attrs_toff[] = {
  659|       |        // *INDENT-OFF*
  660|  2.72k|        {"class",     t_check,   .dflt.check = "TOFF"},
  661|  2.72k|        {"device",    t_string,  .addr.string = gpsdata->dev.path,
  662|  2.72k|                                 .len = sizeof(gpsdata->dev.path)},
  663|  2.72k|        {"real_sec",  t_integer, .addr.integer = &real_sec,
  664|  2.72k|                                 .dflt.integer = 0},
  665|  2.72k|        {"real_nsec", t_integer, .addr.integer = &real_nsec,
  666|  2.72k|                                 .dflt.integer = 0},
  667|  2.72k|        {"clock_sec", t_integer, .addr.integer = &clock_sec,
  668|  2.72k|                                 .dflt.integer = 0},
  669|  2.72k|        {"clock_nsec",t_integer, .addr.integer = &clock_nsec,
  670|  2.72k|                                 .dflt.integer = 0},
  671|       |        // ignore unknown keys, for cross-version compatibility
  672|  2.72k|        {"", t_ignore},
  673|  2.72k|        {NULL},
  674|       |        // *INDENT-ON*
  675|  2.72k|    };
  676|  2.72k|    int status;
  677|       |
  678|  2.72k|    memset(&gpsdata->toff, 0, sizeof(gpsdata->toff));
  679|  2.72k|    status = json_read_object(buf, json_attrs_toff, endptr);
  680|  2.72k|    gpsdata->toff.real.tv_sec = (time_t)real_sec;
  681|  2.72k|    gpsdata->toff.real.tv_nsec = (long)real_nsec;
  682|  2.72k|    gpsdata->toff.clock.tv_sec = (time_t)clock_sec;
  683|  2.72k|    gpsdata->toff.clock.tv_nsec = (long)clock_nsec;
  684|  2.72k|    if (status != 0)
  ------------------
  |  Branch (684:9): [True: 1.46k, False: 1.26k]
  ------------------
  685|  1.46k|        return status;
  686|       |
  687|  1.26k|    return status;
  688|  2.72k|}
json_pps_read:
  692|     36|{
  693|     36|    int real_sec = 0, real_nsec = 0, clock_sec = 0, clock_nsec = 0, precision=0;
  694|     36|    int qErr = 0;
  695|       |
  696|     36|    const struct json_attr_t json_attrs_pps[] = {
  697|       |        // *INDENT-OFF*
  698|     36|        {"class",     t_check,   .dflt.check = "PPS"},
  699|     36|        {"device",    t_string,  .addr.string = gpsdata->dev.path,
  700|     36|                                 .len = sizeof(gpsdata->dev.path)},
  701|     36|        {"real_sec",  t_integer, .addr.integer = &real_sec,
  702|     36|                                 .dflt.integer = 0},
  703|     36|        {"real_nsec", t_integer, .addr.integer = &real_nsec,
  704|     36|                                 .dflt.integer = 0},
  705|     36|        {"clock_sec", t_integer, .addr.integer = &clock_sec,
  706|     36|                                 .dflt.integer = 0},
  707|     36|        {"clock_nsec",t_integer, .addr.integer = &clock_nsec,
  708|     36|                                 .dflt.integer = 0},
  709|     36|        {"precision", t_integer, .addr.integer = &precision,
  710|     36|                                 .dflt.integer = 0},
  711|     36|        {"qErr", t_integer, .addr.integer = &qErr,
  712|     36|                                 .dflt.integer = 0},
  713|       |        // ignore unknown keys, for cross-version compatibility
  714|     36|        {"", t_ignore},
  715|     36|        {NULL},
  716|       |        // *INDENT-ON*
  717|     36|    };
  718|     36|    int status;
  719|       |
  720|     36|    memset(&gpsdata->pps, 0, sizeof(gpsdata->pps));
  721|     36|    status = json_read_object(buf, json_attrs_pps, endptr);
  722|       |
  723|       |    // This is good until GPS are more than nanosec accurate
  724|     36|    gpsdata->pps.real.tv_sec = (time_t)real_sec;
  725|     36|    gpsdata->pps.real.tv_nsec = (long)real_nsec;
  726|     36|    gpsdata->pps.clock.tv_sec = (time_t)clock_sec;
  727|     36|    gpsdata->pps.clock.tv_nsec = (long)clock_nsec;
  728|       |    // hope qErr fits in int
  729|     36|    gpsdata->qErr = (long)qErr;
  730|       |
  731|       |    // FIXME: precision is currently parsed but discarded
  732|     36|    return status;
  733|     36|}
json_oscillator_read:
  737|     14|{
  738|     14|    bool running = false, reference = false, disciplined = false;
  739|     14|    int delta = 0;
  740|     14|    const struct json_attr_t json_attrs_osc[] = {
  741|       |        // *INDENT-OFF*
  742|     14|        {"class",       t_check,   .dflt.check = "OSC"},
  743|     14|        {"device",      t_string,  .addr.string = gpsdata->dev.path,
  744|     14|                                   .len = sizeof(gpsdata->dev.path)},
  745|     14|        {"running",     t_boolean, .addr.boolean = &running,
  746|     14|                                   .dflt.boolean = false},
  747|     14|        {"reference",   t_boolean, .addr.boolean = &reference,
  748|     14|                                   .dflt.boolean = false},
  749|     14|        {"disciplined", t_boolean, .addr.boolean = &disciplined,
  750|     14|                                   .dflt.boolean = false},
  751|     14|        {"delta",       t_integer, .addr.integer = &delta,
  752|     14|                                   .dflt.integer = 0},
  753|       |        // ignore unknown keys, for cross-version compatibility
  754|     14|        {"", t_ignore},
  755|     14|        {NULL},
  756|       |        // *INDENT-ON*
  757|     14|    };
  758|     14|    int status;
  759|       |
  760|     14|    memset(&gpsdata->osc, 0, sizeof(gpsdata->osc));
  761|     14|    status = json_read_object(buf, json_attrs_osc, endptr);
  762|       |
  763|     14|    gpsdata->osc.running = running;
  764|     14|    gpsdata->osc.reference = reference;
  765|     14|    gpsdata->osc.disciplined = disciplined;
  766|     14|    gpsdata->osc.delta = delta;
  767|       |
  768|     14|    return status;
  769|     14|}
libgps_json_unpack:
  781|  2.70k|{
  782|  2.70k|    int status;
  783|  2.70k|    char *classtag = strstr(buf, "\"class\":");
  784|       |
  785|  2.70k|    if (NULL == classtag) {
  ------------------
  |  Branch (785:9): [True: 379, False: 2.32k]
  ------------------
  786|    379|        return -1;
  787|    379|    }
  788|       |
  789|  2.32k|    if (str_starts_with(classtag, "\"class\":\"TPV\"")) {
  ------------------
  |  Branch (789:9): [True: 534, False: 1.79k]
  ------------------
  790|    534|        status = json_tpv_read(buf, gpsdata, end);
  791|    534|        gpsdata->set = STATUS_SET;
  ------------------
  |  | 2791|    534|#define STATUS_SET      (1llu<<9)
  ------------------
  792|    534|        if (0 != gpsdata->fix.time.tv_sec) {
  ------------------
  |  Branch (792:13): [True: 157, False: 377]
  ------------------
  793|    157|            gpsdata->set |= TIME_SET;
  ------------------
  |  | 2784|    157|#define TIME_SET        (1llu<<2)
  ------------------
  794|    157|        }
  795|    534|        if (0 != isfinite(gpsdata->fix.ept)) {
  ------------------
  |  Branch (795:13): [True: 2, False: 532]
  ------------------
  796|      2|            gpsdata->set |= TIMERR_SET;
  ------------------
  |  | 2785|      2|#define TIMERR_SET      (1llu<<3)
  ------------------
  797|      2|        }
  798|    534|        if (0 != isfinite(gpsdata->fix.longitude)) {
  ------------------
  |  Branch (798:13): [True: 3, False: 531]
  ------------------
  799|      3|            gpsdata->set |= LATLON_SET;
  ------------------
  |  | 2786|      3|#define LATLON_SET      (1llu<<4)
  ------------------
  800|      3|        }
  801|    534|        if (0 != isfinite(gpsdata->fix.altitude) ||
  ------------------
  |  Branch (801:13): [True: 4, False: 530]
  ------------------
  802|    534|            0 != isfinite(gpsdata->fix.altHAE) ||
  ------------------
  |  Branch (802:13): [True: 1, False: 529]
  ------------------
  803|    534|            0 != isfinite(gpsdata->fix.depth) ||
  ------------------
  |  Branch (803:13): [True: 1, False: 528]
  ------------------
  804|    534|            0 != isfinite(gpsdata->fix.altMSL)) {
  ------------------
  |  Branch (804:13): [True: 1, False: 527]
  ------------------
  805|      7|            gpsdata->set |= ALTITUDE_SET;
  ------------------
  |  | 2787|      7|#define ALTITUDE_SET    (1llu<<5)
  ------------------
  806|      7|        }
  807|    534|        if (0 != isfinite(gpsdata->fix.epx) &&
  ------------------
  |  Branch (807:13): [True: 54, False: 480]
  ------------------
  808|    534|            0 != isfinite(gpsdata->fix.epy)) {
  ------------------
  |  Branch (808:13): [True: 5, False: 49]
  ------------------
  809|      5|            gpsdata->set |= HERR_SET;
  ------------------
  |  | 2794|      5|#define HERR_SET        (1llu<<12)
  ------------------
  810|      5|        }
  811|    534|        if (0 != isfinite(gpsdata->fix.epv)) {
  ------------------
  |  Branch (811:13): [True: 7, False: 527]
  ------------------
  812|      7|            gpsdata->set |= VERR_SET;
  ------------------
  |  | 2795|      7|#define VERR_SET        (1llu<<13)
  ------------------
  813|      7|        }
  814|    534|        if (0 != isfinite(gpsdata->fix.track)) {
  ------------------
  |  Branch (814:13): [True: 1, False: 533]
  ------------------
  815|      1|            gpsdata->set |= TRACK_SET;
  ------------------
  |  | 2789|      1|#define TRACK_SET       (1llu<<7)
  ------------------
  816|      1|        }
  817|    534|        if (0 != isfinite(gpsdata->fix.magnetic_track) ||
  ------------------
  |  Branch (817:13): [True: 1, False: 533]
  ------------------
  818|    534|            0 != isfinite(gpsdata->fix.magnetic_var)) {
  ------------------
  |  Branch (818:13): [True: 1, False: 532]
  ------------------
  819|      2|            gpsdata->set |= MAGNETIC_TRACK_SET;
  ------------------
  |  | 2820|      2|#define MAGNETIC_TRACK_SET (1llu<<38)
  ------------------
  820|      2|        }
  821|    534|        if (0 != isfinite(gpsdata->fix.speed)) {
  ------------------
  |  Branch (821:13): [True: 1, False: 533]
  ------------------
  822|      1|            gpsdata->set |= SPEED_SET;
  ------------------
  |  | 2788|      1|#define SPEED_SET       (1llu<<6)
  ------------------
  823|      1|        }
  824|    534|        if (0 != isfinite(gpsdata->fix.climb)) {
  ------------------
  |  Branch (824:13): [True: 1, False: 533]
  ------------------
  825|      1|            gpsdata->set |= CLIMB_SET;
  ------------------
  |  | 2790|      1|#define CLIMB_SET       (1llu<<8)
  ------------------
  826|      1|        }
  827|    534|        if (0 != isfinite(gpsdata->fix.epd)) {
  ------------------
  |  Branch (827:13): [True: 40, False: 494]
  ------------------
  828|     40|            gpsdata->set |= TRACKERR_SET;
  ------------------
  |  | 2799|     40|#define TRACKERR_SET    (1llu<<17)
  ------------------
  829|     40|        }
  830|    534|        if (0 != isfinite(gpsdata->fix.eps)) {
  ------------------
  |  Branch (830:13): [True: 17, False: 517]
  ------------------
  831|     17|            gpsdata->set |= SPEEDERR_SET;
  ------------------
  |  | 2798|     17|#define SPEEDERR_SET    (1llu<<16)
  ------------------
  832|     17|        }
  833|    534|        if (0 != isfinite(gpsdata->fix.epc)) {
  ------------------
  |  Branch (833:13): [True: 3, False: 531]
  ------------------
  834|      3|            gpsdata->set |= CLIMBERR_SET;
  ------------------
  |  | 2800|      3|#define CLIMBERR_SET    (1llu<<18)
  ------------------
  835|      3|        }
  836|    534|        if (MODE_NOT_SEEN != gpsdata->fix.mode) {
  ------------------
  |  |  186|    534|#define MODE_NOT_SEEN   0       // mode update not seen yet
  ------------------
  |  Branch (836:13): [True: 55, False: 479]
  ------------------
  837|     55|            gpsdata->set |= MODE_SET;
  ------------------
  |  | 2792|     55|#define MODE_SET        (1llu<<10)
  ------------------
  838|     55|        }
  839|    534|        if (0 != isfinite(gpsdata->fix.wanglem) ||
  ------------------
  |  Branch (839:13): [True: 1, False: 533]
  ------------------
  840|    534|            0 != isfinite(gpsdata->fix.wangler) ||
  ------------------
  |  Branch (840:13): [True: 1, False: 532]
  ------------------
  841|    534|            0 != isfinite(gpsdata->fix.wanglet) ||
  ------------------
  |  Branch (841:13): [True: 1, False: 531]
  ------------------
  842|    534|            0 != isfinite(gpsdata->fix.wspeedr) ||
  ------------------
  |  Branch (842:13): [True: 1, False: 530]
  ------------------
  843|    534|            0 != isfinite(gpsdata->fix.wspeedt)) {
  ------------------
  |  Branch (843:13): [True: 1, False: 529]
  ------------------
  844|      5|            gpsdata->set |= NAVDATA_SET;
  ------------------
  |  | 2816|      5|#define NAVDATA_SET     (1llu<<34)
  ------------------
  845|      5|        }
  846|    534|        if (0 != isfinite(gpsdata->fix.NED.relPosN) ||
  ------------------
  |  Branch (846:13): [True: 1, False: 533]
  ------------------
  847|    534|            0 != isfinite(gpsdata->fix.NED.relPosE) ||
  ------------------
  |  Branch (847:13): [True: 1, False: 532]
  ------------------
  848|    534|            0 != isfinite(gpsdata->fix.NED.relPosD) ||
  ------------------
  |  Branch (848:13): [True: 1, False: 531]
  ------------------
  849|    534|            0 != isfinite(gpsdata->fix.NED.relPosH) ||
  ------------------
  |  Branch (849:13): [True: 1, False: 530]
  ------------------
  850|    534|            0 != isfinite(gpsdata->fix.NED.relPosL) ||
  ------------------
  |  Branch (850:13): [True: 1, False: 529]
  ------------------
  851|    534|            0 != isfinite(gpsdata->fix.NED.velN) ||
  ------------------
  |  Branch (851:13): [True: 1, False: 528]
  ------------------
  852|    534|            0 != isfinite(gpsdata->fix.NED.velE) ||
  ------------------
  |  Branch (852:13): [True: 1, False: 527]
  ------------------
  853|    534|            0 != isfinite(gpsdata->fix.NED.velD)) {
  ------------------
  |  Branch (853:13): [True: 1, False: 526]
  ------------------
  854|      8|            gpsdata->set |= NED_SET;
  ------------------
  |  | 2822|      8|#define NED_SET         (1llu<<40)
  ------------------
  855|      8|        }
  856|    534|        if ((0 != isfinite(gpsdata->fix.ecef.x)) &&
  ------------------
  |  Branch (856:13): [True: 5, False: 529]
  ------------------
  857|    534|            (0 != isfinite(gpsdata->fix.ecef.y)) &&
  ------------------
  |  Branch (857:13): [True: 4, False: 1]
  ------------------
  858|    534|            (0 != isfinite(gpsdata->fix.ecef.z))) {
  ------------------
  |  Branch (858:13): [True: 1, False: 3]
  ------------------
  859|       |            // All, or none.  Clients can just do their own isfinite()s
  860|      1|            gpsdata->set |= ECEF_SET;
  ------------------
  |  | 2818|      1|#define ECEF_SET        (1llu<<36)
  ------------------
  861|      1|        }
  862|    534|        if ((0 != isfinite(gpsdata->fix.ecef.vx)) &&
  ------------------
  |  Branch (862:13): [True: 3, False: 531]
  ------------------
  863|    534|            (0 != isfinite(gpsdata->fix.ecef.vy)) &&
  ------------------
  |  Branch (863:13): [True: 2, False: 1]
  ------------------
  864|    534|            (0 != isfinite(gpsdata->fix.ecef.vz))) {
  ------------------
  |  Branch (864:13): [True: 1, False: 1]
  ------------------
  865|       |            // All, or none.  Clients can just do their own isfinite()s
  866|      1|            gpsdata->set |= VECEF_SET;
  ------------------
  |  | 2819|      1|#define VECEF_SET       (1llu<<37)
  ------------------
  867|      1|        }
  868|    534|        return FILTER(status);
  ------------------
  |  |  776|    534|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|    534|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 534]
  |  |  ------------------
  ------------------
  869|    534|    }
  870|  1.79k|    if (str_starts_with(classtag, "\"class\":\"GST\"")) {
  ------------------
  |  Branch (870:9): [True: 44, False: 1.74k]
  ------------------
  871|     44|        status = json_noise_read(buf, gpsdata, end);
  872|     44|        if (PASS(status)) {
  ------------------
  |  |  775|     44|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|     26|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 18, False: 26]
  |  |  |  Branch (775:32): [True: 0, False: 26]
  |  |  ------------------
  ------------------
  873|     18|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|     18|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|     18|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|     18|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|     18|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|     18|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|     18|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|     18|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|     18|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|     18|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|     18|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|     18|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|     18|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|     18|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|     18|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|     18|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  874|     18|            gpsdata->set |= GST_SET;
  ------------------
  |  | 2809|     18|#define GST_SET         (1llu<<27)
  ------------------
  875|     18|        }
  876|     44|        return FILTER(status);
  ------------------
  |  |  776|     44|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     44|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 44]
  |  |  ------------------
  ------------------
  877|     44|    }
  878|  1.74k|    if (str_starts_with(classtag, "\"class\":\"SKY\"")) {
  ------------------
  |  Branch (878:9): [True: 228, False: 1.51k]
  ------------------
  879|    228|        status = json_sky_read(buf, gpsdata, end);
  880|    228|        return FILTER(status);
  ------------------
  |  |  776|    228|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|    228|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 228]
  |  |  ------------------
  ------------------
  881|    228|    }
  882|  1.51k|    if (str_starts_with(classtag, "\"class\":\"ATT\"")) {
  ------------------
  |  Branch (882:9): [True: 58, False: 1.46k]
  ------------------
  883|     58|        status = json_att_read(buf, gpsdata, end);
  884|     58|        if (PASS(status)) {
  ------------------
  |  |  775|     58|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|     32|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 26, False: 32]
  |  |  |  Branch (775:32): [True: 0, False: 32]
  |  |  ------------------
  ------------------
  885|     26|            gpsdata->set |= ATTITUDE_SET;
  ------------------
  |  | 2796|     26|#define ATTITUDE_SET    (1llu<<14)
  ------------------
  886|     26|        }
  887|     58|        return FILTER(status);
  ------------------
  |  |  776|     58|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     58|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 58]
  |  |  ------------------
  ------------------
  888|     58|    }
  889|  1.46k|    if (str_starts_with(classtag, "\"class\":\"IMU\"")) {
  ------------------
  |  Branch (889:9): [True: 64, False: 1.39k]
  ------------------
  890|     64|        status = json_imu_read(buf, gpsdata, end);
  891|     64|        if (PASS(status)) {
  ------------------
  |  |  775|     64|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|     52|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 12, False: 52]
  |  |  |  Branch (775:32): [True: 0, False: 52]
  |  |  ------------------
  ------------------
  892|     12|            gpsdata->set |= IMU_SET;
  ------------------
  |  | 2825|     12|#define IMU_SET         (1llu<<43)
  ------------------
  893|     12|        }
  894|     64|        return FILTER(status);
  ------------------
  |  |  776|     64|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     64|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 64]
  |  |  ------------------
  ------------------
  895|     64|    }
  896|  1.39k|    if (str_starts_with(classtag, "\"class\":\"DEVICES\"")) {
  ------------------
  |  Branch (896:9): [True: 58, False: 1.33k]
  ------------------
  897|     58|        status = json_devicelist_read(buf, gpsdata, end);
  898|     58|        if (PASS(status)) {
  ------------------
  |  |  775|     58|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|     57|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 1, False: 57]
  |  |  |  Branch (775:32): [True: 0, False: 57]
  |  |  ------------------
  ------------------
  899|      1|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|      1|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|      1|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|      1|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|      1|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|      1|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|      1|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|      1|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|      1|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|      1|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|      1|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|      1|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|      1|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|      1|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|      1|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|      1|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  900|      1|            gpsdata->set |= DEVICELIST_SET;
  ------------------
  |  | 2802|      1|#define DEVICELIST_SET  (1llu<<20)
  ------------------
  901|      1|        }
  902|     58|        return FILTER(status);
  ------------------
  |  |  776|     58|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     58|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 58]
  |  |  ------------------
  ------------------
  903|     58|    }
  904|  1.33k|    if (str_starts_with(classtag, "\"class\":\"DEVICE\"")) {
  ------------------
  |  Branch (904:9): [True: 23, False: 1.31k]
  ------------------
  905|     23|        status = json_device_read(buf, &gpsdata->dev, end);
  906|     23|        if (PASS(status))
  ------------------
  |  |  775|     23|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|     20|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 3, False: 20]
  |  |  |  Branch (775:32): [True: 0, False: 20]
  |  |  ------------------
  ------------------
  907|      3|            gpsdata->set |= DEVICE_SET;
  ------------------
  |  | 2801|      3|#define DEVICE_SET      (1llu<<19)
  ------------------
  908|     23|        return FILTER(status);
  ------------------
  |  |  776|     23|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     23|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 23]
  |  |  ------------------
  ------------------
  909|     23|    }
  910|  1.31k|    if (str_starts_with(classtag, "\"class\":\"WATCH\"")) {
  ------------------
  |  Branch (910:9): [True: 52, False: 1.26k]
  ------------------
  911|     52|        status = json_watch_read(buf, &gpsdata->policy, end);
  912|     52|        if (PASS(status)) {
  ------------------
  |  |  775|     52|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|     16|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 36, False: 16]
  |  |  |  Branch (775:32): [True: 0, False: 16]
  |  |  ------------------
  ------------------
  913|     36|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|     36|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|     36|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|     36|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|     36|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|     36|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|     36|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|     36|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|     36|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|     36|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|     36|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|     36|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|     36|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|     36|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|     36|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|     36|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  914|     36|            gpsdata->set |= POLICY_SET;
  ------------------
  |  | 2811|     36|#define POLICY_SET      (1llu<<29)
  ------------------
  915|     36|        }
  916|     52|        return FILTER(status);
  ------------------
  |  |  776|     52|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     52|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 52]
  |  |  ------------------
  ------------------
  917|     52|    }
  918|  1.26k|    if (str_starts_with(classtag, "\"class\":\"VERSION\"")) {
  ------------------
  |  Branch (918:9): [True: 9, False: 1.25k]
  ------------------
  919|      9|        status = json_version_read(buf, gpsdata, end);
  920|      9|        if (status ==  0) {
  ------------------
  |  Branch (920:13): [True: 3, False: 6]
  ------------------
  921|      3|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|      3|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|      3|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|      3|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|      3|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|      3|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|      3|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|      3|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|      3|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|      3|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|      3|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|      3|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|      3|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|      3|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|      3|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|      3|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  922|      3|            gpsdata->set |= VERSION_SET;
  ------------------
  |  | 2810|      3|#define VERSION_SET     (1llu<<28)
  ------------------
  923|      3|        }
  924|      9|        return FILTER(status);
  ------------------
  |  |  776|      9|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|      9|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 9]
  |  |  ------------------
  ------------------
  925|      9|    }
  926|  1.25k|#ifdef RTCM104V2_ENABLE
  927|  1.25k|    if (str_starts_with(classtag, "\"class\":\"RTCM2\"")) {
  ------------------
  |  Branch (927:9): [True: 319, False: 935]
  ------------------
  928|    319|        status = json_rtcm2_read(buf,
  929|    319|                                 gpsdata->dev.path, sizeof(gpsdata->dev.path),
  930|    319|                                 &gpsdata->rtcm2, end);
  931|    319|        if (PASS(status)) {
  ------------------
  |  |  775|    319|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|    226|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 93, False: 226]
  |  |  |  Branch (775:32): [True: 21, False: 205]
  |  |  ------------------
  ------------------
  932|    114|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|    114|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|    114|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|    114|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|    114|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|    114|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|    114|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|    114|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|    114|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|    114|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|    114|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|    114|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|    114|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|    114|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|    114|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|    114|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  933|    114|            gpsdata->set |= RTCM2_SET;
  ------------------
  |  | 2804|    114|#define RTCM2_SET       (1llu<<22)
  ------------------
  934|    114|        }
  935|    319|        return FILTER(status);
  ------------------
  |  |  776|    319|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|    319|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 21, False: 298]
  |  |  ------------------
  ------------------
  936|    319|    }
  937|    935|#endif  // RTCM104V2_ENABLE
  938|    935|#ifdef RTCM104V3_ENABLE
  939|    935|    if (str_starts_with(classtag, "\"class\":\"RTCM3\"")) {
  ------------------
  |  Branch (939:9): [True: 156, False: 779]
  ------------------
  940|    156|        status = json_rtcm3_read(buf,
  941|    156|                                 gpsdata->dev.path, sizeof(gpsdata->dev.path),
  942|    156|                                 &gpsdata->rtcm3, end);
  943|    156|        if (PASS(status)) {
  ------------------
  |  |  775|    156|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|    131|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 25, False: 131]
  |  |  |  Branch (775:32): [True: 2, False: 129]
  |  |  ------------------
  ------------------
  944|     27|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|     27|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|     27|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|     27|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|     27|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|     27|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|     27|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|     27|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|     27|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|     27|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|     27|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|     27|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|     27|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|     27|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|     27|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|     27|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  945|     27|            gpsdata->set |= RTCM3_SET;
  ------------------
  |  | 2805|     27|#define RTCM3_SET       (1llu<<23)
  ------------------
  946|     27|        }
  947|    156|        return FILTER(status);
  ------------------
  |  |  776|    156|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|    156|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 2, False: 154]
  |  |  ------------------
  ------------------
  948|    156|    }
  949|    779|#endif  // RTCM104V3_ENABLE
  950|    779|#ifdef AIVDM_ENABLE
  951|    779|    if (str_starts_with(classtag, "\"class\":\"AIS\"")) {
  ------------------
  |  Branch (951:9): [True: 343, False: 436]
  ------------------
  952|    343|        status = json_ais_read(buf,
  953|    343|                               gpsdata->dev.path, sizeof(gpsdata->dev.path),
  954|    343|                               &gpsdata->ais, end);
  955|    343|        if (PASS(status)) {
  ------------------
  |  |  775|    343|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|    191|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 152, False: 191]
  |  |  |  Branch (775:32): [True: 29, False: 162]
  |  |  ------------------
  ------------------
  956|    181|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|    181|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|    181|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|    181|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|    181|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|    181|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|    181|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|    181|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|    181|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|    181|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|    181|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|    181|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|    181|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|    181|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|    181|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|    181|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  957|    181|            gpsdata->set |= AIS_SET;
  ------------------
  |  | 2806|    181|#define AIS_SET         (1llu<<24)
  ------------------
  958|    181|        }
  959|    343|        return FILTER(status);
  ------------------
  |  |  776|    343|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|    343|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 29, False: 314]
  |  |  ------------------
  ------------------
  960|    343|    }
  961|    436|#endif  // AIVDM_ENABLE
  962|    436|    if (str_starts_with(classtag, "\"class\":\"ERROR\"")) {
  ------------------
  |  Branch (962:9): [True: 8, False: 428]
  ------------------
  963|      8|        status = json_error_read(buf, gpsdata, end);
  964|      8|        if (PASS(status)) {
  ------------------
  |  |  775|      8|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|      6|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 2, False: 6]
  |  |  |  Branch (775:32): [True: 0, False: 6]
  |  |  ------------------
  ------------------
  965|      2|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|      2|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|      2|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|      2|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|      2|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|      2|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|      2|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|      2|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|      2|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|      2|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|      2|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|      2|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|      2|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|      2|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|      2|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|      2|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  966|      2|            gpsdata->set |= ERROR_SET;
  ------------------
  |  | 2813|      2|#define ERROR_SET       (1llu<<31)
  ------------------
  967|      2|        }
  968|      8|        return FILTER(status);
  ------------------
  |  |  776|      8|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|      8|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 8]
  |  |  ------------------
  ------------------
  969|      8|    }
  970|    428|    if (str_starts_with(classtag, "\"class\":\"TOFF\"")) {
  ------------------
  |  Branch (970:9): [True: 21, False: 407]
  ------------------
  971|     21|        status = json_toff_read(buf, gpsdata, end);
  972|     21|        if (PASS(status)) {
  ------------------
  |  |  775|     21|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|     13|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 8, False: 13]
  |  |  |  Branch (775:32): [True: 0, False: 13]
  |  |  ------------------
  ------------------
  973|      8|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|      8|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|      8|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|      8|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|      8|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|      8|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|      8|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|      8|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|      8|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|      8|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|      8|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|      8|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|      8|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|      8|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|      8|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|      8|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  974|      8|            gpsdata->set |= TOFF_SET;
  ------------------
  |  | 2814|      8|#define TOFF_SET        (1llu<<32)      // not yet used
  ------------------
  975|      8|        }
  976|     21|        return FILTER(status);
  ------------------
  |  |  776|     21|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     21|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 21]
  |  |  ------------------
  ------------------
  977|     21|    }
  978|    407|    if (str_starts_with(classtag, "\"class\":\"PPS\"")) {
  ------------------
  |  Branch (978:9): [True: 36, False: 371]
  ------------------
  979|     36|        status = json_pps_read(buf, gpsdata, end);
  980|     36|        if (PASS(status)) {
  ------------------
  |  |  775|     36|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|     12|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 24, False: 12]
  |  |  |  Branch (775:32): [True: 0, False: 12]
  |  |  ------------------
  ------------------
  981|     24|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|     24|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|     24|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|     24|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|     24|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|     24|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|     24|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|     24|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|     24|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|     24|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|     24|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|     24|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|     24|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|     24|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|     24|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|     24|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  982|     24|            gpsdata->set |= PPS_SET;
  ------------------
  |  | 2815|     24|#define PPS_SET         (1llu<<33)
  ------------------
  983|     24|        }
  984|     36|        return FILTER(status);
  ------------------
  |  |  776|     36|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     36|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 36]
  |  |  ------------------
  ------------------
  985|     36|    }
  986|    371|    if (str_starts_with(classtag, "\"class\":\"OSC\"")) {
  ------------------
  |  Branch (986:9): [True: 14, False: 357]
  ------------------
  987|     14|        status = json_oscillator_read(buf, gpsdata, end);
  988|     14|        if (PASS(status)) {
  ------------------
  |  |  775|     14|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|      6|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 8, False: 6]
  |  |  |  Branch (775:32): [True: 0, False: 6]
  |  |  ------------------
  ------------------
  989|      8|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|      8|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|      8|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|      8|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|      8|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|      8|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|      8|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|      8|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|      8|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|      8|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|      8|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|      8|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|      8|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|      8|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|      8|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|      8|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  990|      8|            gpsdata->set |= OSCILLATOR_SET;
  ------------------
  |  | 2817|      8|#define OSCILLATOR_SET  (1llu<<35)
  ------------------
  991|      8|        }
  992|     14|        return FILTER(status);
  ------------------
  |  |  776|     14|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|     14|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 14]
  |  |  ------------------
  ------------------
  993|     14|    }
  994|    357|    if (str_starts_with(classtag, "\"class\":\"RAW\"")) {
  ------------------
  |  Branch (994:9): [True: 136, False: 221]
  ------------------
  995|    136|        status = json_raw_read(buf, gpsdata, end);
  996|    136|        if (PASS(status)) {
  ------------------
  |  |  775|    136|#define PASS(n) (((n) == 0) || ((n) == JSON_ERR_BADATTR))
  |  |  ------------------
  |  |  |  |  154|    108|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (775:18): [True: 28, False: 108]
  |  |  |  Branch (775:32): [True: 0, False: 108]
  |  |  ------------------
  ------------------
  997|     28|            gpsdata->set &= ~UNION_SET;
  ------------------
  |  | 2880|     28|#define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2806|     28|#define AIS_SET         (1llu<<24)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2813|     28|#define ERROR_SET       (1llu<<31)
  |  |  ------------------
  |  |               #define UNION_SET       (AIS_SET|ERROR_SET|GST_SET| \
  |  |  ------------------
  |  |  |  | 2809|     28|#define GST_SET         (1llu<<27)
  |  |  ------------------
  |  | 2881|     28|                         LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2812|     28|#define LOGMESSAGE_SET  (1llu<<30)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2817|     28|#define OSCILLATOR_SET  (1llu<<35)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2815|     28|#define PPS_SET         (1llu<<33)
  |  |  ------------------
  |  |                                        LOGMESSAGE_SET|OSCILLATOR_SET|PPS_SET|RAW_SET| \
  |  |  ------------------
  |  |  |  | 2821|     28|#define RAW_SET         (1llu<<39)
  |  |  ------------------
  |  | 2882|     28|                         RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2804|     28|#define RTCM2_SET       (1llu<<22)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2805|     28|#define RTCM3_SET       (1llu<<23)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2808|     28|#define SUBFRAME_SET    (1llu<<26)
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2814|     28|#define TOFF_SET        (1llu<<32)      // not yet used
  |  |  ------------------
  |  |                                        RTCM2_SET|RTCM3_SET|SUBFRAME_SET|TOFF_SET|VERSION_SET)
  |  |  ------------------
  |  |  |  | 2810|     28|#define VERSION_SET     (1llu<<28)
  |  |  ------------------
  ------------------
  998|     28|            gpsdata->set |= RAW_SET;
  ------------------
  |  | 2821|     28|#define RAW_SET         (1llu<<39)
  ------------------
  999|     28|        }
 1000|    136|        return FILTER(status);
  ------------------
  |  |  776|    136|#define FILTER(n) ((n) == JSON_ERR_BADATTR ? 0 : n)
  |  |  ------------------
  |  |  |  |  154|    136|#define JSON_ERR_BADATTR         3      // unknown attribute name
  |  |  ------------------
  |  |  |  Branch (776:20): [True: 0, False: 136]
  |  |  ------------------
  ------------------
 1001|    136|    }
 1002|       |    // else, unkwown class type
 1003|    221|    return -1;
 1004|    357|}
libgps_json.c:json_tpv_read:
   37|    534|{
   38|    534|    int ret;
   39|       |
   40|    534|    const struct json_attr_t json_attrs_1[] = {
   41|       |        // *INDENT-OFF*
   42|    534|        {"class",  t_check,   .dflt.check = "TPV"},
   43|    534|        {"alt",    t_real,    .addr.real = &gpsdata->fix.altitude,
   44|    534|                                 .dflt.real = NAN}, // DEPRECATED, undefined
   45|    534|        {"altHAE", t_real,    .addr.real = &gpsdata->fix.altHAE,
   46|    534|                                 .dflt.real = NAN},
   47|    534|        {"altMSL", t_real,    .addr.real = &gpsdata->fix.altMSL,
   48|    534|                                 .dflt.real = NAN},
   49|    534|        {"ant",    t_integer, .addr.integer = &gpsdata->fix.ant_stat,
   50|    534|                                 .dflt.integer = 0},
   51|    534|        {"baseS",     t_integer,   .addr.integer = &gpsdata->fix.base.status,
   52|    534|         .dflt.integer = STATUS_UNK},     // aka zero
  ------------------
  |  |  197|    534|#define STATUS_UNK      0       // Unknown status
  ------------------
   53|    534|        {"baseE",     t_real,      .addr.real = &gpsdata->fix.base.east,
   54|    534|         .dflt.real = NAN},
   55|    534|        {"baseN",     t_real,      .addr.real = &gpsdata->fix.base.north,
   56|    534|         .dflt.real = NAN},
   57|    534|        {"baseU",     t_real,      .addr.real = &gpsdata->fix.base.up,
   58|    534|         .dflt.real = NAN},
   59|    534|        {"baseL",     t_real,      .addr.real = &gpsdata->fix.base.length,
   60|    534|         .dflt.real = NAN},
   61|    534|        {"baseC",     t_real,      .addr.real = &gpsdata->fix.base.course,
   62|    534|         .dflt.real = NAN},
   63|    534|        {"climb",  t_real,    .addr.real = &gpsdata->fix.climb,
   64|    534|                                 .dflt.real = NAN},
   65|    534|        {"datum",  t_string,  .addr.string = gpsdata->fix.datum,
   66|    534|                                 .len = sizeof(gpsdata->fix.datum)},
   67|    534|        {"device", t_string,  .addr.string = gpsdata->dev.path,
   68|    534|                                 .len = sizeof(gpsdata->dev.path)},
   69|    534|        {"depth", t_real,  .addr.real = &gpsdata->fix.depth,
   70|    534|                                 .dflt.real = NAN},
   71|    534|        {"dgpsAge", t_real, .addr.real = &gpsdata->fix.dgps_age,
   72|    534|                                 .dflt.real = NAN},
   73|    534|        {"dgpsRatio", t_real, .addr.real = &gpsdata->fix.base.ratio,
   74|    534|                                 .dflt.real = NAN},
   75|    534|        {"dgpsSta", t_integer, .addr.integer = &gpsdata->fix.dgps_station,
   76|    534|                                 .dflt.integer = -1},
   77|    534|        {"ecefx",  t_real,    .addr.real = &gpsdata->fix.ecef.x,
   78|    534|                                 .dflt.real = NAN},
   79|    534|        {"ecefy",  t_real,    .addr.real = &gpsdata->fix.ecef.y,
   80|    534|                                 .dflt.real = NAN},
   81|    534|        {"ecefz",  t_real,    .addr.real = &gpsdata->fix.ecef.z,
   82|    534|                                 .dflt.real = NAN},
   83|    534|        {"ecefvx", t_real,    .addr.real = &gpsdata->fix.ecef.vx,
   84|    534|                                 .dflt.real = NAN},
   85|    534|        {"ecefvy", t_real,    .addr.real = &gpsdata->fix.ecef.vy,
   86|    534|                                 .dflt.real = NAN},
   87|    534|        {"ecefvz", t_real,    .addr.real = &gpsdata->fix.ecef.vz,
   88|    534|                                 .dflt.real = NAN},
   89|    534|        {"ecefpAcc", t_real,  .addr.real = &gpsdata->fix.ecef.pAcc,
   90|    534|                                 .dflt.real = NAN},
   91|    534|        {"ecefvAcc", t_real,  .addr.real = &gpsdata->fix.ecef.vAcc,
   92|    534|                                 .dflt.real = NAN},
   93|    534|        {"epc",    t_real,    .addr.real = &gpsdata->fix.epc,
   94|    534|                                 .dflt.real = NAN},
   95|    534|        {"epd",    t_real,    .addr.real = &gpsdata->fix.epd,
   96|    534|                                 .dflt.real = NAN},
   97|    534|        {"eph",    t_real,    .addr.real = &gpsdata->fix.eph,
   98|    534|                                 .dflt.real = NAN},
   99|    534|        {"eps",    t_real,    .addr.real = &gpsdata->fix.eps,
  100|    534|                                 .dflt.real = NAN},
  101|    534|        {"ept",    t_real,    .addr.real = &gpsdata->fix.ept,
  102|    534|                                 .dflt.real = NAN},
  103|    534|        {"epx",    t_real,    .addr.real = &gpsdata->fix.epx,
  104|    534|                                 .dflt.real = NAN},
  105|    534|        {"epy",    t_real,    .addr.real = &gpsdata->fix.epy,
  106|    534|                                 .dflt.real = NAN},
  107|    534|        {"epv",    t_real,    .addr.real = &gpsdata->fix.epv,
  108|    534|                                 .dflt.real = NAN},
  109|    534|        {"geoidSep", t_real,  .addr.real = &gpsdata->fix.geoid_sep,
  110|    534|                                 .dflt.real = NAN},
  111|    534|        {"lat",    t_real,    .addr.real = &gpsdata->fix.latitude,
  112|    534|                                 .dflt.real = NAN},
  113|    534|        {"leapseconds",   t_integer, .addr.integer = &gpsdata->leap_seconds,
  114|    534|                                 .dflt.integer = 0},
  115|    534|        {"lon",    t_real,    .addr.real = &gpsdata->fix.longitude,
  116|    534|                                 .dflt.real = NAN},
  117|    534|        {"magtrack",  t_real,    .addr.real = &gpsdata->fix.magnetic_track,
  118|    534|                                 .dflt.real = NAN},
  119|    534|        {"magvar",  t_real,   .addr.real = &gpsdata->fix.magnetic_var,
  120|    534|                                 .dflt.real = NAN},
  121|    534|        {"mode",   t_integer, .addr.integer = &gpsdata->fix.mode,
  122|    534|                                 .dflt.integer = MODE_NOT_SEEN},
  ------------------
  |  |  186|    534|#define MODE_NOT_SEEN   0       // mode update not seen yet
  ------------------
  123|    534|        {"relD", t_real,  .addr.real = &gpsdata->fix.NED.relPosD,
  124|    534|                                 .dflt.real = NAN},
  125|    534|        {"relE", t_real,  .addr.real = &gpsdata->fix.NED.relPosE,
  126|    534|                                 .dflt.real = NAN},
  127|    534|        {"relN", t_real,  .addr.real = &gpsdata->fix.NED.relPosN,
  128|    534|                                 .dflt.real = NAN},
  129|    534|        {"relH", t_real,  .addr.real = &gpsdata->fix.NED.relPosH,
  130|    534|                                 .dflt.real = NAN},
  131|    534|        {"relL", t_real,  .addr.real = &gpsdata->fix.NED.relPosL,
  132|    534|                                 .dflt.real = NAN},
  133|    534|        {"temp",   t_real, .addr.real = &gpsdata->fix.temp,
  134|    534|                                 .dflt.real = NAN},
  135|    534|        {"time",   t_time,    .addr.ts = &gpsdata->fix.time,
  136|    534|                                 .dflt.ts = {0, 0}},
  137|    534|        {"track",  t_real,    .addr.real = &gpsdata->fix.track,
  138|    534|                                 .dflt.real = NAN},
  139|    534|        {"sep",    t_real,    .addr.real = &gpsdata->fix.sep,
  140|    534|                                 .dflt.real = NAN},
  141|    534|        {"speed",  t_real,    .addr.real = &gpsdata->fix.speed,
  142|    534|                                 .dflt.real = NAN},
  143|    534|        {"status", t_integer, .addr.integer = &gpsdata->fix.status,
  144|    534|                                 .dflt.integer = STATUS_UNK},
  ------------------
  |  |  197|    534|#define STATUS_UNK      0       // Unknown status
  ------------------
  145|    534|        {"velD", t_real,  .addr.real = &gpsdata->fix.NED.velD,
  146|    534|                                 .dflt.real = NAN},
  147|    534|        {"velE", t_real,  .addr.real = &gpsdata->fix.NED.velE,
  148|    534|                                 .dflt.real = NAN},
  149|    534|        {"velN", t_real,  .addr.real = &gpsdata->fix.NED.velN,
  150|    534|                                 .dflt.real = NAN},
  151|    534|        {"wanglem", t_real, .addr.real = &gpsdata->fix.wanglem,
  152|    534|                                 .dflt.real = NAN},
  153|    534|        {"wangler", t_real, .addr.real = &gpsdata->fix.wangler,
  154|    534|                                 .dflt.real = NAN},
  155|    534|        {"wanglet", t_real, .addr.real = &gpsdata->fix.wanglet,
  156|    534|                                 .dflt.real = NAN},
  157|    534|        {"wspeedr", t_real, .addr.real = &gpsdata->fix.wspeedr,
  158|    534|                                 .dflt.real = NAN},
  159|    534|        {"wspeedt", t_real, .addr.real = &gpsdata->fix.wspeedt,
  160|    534|                                 .dflt.real = NAN},
  161|    534|        {"wtemp", t_real, .addr.real = &gpsdata->fix.wtemp,
  162|    534|                                 .dflt.real = NAN},
  163|       |        // ignore unknown keys, for cross-version compatibility
  164|    534|        {"", t_ignore},
  165|       |
  166|    534|        {NULL},
  167|       |        // *INDENT-ON*
  168|    534|    };
  169|       |
  170|    534|    ret = json_read_object(buf, json_attrs_1, endptr);
  171|    534|    return ret;
  172|    534|}
libgps_json.c:json_noise_read:
  176|     44|{
  177|     44|    int ret;
  178|       |
  179|     44|    const struct json_attr_t json_attrs_1[] = {
  180|       |        // *INDENT-OFF*
  181|     44|        {"class",  t_check,   .dflt.check = "GST"},
  182|     44|        {"device", t_string,  .addr.string = gpsdata->dev.path,
  183|     44|                                 .len = sizeof(gpsdata->dev.path)},
  184|     44|        {"time",   t_time,    .addr.ts = &gpsdata->gst.utctime,
  185|     44|                                 .dflt.ts = {0, 0}},
  186|     44|        {"rms",    t_real,    .addr.real = &gpsdata->gst.rms_deviation,
  187|     44|                                 .dflt.real = NAN},
  188|     44|        {"major",  t_real,    .addr.real = &gpsdata->gst.smajor_deviation,
  189|     44|                                 .dflt.real = NAN},
  190|     44|        {"minor",  t_real,    .addr.real = &gpsdata->gst.sminor_deviation,
  191|     44|                                 .dflt.real = NAN},
  192|     44|        {"orient", t_real,    .addr.real = &gpsdata->gst.smajor_orientation,
  193|     44|                                 .dflt.real = NAN},
  194|     44|        {"lat",    t_real,    .addr.real = &gpsdata->gst.lat_err_deviation,
  195|     44|                                 .dflt.real = NAN},
  196|     44|        {"lon",    t_real,    .addr.real = &gpsdata->gst.lon_err_deviation,
  197|     44|                                 .dflt.real = NAN},
  198|     44|        {"alt",    t_real,    .addr.real = &gpsdata->gst.alt_err_deviation,
  199|     44|                                 .dflt.real = NAN},
  200|       |        // ignore unknown keys, for cross-version compatibility
  201|     44|        {"", t_ignore},
  202|     44|        {NULL},
  203|       |        // *INDENT-ON*
  204|     44|    };
  205|       |
  206|     44|    ret = json_read_object(buf, json_attrs_1, endptr);
  207|       |
  208|     44|    return ret;
  209|     44|}
libgps_json.c:json_sky_read:
  286|    228|{
  287|       |
  288|    228|    const struct json_attr_t json_attrs_satellites[] = {
  289|       |        // *INDENT-OFF*
  290|    228|        {"PRN",    t_short,   STRUCTOBJECT(struct satellite_t, PRN)},
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  291|    228|        {"el",     t_real,    STRUCTOBJECT(struct satellite_t, elevation),
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  292|    228|                              .dflt.real = NAN},
  293|    228|        {"az",     t_real,    STRUCTOBJECT(struct satellite_t, azimuth),
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  294|    228|                              .dflt.real = NAN},
  295|    228|        {"ss",     t_real,    STRUCTOBJECT(struct satellite_t, ss),
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  296|    228|                              .dflt.real = NAN},
  297|    228|        {"used",   t_boolean, STRUCTOBJECT(struct satellite_t, used)},
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  298|    228|        {"gnssid", t_ubyte,   STRUCTOBJECT(struct satellite_t, gnssid)},
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  299|    228|        {"svid",   t_ubyte,   STRUCTOBJECT(struct satellite_t, svid)},
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  300|    228|        {"sigid",  t_ubyte,   STRUCTOBJECT(struct satellite_t, sigid)},
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  301|    228|        {"freqid", t_byte,    STRUCTOBJECT(struct satellite_t, freqid),
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  302|    228|                              .dflt.byte = -1},
  303|    228|        {"health", t_ubyte,   STRUCTOBJECT(struct satellite_t, health),
  ------------------
  |  |  188|    228|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  304|    228|                              .dflt.ubyte = SAT_HEALTH_UNK},
  ------------------
  |  | 2529|    228|#define SAT_HEALTH_UNK 0
  ------------------
  305|       |        // ignore unknown keys, for cross-version compatibility
  306|    228|        {"", t_ignore},
  307|       |        // *INDENT-ON*
  308|    228|        {NULL},
  309|    228|    };
  310|       |
  311|    228|    int nSat = -1;  // Use nSat only to know if sats are in SKY
  312|       |
  313|    228|    const struct json_attr_t json_attrs_2[] = {
  314|       |        // *INDENT-OFF*
  315|    228|        {"class",      t_check,   .dflt.check = "SKY"},
  316|    228|        {"device",     t_string,  .addr.string  = gpsdata->dev.path,
  317|    228|                                     .len = sizeof(gpsdata->dev.path)},
  318|    228|        {"gdop",       t_real,    .addr.real    = &gpsdata->dop.gdop,
  319|    228|                                     .dflt.real = NAN},
  320|    228|        {"hdop",       t_real,    .addr.real    = &gpsdata->dop.hdop,
  321|    228|                                     .dflt.real = NAN},
  322|    228|        {"nSat",       t_integer, .addr.integer = &nSat,
  323|    228|                                     .dflt.integer = -1},
  324|    228|        {"pdop",       t_real,    .addr.real    = &gpsdata->dop.pdop,
  325|    228|                                     .dflt.real = NAN},
  326|    228|        {"tdop",       t_real,    .addr.real    = &gpsdata->dop.tdop,
  327|    228|                                     .dflt.real = NAN},
  328|    228|        {"vdop",       t_real,    .addr.real    = &gpsdata->dop.vdop,
  329|    228|                                     .dflt.real = NAN},
  330|    228|        {"xdop",       t_real,    .addr.real    = &gpsdata->dop.xdop,
  331|    228|                                     .dflt.real = NAN},
  332|    228|        {"ydop",       t_real,    .addr.real    = &gpsdata->dop.ydop,
  333|    228|                                     .dflt.real = NAN},
  334|    228|        {"satellites", t_array,
  335|    228|                                   STRUCTARRAY(gpsdata->skyview,
  ------------------
  |  |  190|    228|        .addr.array.element_type = t_structobject, \
  |  |  191|    228|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    228|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    228|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    228|        .addr.array.count = n, \
  |  |  195|    228|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    228|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    228|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    228|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    228|            struct { \
  |  |  |  |  |  |   71|    228|                int unused_int; \
  |  |  |  |  |  |   72|    228|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    228|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    228|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    228|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    228|            }; \
  |  |  |  |  |  |   77|    228|            1; \
  |  |  |  |  |  |   78|    228|        })) \
  |  |  |  |  |  |   79|    228|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  336|    228|                                         json_attrs_satellites,
  337|    228|                                         &gpsdata->satellites_visible)},
  338|    228|        {"time",       t_time,    .addr.ts = &gpsdata->skyview_time,
  339|    228|                                     .dflt.ts = {0, 0}},
  340|    228|        {"uSat",       t_integer, .addr.integer = &gpsdata->satellites_used,
  341|    228|                                     .dflt.integer = 0},
  342|       |        // ignore unknown keys, for cross-version compatibility
  343|    228|        {"", t_ignore},
  344|    228|        {NULL},
  345|       |        // *INDENT-ON*
  346|    228|    };
  347|    228|    int status, i;
  348|       |
  349|    228|    memset(&gpsdata->skyview, 0, sizeof(gpsdata->skyview));
  350|       |
  351|    228|    status = json_read_object(buf, json_attrs_2, endptr);
  352|    228|    if (0 != status) {
  ------------------
  |  Branch (352:9): [True: 102, False: 126]
  ------------------
  353|    102|        return status;
  354|    102|    }
  355|       |
  356|    126|    if (1 == isfinite(gpsdata->dop.hdop) ||
  ------------------
  |  Branch (356:9): [True: 1, False: 125]
  ------------------
  357|    126|        1 == isfinite(gpsdata->dop.xdop) ||
  ------------------
  |  Branch (357:9): [True: 1, False: 124]
  ------------------
  358|    126|        1 == isfinite(gpsdata->dop.ydop) ||
  ------------------
  |  Branch (358:9): [True: 1, False: 123]
  ------------------
  359|    126|        1 == isfinite(gpsdata->dop.vdop) ||
  ------------------
  |  Branch (359:9): [True: 1, False: 122]
  ------------------
  360|    126|        1 == isfinite(gpsdata->dop.tdop) ||
  ------------------
  |  Branch (360:9): [True: 1, False: 121]
  ------------------
  361|    126|        1 == isfinite(gpsdata->dop.pdop) ||
  ------------------
  |  Branch (361:9): [True: 1, False: 120]
  ------------------
  362|    126|        1 == isfinite(gpsdata->dop.gdop)) {
  ------------------
  |  Branch (362:9): [True: 1, False: 119]
  ------------------
  363|       |        // got at least one DOP
  364|      7|        gpsdata->set |= DOP_SET;
  ------------------
  |  | 2793|      7|#define DOP_SET         (1llu<<11)
  ------------------
  365|      7|    }
  366|       |
  367|    126|    gpsdata->satellites_visible = 0;
  368|       |
  369|    126|    if (-1 == nSat) {
  ------------------
  |  Branch (369:9): [True: 24, False: 102]
  ------------------
  370|       |        // no sats in the SKY, likely just dops.  Maybe uSat
  371|     24|        gpsdata->set &= ~SATELLITE_SET;
  ------------------
  |  | 2797|     24|#define SATELLITE_SET   (1llu<<15)
  ------------------
  372|     24|        return 0;
  373|     24|    }
  374|    102|    gpsdata->satellites_used = 0;
  375|       |
  376|    102|    gpsdata->set |= SATELLITE_SET;
  ------------------
  |  | 2797|    102|#define SATELLITE_SET   (1llu<<15)
  ------------------
  377|       |    // recalculate used and visible, do not use nSat, uSat
  378|  14.3k|    for (i = 0; i < MAXCHANNELS; i++) {
  ------------------
  |  |  114|  14.3k|#define MAXCHANNELS     140     // u-blox 9 tracks 140 signals
  ------------------
  |  Branch (378:17): [True: 14.2k, False: 102]
  ------------------
  379|  14.2k|        if (0 < gpsdata->skyview[i].PRN) {
  ------------------
  |  Branch (379:13): [True: 996, False: 13.2k]
  ------------------
  380|    996|            gpsdata->satellites_visible++;
  381|    996|        }
  382|  14.2k|        if (gpsdata->skyview[i].used) {
  ------------------
  |  Branch (382:13): [True: 988, False: 13.2k]
  ------------------
  383|    988|            gpsdata->satellites_used++;
  384|    988|        }
  385|  14.2k|    }
  386|       |
  387|    102|    return 0;
  388|    126|}
libgps_json.c:json_att_read:
  393|     58|{
  394|     58|    struct attitude_t *datap = &gpsdata->attitude;
  395|       |
  396|     58|    const struct json_attr_t json_attrs_1[] = {
  397|       |        // *INDENT-OFF*
  398|     58|        {"class",     t_check,     .dflt.check = "ATT"},
  399|     58|        {"device",    t_string,    .addr.string = gpsdata->dev.path,
  400|     58|         .len = sizeof(gpsdata->dev.path)},
  401|     58|        {"acc_len",   t_real,      .addr.real = &datap->acc_len,
  402|     58|         .dflt.real = NAN},
  403|     58|        {"acc_x",     t_real,      .addr.real = &datap->acc_x,
  404|     58|         .dflt.real = NAN},
  405|     58|        {"acc_y",     t_real,      .addr.real = &datap->acc_y,
  406|     58|         .dflt.real = NAN},
  407|     58|        {"acc_z",     t_real,      .addr.real = &datap->acc_z,
  408|     58|         .dflt.real = NAN},
  409|     58|        {"baseS",     t_integer,   .addr.integer = &datap->base.status,
  410|     58|         .dflt.integer = STATUS_UNK},     // aka zero
  ------------------
  |  |  197|     58|#define STATUS_UNK      0       // Unknown status
  ------------------
  411|     58|        {"baseE",     t_real,      .addr.real = &datap->base.east,
  412|     58|         .dflt.real = NAN},
  413|     58|        {"baseN",     t_real,      .addr.real = &datap->base.north,
  414|     58|         .dflt.real = NAN},
  415|     58|        {"baseU",     t_real,      .addr.real = &datap->base.up,
  416|     58|         .dflt.real = NAN},
  417|     58|        {"baseL",     t_real,      .addr.real = &datap->base.length,
  418|     58|         .dflt.real = NAN},
  419|     58|        {"baseC",     t_real,      .addr.real = &datap->base.course,
  420|     58|         .dflt.real = NAN},
  421|     58|        {"dgpsRatio", t_real, .addr.real = &datap->base.ratio,
  422|     58|         .dflt.real = NAN},
  423|     58|        {"depth",     t_real,      .addr.real = &datap->depth,
  424|     58|         .dflt.real = NAN},
  425|     58|        {"dip",       t_real,      .addr.real = &datap->dip,
  426|     58|         .dflt.real = NAN},
  427|     58|        {"gyro_temp", t_real,      .addr.real = &datap->gyro_x,
  428|     58|         .dflt.real = NAN},
  429|     58|        {"gyro_x",    t_real,      .addr.real = &datap->gyro_x,
  430|     58|         .dflt.real = NAN},
  431|     58|        {"gyro_y",    t_real,      .addr.real = &datap->gyro_y,
  432|     58|         .dflt.real = NAN},
  433|     58|        {"gyro_z",    t_real,      .addr.real = &datap->gyro_z,
  434|     58|         .dflt.real = NAN},
  435|     58|        {"heading",   t_real,      .addr.real = &datap->heading,
  436|     58|         .dflt.real = NAN},
  437|     58|        {"mag_len",   t_real,      .addr.real = &datap->mag_len,
  438|     58|         .dflt.real = NAN},
  439|     58|        {"mag_st",    t_character, .addr.character = &datap->mag_st},
  440|     58|        {"mag_x",     t_real,      .addr.real = &datap->mag_x,
  441|     58|         .dflt.real = NAN},
  442|     58|        {"mag_y",     t_real,      .addr.real = &datap->mag_y,
  443|     58|         .dflt.real = NAN},
  444|     58|        {"mag_z",     t_real,      .addr.real = &datap->mag_z,
  445|     58|         .dflt.real = NAN},
  446|     58|        {"mheading",   t_real,     .addr.real = &datap->mheading,
  447|     58|         .dflt.real = NAN},
  448|     58|        {"msg",       t_string,    .addr.string = datap->msg,
  449|     58|         .len = sizeof(datap->msg)},
  450|     58|        {"pitch_st",  t_character, .addr.character = &datap->pitch_st},
  451|     58|        {"pitch",     t_real,      .addr.real = &datap->pitch,
  452|     58|         .dflt.real = NAN},
  453|     58|        {"roll_st",   t_character, .addr.character = &datap->roll_st},
  454|     58|        {"roll",      t_real,      .addr.real = &datap->roll,
  455|     58|         .dflt.real = NAN},
  456|     58|        {"temp",      t_real,      .addr.real = &datap->temp,
  457|     58|         .dflt.real = NAN},
  458|     58|        {"time",      t_time,      .addr.ts = &datap->mtime, .dflt.ts = {0, 0}},
  459|     58|        {"timeTag",   t_ulongint,  .addr.ulongint = &datap->timeTag,
  460|     58|         .dflt.ulongint = 0},
  461|     58|        {"yaw_st",    t_character, .addr.character = &datap->yaw_st},
  462|     58|        {"yaw",       t_real,      .addr.real = &datap->yaw, .dflt.real = NAN},
  463|       |
  464|       |        // ignore unknown keys, for cross-version compatibility
  465|     58|        {"", t_ignore},
  466|     58|        {NULL},
  467|       |        // *INDENT-ON*
  468|     58|    };
  469|       |
  470|     58|    return json_read_object(buf, json_attrs_1, endptr);
  471|     58|}
libgps_json.c:json_imu_read:
  476|     64|{
  477|       |    // the client only uses the first slot.
  478|     64|    struct attitude_t *datap = &gpsdata->imu[0];
  479|       |
  480|     64|    const struct json_attr_t json_attrs_1[] = {
  481|       |        // *INDENT-OFF*
  482|     64|        {"class",     t_check,     .dflt.check = "IMU"},
  483|     64|        {"device",    t_string,    .addr.string = gpsdata->dev.path,
  484|     64|         .len = sizeof(gpsdata->dev.path)},
  485|     64|        {"acc_len",   t_real,      .addr.real = &datap->acc_len,
  486|     64|         .dflt.real = NAN},
  487|     64|        {"acc_x",     t_real,      .addr.real = &datap->acc_x,
  488|     64|         .dflt.real = NAN},
  489|     64|        {"acc_y",     t_real,      .addr.real = &datap->acc_y,
  490|     64|         .dflt.real = NAN},
  491|     64|        {"acc_z",     t_real,      .addr.real = &datap->acc_z,
  492|     64|         .dflt.real = NAN},
  493|     64|        {"depth",     t_real,      .addr.real = &datap->depth,
  494|     64|         .dflt.real = NAN},
  495|     64|        {"dip",       t_real,      .addr.real = &datap->dip,
  496|     64|         .dflt.real = NAN},
  497|     64|        {"gyro_temp", t_real,      .addr.real = &datap->gyro_temp,
  498|     64|         .dflt.real = NAN},
  499|     64|        {"gyro_x",    t_real,      .addr.real = &datap->gyro_x,
  500|     64|         .dflt.real = NAN},
  501|     64|        {"gyro_y",    t_real,      .addr.real = &datap->gyro_y,
  502|     64|         .dflt.real = NAN},
  503|     64|        {"gyro_z",    t_real,      .addr.real = &datap->gyro_z,
  504|     64|         .dflt.real = NAN},
  505|     64|        {"heading",   t_real,      .addr.real = &datap->heading,
  506|     64|         .dflt.real = NAN},
  507|     64|        {"mag_len",   t_real,      .addr.real = &datap->mag_len,
  508|     64|         .dflt.real = NAN},
  509|     64|        {"mag_st",    t_character, .addr.character = &datap->mag_st},
  510|     64|        {"mag_x",     t_real,      .addr.real = &datap->mag_x,
  511|     64|         .dflt.real = NAN},
  512|     64|        {"mag_y",     t_real,      .addr.real = &datap->mag_y,
  513|     64|         .dflt.real = NAN},
  514|     64|        {"mag_z",     t_real,      .addr.real = &datap->mag_z,
  515|     64|         .dflt.real = NAN},
  516|     64|        {"msg",       t_string,    .addr.string = datap->msg,
  517|     64|         .len = sizeof(datap->msg)},
  518|     64|        {"pitch_st",  t_character, .addr.character = &datap->pitch_st},
  519|     64|        {"pitch",     t_real,      .addr.real = &datap->pitch,
  520|     64|         .dflt.real = NAN},
  521|     64|        {"roll_st",   t_character, .addr.character = &datap->roll_st},
  522|     64|        {"roll",      t_real,      .addr.real = &datap->roll,
  523|     64|         .dflt.real = NAN},
  524|     64|        {"temp",      t_real,      .addr.real = &datap->temp,
  525|     64|         .dflt.real = NAN},
  526|     64|        {"time",      t_time,      .addr.ts = &datap->mtime, .dflt.ts = {0, 0}},
  527|     64|        {"timeTag",   t_ulongint,  .addr.ulongint = &datap->timeTag,
  528|     64|         .dflt.ulongint = 0},
  529|     64|        {"yaw_st",    t_character, .addr.character = &datap->yaw_st},
  530|     64|        {"yaw",       t_real,      .addr.real = &datap->yaw, .dflt.real = NAN},
  531|       |
  532|       |        // ignore unknown keys, for cross-version compatibility
  533|     64|        {"", t_ignore},
  534|     64|        {NULL},
  535|       |        // *INDENT-ON*
  536|     64|    };
  537|       |
  538|     64|    return json_read_object(buf, json_attrs_1, endptr);
  539|     64|}
libgps_json.c:json_devicelist_read:
  543|     58|{
  544|     58|    const struct json_attr_t json_attrs_subdevices[] = {
  545|       |        // *INDENT-OFF*
  546|     58|        {"class",      t_check,      .dflt.check = "DEVICE"},
  547|     58|        {"path",       t_string,     STRUCTOBJECT(struct devconfig_t, path),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  548|     58|         .len = sizeof(gpsdata->devices.list[0].path)},
  549|     58|        {"activated",  t_time,
  550|     58|         STRUCTOBJECT(struct devconfig_t, activated)},
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  551|     58|        {"activated",  t_real,
  552|     58|         STRUCTOBJECT(struct devconfig_t, activated)},
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  553|     58|        {"flags",      t_integer,    STRUCTOBJECT(struct devconfig_t, flags)},
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  554|     58|        {"driver",     t_string,     STRUCTOBJECT(struct devconfig_t, driver),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  555|     58|         .len = sizeof(gpsdata->devices.list[0].driver)},
  556|     58|        {"hexdata",    t_string,     STRUCTOBJECT(struct devconfig_t, hexdata),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  557|     58|         .len = sizeof(gpsdata->devices.list[0].hexdata)},
  558|     58|        {"sernum",     t_string,     STRUCTOBJECT(struct devconfig_t, sernum),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  559|     58|                            .len = sizeof(gpsdata->devices.list[0].sernum)},
  560|     58|        {"subtype",    t_string,     STRUCTOBJECT(struct devconfig_t, subtype),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  561|     58|                            .len = sizeof(gpsdata->devices.list[0].subtype)},
  562|     58|        {"subtype1",   t_string,     STRUCTOBJECT(struct devconfig_t, subtype1),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  563|     58|                            .len = sizeof(gpsdata->devices.list[0].subtype1)},
  564|     58|        {"native",     t_integer, STRUCTOBJECT(struct devconfig_t, driver_mode),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  565|     58|                                        .dflt.integer = -1},
  566|     58|        {"bps",        t_uinteger,   STRUCTOBJECT(struct devconfig_t, baudrate),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  567|     58|                                        .dflt.uinteger = DEVDEFAULT_BPS},
  ------------------
  |  |   53|     58|#define DEVDEFAULT_BPS          0
  ------------------
  568|     58|        {"parity",     t_character,  STRUCTOBJECT(struct devconfig_t, parity),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  569|     58|                                        .dflt.character = DEVDEFAULT_PARITY},
  ------------------
  |  |   54|     58|#define DEVDEFAULT_PARITY       'X'
  ------------------
  570|     58|        {"stopbits",   t_uinteger,   STRUCTOBJECT(struct devconfig_t, stopbits),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  571|     58|                                        .dflt.integer = DEVDEFAULT_STOPBITS},
  ------------------
  |  |   55|     58|#define DEVDEFAULT_STOPBITS     3
  ------------------
  572|     58|        {"cycle",      t_timespec,   STRUCTOBJECT(struct devconfig_t, cycle),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  573|     58|                                        .dflt.ts = {0,0}},
  574|     58|        {"mincycle",   t_timespec,   STRUCTOBJECT(struct devconfig_t, mincycle),
  ------------------
  |  |  188|     58|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  575|     58|                                        .dflt.ts = {0,0}},
  576|       |        // ignore unknown keys, for cross-version compatibility
  577|     58|        {"", t_ignore},
  578|     58|        {NULL},
  579|       |        // *INDENT-ON*
  580|     58|    };
  581|     58|    const struct json_attr_t json_attrs_devices[] = {
  582|     58|        {"class", t_check,.dflt.check = "DEVICES"},
  583|     58|        {"devices", t_array, STRUCTARRAY(gpsdata->devices.list,
  ------------------
  |  |  190|     58|        .addr.array.element_type = t_structobject, \
  |  |  191|     58|        .addr.array.arr.objects.subtype = e, \
  |  |  192|     58|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|     58|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|     58|        .addr.array.count = n, \
  |  |  195|     58|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|     58|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|     58|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|     58|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|     58|            struct { \
  |  |  |  |  |  |   71|     58|                int unused_int; \
  |  |  |  |  |  |   72|     58|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|     58|            } zero_init = {0}; \
  |  |  |  |  |  |   74|     58|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|     58|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|     58|            }; \
  |  |  |  |  |  |   77|     58|            1; \
  |  |  |  |  |  |   78|     58|        })) \
  |  |  |  |  |  |   79|     58|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  584|     58|                                         json_attrs_subdevices,
  585|     58|                                         &gpsdata->devices.ndevices)},
  586|       |        // ignore unknown keys, for cross-version compatibility
  587|     58|        {"", t_ignore},
  588|     58|        {NULL},
  589|     58|    };
  590|     58|    int status;
  591|       |
  592|     58|    memset(&gpsdata->devices, 0, sizeof(gpsdata->devices));
  593|     58|    status = json_read_object(buf, json_attrs_devices, endptr);
  594|     58|    if (status != 0) {
  ------------------
  |  Branch (594:9): [True: 57, False: 1]
  ------------------
  595|     57|        return status;
  596|     57|    }
  597|       |
  598|      1|    (void)clock_gettime(CLOCK_REALTIME, &gpsdata->devices.time);
  599|      1|    return 0;
  600|     58|}
libgps_json.c:json_version_read:
  604|      9|{
  605|      9|    const struct json_attr_t json_attrs_version[] = {
  606|       |        // *INDENT-OFF*
  607|      9|        {"class",     t_check,   .dflt.check = "VERSION"},
  608|      9|        {"release",   t_string,  .addr.string  = gpsdata->version.release,
  609|      9|                                    .len = sizeof(gpsdata->version.release)},
  610|      9|        {"rev",       t_string,  .addr.string  = gpsdata->version.rev,
  611|      9|                                    .len = sizeof(gpsdata->version.rev)},
  612|      9|        {"proto_major", t_integer,
  613|      9|         .addr.integer = &gpsdata->version.proto_major},
  614|      9|        {"proto_minor", t_integer,
  615|      9|         .addr.integer = &gpsdata->version.proto_minor},
  616|      9|        {"remote",    t_string,  .addr.string  = gpsdata->version.remote,
  617|      9|                                    .len = sizeof(gpsdata->version.remote)},
  618|       |        // ignore unknown keys, for cross-version compatibility
  619|      9|        {"", t_ignore},
  620|      9|        {NULL},
  621|       |        // *INDENT-ON*
  622|      9|    };
  623|      9|    int status;
  624|       |
  625|      9|    memset(&gpsdata->version, 0, sizeof(gpsdata->version));
  626|      9|    status = json_read_object(buf, json_attrs_version, endptr);
  627|       |
  628|      9|    return status;
  629|      9|}
libgps_json.c:json_error_read:
  633|      8|{
  634|      8|    const struct json_attr_t json_attrs_error[] = {
  635|       |        // *INDENT-OFF*
  636|      8|        {"class",     t_check,   .dflt.check = "ERROR"},
  637|      8|        {"message",   t_string,  .addr.string  = gpsdata->error,
  638|      8|                                    .len = sizeof(gpsdata->error)},
  639|       |        // ignore unknown keys, for cross-version compatibility
  640|      8|        {"", t_ignore},
  641|      8|        {NULL},
  642|       |        // *INDENT-ON*
  643|      8|    };
  644|      8|    int status;
  645|       |
  646|      8|    memset(&gpsdata->error, 0, sizeof(gpsdata->error));
  647|      8|    status = json_read_object(buf, json_attrs_error, endptr);
  648|      8|    if (status != 0)
  ------------------
  |  Branch (648:9): [True: 6, False: 2]
  ------------------
  649|      6|        return status;
  650|       |
  651|      2|    return status;
  652|      8|}
libgps_json.c:json_raw_read:
  214|    136|{
  215|    136|    int measurements;
  216|       |    // initialized to shut up clang
  217|    136|    double mtime_s = 0.0, mtime_ns = 0.0;
  218|       |
  219|    136|    const struct json_attr_t json_attrs_meas[] = {
  220|       |        // *INDENT-OFF*
  221|    136|        {"gnssid",       t_ubyte,    STRUCTOBJECT(struct meas_t, gnssid)},
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  222|    136|        {"svid",         t_ubyte,    STRUCTOBJECT(struct meas_t, svid)},
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  223|    136|        {"sigid",        t_ubyte,    STRUCTOBJECT(struct meas_t, sigid),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  224|    136|                                     .dflt.ubyte = 0},
  225|    136|        {"snr",          t_ubyte,    STRUCTOBJECT(struct meas_t, snr)},
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  226|    136|        {"freqid",       t_ubyte,    STRUCTOBJECT(struct meas_t, freqid),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  227|    136|                                     .dflt.ubyte = 0},
  228|    136|        {"obs",          t_string,   STRUCTOBJECT(struct meas_t, obs_code),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  229|    136|                                .len = sizeof(gpsdata->raw.meas[0].obs_code)},
  230|    136|        {"lli",          t_ubyte,    STRUCTOBJECT(struct meas_t, lli),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  231|    136|                                     .dflt.ubyte = 0},
  232|    136|        {"locktime",     t_uinteger, STRUCTOBJECT(struct meas_t, locktime),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  233|    136|                                     .dflt.uinteger = 0},
  234|    136|        {"carrierphase", t_real,     STRUCTOBJECT(struct meas_t, carrierphase),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  235|    136|                                     .dflt.real = NAN},
  236|    136|        {"pseudorange",  t_real,     STRUCTOBJECT(struct meas_t, pseudorange),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  237|    136|                                     .dflt.real = NAN},
  238|    136|        {"doppler",      t_real,     STRUCTOBJECT(struct meas_t, doppler),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  239|    136|                                     .dflt.real = NAN},
  240|    136|        {"c2c",          t_real,     STRUCTOBJECT(struct meas_t, c2c),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  241|    136|                                    .dflt.real = NAN},
  242|    136|        {"l2c",          t_real,     STRUCTOBJECT(struct meas_t, l2c),
  ------------------
  |  |  188|    136|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  243|    136|                                    .dflt.real = NAN},
  244|       |        // ignore unknown keys, for cross-version compatibility
  245|    136|        {"", t_ignore},
  246|       |        // *INDENT-ON*
  247|    136|        {NULL},
  248|    136|    };
  249|    136|    const struct json_attr_t json_attrs_raw[] = {
  250|       |        // *INDENT-OFF*
  251|    136|        {"class",      t_check,   .dflt.check = "RAW"},
  252|    136|        {"device",     t_string,  .addr.string  = gpsdata->dev.path,
  253|    136|                                    .len = sizeof(gpsdata->dev.path)},
  254|    136|        {"time",       t_real,    .addr.real = &mtime_s,
  255|    136|                                 .dflt.real = NAN},
  256|    136|        {"nsec",       t_real,    .addr.real = &mtime_ns,
  257|    136|                                 .dflt.real = NAN},
  258|    136|        {"rawdata",    t_array,   STRUCTARRAY(gpsdata->raw.meas,
  ------------------
  |  |  190|    136|        .addr.array.element_type = t_structobject, \
  |  |  191|    136|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    136|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    136|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    136|        .addr.array.count = n, \
  |  |  195|    136|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    136|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    136|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    136|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    136|            struct { \
  |  |  |  |  |  |   71|    136|                int unused_int; \
  |  |  |  |  |  |   72|    136|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    136|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    136|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    136|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    136|            }; \
  |  |  |  |  |  |   77|    136|            1; \
  |  |  |  |  |  |   78|    136|        })) \
  |  |  |  |  |  |   79|    136|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  259|    136|                                     json_attrs_meas, &measurements)},
  260|       |        // ignore unknown keys, for cross-version compatibility
  261|    136|        {"", t_ignore},
  262|    136|        {NULL},
  263|       |        // *INDENT-ON*
  264|    136|    };
  265|    136|    int status;
  266|       |
  267|    136|    memset(&gpsdata->raw, 0, sizeof(gpsdata->raw));
  268|       |
  269|    136|    status = json_read_object(buf, json_attrs_raw, endptr);
  270|    136|    if (0 != status) {
  ------------------
  |  Branch (270:9): [True: 108, False: 28]
  ------------------
  271|    108|        return status;
  272|    108|    }
  273|     28|    gpsdata->set |= RAW_SET;
  ------------------
  |  | 2821|     28|#define RAW_SET         (1llu<<39)
  ------------------
  274|     28|    if (0 == isfinite(mtime_s) ||
  ------------------
  |  Branch (274:9): [True: 26, False: 2]
  ------------------
  275|     28|        0 == isfinite(mtime_ns)) {
  ------------------
  |  Branch (275:9): [True: 1, False: 1]
  ------------------
  276|     27|        return status;
  277|     27|    }
  278|      1|    gpsdata->raw.mtime.tv_sec = (time_t)mtime_s;
  279|      1|    gpsdata->raw.mtime.tv_nsec = (long)mtime_ns;
  280|       |
  281|      1|    return 0;
  282|     28|}

strlcpy:
  289|    945|{
  290|    945|    size_t len = strlen(src);
  291|    945|    if (0!= siz ) {
  ------------------
  |  Branch (291:9): [True: 945, False: 0]
  ------------------
  292|    945|        if (len >= siz) {
  ------------------
  |  Branch (292:13): [True: 194, False: 751]
  ------------------
  293|    194|            memcpy(dst, src, siz - 1);
  294|    194|            dst[siz - 1] = '\0';
  295|    751|        } else {
  296|    751|            memcpy(dst, src, len + 1);
  297|    751|        }
  298|    945|    }
  299|    945|    return len;
  300|    945|}

json_rtcm2_read:
   33|    319|{
   34|       |
   35|    319|    static char *stringptrs[NITEMS(rtcm2->words)];
   36|    319|    static char stringstore[sizeof(rtcm2->words) * 2];
   37|    319|    static int stringcount;
   38|       |
   39|       |/* *INDENT-OFF* */
   40|    319|#define RTCM2_HEADER \
   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
   43|    319|        {"device",         t_string,   .addr.string = path, \
   44|    319|                                          .len = pathlen}, \
   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
   47|    319|                                          .dflt.real = NAN}, \
   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
   51|       |
   52|    319|    int status = 0, satcount = 0;
   53|       |
   54|    319|    const struct json_attr_t rtcm1_satellite[] = {
   55|    319|        {"ident",     t_uinteger, STRUCTOBJECT(struct gps_rangesat_t, ident)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   56|    319|        {"udre",      t_uinteger, STRUCTOBJECT(struct gps_rangesat_t, udre)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   57|    319|        {"iod",       t_uinteger, STRUCTOBJECT(struct gps_rangesat_t, iod)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   58|    319|        {"prc",       t_real,     STRUCTOBJECT(struct gps_rangesat_t, prc)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   59|    319|        {"rrc",       t_real,     STRUCTOBJECT(struct gps_rangesat_t, rrc)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
   60|    319|        {NULL},
   61|    319|    };
   62|    319|    const struct json_attr_t json_rtcm1[] = {
   63|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
   64|    319|        {"satellites", t_array, STRUCTARRAY(rtcm2->gps_ranges.sat,
  ------------------
  |  |  190|    319|        .addr.array.element_type = t_structobject, \
  |  |  191|    319|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    319|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    319|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    319|        .addr.array.count = n, \
  |  |  195|    319|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    319|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    319|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    319|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    319|            struct { \
  |  |  |  |  |  |   71|    319|                int unused_int; \
  |  |  |  |  |  |   72|    319|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    319|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    319|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    319|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    319|            }; \
  |  |  |  |  |  |   77|    319|            1; \
  |  |  |  |  |  |   78|    319|        })) \
  |  |  |  |  |  |   79|    319|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   65|    319|                                            rtcm1_satellite, &satcount)},
   66|    319|        {NULL},
   67|    319|    };
   68|       |
   69|    319|    const struct json_attr_t json_rtcm3[] = {
   70|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
   71|    319|        {"x",              t_real,    .addr.real = &rtcm2->ref_sta.x,
   72|    319|                                         .dflt.real = NAN},
   73|    319|        {"y",              t_real,    .addr.real = &rtcm2->ref_sta.y,
   74|    319|                                         .dflt.real = NAN},
   75|    319|        {"z",              t_real,    .addr.real = &rtcm2->ref_sta.z,
   76|    319|                                         .dflt.real = NAN},
   77|    319|        {NULL},
   78|    319|    };
   79|       |
   80|       |    /*
   81|       |     * Beware! Needs to stay synchronized with a corresponding
   82|       |     * name array in the RTCM2 JSON dump code. This interpretation of
   83|       |     * NAVSYSTEM_GALILEO is assumed from RTCM3, it's not actually
   84|       |     * documented in RTCM 2.1.
   85|       |     */
   86|    319|    const struct json_enum_t system_table[] = {
   87|    319|        {"GPS", 0}, {"GLONASS", 1}, {"GALILEO", 2}, {"UNKNOWN", 3}, {NULL}
   88|    319|    };
   89|    319|    const struct json_attr_t json_rtcm4[] = {
   90|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
   91|    319|        {"valid",          t_boolean, .addr.boolean = &rtcm2->reference.valid},
   92|    319|        {"system",         t_integer, .addr.integer = &rtcm2->reference.system,
   93|    319|                                         .map=system_table},
   94|    319|        {"sense",          t_integer, .addr.integer = &rtcm2->reference.sense},
   95|    319|        {"datum",          t_string,  .addr.string = rtcm2->reference.datum,
   96|    319|                                         .len = sizeof(rtcm2->reference.datum)},
   97|    319|        {"dx",             t_real,    .addr.real = &rtcm2->reference.dx,
   98|    319|                                         .dflt.real = NAN},
   99|    319|        {"dy",             t_real,    .addr.real = &rtcm2->reference.dy,
  100|    319|                                         .dflt.real = NAN},
  101|    319|        {"dz",             t_real,    .addr.real = &rtcm2->reference.dz,
  102|    319|                                         .dflt.real = NAN},
  103|    319|        {NULL},
  104|    319|    };
  105|       |
  106|    319|    const struct json_attr_t rtcm5_satellite[] = {
  107|    319|        {"ident",       t_uinteger, STRUCTOBJECT(struct consat_t, ident)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  108|    319|        {"iodl",        t_boolean,  STRUCTOBJECT(struct consat_t, iodl)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  109|    319|        {"health",      t_uinteger, STRUCTOBJECT(struct consat_t, health)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  110|    319|        {"snr",         t_integer,  STRUCTOBJECT(struct consat_t, snr)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  111|    319|        {"health_en",   t_boolean,  STRUCTOBJECT(struct consat_t, health_en)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  112|    319|        {"new_data",    t_boolean,  STRUCTOBJECT(struct consat_t, new_data)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  113|    319|        {"los_warning", t_boolean,  STRUCTOBJECT(struct consat_t, los_warning)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  114|    319|        {"tou",         t_uinteger, STRUCTOBJECT(struct consat_t, tou)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  115|    319|        {NULL},
  116|    319|    };
  117|    319|    const struct json_attr_t json_rtcm5[] = {
  118|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  119|    319|        {"satellites", t_array, STRUCTARRAY(rtcm2->conhealth.sat,
  ------------------
  |  |  190|    319|        .addr.array.element_type = t_structobject, \
  |  |  191|    319|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    319|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    319|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    319|        .addr.array.count = n, \
  |  |  195|    319|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    319|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    319|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    319|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    319|            struct { \
  |  |  |  |  |  |   71|    319|                int unused_int; \
  |  |  |  |  |  |   72|    319|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    319|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    319|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    319|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    319|            }; \
  |  |  |  |  |  |   77|    319|            1; \
  |  |  |  |  |  |   78|    319|        })) \
  |  |  |  |  |  |   79|    319|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  120|    319|                                            rtcm5_satellite, &satcount)},
  121|    319|        {NULL},
  122|    319|    };
  123|       |
  124|    319|    const struct json_attr_t json_rtcm6[] = {
  125|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  126|       |        // No-op or keepalive message
  127|    319|        {NULL},
  128|    319|    };
  129|       |
  130|    319|    const struct json_attr_t rtcm7_satellite[] = {
  131|    319|        {"lat",         t_real,     STRUCTOBJECT(struct station_t, latitude)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  132|    319|        {"lon",         t_real,     STRUCTOBJECT(struct station_t, longitude)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  133|    319|        {"range",       t_uinteger, STRUCTOBJECT(struct station_t, range)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  134|    319|        {"frequency",   t_real,     STRUCTOBJECT(struct station_t, frequency)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  135|    319|        {"health",      t_uinteger, STRUCTOBJECT(struct station_t, health)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  136|    319|        {"station_id",  t_uinteger, STRUCTOBJECT(struct station_t, station_id)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  137|    319|        {"bitrate",     t_uinteger, STRUCTOBJECT(struct station_t, bitrate)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  138|    319|        {NULL},
  139|    319|    };
  140|    319|    const struct json_attr_t json_rtcm7[] = {
  141|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  142|    319|        {"satellites", t_array, STRUCTARRAY(rtcm2->almanac.station,
  ------------------
  |  |  190|    319|        .addr.array.element_type = t_structobject, \
  |  |  191|    319|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    319|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    319|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    319|        .addr.array.count = n, \
  |  |  195|    319|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    319|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    319|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    319|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    319|            struct { \
  |  |  |  |  |  |   71|    319|                int unused_int; \
  |  |  |  |  |  |   72|    319|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    319|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    319|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    319|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    319|            }; \
  |  |  |  |  |  |   77|    319|            1; \
  |  |  |  |  |  |   78|    319|        })) \
  |  |  |  |  |  |   79|    319|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  143|    319|                                            rtcm7_satellite, &satcount)},
  144|    319|        {NULL},
  145|    319|    };
  146|       |
  147|    319|    const struct json_attr_t json_rtcm13[] = {
  148|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  149|    319|        {"status",       t_boolean,  .addr.boolean = &rtcm2->xmitter.status},
  150|    319|        {"rangeflag",    t_boolean,  .addr.boolean = &rtcm2->xmitter.rangeflag},
  151|    319|        {"lat",          t_real,     .addr.real = &rtcm2->xmitter.lat,
  152|    319|                                        .dflt.real = NAN},
  153|    319|        {"lon",          t_real,     .addr.real = &rtcm2->xmitter.lon,
  154|    319|                                        .dflt.real = NAN},
  155|    319|        {"range",        t_uinteger, .addr.uinteger = &rtcm2->xmitter.range},
  156|    319|        {NULL},
  157|    319|    };
  158|       |
  159|    319|    const struct json_attr_t json_rtcm14[] = {
  160|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  161|    319|        {"week",              t_uinteger,
  162|    319|                              .addr.uinteger = &rtcm2->gpstime.week},
  163|    319|        {"hour",              t_uinteger,
  164|    319|                              .addr.uinteger = &rtcm2->gpstime.hour},
  165|    319|        {"leapsecs",          t_uinteger,
  166|    319|                              .addr.uinteger = &rtcm2->gpstime.leapsecs},
  167|    319|        {NULL},
  168|    319|    };
  169|       |
  170|    319|    const struct json_attr_t json_rtcm16[] = {
  171|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  172|    319|        {"message",        t_string,  .addr.string = rtcm2->message,
  173|    319|                                         .len = sizeof(rtcm2->message)},
  174|    319|        {NULL},
  175|    319|    };
  176|       |
  177|    319|    const struct json_attr_t rtcm31_satellite[] = {
  178|    319|        {"ident",     t_uinteger,
  179|    319|                              STRUCTOBJECT(struct glonass_rangesat_t, ident)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  180|    319|        {"udre",      t_uinteger,
  181|    319|                              STRUCTOBJECT(struct glonass_rangesat_t, udre)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  182|    319|        {"change",    t_boolean,
  183|    319|                              STRUCTOBJECT(struct glonass_rangesat_t, change)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  184|    319|        {"tod",       t_uinteger, STRUCTOBJECT(struct glonass_rangesat_t, tod)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  185|    319|        {"prc",       t_real,     STRUCTOBJECT(struct glonass_rangesat_t, prc)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  186|    319|        {"rrc",       t_real,     STRUCTOBJECT(struct glonass_rangesat_t, rrc)},
  ------------------
  |  |  188|    319|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  ------------------
  187|    319|        {NULL},
  188|    319|    };
  189|    319|    const struct json_attr_t json_rtcm31[] = {
  190|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  191|    319|        {"satellites", t_array, STRUCTARRAY(rtcm2->glonass_ranges.sat,
  ------------------
  |  |  190|    319|        .addr.array.element_type = t_structobject, \
  |  |  191|    319|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    319|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    319|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    319|        .addr.array.count = n, \
  |  |  195|    319|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    319|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    319|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    319|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    319|            struct { \
  |  |  |  |  |  |   71|    319|                int unused_int; \
  |  |  |  |  |  |   72|    319|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    319|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    319|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    319|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    319|            }; \
  |  |  |  |  |  |   77|    319|            1; \
  |  |  |  |  |  |   78|    319|        })) \
  |  |  |  |  |  |   79|    319|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  192|    319|                                            rtcm31_satellite, &satcount)},
  193|    319|        {NULL},
  194|    319|    };
  195|       |
  196|    319|    const struct json_attr_t json_rtcm2_fallback[] = {
  197|    319|        RTCM2_HEADER
  ------------------
  |  |   41|    319|        {"class",          t_check,    .dflt.check = "RTCM2"}, \
  |  |   42|    319|        {"type",           t_uinteger, .addr.uinteger = &rtcm2->type}, \
  |  |   43|    319|        {"device",         t_string,   .addr.string = path, \
  |  |   44|    319|                                          .len = pathlen}, \
  |  |   45|    319|        {"station_id",     t_uinteger, .addr.uinteger = &rtcm2->refstaid}, \
  |  |   46|    319|        {"zcount",         t_real,     .addr.real = &rtcm2->zcount, \
  |  |   47|    319|                                          .dflt.real = NAN}, \
  |  |   48|    319|        {"seqnum",         t_uinteger, .addr.uinteger = &rtcm2->seqnum}, \
  |  |   49|    319|        {"length",         t_uinteger, .addr.uinteger = &rtcm2->length}, \
  |  |   50|    319|        {"station_health", t_uinteger, .addr.uinteger = &rtcm2->stathlth},
  ------------------
  198|    319|        {"data",         t_array, .addr.array.element_type = t_string,
  199|    319|                         .addr.array.arr.strings.ptrs = stringptrs,
  200|    319|                         .addr.array.arr.strings.store = stringstore,
  201|    319|                         .addr.array.arr.strings.storelen = sizeof(stringstore),
  202|    319|                         .addr.array.count = &stringcount,
  203|    319|                         .addr.array.maxlen = NITEMS(stringptrs)},
  ------------------
  |  | 1165|    319|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  ------------------
  |  |  |  |   68|    319|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |   69|    319|        0 * (int) sizeof(({ \
  |  |  |  |   70|    319|            struct { \
  |  |  |  |   71|    319|                int unused_int; \
  |  |  |  |   72|    319|                __typeof__(arr) unused_arr; \
  |  |  |  |   73|    319|            } zero_init = {0}; \
  |  |  |  |   74|    319|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |   75|    319|                zero_init.unused_arr[0], \
  |  |  |  |   76|    319|            }; \
  |  |  |  |   77|    319|            1; \
  |  |  |  |   78|    319|        })) \
  |  |  |  |   79|    319|    )
  |  |  ------------------
  ------------------
  204|    319|        {NULL},
  205|    319|    };
  206|       |
  207|    319|#undef RTCM2_HEADER
  208|       |/* *INDENT-ON* */
  209|       |
  210|    319|    memset(rtcm2, '\0', sizeof(struct rtcm2_t));
  211|       |
  212|    319|    if (strstr(buf, "\"type\":1,") != NULL
  ------------------
  |  Branch (212:9): [True: 5, False: 314]
  ------------------
  213|    319|        || strstr(buf, "\"type\":9,") != NULL) {
  ------------------
  |  Branch (213:12): [True: 1, False: 313]
  ------------------
  214|      6|        status = json_read_object(buf, json_rtcm1, endptr);
  215|      6|        if (status == 0)
  ------------------
  |  Branch (215:13): [True: 1, False: 5]
  ------------------
  216|      1|            rtcm2->gps_ranges.nentries = (unsigned)satcount;
  217|    313|    } else if (strstr(buf, "\"type\":3,") != NULL) {
  ------------------
  |  Branch (217:16): [True: 89, False: 224]
  ------------------
  218|     89|        status = json_read_object(buf, json_rtcm3, endptr);
  219|     89|        if (status == 0) {
  ------------------
  |  Branch (219:13): [True: 84, False: 5]
  ------------------
  220|     84|            rtcm2->ref_sta.valid = (isfinite(rtcm2->ref_sta.x) != 0)
  ------------------
  |  Branch (220:36): [True: 46, False: 38]
  ------------------
  221|     84|                && (isfinite(rtcm2->ref_sta.y) != 0)
  ------------------
  |  Branch (221:20): [True: 32, False: 14]
  ------------------
  222|     84|                && (isfinite(rtcm2->ref_sta.z) != 0);
  ------------------
  |  Branch (222:20): [True: 6, False: 26]
  ------------------
  223|     84|        }
  224|    224|    } else if (strstr(buf, "\"type\":4,") != NULL) {
  ------------------
  |  Branch (224:16): [True: 93, False: 131]
  ------------------
  225|     93|        status = json_read_object(buf, json_rtcm4, endptr);
  226|     93|        if (status == 0)
  ------------------
  |  Branch (226:13): [True: 3, False: 90]
  ------------------
  227|      3|            rtcm2->reference.valid = (isfinite(rtcm2->reference.dx) != 0)
  ------------------
  |  Branch (227:38): [True: 2, False: 1]
  ------------------
  228|      3|                && (isfinite(rtcm2->reference.dy) != 0)
  ------------------
  |  Branch (228:20): [True: 1, False: 1]
  ------------------
  229|      3|                && (isfinite(rtcm2->reference.dz) != 0);
  ------------------
  |  Branch (229:20): [True: 0, False: 1]
  ------------------
  230|    131|    } else if (strstr(buf, "\"type\":5,") != NULL) {
  ------------------
  |  Branch (230:16): [True: 4, False: 127]
  ------------------
  231|      4|        status = json_read_object(buf, json_rtcm5, endptr);
  232|      4|        if (status == 0)
  ------------------
  |  Branch (232:13): [True: 1, False: 3]
  ------------------
  233|      1|            rtcm2->conhealth.nentries = (unsigned)satcount;
  234|    127|    } else if (strstr(buf, "\"type\":6,") != NULL) {
  ------------------
  |  Branch (234:16): [True: 1, False: 126]
  ------------------
  235|      1|        status = json_read_object(buf, json_rtcm6, endptr);
  236|    126|    } else if (strstr(buf, "\"type\":7,") != NULL) {
  ------------------
  |  Branch (236:16): [True: 6, False: 120]
  ------------------
  237|      6|        status = json_read_object(buf, json_rtcm7, endptr);
  238|      6|        if (status == 0)
  ------------------
  |  Branch (238:13): [True: 1, False: 5]
  ------------------
  239|      1|            rtcm2->almanac.nentries = (unsigned)satcount;
  240|    120|    } else if (strstr(buf, "\"type\":13,") != NULL) {
  ------------------
  |  Branch (240:16): [True: 1, False: 119]
  ------------------
  241|      1|        status = json_read_object(buf, json_rtcm13, endptr);
  242|    119|    } else if (strstr(buf, "\"type\":14,") != NULL) {
  ------------------
  |  Branch (242:16): [True: 1, False: 118]
  ------------------
  243|      1|        status = json_read_object(buf, json_rtcm14, endptr);
  244|    118|    } else if (strstr(buf, "\"type\":16,") != NULL) {
  ------------------
  |  Branch (244:16): [True: 1, False: 117]
  ------------------
  245|      1|        status = json_read_object(buf, json_rtcm16, endptr);
  246|    117|    } else if (strstr(buf, "\"type\":31,") != NULL) {
  ------------------
  |  Branch (246:16): [True: 5, False: 112]
  ------------------
  247|      5|        status = json_read_object(buf, json_rtcm31, endptr);
  248|      5|        if (status == 0)
  ------------------
  |  Branch (248:13): [True: 1, False: 4]
  ------------------
  249|      1|            rtcm2->glonass_ranges.nentries = (unsigned)satcount;
  250|    112|    } else {
  251|    112|        int n;
  252|    112|        status = json_read_object(buf, json_rtcm2_fallback, endptr);
  253|  2.82k|        for (n = 0; n < NITEMS(rtcm2->words); n++) {
  ------------------
  |  | 1165|  2.82k|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  ------------------
  |  |  |  |   68|  2.82k|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |   69|  2.82k|        0 * (int) sizeof(({ \
  |  |  |  |   70|  2.82k|            struct { \
  |  |  |  |   71|  2.82k|                int unused_int; \
  |  |  |  |   72|  2.82k|                __typeof__(arr) unused_arr; \
  |  |  |  |   73|  2.82k|            } zero_init = {0}; \
  |  |  |  |   74|  2.82k|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |   75|  2.82k|                zero_init.unused_arr[0], \
  |  |  |  |   76|  2.82k|            }; \
  |  |  |  |   77|  2.82k|            1; \
  |  |  |  |   78|  2.82k|        })) \
  |  |  |  |   79|  2.82k|    )
  |  |  ------------------
  ------------------
  |  Branch (253:21): [True: 2.74k, False: 87]
  ------------------
  254|  2.74k|            if (n >= stringcount) {
  ------------------
  |  Branch (254:17): [True: 2.54k, False: 200]
  ------------------
  255|  2.54k|                rtcm2->words[n] = 0;
  256|  2.54k|            } else {
  257|    200|                unsigned int u;
  258|    200|                int fldcount = sscanf(stringptrs[n], "0x%08x\n", &u);
  259|    200|                if (fldcount != 1)
  ------------------
  |  Branch (259:21): [True: 25, False: 175]
  ------------------
  260|     25|                    return JSON_ERR_MISC;
  ------------------
  |  |  172|     25|#define JSON_ERR_MISC           21      // other data conversion error
  ------------------
  261|    175|                else
  262|    175|                    rtcm2->words[n] = (isgps30bits_t) u;
  263|    200|            }
  264|  2.74k|        }
  265|    112|    }
  266|    294|    return status;
  267|    319|}

json_rtcm3_read:
   31|    156|{
   32|    156|    static char *stringptrs[NITEMS(rtcm3->rtcmtypes.data)];
   33|    156|    static char stringstore[sizeof(rtcm3->rtcmtypes.data) * 2];
   34|    156|    static int stringcount;
   35|       |
   36|       |/* *INDENT-OFF* */
   37|    156|#define RTCM3_HEADER \
   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
   42|       |
   43|    156|    int status = 0, satcount = 0;
   44|       |
   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
   46|    156|    const struct json_attr_t rtcm1001_satellite[] = {
   47|    156|        {"ident",     t_uinteger, RTCM3FIELD(1001, ident)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   48|    156|        {"ind",       t_uinteger, RTCM3FIELD(1001, L1.indicator)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   49|    156|        {"prange",    t_real,     RTCM3FIELD(1001, L1.pseudorange)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   50|    156|        {"delta",     t_real,     RTCM3FIELD(1001, L1.rangediff)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   51|    156|        {"lockt",     t_uinteger, RTCM3FIELD(1001, L1.locktime)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   52|    156|        {NULL},
   53|    156|    };
   54|       |
   55|    156|    const struct json_attr_t rtcm1002_satellite[] = {
   56|    156|        {"ident",     t_uinteger, RTCM3FIELD(1002, ident)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   57|    156|        {"ind",       t_uinteger, RTCM3FIELD(1002, L1.indicator)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   58|    156|        {"prange",    t_real,     RTCM3FIELD(1002, L1.pseudorange)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   59|    156|        {"delta",     t_real,     RTCM3FIELD(1002, L1.rangediff)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   60|    156|        {"lockt",     t_uinteger, RTCM3FIELD(1002, L1.locktime)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   61|    156|        {"amb",       t_uinteger, RTCM3FIELD(1002, L1.ambiguity)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   62|    156|        {"CNR",       t_real,     RTCM3FIELD(1002, L1.CNR)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   63|    156|        {NULL},
   64|    156|    };
   65|       |
   66|    156|    const struct json_attr_t rtcm1009_satellite[] = {
   67|    156|        {"ident",     t_uinteger, RTCM3FIELD(1009, ident)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   68|    156|        {"ind",       t_uinteger, RTCM3FIELD(1009, L1.indicator)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   69|    156|        {"channel",   t_uinteger, RTCM3FIELD(1009, L1.channel)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   70|    156|        {"prange",    t_real,     RTCM3FIELD(1009, L1.pseudorange)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   71|    156|        {"delta",     t_real,     RTCM3FIELD(1009, L1.rangediff)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   72|    156|        {"lockt",     t_uinteger, RTCM3FIELD(1009, L1.locktime)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   73|    156|        {NULL},
   74|    156|    };
   75|       |
   76|    156|    const struct json_attr_t rtcm1010_satellite[] = {
   77|    156|        {"ident",     t_uinteger, RTCM3FIELD(1010, ident)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   78|    156|        {"ind",       t_uinteger, RTCM3FIELD(1010, L1.indicator)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   79|    156|        {"channel",   t_uinteger, RTCM3FIELD(1010, L1.channel)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   80|    156|        {"prange",    t_real,     RTCM3FIELD(1010, L1.pseudorange)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   81|    156|        {"delta",     t_real,     RTCM3FIELD(1010, L1.rangediff)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   82|    156|        {"lockt",     t_uinteger, RTCM3FIELD(1010, L1.locktime)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   83|    156|        {"amb",       t_uinteger, RTCM3FIELD(1010, L1.ambiguity)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   84|    156|        {"CNR",       t_real,     RTCM3FIELD(1010, L1.CNR)},
  ------------------
  |  |   45|    156|#define RTCM3FIELD(type, fld)   STRUCTOBJECT(struct rtcm3_ ## type ## _t, fld)
  |  |  ------------------
  |  |  |  |  188|    156|#define STRUCTOBJECT(s, f)      .addr.offset = offsetof(s, f)
  |  |  ------------------
  ------------------
   85|    156|        {NULL},
   86|    156|    };
   87|    156|#undef RTCM3FIELD
   88|       |
   89|    156|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
   90|    156|    const struct json_attr_t json_rtcm1001[] = {
   91|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
   92|    156|        {"station_id", t_uinteger, .addr.uinteger = R1001.station_id},
  ------------------
  |  |   89|    156|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   93|    156|        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1001.tow},
  ------------------
  |  |   89|    156|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   94|    156|        {"sync",       t_boolean,  .addr.boolean = R1001.sync},
  ------------------
  |  |   89|    156|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   95|    156|        {"smoothing",  t_boolean,  .addr.boolean = R1001.smoothing},
  ------------------
  |  |   89|    156|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   96|    156|        {"interval",   t_uinteger, .addr.uinteger = R1001.interval},
  ------------------
  |  |   89|    156|#define R1001   &rtcm3->rtcmtypes.rtcm3_1001.header
  ------------------
   97|    156|        {"satellites", t_array,
   98|    156|         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1001.rtk_data,
  ------------------
  |  |  190|    156|        .addr.array.element_type = t_structobject, \
  |  |  191|    156|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    156|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    156|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    156|        .addr.array.count = n, \
  |  |  195|    156|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    156|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    156|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    156|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    156|            struct { \
  |  |  |  |  |  |   71|    156|                int unused_int; \
  |  |  |  |  |  |   72|    156|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    156|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    156|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    156|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    156|            }; \
  |  |  |  |  |  |   77|    156|            1; \
  |  |  |  |  |  |   78|    156|        })) \
  |  |  |  |  |  |   79|    156|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
   99|    156|         rtcm1001_satellite, &satcount)},
  100|    156|        {NULL},
  101|    156|    };
  102|    156|#undef R1001
  103|       |
  104|    156|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  105|    156|    const struct json_attr_t json_rtcm1002[] = {
  106|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  107|    156|        {"station_id", t_uinteger, .addr.uinteger = R1002.station_id},
  ------------------
  |  |  104|    156|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  108|    156|        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1002.tow},
  ------------------
  |  |  104|    156|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  109|    156|        {"sync",       t_boolean,  .addr.boolean = R1002.sync},
  ------------------
  |  |  104|    156|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  110|    156|        {"smoothing",  t_boolean,  .addr.boolean = R1002.smoothing},
  ------------------
  |  |  104|    156|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  111|    156|        {"interval",   t_uinteger, .addr.uinteger = R1002.interval},
  ------------------
  |  |  104|    156|#define R1002   &rtcm3->rtcmtypes.rtcm3_1002.header
  ------------------
  112|    156|        {"satellites", t_array,
  113|    156|         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1002.rtk_data,
  ------------------
  |  |  190|    156|        .addr.array.element_type = t_structobject, \
  |  |  191|    156|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    156|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    156|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    156|        .addr.array.count = n, \
  |  |  195|    156|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    156|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    156|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    156|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    156|            struct { \
  |  |  |  |  |  |   71|    156|                int unused_int; \
  |  |  |  |  |  |   72|    156|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    156|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    156|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    156|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    156|            }; \
  |  |  |  |  |  |   77|    156|            1; \
  |  |  |  |  |  |   78|    156|        })) \
  |  |  |  |  |  |   79|    156|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  114|    156|         rtcm1002_satellite, &satcount)},
  115|    156|        {NULL},
  116|    156|    };
  117|    156|#undef R1002
  118|       |
  119|    156|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  120|    156|    const struct json_attr_t json_rtcm1007[] = {
  121|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  122|    156|        {"station_id", t_uinteger, .addr.uinteger = &R1007.station_id},
  ------------------
  |  |  119|    156|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  ------------------
  123|    156|        {"desc",       t_string,   .addr.string = R1007.descriptor,
  ------------------
  |  |  119|    156|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  ------------------
  124|    156|                                         .len = sizeof(R1007.descriptor)},
  ------------------
  |  |  119|    156|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  ------------------
  125|    156|        {"setup_id",   t_uinteger, .addr.uinteger = &R1007.setup_id},
  ------------------
  |  |  119|    156|#define R1007   rtcm3->rtcmtypes.rtcm3_1007
  ------------------
  126|    156|        {NULL},
  127|    156|    };
  128|    156|#undef R1002
  129|       |
  130|    156|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  131|    156|    const struct json_attr_t json_rtcm1008[] = {
  132|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  133|    156|        {"station_id", t_uinteger, .addr.uinteger = &R1008.station_id},
  ------------------
  |  |  130|    156|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  134|    156|        {"desc",       t_string,   .addr.string = R1008.descriptor,
  ------------------
  |  |  130|    156|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  135|    156|                                         .len = sizeof(R1008.descriptor)},
  ------------------
  |  |  130|    156|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  136|    156|        {"setup_id",   t_uinteger, .addr.uinteger = &R1008.setup_id},
  ------------------
  |  |  130|    156|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  137|    156|        {"serial",     t_string,   .addr.string = R1008.serial,
  ------------------
  |  |  130|    156|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  138|    156|                                         .len = sizeof(R1008.serial)},
  ------------------
  |  |  130|    156|#define R1008   rtcm3->rtcmtypes.rtcm3_1008
  ------------------
  139|    156|        {NULL},
  140|    156|    };
  141|    156|#undef R1008
  142|       |
  143|    156|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  144|    156|    const struct json_attr_t json_rtcm1009[] = {
  145|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  146|    156|        {"station_id", t_uinteger, .addr.uinteger = R1009.station_id},
  ------------------
  |  |  143|    156|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  147|    156|        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1009.tow},
  ------------------
  |  |  143|    156|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  148|    156|        {"sync",       t_boolean,  .addr.boolean = R1009.sync},
  ------------------
  |  |  143|    156|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  149|    156|        {"smoothing",  t_boolean,  .addr.boolean = R1009.smoothing},
  ------------------
  |  |  143|    156|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  150|    156|        {"interval",   t_uinteger, .addr.uinteger = R1009.interval},
  ------------------
  |  |  143|    156|#define R1009   &rtcm3->rtcmtypes.rtcm3_1009.header
  ------------------
  151|    156|        {"satellites", t_array,
  152|    156|         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1009.rtk_data,
  ------------------
  |  |  190|    156|        .addr.array.element_type = t_structobject, \
  |  |  191|    156|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    156|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    156|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    156|        .addr.array.count = n, \
  |  |  195|    156|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    156|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    156|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    156|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    156|            struct { \
  |  |  |  |  |  |   71|    156|                int unused_int; \
  |  |  |  |  |  |   72|    156|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    156|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    156|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    156|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    156|            }; \
  |  |  |  |  |  |   77|    156|            1; \
  |  |  |  |  |  |   78|    156|        })) \
  |  |  |  |  |  |   79|    156|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  153|    156|         rtcm1009_satellite, &satcount)},
  154|    156|        {NULL},
  155|    156|    };
  156|    156|#undef R1010
  157|       |
  158|    156|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  159|    156|    const struct json_attr_t json_rtcm1010[] = {
  160|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  161|    156|        {"station_id", t_uinteger, .addr.uinteger = R1010.station_id},
  ------------------
  |  |  158|    156|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  162|    156|        {"tow",        t_uinteger, .addr.uinteger = (unsigned int *)R1010.tow},
  ------------------
  |  |  158|    156|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  163|    156|        {"sync",       t_boolean,  .addr.boolean = R1010.sync},
  ------------------
  |  |  158|    156|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  164|    156|        {"smoothing",  t_boolean,  .addr.boolean = R1010.smoothing},
  ------------------
  |  |  158|    156|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  165|    156|        {"interval",   t_uinteger, .addr.uinteger = R1010.interval},
  ------------------
  |  |  158|    156|#define R1010   &rtcm3->rtcmtypes.rtcm3_1010.header
  ------------------
  166|    156|        {"satellites", t_array,
  167|    156|         STRUCTARRAY(rtcm3->rtcmtypes.rtcm3_1010.rtk_data,
  ------------------
  |  |  190|    156|        .addr.array.element_type = t_structobject, \
  |  |  191|    156|        .addr.array.arr.objects.subtype = e, \
  |  |  192|    156|        .addr.array.arr.objects.base = (char*)a, \
  |  |  193|    156|        .addr.array.arr.objects.stride = sizeof(a[0]), \
  |  |  194|    156|        .addr.array.count = n, \
  |  |  195|    156|        .addr.array.maxlen = NITEMS(a)
  |  |  ------------------
  |  |  |  | 1165|    156|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  |  |  ------------------
  |  |  |  |  |  |   68|    156|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |  |  |   69|    156|        0 * (int) sizeof(({ \
  |  |  |  |  |  |   70|    156|            struct { \
  |  |  |  |  |  |   71|    156|                int unused_int; \
  |  |  |  |  |  |   72|    156|                __typeof__(arr) unused_arr; \
  |  |  |  |  |  |   73|    156|            } zero_init = {0}; \
  |  |  |  |  |  |   74|    156|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |  |  |   75|    156|                zero_init.unused_arr[0], \
  |  |  |  |  |  |   76|    156|            }; \
  |  |  |  |  |  |   77|    156|            1; \
  |  |  |  |  |  |   78|    156|        })) \
  |  |  |  |  |  |   79|    156|    )
  |  |  |  |  ------------------
  |  |  ------------------
  ------------------
  168|    156|         rtcm1010_satellite, &satcount)},
  169|    156|        {NULL},
  170|    156|    };
  171|    156|#undef R1010
  172|       |
  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  174|    156|    const struct json_attr_t json_rtcm1014[] = {
  175|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  176|    156|        {"netid",      t_uinteger, .addr.uinteger = R1014.network_id},
  ------------------
  |  |  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  177|    156|        {"subnetid",   t_uinteger, .addr.uinteger = R1014.subnetwork_id},
  ------------------
  |  |  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  178|    156|        {"statcount",  t_uinteger, .addr.uinteger = R1014.stationcount},
  ------------------
  |  |  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  179|    156|        {"master",     t_uinteger, .addr.uinteger = R1014.master_id},
  ------------------
  |  |  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  180|    156|        {"aux",        t_uinteger, .addr.uinteger = R1014.aux_id},
  ------------------
  |  |  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  181|    156|        {"lat",        t_real,     .addr.real = R1014.d_lat},
  ------------------
  |  |  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  182|    156|        {"lon",        t_real,     .addr.real = R1014.d_lon},
  ------------------
  |  |  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  183|    156|        {"alt",        t_real,     .addr.real = R1014.d_alt},
  ------------------
  |  |  173|    156|#define R1014   &rtcm3->rtcmtypes.rtcm3_1014
  ------------------
  184|    156|        {NULL},
  185|    156|    };
  186|    156|#undef R1014
  187|       |
  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  189|    156|    const struct json_attr_t json_rtcm1033[] = {
  190|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  191|    156|        {"station_id", t_uinteger, .addr.uinteger = &R1033.station_id},
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  192|    156|        {"desc",       t_string,   .addr.string = R1033.descriptor,
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  193|    156|                                         .len = sizeof(R1033.descriptor)},
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  194|    156|        {"setup_id",   t_uinteger, .addr.uinteger = &R1033.setup_id},
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  195|    156|        {"serial",     t_string,   .addr.string = R1033.serial,
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  196|    156|                                         .len = sizeof(R1033.serial)},
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  197|    156|        {"receiver",   t_string,   .addr.string = R1033.receiver,
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  198|    156|                                         .len = sizeof(R1033.receiver)},
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  199|    156|        {"firmware",   t_string,   .addr.string = R1033.firmware,
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  200|    156|                                         .len = sizeof(R1033.firmware)},
  ------------------
  |  |  188|    156|#define R1033   rtcm3->rtcmtypes.rtcm3_1033
  ------------------
  201|    156|        {NULL},
  202|    156|    };
  203|    156|#undef R1033
  204|       |
  205|    156|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  206|    156|    const struct json_attr_t json_rtcm1230[] = {
  207|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  208|    156|        {"station_id", t_uinteger, .addr.uinteger = &R1230.station_id},
  ------------------
  |  |  205|    156|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  209|    156|        {"bi",         t_ubyte,    .addr.ubyte = &R1230.bias_indicator},
  ------------------
  |  |  205|    156|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  210|    156|        {"sm",         t_ubyte,    .addr.ubyte = &R1230.signals_mask},
  ------------------
  |  |  205|    156|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  211|    156|        {"l1ca",       t_integer,  .addr.integer = &R1230.l1_ca_bias,
  ------------------
  |  |  205|    156|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  212|    156|                                   .dflt.integer = 0},
  213|    156|        {"l1p",        t_integer,  .addr.integer = &R1230.l1_p_bias,
  ------------------
  |  |  205|    156|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  214|    156|                                   .dflt.integer = 0},
  215|    156|        {"l2ca",       t_integer,  .addr.integer = &R1230.l2_ca_bias,
  ------------------
  |  |  205|    156|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  216|    156|                                   .dflt.integer = 0},
  217|    156|        {"l2p",        t_integer,  .addr.integer = &R1230.l2_p_bias,
  ------------------
  |  |  205|    156|#define R1230   rtcm3->rtcmtypes.rtcm3_1230
  ------------------
  218|    156|                                   .dflt.integer = 0},
  219|    156|        {NULL},
  220|    156|    };
  221|    156|#undef R1033
  222|       |
  223|    156|    const struct json_attr_t json_rtcm3_fallback[] = {
  224|    156|        RTCM3_HEADER
  ------------------
  |  |   38|    156|        {"class",          t_check,    .dflt.check = "RTCM3"}, \
  |  |   39|    156|        {"type",           t_uinteger, .addr.uinteger = &rtcm3->type}, \
  |  |   40|    156|        {"device",         t_string,   .addr.string = path, .len = pathlen}, \
  |  |   41|    156|        {"length",         t_uinteger, .addr.uinteger = &rtcm3->length},
  ------------------
  225|    156|        {"data", t_array, .addr.array.element_type = t_string,
  226|    156|                          .addr.array.arr.strings.ptrs = stringptrs,
  227|    156|                          .addr.array.arr.strings.store = stringstore,
  228|    156|                         .addr.array.arr.strings.storelen = sizeof(stringstore),
  229|    156|                          .addr.array.count = &stringcount,
  230|    156|                          .addr.array.maxlen = NITEMS(stringptrs)},
  ------------------
  |  | 1165|    156|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  ------------------
  |  |  |  |   68|    156|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |   69|    156|        0 * (int) sizeof(({ \
  |  |  |  |   70|    156|            struct { \
  |  |  |  |   71|    156|                int unused_int; \
  |  |  |  |   72|    156|                __typeof__(arr) unused_arr; \
  |  |  |  |   73|    156|            } zero_init = {0}; \
  |  |  |  |   74|    156|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |   75|    156|                zero_init.unused_arr[0], \
  |  |  |  |   76|    156|            }; \
  |  |  |  |   77|    156|            1; \
  |  |  |  |   78|    156|        })) \
  |  |  |  |   79|    156|    )
  |  |  ------------------
  ------------------
  231|    156|        {NULL},
  232|    156|    };
  233|       |
  234|    156|#undef RTCM3_HEADER
  235|       |/* *INDENT-ON* */
  236|       |
  237|    156|    memset(rtcm3, '\0', sizeof(struct rtcm3_t));
  238|       |
  239|    156|    if (strstr(buf, "\"type\":1001,") != NULL) {
  ------------------
  |  Branch (239:9): [True: 5, False: 151]
  ------------------
  240|      5|        status = json_read_object(buf, json_rtcm1001, endptr);
  241|      5|        if (status == 0)
  ------------------
  |  Branch (241:13): [True: 1, False: 4]
  ------------------
  242|      1|            rtcm3->rtcmtypes.rtcm3_1001.header.satcount =
  243|      1|                (unsigned short)satcount;
  244|    151|    } else if (strstr(buf, "\"type\":1002,") != NULL) {
  ------------------
  |  Branch (244:16): [True: 5, False: 146]
  ------------------
  245|      5|        status = json_read_object(buf, json_rtcm1002, endptr);
  246|      5|        if (status == 0)
  ------------------
  |  Branch (246:13): [True: 1, False: 4]
  ------------------
  247|      1|            rtcm3->rtcmtypes.rtcm3_1002.header.satcount =
  248|      1|               (unsigned short)satcount;
  249|    146|    } else if (strstr(buf, "\"type\":1007,") != NULL) {
  ------------------
  |  Branch (249:16): [True: 1, False: 145]
  ------------------
  250|      1|        status = json_read_object(buf, json_rtcm1007, endptr);
  251|    145|    } else if (strstr(buf, "\"type\":1008,") != NULL) {
  ------------------
  |  Branch (251:16): [True: 1, False: 144]
  ------------------
  252|      1|        status = json_read_object(buf, json_rtcm1008, endptr);
  253|    144|    } else if (strstr(buf, "\"type\":1009,") != NULL) {
  ------------------
  |  Branch (253:16): [True: 2, False: 142]
  ------------------
  254|      2|        status = json_read_object(buf, json_rtcm1009, endptr);
  255|    142|    } else if (strstr(buf, "\"type\":1010,") != NULL) {
  ------------------
  |  Branch (255:16): [True: 1, False: 141]
  ------------------
  256|      1|        status = json_read_object(buf, json_rtcm1010, endptr);
  257|    141|    } else if (strstr(buf, "\"type\":1014,") != NULL) {
  ------------------
  |  Branch (257:16): [True: 1, False: 140]
  ------------------
  258|      1|        status = json_read_object(buf, json_rtcm1014, endptr);
  259|    140|    } else if (strstr(buf, "\"type\":1033,") != NULL) {
  ------------------
  |  Branch (259:16): [True: 1, False: 139]
  ------------------
  260|      1|        status = json_read_object(buf, json_rtcm1033, endptr);
  261|    139|    } else if (strstr(buf, "\"type\":1230,") != NULL) {
  ------------------
  |  Branch (261:16): [True: 23, False: 116]
  ------------------
  262|     23|        status = json_read_object(buf, json_rtcm1230, endptr);
  263|    116|    } else {
  264|    116|        int n;
  265|    116|        status = json_read_object(buf, json_rtcm3_fallback, endptr);
  266|  76.9k|        for (n = 0; n < NITEMS(rtcm3->rtcmtypes.data); n++) {
  ------------------
  |  | 1165|  76.9k|#define NITEMS(x) ((int) (sizeof(x) / sizeof(x[0]) + COMPILE_CHECK_IS_ARRAY(x)))
  |  |  ------------------
  |  |  |  |   68|  76.9k|    #define COMPILE_CHECK_IS_ARRAY(arr) ( \
  |  |  |  |   69|  76.9k|        0 * (int) sizeof(({ \
  |  |  |  |   70|  76.9k|            struct { \
  |  |  |  |   71|  76.9k|                int unused_int; \
  |  |  |  |   72|  76.9k|                __typeof__(arr) unused_arr; \
  |  |  |  |   73|  76.9k|            } zero_init = {0}; \
  |  |  |  |   74|  76.9k|            __typeof__(arr) arg_is_not_array UNUSED = { \
  |  |  |  |   75|  76.9k|                zero_init.unused_arr[0], \
  |  |  |  |   76|  76.9k|            }; \
  |  |  |  |   77|  76.9k|            1; \
  |  |  |  |   78|  76.9k|        })) \
  |  |  |  |   79|  76.9k|    )
  |  |  ------------------
  ------------------
  |  Branch (266:21): [True: 76.9k, False: 75]
  ------------------
  267|  76.9k|            if (n >= stringcount) {
  ------------------
  |  Branch (267:17): [True: 74.9k, False: 1.90k]
  ------------------
  268|  74.9k|                rtcm3->rtcmtypes.data[n] = '\0';
  269|  74.9k|            } else {
  270|  1.90k|                unsigned int u;
  271|  1.90k|                int fldcount = sscanf(stringptrs[n], "0x%02x\n", &u);
  272|  1.90k|                if (fldcount != 1)
  ------------------
  |  Branch (272:21): [True: 41, False: 1.86k]
  ------------------
  273|     41|                    return JSON_ERR_MISC;
  ------------------
  |  |  172|     41|#define JSON_ERR_MISC           21      // other data conversion error
  ------------------
  274|  1.86k|                else
  275|  1.86k|                    rtcm3->rtcmtypes.data[n] = (char)u;
  276|  1.90k|            }
  277|  76.9k|        }
  278|    116|    }
  279|    115|    return status;
  280|    156|}

json_device_read:
   32|     23|{
   33|       |    // initialized to shut up clang
   34|     23|    double d_cycle = 0.0, d_mincycle = 0.0;
   35|       |
   36|       |    // *INDENT-OFF*
   37|     23|    const struct json_attr_t json_attrs_device[] = {
   38|     23|        {"class",      t_check,      .dflt.check = "DEVICE"},
   39|       |
   40|     23|        {"path",       t_string,     .addr.string  = dev->path,
   41|     23|                                        .len = sizeof(dev->path)},
   42|       |        // odd, device->gpsdata.online is sent, but put in dev->activated?
   43|     23|        {"activated",  t_time,       .addr.ts = &dev->activated,
   44|     23|                                        .dflt.ts = {0, 0}},
   45|     23|        {"flags",      t_integer,    .addr.integer = &dev->flags},
   46|     23|        {"driver",     t_string,     .addr.string  = dev->driver,
   47|     23|                                        .len = sizeof(dev->driver)},
   48|     23|        {"sernum",     t_string,     .addr.string  = dev->sernum,
   49|     23|                                        .len = sizeof(dev->sernum)},
   50|     23|        {"subtype",    t_string,     .addr.string  = dev->subtype,
   51|     23|                                        .len = sizeof(dev->subtype)},
   52|     23|        {"subtype1",   t_string,     .addr.string  = dev->subtype1,
   53|     23|                                        .len = sizeof(dev->subtype1)},
   54|     23|        {"hexdata",    t_string,     .addr.string  = dev->hexdata,
   55|     23|                                        .len = sizeof(dev->hexdata)},
   56|     23|        {"native",     t_integer,    .addr.integer = &dev->driver_mode,
   57|     23|                                        .dflt.integer = DEVDEFAULT_NATIVE},
  ------------------
  |  |   56|     23|#define DEVDEFAULT_NATIVE       -1
  ------------------
   58|     23|        {"bps",        t_uinteger,   .addr.uinteger = &dev->baudrate,
   59|     23|                                        .dflt.uinteger = DEVDEFAULT_BPS},
  ------------------
  |  |   53|     23|#define DEVDEFAULT_BPS          0
  ------------------
   60|     23|        {"parity",     t_character,  .addr.character = &dev->parity,
   61|     23|                                        .dflt.character = DEVDEFAULT_PARITY},
  ------------------
  |  |   54|     23|#define DEVDEFAULT_PARITY       'X'
  ------------------
   62|     23|        {"stopbits",   t_uinteger,   .addr.uinteger = &dev->stopbits,
   63|     23|                                        .dflt.uinteger = DEVDEFAULT_STOPBITS},
  ------------------
  |  |   55|     23|#define DEVDEFAULT_STOPBITS     3
  ------------------
   64|     23|        {"cycle",      t_real,       .addr.real = &d_cycle,
   65|     23|                                        .dflt.real = NAN},
   66|     23|        {"mincycle",   t_real,       .addr.real = &d_mincycle,
   67|     23|                                        .dflt.real = NAN},
   68|       |        // ignore unknown keys, for cross-version compatibility
   69|     23|        {"", t_ignore},
   70|     23|        {NULL},
   71|     23|    };
   72|       |    // *INDENT-ON*
   73|     23|    int status;
   74|       |
   75|     23|    status = json_read_object(buf, json_attrs_device, endptr);
   76|     23|    if (0 != status) {
  ------------------
  |  Branch (76:9): [True: 20, False: 3]
  ------------------
   77|     20|        return status;
   78|     20|    }
   79|       |
   80|      3|    if (0 == isfinite(d_cycle)) {
  ------------------
  |  Branch (80:9): [True: 2, False: 1]
  ------------------
   81|      2|        dev->cycle.tv_sec = 0;
   82|      2|        dev->cycle.tv_nsec = 0;
   83|      2|    } else {
   84|      1|        DTOTS(&dev->cycle, d_cycle);
  ------------------
  |  |  143|      1|    do { \
  |  |  144|      1|        double int_part; \
  |  |  145|      1|        (ts)->tv_nsec = (long)(modf(d, &int_part) * 1e9); \
  |  |  146|      1|        (ts)->tv_sec = (time_t)int_part; \
  |  |  147|      1|    } while (0)
  |  |  ------------------
  |  |  |  Branch (147:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   85|      1|    }
   86|      3|    if (0 == isfinite(d_mincycle)) {
  ------------------
  |  Branch (86:9): [True: 2, False: 1]
  ------------------
   87|      2|        dev->mincycle.tv_sec = 0;
   88|      2|        dev->mincycle.tv_nsec = 0;
   89|      2|    } else {
   90|      1|        DTOTS(&dev->mincycle, d_mincycle);
  ------------------
  |  |  143|      1|    do { \
  |  |  144|      1|        double int_part; \
  |  |  145|      1|        (ts)->tv_nsec = (long)(modf(d, &int_part) * 1e9); \
  |  |  146|      1|        (ts)->tv_sec = (time_t)int_part; \
  |  |  147|      1|    } while (0)
  |  |  ------------------
  |  |  |  Branch (147:14): [Folded - Ignored]
  |  |  ------------------
  ------------------
   91|      1|    }
   92|       |
   93|      3|    return 0;
   94|     23|}
json_watch_read:
   99|     52|{
  100|       |    // *INDENT-OFF*
  101|     52|    struct json_attr_t chanconfig_attrs[] = {
  102|     52|        {"class",          t_check,    .dflt.check = "WATCH"},
  103|       |
  104|     52|        {"device",         t_string,   .addr.string = ccp->devpath,
  105|     52|                                          .len = sizeof(ccp->devpath)},
  106|     52|        {"enable",         t_boolean,  .addr.boolean = &ccp->watcher,
  107|     52|                                          .dflt.boolean = true},
  108|     52|        {"json",           t_boolean,  .addr.boolean = &ccp->json,
  109|     52|                                          .nodefault = true},
  110|     52|        {"nmea",           t_boolean,  .addr.boolean = &ccp->nmea,
  111|     52|                                          .nodefault = true},
  112|     52|        {"pps",            t_boolean,  .addr.boolean = &ccp->pps},
  113|     52|        {"raw",            t_integer,  .addr.integer = &ccp->raw,
  114|     52|                                          .nodefault = true},
  115|     52|        {"remote",         t_string,   .addr.string = ccp->remote,
  116|     52|                                          .len = sizeof(ccp->remote)},
  117|     52|        {"scaled",         t_boolean,  .addr.boolean = &ccp->scaled},
  118|     52|        {"split24",        t_boolean,  .addr.boolean = &ccp->split24},
  119|     52|        {"timing",         t_boolean,  .addr.boolean = &ccp->timing},
  120|       |        // ignore unknown keys, for cross-version compatibility
  121|     52|        {"", t_ignore},
  122|     52|        {NULL},
  123|     52|    };
  124|       |    // *INDENT-ON*
  125|     52|    int status;
  126|       |
  127|     52|    status = json_read_object(buf, chanconfig_attrs, endptr);
  128|     52|    return status;
  129|     52|}

