Coverage Report

Created: 2026-08-13 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gpsd/gpsd-3.27.6~dev/libgps/ais_json.c
Line
Count
Source
1
/****************************************************************************
2
3
NAME
4
   ais_json.c - deserialize AIS JSON
5
6
DESCRIPTION
7
   This module uses the generic JSON parser to get data from AIS
8
representations to libgps structures.
9
10
This file is Copyright by the GPSD project
11
SPDX-License-Identifier: BSD-2-clause
12
***************************************************************************/
13
14
#include "../include/gpsd_config.h"  // must be before all includes
15
16
#include <stdio.h>
17
#include <string.h>
18
#include <stdbool.h>
19
#include <stdlib.h>
20
#include <stddef.h>
21
#include <time.h>
22
23
#include "../include/gps.h"
24
#include "../include/json.h"
25
#include "../include/libgps.h"
26
27
static void lenhex_unpack(const char *from,
28
                          size_t * plen, char *to, size_t maxlen)
29
122
{
30
122
    const char *colon = strchr(from, ':');
31
32
122
    *plen = (size_t)atoi(from);
33
122
    if (NULL != colon) {
34
113
        (void)gps_hexpack(colon + 1, (unsigned char *)to, maxlen);
35
113
    }
36
122
}
37
38
39
int json_ais_read(const char *buf,
40
                  char *path, size_t pathlen, struct ais_t *ais,
41
                  const char **endptr)
