Subversion Repositories public

Rev

Rev 136 | 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
{
246 andreas 69
  char * start;
70
  char * cursor;
71
  int    allow;
93 andreas 72
  char * ret    = NULL;
73
  int    bytes  = 0;
74
 
75
  /* early exit */
246 andreas 76
  if (!p || !offset) return NULL;
93 andreas 77
 
246 andreas 78
  start  = (char *)(p->packet.data + *offset);
79
  cursor = start;
80
  allow  = garmin_packet_size(p) - *offset;
81
 
93 andreas 82
  if ( allow <= 0 ) return NULL;
83
 
84
  /* OK, we have space to work with. */
85
 
86
  do { bytes++; } while ( --allow && *cursor++ );
87
 
88
  ret = malloc(bytes);
89
  strncpy(ret,start,bytes-1);
90
 
91
  *offset += bytes;
92
 
93
  return ret;
94
}
95
 
96
 
97
/* 
98
   Same as above, but straight from the buffer until we hit a NULL, and
99
   update the buffer to point to the start of the next string.
100
*/
101
 
102
char *
103
get_vstring ( uint8 ** buf )
104
{
105
  char * start  = (char *)*buf;
106
  char * cursor = start;
107
  char * ret    = NULL;
108
  int    bytes  = 0;
109
 
246 andreas 110
  if (!buf) return NULL;
111
 
93 andreas 112
  do { bytes++; } while ( *cursor++ );
113
 
114
  ret = malloc(bytes);
115
  strncpy(ret,start,bytes-1);
116
 
117
  *buf += bytes;
118
 
119
  return ret;
120
}
121
 
122
 
123
void
124
put_vstring ( uint8 ** buf, const char * x )
125
{
126
  if ( x != NULL ) {
136 andreas 127
    strcpy((char *)*buf,x);
93 andreas 128
    *buf += strlen(x)+1;
129
  }
130
}
131
 
132
 
133
/* 
134
   Return a NULL-terminated list of strings, and set the 'pos' argument
135
   to point to the next position.
136
*/
137
 
138
char **
139
get_strings ( garmin_packet * p, int * offset )
140
{
136 andreas 141
  char *  start  = (char *)(p->packet.data + *offset);
93 andreas 142
  char *  cursor = start;
143
  int     allow  = garmin_packet_size(p) - *offset;
144
  char ** ret    = NULL;
145
  char *  elem   = NULL;
146
  int     nstr   = 0;
147
  int     bytes  = 0;
148
 
149
  /* early exit */
150
 
151
  if ( allow <= 0 ) return NULL;
152
 
153
  /* OK, we have space to work with. */
154
 
155
  while ( allow ) {
156
 
157
    /* extract the next string from the buffer */
158
 
159
    do { bytes++; } while ( --allow && *cursor++ );
160
 
161
    elem = malloc(bytes);
162
    strncpy(elem,start,bytes-1);
163
 
164
    /* append it to the list of strings */
165
 
166
    if ( ret != NULL ) ret = realloc(ret,(nstr+2) * sizeof(char *));
167
    else               ret = malloc(2 * sizeof(char *));
168
 
169
    ret[nstr++] = elem;
170
    ret[nstr]   = NULL;
171
 
172
    /* update the offset */
173
 
174
    *offset += bytes;
175
  }
176
 
177
  return ret;
178
}