Subversion Repositories public

Rev

Rev 93 | 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 <stdlib.h>
3
#include <string.h>
4
#include "garmin.h"
5
 
6
 
7
#ifdef WORDS_BIGENDIAN
8
#define ENDIAN_FOR(i,x)     for ( i = sizeof(x)-1; i >= 0; i-- )
9
#define ENDIAN_GET(i,x,y,z) ENDIAN_FOR(i,x) *z++ = y[i]
10
#define ENDIAN_PUT(i,x,y,z) ENDIAN_FOR(i,x) z[i] = *y++
11
#else /* WORDS_BIGENDIAN */
12
#define ENDIAN_FOR(i,x)     for ( i = 0; i < (int)sizeof(x); i++ )
13
#define ENDIAN_GET(i,x,y,z) ENDIAN_FOR(i,x) *z++ = y[i]
14
#define ENDIAN_PUT(i,x,y,z) ENDIAN_FOR(i,x) z[i] = *y++
15
#endif /* WORDS_BIGENDIAN */
16
 
17
#define DEF_ENDIAN_GET(x)          \
18
  x                                \
19
  get_##x ( const uint8 * d )      \
20
  {                                \
21
    x       v;                     \
22
    uint8 * b;                     \
23
    int     i;                     \
24
                                   \
25
    b = (uint8 *)&v;               \
26
    ENDIAN_GET(i,x,d,b);           \
27
                                   \
28
    return v;                      \
29
  }
30
 
31
 
32
#define DEF_ENDIAN_PUT(x)          \
33
  void                             \
34
  put_##x ( uint8 * d, const x v ) \
35
  {                                \
36
    uint8 * b;                     \
37
    int     i;                     \
38
                                   \
39
    b = (uint8 *)&v;               \
40
    ENDIAN_PUT(i,x,b,d);           \
41
  }
42
 
43
 
44
/* Here are the definitions for the get/put functions. */
45
 
46
DEF_ENDIAN_GET(uint16)
47
DEF_ENDIAN_GET(sint16)
48
DEF_ENDIAN_GET(uint32)
49
DEF_ENDIAN_GET(sint32)
50
DEF_ENDIAN_GET(float32)
51
DEF_ENDIAN_GET(float64)
52
 
53
DEF_ENDIAN_PUT(uint16)
54
DEF_ENDIAN_PUT(sint16)
55
DEF_ENDIAN_PUT(uint32)
56
DEF_ENDIAN_PUT(sint32)
57
DEF_ENDIAN_PUT(float32)
58
DEF_ENDIAN_PUT(float64)
59
 
60
 
61
/* 
62
   Return a memory-allocated, NULL-terminated string and set the 'pos'
63
   argument to point to the next position. 
64
*/
65
 
66
char *
67
get_string ( garmin_packet * p, int * offset )
68
{
136 andreas 69
  char * start  = (char *)(p->packet.data + *offset);
93 andreas 70
  char * cursor = start;
71
  int    allow  = garmin_packet_size(p) - *offset;
72
  char * ret    = NULL;
73
  int    bytes  = 0;
74
 
75
  /* early exit */
76
 
77
  if ( allow <= 0 ) return NULL;
78
 
79
  /* OK, we have space to work with. */
80
 
81
  do { bytes++; } while ( --allow && *cursor++ );
82
 
83
  ret = malloc(bytes);
84
  strncpy(ret,start,bytes-1);
85
 
86
  *offset += bytes;
87
 
88
  return ret;
89
}
90
 
91
 
92
/* 
93
   Same as above, but straight from the buffer until we hit a NULL, and
94
   update the buffer to point to the start of the next string.
95
*/
96
 
97
char *
98
get_vstring ( uint8 ** buf )
99
{
100
  char * start  = (char *)*buf;
101
  char * cursor = start;
102
  char * ret    = NULL;
103
  int    bytes  = 0;
104
 
105
  do { bytes++; } while ( *cursor++ );
106
 
107
  ret = malloc(bytes);
108
  strncpy(ret,start,bytes-1);
109
 
110
  *buf += bytes;
111
 
112
  return ret;
113
}
114
 
115
 
116
void
117
put_vstring ( uint8 ** buf, const char * x )
118
{
119
  if ( x != NULL ) {
136 andreas 120
    strcpy((char *)*buf,x);
93 andreas 121
    *buf += strlen(x)+1;
122
  }
123
}
124
 
125
 
126
/* 
127
   Return a NULL-terminated list of strings, and set the 'pos' argument
128
   to point to the next position.
129
*/
130
 
131
char **
132
get_strings ( garmin_packet * p, int * offset )
133
{
136 andreas 134
  char *  start  = (char *)(p->packet.data + *offset);
93 andreas 135
  char *  cursor = start;
136
  int     allow  = garmin_packet_size(p) - *offset;
137
  char ** ret    = NULL;
138
  char *  elem   = NULL;
139
  int     nstr   = 0;
140
  int     bytes  = 0;
141
 
142
  /* early exit */
143
 
144
  if ( allow <= 0 ) return NULL;
145
 
146
  /* OK, we have space to work with. */
147
 
148
  while ( allow ) {
149
 
150
    /* extract the next string from the buffer */
151
 
152
    do { bytes++; } while ( --allow && *cursor++ );
153
 
154
    elem = malloc(bytes);
155
    strncpy(elem,start,bytes-1);
156
 
157
    /* append it to the list of strings */
158
 
159
    if ( ret != NULL ) ret = realloc(ret,(nstr+2) * sizeof(char *));
160
    else               ret = malloc(2 * sizeof(char *));
161
 
162
    ret[nstr++] = elem;
163
    ret[nstr]   = NULL;
164
 
165
    /* update the offset */
166
 
167
    *offset += bytes;
168
  }
169
 
170
  return ret;
171
}