42
333
{
43
    // collected but not actually used yet
44
333
    bool scaled;
45
46
333
#define AIS_HEADER \
47
16.3k
        {"class",          t_check,    .dflt.check = "AIS"}, \
48
16.3k
        {"type",           t_uinteger, .addr.uinteger = &ais->type}, \
49
16.3k
        {"device",         t_string,   .addr.string = path, \
50
16.3k
                                          .len = pathlen}, \
51
16.3k
        {"repeat",         t_uinteger, .addr.uinteger = &ais->repeat}, \
52
16.3k
        {"scaled",         t_boolean,  .addr.boolean = &scaled, \
53
16.3k
                                          .dflt.boolean = false}, \
54
16.3k
        {"mmsi",           t_uinteger, .addr.uinteger = &ais->mmsi},
55
56
333
#define AIS_TYPE6 \
57
4.66k
        {"seqno",         t_uinteger,  .addr.uinteger = &ais->type6.seqno,\
58
4.66k
                                       .dflt.uinteger = 0},\
59
4.66k
        {"dest_mmsi",     t_uinteger,  .addr.uinteger = &ais->type6.dest_mmsi,\
60
4.66k
                                       .dflt.uinteger = 0},\
61
4.66k
        {"retransmit",    t_boolean,   .addr.boolean = &ais->type6.retransmit,\
62
4.66k
                                       .dflt.boolean = false},\
63
4.66k
        {"dac",           t_uinteger,  .addr.uinteger = &ais->type6.dac,\
64
4.66k
                                       .dflt.uinteger = 0},\
65
4.66k
        {"fid",           t_uinteger,  .addr.uinteger = &ais->type6.fid,\
66
4.66k
                                       .dflt.uinteger = 0},
67
333
#define AIS_TYPE8 \
68
4.66k
        {"dac",           t_uinteger,  .addr.uinteger = &ais->type8.dac,\
69
4.66k
                                       .dflt.uinteger = 0},\
70
4.66k
        {"fid",           t_uinteger,  .addr.uinteger = &ais->type8.fid,\
71
4.66k
                                       .dflt.uinteger = 0},
72
73
333
    int status;
74
75
333
#include "ais_json.i"           // JSON parser template structures
76
77
333
#undef AIS_HEADER
78
79
333
    memset(ais, '\0', sizeof(struct ais_t));
80
81
333
    if (NULL != strstr(buf, "\"type\":1,") ||
82
333
        NULL != strstr(buf, "\"type\":2,") ||
83
333
        NULL != strstr(buf, "\"type\":3,")) {
84
5
        status = json_read_object(buf, json_ais1, endptr);
85
328
    } else if (NULL != strstr(buf, "\"type\":4,") ||
86
328
               NULL != strstr(buf, "\"type\":11,")) {
87
6
        status = json_read_object(buf, json_ais4, endptr);
88
6
        if (0 == status) {
89
            // no need to set zeros, again.
90
            // ais->type4.year = AIS_YEAR_NOT_AVAILABLE;
91
            // ais->type4.month = AIS_MONTH_NOT_AVAILABLE;
92
            // ais->type4.day = AIS_DAY_NOT_AVAILABLE;
93
1
            ais->type4.hour = AIS_HOUR_NOT_AVAILABLE;
94
1
            ais->type4.minute = AIS_MINUTE_NOT_AVAILABLE;
95
1
            ais->type4.second = AIS_SECOND_NOT_AVAILABLE;
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
322
    } else if (strstr(buf, "\"type\":5,") != NULL) {
107
14
        status = json_read_object(buf, json_ais5, endptr);
108
14
        if (status == 0) {
109
            // no need to set zeros, again.
110
            // ais->type5.month = AIS_MONTH_NOT_AVAILABLE;
111
            // ais->type5.day = AIS_DAY_NOT_AVAILABLE;
112
2
            ais->type5.hour = AIS_HOUR_NOT_AVAILABLE;
113
2
            ais->type5.minute = AIS_MINUTE_NOT_AVAILABLE;
114
2
            (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
115
2
                         &ais->type5.month,
116
2
                         &ais->type5.day,
117
2
                         &ais->type5.hour,
118
2
                         &ais->type5.minute);
119
2
        }
120
308
    } else if (strstr(buf, "\"type\":6,") != NULL) {
121
132
        bool structured = false;
122
132
        if (strstr(buf, "\"dac\":1,") != NULL) {
123
32
            if (strstr(buf, "\"fid\":12,") != NULL) {
124
6
                status = json_read_object(buf, json_ais6_fid12, endptr);
125
6
                if (status == 0) {
126
                    // no need to set zeros, again.
127
                    // ais->type6.dac1fid12.lmonth = AIS_MONTH_NOT_AVAILABLE;
128
                    // ais->type6.dac1fid12.lday = AIS_DAY_NOT_AVAILABLE;
129
1
                    ais->type6.dac1fid12.lhour = AIS_HOUR_NOT_AVAILABLE;
130
1
                    ais->type6.dac1fid12.lminute = AIS_MINUTE_NOT_AVAILABLE;
131
                    // ais->type6.dac1fid12.nmonth = AIS_MONTH_NOT_AVAILABLE;
132
                    // ais->type6.dac1fid12.nday = AIS_DAY_NOT_AVAILABLE;
133
1
                    ais->type6.dac1fid12.nhour = AIS_HOUR_NOT_AVAILABLE;
134
1
                    ais->type6.dac1fid12.nminute = AIS_MINUTE_NOT_AVAILABLE;
135
1
                    (void)sscanf(departure, "%02u-%02uT%02u:%02uZ",
136
1
                                 &ais->type6.dac1fid12.lmonth,
137
1
                                 &ais->type6.dac1fid12.lday,
138
1
                                 &ais->type6.dac1fid12.lhour,
139
1
                                 &ais->type6.dac1fid12.lminute);
140
1
                    (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
141
1
                                 &ais->type6.dac1fid12.nmonth,
142
1
                                 &ais->type6.dac1fid12.nday,
143
1
                                 &ais->type6.dac1fid12.nhour,
144
1
                                 &ais->type6.dac1fid12.nminute);
145
1
                }
146
6
                structured = true;
147
6
            }
148
26
            else if (strstr(buf, "\"fid\":15,") != NULL) {
149
1
                status = json_read_object(buf, json_ais6_fid15, endptr);
150
1
                structured = true;
151
1
            }
152
25
            else if (strstr(buf, "\"fid\":16,") != NULL) {
153
1
                status = json_read_object(buf, json_ais6_fid16, endptr);
154
1
                structured = true;
155
1
            }
156
24
            else if (strstr(buf, "\"fid\":18,") != NULL) {
157
5
                status = json_read_object(buf, json_ais6_fid18, endptr);
158
5
                if (status == 0) {
159
                    // no need to set zeros, again.
160
                    // ais->type6.dac1fid18.month = AIS_MONTH_NOT_AVAILABLE;
161
                    // ais->type6.dac1fid18.day = AIS_DAY_NOT_AVAILABLE;
162
1
                    ais->type6.dac1fid18.hour = AIS_HOUR_NOT_AVAILABLE;
163
1
                    ais->type6.dac1fid18.minute = AIS_MINUTE_NOT_AVAILABLE;
164
1
                    (void)sscanf(arrival, "%02u-%02uT%02u:%02uZ",
165
1
                                 &ais->type6.dac1fid18.month,
166
1
                                 &ais->type6.dac1fid18.day,
167
1
                                 &ais->type6.dac1fid18.hour,
168
1
                                 &ais->type6.dac1fid18.minute);
169
1
                }
170
5
                structured = true;
171
5
            }
172
19
            else if (strstr(buf, "\"fid\":20,") != NULL) {
173
7
                status = json_read_object(buf, json_ais6_fid20, endptr);
174
7
                if (status == 0) {
175
                    // no need to set zeros, again.
176
                    // ais->type6.dac1fid20.month = AIS_MONTH_NOT_AVAILABLE;
177
                    // ais->type6.dac1fid20.day = AIS_DAY_NOT_AVAILABLE;
178
2
                    ais->type6.dac1fid20.hour = AIS_HOUR_NOT_AVAILABLE;
179
2
                    ais->type6.dac1fid20.minute = AIS_MINUTE_NOT_AVAILABLE;
180
2
                    (void)sscanf(arrival, "%02u-%02uT%02u:%02uZ",
181
2
                                 &ais->type6.dac1fid20.month,
182
2
                                 &ais->type6.dac1fid20.day,
183
2
                                 &ais->type6.dac1fid20.hour,
184
2
                                 &ais->type6.dac1fid20.minute);
185
2
                }
186
7
                structured = true;
187
7
            }
188
12
            else if (strstr(buf, "\"fid\":25,") != NULL) {
189
3
                status = json_read_object(buf, json_ais6_fid25, endptr);
190
3
                structured = true;
191
3
            }
192
9
            else if (strstr(buf, "\"fid\":28,") != NULL) {
193
5
                status = json_read_object(buf, json_ais6_fid28, endptr);
194
5
                if (status == 0) {
195
                    // no need to set zeros, again.
196
                    // ais->type6.dac1fid28.month = AIS_MONTH_NOT_AVAILABLE;
197
                    // ais->type6.dac1fid28.day = AIS_DAY_NOT_AVAILABLE;
198
1
                    ais->type6.dac1fid28.hour = AIS_HOUR_NOT_AVAILABLE;
199
1
                    ais->type6.dac1fid28.minute = AIS_MINUTE_NOT_AVAILABLE;
200
1
                    (void)sscanf(start, "%02u-%02uT%02u:%02uZ",
201
1
                                 &ais->type6.dac1fid28.month,
202
1
                                 &ais->type6.dac1fid28.day,
203
1
                                 &ais->type6.dac1fid28.hour,
204
1
                                 &ais->type6.dac1fid28.minute);
205
1
                }
206
5
                structured = true;
207
5
            }
208
4
            else if (strstr(buf, "\"fid\":30,") != NULL) {
209
1
                status = json_read_object(buf, json_ais6_fid30, endptr);
210
1
                structured = true;
211
1
            }
212
3
            else if (strstr(buf, "\"fid\":32,") != NULL ||
213
2
                     strstr(buf, "\"fid\":14,") != NULL) {
214
2
                status = json_read_object(buf, json_ais6_fid32, endptr);
215
2
                structured = true;
216
2
            }
217
32
        }
218
100
        else if (strstr(buf, "\"dac\":235,") != NULL ||
219
98
                 strstr(buf, "\"dac\":250,") != NULL) {
220
4
            if (strstr(buf, "\"fid\":10,") != NULL) {
221
2
                status = json_read_object(buf, json_ais6_fid10, endptr);
222
2
                structured = true;
223
2
            }
224
4
        }
225
96
        else if (strstr(buf, "\"dac\":200,") != NULL) {
226
11
            if (strstr(buf, "\"fid\":21,") != NULL) {
227
5
                status = json_read_object(buf, json_ais6_fid21, endptr);
228
5
                structured = true;
229
5
                if (status == 0) {
230
                    // no need to set zeros, again.
231
                    // ais->type6.dac200fid21.month = AIS_MONTH_NOT_AVAILABLE;
232
                    // ais->type6.dac200fid21.day = AIS_DAY_NOT_AVAILABLE;
233
1
                    ais->type6.dac200fid21.hour = AIS_HOUR_NOT_AVAILABLE;
234
1
                    ais->type6.dac200fid21.minute = AIS_MINUTE_NOT_AVAILABLE;
235
1
                    (void)sscanf(eta, "%02u-%02uT%02u:%02u",
236
1
                                 &ais->type6.dac200fid21.month,
237
1
                                 &ais->type6.dac200fid21.day,
238
1
                                 &ais->type6.dac200fid21.hour,
239
1
                                 &ais->type6.dac200fid21.minute);
240
1
                }
241
5
            }
242
6
            else if (strstr(buf, "\"fid\":22,") != NULL) {
243
4
                status = json_read_object(buf, json_ais6_fid22, endptr);
244
4
                structured = true;
245
4
                if (status == 0) {
246
                    // no need to set zeros, again.
247
                    // ais->type6.dac200fid22.month = AIS_MONTH_NOT_AVAILABLE;
248
                    // ais->type6.dac200fid22.day = AIS_DAY_NOT_AVAILABLE;
249
1
                    ais->type6.dac200fid22.hour = AIS_HOUR_NOT_AVAILABLE;
250
1
                    ais->type6.dac200fid22.minute = AIS_MINUTE_NOT_AVAILABLE;
251
1
                    (void)sscanf(rta, "%02u-%02uT%02u:%02u",
252
1
                                 &ais->type6.dac200fid22.month,
253
1
                                 &ais->type6.dac200fid22.day,
254
1
                                 &ais->type6.dac200fid22.hour,
255
1
                                 &ais->type6.dac200fid22.minute);
256
1
                }
257
4
            }
258
2
            else if (strstr(buf, "\"fid\":55,") != NULL) {
259
1
                status = json_read_object(buf, json_ais6_fid55, endptr);
260
1
                structured = true;
261
1
            }
262
11
        }
263
132
        if (!structured) {
264
89
            status = json_read_object(buf, json_ais6, endptr);
265
89
            if (status == 0)
266
81
                lenhex_unpack(data, &ais->type6.bitcount,
267
81
                              ais->type6.bitdata, sizeof(ais->type6.bitdata));
268
89
        }
269
132
        ais->type6.structured = structured;
270
176
    } else if (strstr(buf, "\"type\":7,") != NULL
271
174
               || strstr(buf, "\"type\":13,") != NULL) {
272
3
        status = json_read_object(buf, json_ais7, endptr);
273
173
    } else if (strstr(buf, "\"type\":8,") != NULL) {
274
107
        bool structured = false;
275
107
        if (strstr(buf, "\"dac\":1,") != NULL) {
276
72
            if (strstr(buf, "\"fid\":11,") != NULL) {
277
5
                status = json_read_object(buf, json_ais8_fid11, endptr);
278
5
                if (status == 0) {
279
                    // ais->type8.dac1fid11.day = AIS_DAY_NOT_AVAILABLE;
280
2
                    ais->type8.dac1fid11.hour = AIS_HOUR_NOT_AVAILABLE;
281
2
                    ais->type8.dac1fid11.minute = AIS_MINUTE_NOT_AVAILABLE;
282
2
                    (void)sscanf(timestamp, "%02uT%02u:%02uZ",
283
2
                                 &ais->type8.dac1fid11.day,
284
2
                                 &ais->type8.dac1fid11.hour,
285
2
                                 &ais->type8.dac1fid11.minute);
286
2
                }
287
5
                structured = true;
288
5
            }
289
67
            else if (strstr(buf, "\"fid\":13,") != NULL) {
290
2
                status = json_read_object(buf, json_ais8_fid13, endptr);
291
2
                if (status == 0) {
292
                    // no need to set zeros, again.
293
                    // ais->type8.dac1fid13.fmonth = AIS_MONTH_NOT_AVAILABLE;
294
                    // ais->type8.dac1fid13.fday = AIS_DAY_NOT_AVAILABLE;
295
1
                    ais->type8.dac1fid13.fhour = AIS_HOUR_NOT_AVAILABLE;
296
1
                    ais->type8.dac1fid13.fminute = AIS_MINUTE_NOT_AVAILABLE;
297
1
                    (void)sscanf(departure, "%02u-%02uT%02u:%02uZ",
298
1
                                 &ais->type8.dac1fid13.fmonth,
299
1
                                 &ais->type8.dac1fid13.fday,
300
1
                                 &ais->type8.dac1fid13.fhour,
301
1
                                 &ais->type8.dac1fid13.fminute);
302
                    // no need to set zeros, again.
303
                    // ais->type8.dac1fid13.tmonth = AIS_MONTH_NOT_AVAILABLE;
304
                    // ais->type8.dac1fid13.tday = AIS_DAY_NOT_AVAILABLE;
305
1
                    ais->type8.dac1fid13.thour = AIS_HOUR_NOT_AVAILABLE;
306
1
                    ais->type8.dac1fid13.tminute = AIS_MINUTE_NOT_AVAILABLE;
307
1
                    (void)sscanf(eta, "%02u-%02uT%02u:%02uZ",
308
1
                                 &ais->type8.dac1fid13.tmonth,
309
1
                                 &ais->type8.dac1fid13.tday,
310
1
                                 &ais->type8.dac1fid13.thour,
311
1
                                 &ais->type8.dac1fid13.tminute);
312
1
                }
313
2
                structured = true;
314
2
            }
315
65
            else if (strstr(buf, "\"fid\":15,") != NULL) {
316
1
                status = json_read_object(buf, json_ais8_fid15, endptr);
317
1
                structured = true;
318
1
            }
319
64
            else if (strstr(buf, "\"fid\":16,") != NULL) {
320
46
                status = json_read_object(buf, json_ais8_fid16, endptr);
321
46
                if (status == 0) {
322
1
                        structured = true;
323
1
                }
324
46
            }
325
18
            else if (strstr(buf, "\"fid\":17,") != NULL) {
326
1
                status = json_read_object(buf, json_ais8_fid17, endptr);
327
1
                structured = true;
328
1
            }
329
17
            else if (strstr(buf, "\"fid\":19,") != NULL) {
330
1
                status = json_read_object(buf, json_ais8_fid19, endptr);
331
1
                structured = true;
332
1
            }
333
16
            else if (strstr(buf, "\"fid\":23,") != NULL) {
334
5
                status = json_read_object(buf, json_ais8_fid23, endptr);
335
5
                if (status == 0) {
336
                    // no need to set zeros, again.
337
                    /* ais->type8.dac200fid23.start_year =
338
                     *     AIS_YEAR_NOT_AVAILABLE;
339
                     * ais->type8.dac200fid23.start_month =
340
                     *    AIS_MONTH_NOT_AVAILABLE; */
341
                    // ais->type8.dac200fid23.start_day = AIS_DAY_NOT_AVAILABLE;
342
1
                    ais->type8.dac200fid23.start_hour = AIS_HOUR_NOT_AVAILABLE;
343
1
                    ais->type8.dac200fid23.start_minute = AIS_MINUTE_NOT_AVAILABLE;
344
                    /* ais->type8.dac200fid23.end_year =
345
                     *     AIS_YEAR_NOT_AVAILABLE;
346
                     * ais->type8.dac200fid23.end_month =
347
                     *     AIS_MONTH_NOT_AVAILABLE; */
348
                    // ais->type8.dac200fid23.end_day = AIS_DAY_NOT_AVAILABLE;
349
1
                    ais->type8.dac200fid23.end_hour = AIS_HOUR_NOT_AVAILABLE;
350
1
                    ais->type8.dac200fid23.end_minute = AIS_MINUTE_NOT_AVAILABLE;
351
1
                    (void)sscanf(start, "%09u-%02u-%02uT%02u:%02u",
352
1
                             &ais->type8.dac200fid23.start_year,
353
1
                             &ais->type8.dac200fid23.start_month,
354
1
                             &ais->type8.dac200fid23.start_day,
355
1
                             &ais->type8.dac200fid23.start_hour,
356
1
                             &ais->type8.dac200fid23.start_minute);
357
1
                    (void)sscanf(end, "%09u-%02u-%02uT%02u:%02u",
358
1
                             &ais->type8.dac200fid23.end_year,
359
1
                             &ais->type8.dac200fid23.end_month,
360
1
                             &ais->type8.dac200fid23.end_day,
361
1
                             &ais->type8.dac200fid23.end_hour,
362
1
                             &ais->type8.dac200fid23.end_minute);
363
1
                }
364
5
                structured = true;
365
5
            }
366
11
            else if (strstr(buf, "\"fid\":24,") != NULL) {
367
1
                status = json_read_object(buf, json_ais8_fid24, endptr);
368
1
                structured = true;
369
1
            }
370
10
            else if (strstr(buf, "\"fid\":27,") != NULL) {
371
3
                status = json_read_object(buf, json_ais8_fid27, endptr);
372
3
                if (status == 0) {
373
                    // no need to set zeros, again.
374
                    // ais->type8.dac1fid27.month = AIS_MONTH_NOT_AVAILABLE;
375
                    // ais->type8.dac1fid27.day = AIS_DAY_NOT_AVAILABLE;
376
1
                    ais->type8.dac1fid27.hour = AIS_HOUR_NOT_AVAILABLE;
377
1
                    ais->type8.dac1fid27.minute = AIS_MINUTE_NOT_AVAILABLE;
378
1
                    (void)sscanf(start, "%02u-%02uT%02u:%02uZ",
379
1
                                 &ais->type8.dac1fid27.month,
380
1
                                 &ais->type8.dac1fid27.day,
381
1
                                 &ais->type8.dac1fid27.hour,
382
1
                                 &ais->type8.dac1fid27.minute);
383
1
                }
384
3
                structured = true;
385
3
            }
386
7
            else if (strstr(buf, "\"fid\":29,") != NULL) {
387
1
                status = json_read_object(buf, json_ais8_fid29, endptr);
388
1
                structured = true;
389
1
            }
390
6
            else if (strstr(buf, "\"fid\":31,") != NULL) {
391
5
                status = json_read_object(buf, json_ais8_fid31, endptr);
392
5
                if (status == 0) {
393
                    // ais->type8.dac1fid31.day = AIS_DAY_NOT_AVAILABLE;
394
1
                    ais->type8.dac1fid31.hour = AIS_HOUR_NOT_AVAILABLE;
395
1
                    ais->type8.dac1fid31.minute = AIS_MINUTE_NOT_AVAILABLE;
396
1
                    (void)sscanf(timestamp, "%02uT%02u:%02uZ",
397
1
                                 &ais->type8.dac1fid31.day,
398
1
                                 &ais->type8.dac1fid31.hour,
399
1
                                 &ais->type8.dac1fid31.minute);
400
1
                }
401
5
                structured = true;
402
5
            }
403
72
        }
404
35
        else if (strstr(buf, "\"dac\":200,") != NULL &&
405
6
                 strstr(buf,"data")==NULL) {
406
5
            if (strstr(buf, "\"fid\":10,") != NULL) {
407
3
                status = json_read_object(buf, json_ais8_fid10, endptr);
408
3
                structured = true;
409
3
            }
410
5
            if (strstr(buf, "\"fid\":40,") != NULL) {
411
3
                status = json_read_object(buf, json_ais8_fid40, endptr);
412
3
                structured = true;
413
3
            }
414
5
        }
415
107
        if (!structured) {
416
77
            status = json_read_object(buf, json_ais8, endptr);
417
77
            if (status == 0)
418
25
                lenhex_unpack(data, &ais->type8.bitcount,
419
25
                              ais->type8.bitdata, sizeof(ais->type8.bitdata));
420
77
        }
421
107
        ais->type8.structured = structured;
422
107
    } else if (strstr(buf, "\"type\":9,") != NULL) {
423
1
        status = json_read_object(buf, json_ais9, endptr);
424
65
    } else if (strstr(buf, "\"type\":10,") != NULL) {
425
1
        status = json_read_object(buf, json_ais10, endptr);
426
64
    } else if (strstr(buf, "\"type\":12,") != NULL) {
427
2
        status = json_read_object(buf, json_ais12, endptr);
428
62
    } else if (strstr(buf, "\"type\":14,") != NULL) {
429
2
        status = json_read_object(buf, json_ais14, endptr);
430
60
    } else if (strstr(buf, "\"type\":15,") != NULL) {
431
1
        status = json_read_object(buf, json_ais15, endptr);
432
59
    } else if (strstr(buf, "\"type\":16,") != NULL) {
433
1
        status = json_read_object(buf, json_ais16, endptr);
434
58
    } else if (strstr(buf, "\"type\":17,") != NULL) {
435
4
        status = json_read_object(buf, json_ais17, endptr);
436
4
        if (status == 0)
437
1
            lenhex_unpack(data, &ais->type17.bitcount,
438
1
                          ais->type17.bitdata, sizeof(ais->type17.bitdata));
439
54
    } else if (strstr(buf, "\"type\":18,") != NULL) {
440
4
        status = json_read_object(buf, json_ais18, endptr);
441
50
    } else if (strstr(buf, "\"type\":19,") != NULL) {
442
1
        status = json_read_object(buf, json_ais19, endptr);
443
49
    } else if (strstr(buf, "\"type\":20,") != NULL) {
444
1
        status = json_read_object(buf, json_ais20, endptr);
445
48
    } else if (strstr(buf, "\"type\":21,") != NULL) {
446
2
        status = json_read_object(buf, json_ais21, endptr);
447
46
    } else if (strstr(buf, "\"type\":22,") != NULL) {
448
2
        status = json_read_object(buf, json_ais22, endptr);
449
44
    } else if (strstr(buf, "\"type\":23,") != NULL) {
450
20
        status = json_read_object(buf, json_ais23, endptr);
451
24
    } else if (strstr(buf, "\"type\":24,") != NULL) {
452
1
        status = json_read_object(buf, json_ais24, endptr);
453
23
    } else if (strstr(buf, "\"type\":25,") != NULL) {
454
13
        status = json_read_object(buf, json_ais25, endptr);
455
13
        if (status == 0)
456
11
            lenhex_unpack(data, &ais->type25.bitcount,
457
11
                          ais->type25.bitdata, sizeof(ais->type25.bitdata));
458
13
    } else if (strstr(buf, "\"type\":26,") != NULL) {
459
8
        status = json_read_object(buf, json_ais26, endptr);
460
8
        if (status == 0)
461
4
            lenhex_unpack(data, &ais->type26.bitcount,
462
4
                          ais->type26.bitdata, sizeof(ais->type26.bitdata));
463
8
    } else if (strstr(buf, "\"type\":27,") != NULL) {
464
1
        status = json_read_object(buf, json_ais27, endptr);
465
1
    } else {
466
1
        if (NULL != endptr) {
467
0
            *endptr = NULL;
468
0
        }
469
1
        return JSON_ERR_MISC;
470
1
    }
471
332
    return status;
472
333
}
473
474
// vim: set expandtab shiftwidth=4