Subversion Repositories public

Rev

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