Subversion Repositories public

Rev

Rev 314 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
93 andreas 1
#include "config.h"
2
#include <string.h>
3
#include <stdlib.h>
4
#include "garmin.h"
5
 
6
 
7
static uint32 gListId = 0;
8
 
9
 
10
garmin_data *
11
garmin_alloc_data ( garmin_datatype type )
12
{
13
  garmin_data * d = malloc(sizeof(garmin_data));
14
 
246 andreas 15
  if (!d)
16
     return NULL;
17
 
314 andreas 18
  memset(d, 0, sizeof(garmin_data));
93 andreas 19
  d->type = type;
20
 
21
#define CASE_DATA(x) \
22
  case data_D##x: d->data = calloc(1,sizeof(D##x)); break
23
 
24
  switch ( type ) {
25
  case data_Dlist: d->data = garmin_alloc_list(); break;
26
  CASE_DATA(100);
27
  CASE_DATA(101);
28
  CASE_DATA(102);
29
  CASE_DATA(103);
30
  CASE_DATA(104);
31
  CASE_DATA(105);
32
  CASE_DATA(106);
33
  CASE_DATA(107);
34
  CASE_DATA(108);
35
  CASE_DATA(109);
36
  CASE_DATA(110);
37
  CASE_DATA(120);
38
  CASE_DATA(150);
39
  CASE_DATA(151);
40
  CASE_DATA(152);
41
  CASE_DATA(154);
42
  CASE_DATA(155);
43
  CASE_DATA(200);
44
  CASE_DATA(201);
45
  CASE_DATA(202);
46
  CASE_DATA(210);
47
  CASE_DATA(300);
48
  CASE_DATA(301);
49
  CASE_DATA(302);
50
  CASE_DATA(303);
51
  CASE_DATA(304);
52
  CASE_DATA(310);
53
  CASE_DATA(311);
54
  CASE_DATA(312);
55
  CASE_DATA(400);
56
  CASE_DATA(403);
57
  CASE_DATA(450);
58
  CASE_DATA(500);
59
  CASE_DATA(501);
60
  CASE_DATA(550);
61
  CASE_DATA(551);
62
  CASE_DATA(600);
63
  CASE_DATA(650);
64
  CASE_DATA(700);
65
  CASE_DATA(800);
66
  CASE_DATA(906);
67
  CASE_DATA(1000);
68
  CASE_DATA(1001);
69
  CASE_DATA(1002);
70
  CASE_DATA(1003);
71
  CASE_DATA(1004);
72
  CASE_DATA(1005);
73
  CASE_DATA(1006);
74
  CASE_DATA(1007);
75
  CASE_DATA(1008);
76
  CASE_DATA(1009);
77
  CASE_DATA(1010);
78
  CASE_DATA(1011);
79
  CASE_DATA(1012);
80
  CASE_DATA(1013);
81
  CASE_DATA(1015);
82
  default: d->data = NULL; break;
83
  }
84
 
85
  return d;
86
}
87
 
88
 
89
garmin_list *
90
garmin_alloc_list ( void )
91
{
92
  garmin_list * l;
93
 
246 andreas 94
  if ((l = calloc(1,sizeof(garmin_list))) == NULL)
95
     return NULL;
96
 
93 andreas 97
  l->id = ++gListId;
98
 
99
  return l;
100
}
101
 
102
 
103
garmin_list *
104
garmin_list_append ( garmin_list * list, garmin_data * data )
105
{
314 andreas 106
    garmin_list *      l = list;
107
    garmin_list_node * n;
93 andreas 108
 
314 andreas 109
    if ( data != NULL )
110
    {
111
        if ( l == NULL )
112
        {
113
            if ( ( l = garmin_alloc_list() ) == NULL )
114
                return NULL;
115
        }
93 andreas 116
 
314 andreas 117
        if ( ( n = malloc ( sizeof ( garmin_list_node ) ) ) == NULL )
118
            return NULL;
136 andreas 119
 
314 andreas 120
		memset(n, 0, sizeof(garmin_list_node));
121
        n->data = data;
122
        n->next = NULL;
136 andreas 123
 
314 andreas 124
        if ( l->head == NULL )
125
            l->head = n;
93 andreas 126
 
314 andreas 127
        if ( l->tail != NULL )
128
            l->tail->next = n;
246 andreas 129
 
314 andreas 130
        l->tail = n;
131
        l->elements++;
132
    }
246 andreas 133
 
314 andreas 134
    return l;
93 andreas 135
}
136
 
