DTrackSDK  v2.9.0
DTrackParse.cpp
1 /* DTrackSDK in C++: DTrackParse.cpp
2  *
3  * Functions for parsing ASCII data.
4  *
5  * Copyright (c) 2007-2023 Advanced Realtime Tracking GmbH & Co. KG
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  * notice, this list of conditions and the following disclaimer in the
14  * documentation and/or other materials provided with the distribution.
15  * 3. Neither the name of copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "DTrackParse.hpp"
32 
33 #include <cstdio>
34 #include <cstring>
35 #include <cstdlib>
36 
37 namespace DTrackSDK_Parse {
38 
46 char* string_nextline(char* str, char* start, int len)
47 {
48  char* s = start;
49  char* se = str + len;
50  int crlffound = 0;
51  while (s < se)
52  {
53  if (*s == '\r' || *s == '\n')
54  { // crlf
55  crlffound = 1;
56  } else {
57  if(crlffound)
58  { // begin of new line found
59  return (*s) ? s : NULL; // first character is '\0': end of buffer
60  }
61  }
62  s++;
63  }
64  return NULL; // no new line found in buffer
65 }
66 
67 
75 char* string_get_i(char* str, int* i)
76 {
77  char* s;
78  *i = ( int )strtol( str, &s, 10 );
79  return (s == str) ? NULL : s;
80 }
81 
82 
90 char* string_get_ui(char* str, unsigned int* ui)
91 {
92  char* s;
93  *ui = ( unsigned int )strtoul( str, &s, 10 );
94  return (s == str) ? NULL : s;
95 }
96 
97 
105 char* string_get_d(char* str, double* d)
106 {
107  char* s;
108  *d = strtod(str, &s);
109  return (s == str) ? NULL : s;
110 }
111 
112 
120 char* string_get_f(char* str, float* f)
121 {
122  char* s;
123  *f = (float )strtod(str, &s); // strtof() only available in GNU-C
124  return (s == str) ? NULL : s;
125 }
126 
127 
138 char* string_get_block(char* str, const char* fmt, int* idat, float* fdat, double *ddat)
139 {
140  char* strend;
141  int index_i, index_f;
142 
143  str = strchr( str, '[' );
144  if ( str == NULL)
145  { // search begin of block
146  return NULL;
147  }
148  strend = strchr( str, ']' );
149  if ( strend == NULL )
150  { // search end of block
151  return NULL;
152  }
153  str++; // remove delimiters
154  *strend = '\0';
155  index_i = index_f = 0;
156  while(*fmt)
157  {
158  switch(*fmt++)
159  {
160  case 'i':
161  str = string_get_i( str, &idat[ index_i++ ] );
162  if ( str == NULL )
163  {
164  *strend = ']';
165  return NULL;
166  }
167  break;
168  case 'f':
169  str = string_get_f( str, &fdat[ index_f++ ] );
170  if ( str == NULL )
171  {
172  *strend = ']';
173  return NULL;
174  }
175  break;
176  case 'd':
177  str = string_get_d( str, &ddat[ index_f++ ] );
178  if ( str == NULL )
179  {
180  *strend = ']';
181  return NULL;
182  }
183  break;
184  default: // unknown format character
185  *strend = ']';
186  return NULL;
187  }
188  }
189  // ignore additional data inside the block
190  *strend = ']';
191  return strend + 1;
192 }
193 
194 
202 char* string_get_word(char* str, std::string& w)
203 {
204  char* strend;
205  while (*str == ' ')
206  { // search begin of 'word'
207  str++;
208  }
209 
210  strend = strchr( str, ' ' ); // search end of 'word'
211  if ( strend == NULL )
212  {
213  w.assign(str);
214  strend = str;
215  while (*strend != '\0')
216  { // search end of 'word'
217  strend++;
218  }
219  return (strend == str) ? NULL : strend;
220  }
221  w.assign(str, (int )(strend - str));
222  return strend;
223 }
224 
225 
233 char* string_get_quoted_text(char* str, std::string& qt)
234 {
235  char* strend;
236 
237  str = strchr( str, '\"' ); // search begin of 'quoted text'
238  if ( str == NULL )
239  {
240  return NULL;
241  }
242  str++;
243 
244  strend = strchr( str, '\"' ); // search end of 'quoted text'
245  if ( strend == NULL )
246  {
247  return NULL;
248  }
249  qt.assign(str, (int )(strend - str));
250  return strend + 1;
251 }
252 
253 
254 /*
255  * Compare string regarding DTrack2 parameter rules.
256  */
257 size_t string_cmp_parameter( const std::string& str, size_t pos, const std::string& par )
258 {
259  bool lastwasdigit = false;
260  const char* p = par.c_str();
261  const char* s = str.c_str() + pos;
262 
263  while ( *p )
264  {
265  if (!lastwasdigit)
266  { // skip leading zeros
267  while ( *p == '0' )
268  p++;
269 
270  while ( *s == '0' )
271  s++;
272 
273  if ( *p == '\0' ) // can happen if zeros are last characters in parameter string
274  continue;
275  }
276 
277  if ( ( *p == ' ' ) || ( *s == ' ' ) )
278  { // skip leading white spaces
279  while ( *p == ' ' )
280  p++;
281 
282  while ( *s == ' ' )
283  s++;
284 
285  lastwasdigit = false;
286  continue;
287  }
288 
289  if ( *s != *p )
290  { // compare next character
291  return std::string::npos;
292  }
293 
294  lastwasdigit = ( ( *p >= '0' ) && ( *p <= '9' ) );
295  s++;
296  p++;
297  }
298 
299  while ( *s == ' ' )
300  { // skip leading white spaces in answer part
301  s++;
302  }
303 
304  return s - str.c_str();
305 }
306 
307 
308 } // namespace DTrackSDK_Parse
309