137
 
314 andreas 138
garmin_data *garmin_list_data (garmin_data *data, uint32 which)
93 andreas 139
{
314 andreas 140
garmin_data *       ret = NULL;
141
garmin_list *       list;
142
garmin_list_node *  n;
143
unsigned int        i;
93 andreas 144
 
314 andreas 145
	if (data != NULL && data->type == data_Dlist && (list = data->data) != NULL)
146
	{
147
		for ( i = 0, n = list->head; i < which && n != NULL; i++, n = n->next );
93 andreas 148
 
314 andreas 149
		if ( n != NULL )
150
			ret = n->data;
151
	}
152
 
153
	return ret;
93 andreas 154
}
155
 
156
 
157
void
314 andreas 158
garmin_free_list (garmin_list *l)
93 andreas 159
{
314 andreas 160
garmin_list_node *n;
161
garmin_list_node *x;
93 andreas 162
 
314 andreas 163
    if ( l != NULL )
164
    {
165
        for ( n = l->head; n != NULL; n = x )
166
        {
167
            x = n->next;
168
            garmin_free_data (n->data);
169
            free (n);
170
        }
171
 
172
        free (l);
93 andreas 173
    }
174
}
175
 
176
 
177
void
178
garmin_free_list_only ( garmin_list * l )
179
{
314 andreas 180
    garmin_list_node * n;
181
    garmin_list_node * x;
93 andreas 182
 
314 andreas 183
    if ( l != NULL )
184
    {
185
        for ( n = l->head; n != NULL; n = x )
186
        {
187
            x = n->next;
188
            free ( n );
189
        }
190
        free ( l );
93 andreas 191
    }
192
}
193
 
194
 
195
#define TRYFREE(x) if ( x != NULL ) free(x)
196
 
197
 
198
void
199
garmin_free_data ( garmin_data * d )
200
{
314 andreas 201
    D105 *   d105;
202
    D106 *   d106;
203
    D108 *   d108;
204
    D109 *   d109;
205
    D110 *   d110;
206
    D202 *   d202;
207
    D210 *   d210;
208
    D310 *   d310;
209
    D312 *   d312;
210
    D650 *   d650;
93 andreas 211
 
314 andreas 212
    if ( d != NULL )
213
    {
214
        if ( d->data != NULL )
215
        {
216
            if ( d->type == data_Dlist )
217
            {
218
                garmin_free_list ( ( garmin_list * ) d->data );
219
            }
220
            else
221
            {
222
                switch ( d->type )
223
                {
224
                case data_D105:
225
                    d105 = d->data;
226
                    TRYFREE ( d105->wpt_ident );
227
                    break;
228
                case data_D106:
229
                    d106 = d->data;
230
                    TRYFREE ( d106->wpt_ident );
231
                    TRYFREE ( d106->lnk_ident );
232
                    break;
233
                case data_D108:
234
                    d108 = d->data;
235
                    TRYFREE ( d108->ident );
236
                    TRYFREE ( d108->comment );
237
                    TRYFREE ( d108->facility );
238
                    TRYFREE ( d108->city );
239
                    TRYFREE ( d108->addr );
240
                    TRYFREE ( d108->cross_road );
241
                    break;
242
                case data_D109:
243
                    d109 = d->data;
244
                    TRYFREE ( d109->ident );
245
                    TRYFREE ( d109->comment );
246
                    TRYFREE ( d109->facility );
247
                    TRYFREE ( d109->city );
248
                    TRYFREE ( d109->addr );
249
                    TRYFREE ( d109->cross_road );
250
                    break;
251
                case data_D110:
252
                    d110 = d->data;
253
                    TRYFREE ( d110->ident );
254
                    TRYFREE ( d110->comment );
255
                    TRYFREE ( d110->facility );
256
                    TRYFREE ( d110->city );
257
                    TRYFREE ( d110->addr );
258
                    TRYFREE ( d110->cross_road );
259
                    break;
260
                case data_D202:
261
                    d202 = d->data;
262
                    TRYFREE ( d202->rte_ident );
263
                    break;
264
                case data_D210:
265
                    d210 = d->data;
266
                    TRYFREE ( d210->ident );
267
                    break;
268
                case data_D310:
269
                    d310 = d->data;
270
                    TRYFREE ( d310->trk_ident );
271
                    break;
272
                case data_D312:
273
                    d312 = d->data;
274
                    TRYFREE ( d312->trk_ident );
275
                    break;
276
                case data_D650:
277
                    d650 = d->data;
278
                    TRYFREE ( d650->departure_name );
279
                    TRYFREE ( d650->departure_ident );
280
                    TRYFREE ( d650->arrival_name );
281
                    TRYFREE ( d650->arrival_ident );
282
                    TRYFREE ( d650->ac_id );
283
                    break;
284
                default:
285
                    break;
286
                }
287
                free ( d->data );
288
            }
289
        }
290
        free ( d );
93 andreas 291
    }
292
}
293
 
294
 
314 andreas 295
/*
93 andreas 296
   Returns the number of bytes needed in order to serialize the data.  Note
297
   that this is an upper bound!  Some of the Garmin data structures do not
298
   align to word boundaries.  Their memory representation will take up more
299
   bytes than the serialized representation will.
300
*/
301
 
302
uint32
303
garmin_data_size ( garmin_data * d )
304
{
305
  garmin_list *       list;
306
  garmin_list_node *  node;
307
  uint32              bytes = 0;
136 andreas 308
  char                hv0[256];
93 andreas 309
 
314 andreas 310
  /*
93 andreas 311
     The number of bytes needed in order to serialize a Garmin data structure
312
     is almost equal to the size of its data structure - but not quite.  If
313
     we have variable length strings, we need to add their string lengths
314 andreas 314
     (including space for the terminating '\0') and subtract the size of the
93 andreas 315
     char * placeholders.  We also need 4 bytes for the data type, and 4
316
     additional bytes in which we store the number of bytes that we should
317
     seek forward in order to skip this record.  This allows us to handle
318
     files that include new, unrecognized data types but still conform to
319
     the file format rules (i.e. we can skip data records that we don't
320
     yet know about).
321
  */
322
 
323
#define ADDBYTES(x,y) \
324
  bytes = sizeof(D##x) + 8 - 3 * y
325
 
326
#define ADDSTRING(x,y) \
327
  if (d##x->y != NULL) bytes += strlen(d##x->y)
328
 
329
#define ADDBYTES1(x,a) \
330
  ADDBYTES(x,1);  \
331
  ADDSTRING(x,a)
332
 
333
#define ADDBYTES2(x,a,b) \
334
  ADDBYTES(x,2);  \
335
  ADDSTRING(x,a); \
336
  ADDSTRING(x,b)
337
 
338
#define ADDBYTES5(x,a,b,c,d,e) \
339
  ADDBYTES(x,5);  \
340
  ADDSTRING(x,a); \
341
  ADDSTRING(x,b); \
342
  ADDSTRING(x,c); \
343
  ADDSTRING(x,d); \
344
  ADDSTRING(x,e)
345
 
346
#define ADDBYTES6(x,a,b,c,d,e,f) \
347
  ADDBYTES(x,6);  \
348
  ADDSTRING(x,a); \
349
  ADDSTRING(x,b); \
350
  ADDSTRING(x,c); \
351
  ADDSTRING(x,d); \
352
  ADDSTRING(x,e); \
353
  ADDSTRING(x,f)
354
 
355
#define DATASIZE0(x)              \
356
  case data_D##x:                 \
357
    {                             \
358
      ADDBYTES(x,0);              \
359
    }                             \
360
    break
361
 
362
#define DATASIZE(x,y)             \
363
  case data_D##x:                 \
364
    {                             \
365
      D##x * d##x = d->data;      \
366
                                  \
367
      y;                          \
368
    }                             \
369
    break
370
 
371
#define DATASIZE1(x,a)             DATASIZE(x,ADDBYTES1(x,a))
372
#define DATASIZE2(x,a,b)           DATASIZE(x,ADDBYTES2(x,a,b))
373
#define DATASIZE5(x,a,b,c,d,e)     DATASIZE(x,ADDBYTES5(x,a,b,c,d,e))
374
#define DATASIZE6(x,a,b,c,d,e,f)   DATASIZE(x,ADDBYTES6(x,a,b,c,d,e,f))
375
 
376
 
377
  if ( d != NULL ) {
378
    if ( d->data != NULL ) {
379
      if ( d->type == data_Dlist ) {
380
	list = d->data;
381
	bytes += 16;  /* { datatype, bytes, list ID, element count } */
382
	for ( node = list->head; node != NULL; node = node->next ) {
383
	  bytes += 4; /* list ID */
384
	  bytes += garmin_data_size(node->data);
385
	}
386
      } else {
387
	switch ( d->type ) {
388
        DATASIZE0(100);
389
        DATASIZE0(101);
390
        DATASIZE0(102);
391
        DATASIZE0(103);
392
        DATASIZE0(104);
393
	DATASIZE1(105,wpt_ident);
394
	DATASIZE2(106,wpt_ident,lnk_ident);
395
	DATASIZE0(107);
396
	DATASIZE6(108,ident,comment,facility,city,addr,cross_road);
397
	DATASIZE6(109,ident,comment,facility,city,addr,cross_road);
398
	DATASIZE6(110,ident,comment,facility,city,addr,cross_road);
399
	DATASIZE0(120);
400
	DATASIZE0(150);
401
	DATASIZE0(151);
402
	DATASIZE0(152);
403
	DATASIZE0(154);
404
	DATASIZE0(155);
405
	DATASIZE0(200);
406
	DATASIZE0(201);
407
	DATASIZE1(202,rte_ident);
408
	DATASIZE1(210,ident);
409
	DATASIZE0(300);
410
	DATASIZE0(301);
411
	DATASIZE0(302);
412
	DATASIZE0(303);
413
	DATASIZE0(304);
414
	DATASIZE1(310,trk_ident);
415
	DATASIZE0(311);
416
	DATASIZE1(312,trk_ident);
417
	DATASIZE0(400);
418
	DATASIZE0(403);
419
	DATASIZE0(450);
420
	DATASIZE0(500);
421
	DATASIZE0(501);
422
	DATASIZE0(550);
423
	DATASIZE0(551);
424
	DATASIZE0(600);
425
	DATASIZE5(650,departure_name,departure_ident,
426
		  arrival_name,arrival_ident,ac_id);
427
	DATASIZE0(700);
428
	DATASIZE0(800);
429
	DATASIZE0(906);
430
	DATASIZE0(1000);
431
	DATASIZE0(1001);
432
	DATASIZE0(1002);
433
	DATASIZE0(1003);
434
	DATASIZE0(1004);
435
	DATASIZE0(1005);
436
	DATASIZE0(1006);
437
	DATASIZE0(1007);
438
	DATASIZE0(1008);
439
	DATASIZE0(1009);
440
	DATASIZE0(1010);
441
	DATASIZE0(1011);
442
	DATASIZE0(1012);
443
	DATASIZE0(1013);
444
	DATASIZE0(1015);
445
	default:
136 andreas 446
	  sprintf(hv0, "garmin_data_size: data type %d not supported!",d->type);
447
	  garmin_queue_error(hv0, err_warning);
93 andreas 448
	  break;
449
	}
450
      }
451
    }
452
  }
453
 
454
  return bytes;
455
}