binScanf.cpp
Go to the documentation of this file.
1 /* $Id: scanf.c,v 1.2 2002/08/09 20:56:57 pefo Exp $ */
2 
3 /*
4  * Copyright (c) 2000-2002 Opsycon AB (www.opsycon.se)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. All advertising materials mentioning features or use of this software
15  * must display the following acknowledgement:
16  * This product includes software developed by Opsycon AB.
17  * 4. The name of the author may not be used to endorse or promote products
18  * derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
21  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
24  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  */
33 
34 #define _CRT_SECURE_NO_WARNINGS
35 
36 #include <stdio.h>
37 #include <stdarg.h>
38 #include <string.h>
39 #include <ctype.h>
40 #include <vector>
41 #include "sick_scan/binScanf.hpp"
42 
43 #define MAXLN (10 * 1024)
44 
45 #define ISSPACE " \t\n\r\f\v"
46 
47 int binIsspace(int val)
48 {
49  if (val < 0) // characters >= 80
50  {
51  val = (int) (val & 0xFF);
52  }
53  int ret = isspace(val);
54  return (ret);
55 }
56 
57 static char *
58 _binGetbase(char *p, int *basep)
59 {
60  if (p[0] == '0')
61  {
62  switch (p[1])
63  {
64  case 'x':
65  *basep = 16;
66  break;
67  case 't':
68  case 'n':
69  *basep = 10;
70  break;
71  case 'o':
72  *basep = 8;
73  break;
74  default:
75  *basep = 10;
76  return (p);
77  }
78  return (p + 2);
79  }
80  *basep = 10;
81  return (p);
82 }
83 
84 static int
85 _binAtob(unsigned long *vp, char *p, int base)
86 {
87  unsigned long value, v1, v2;
88  char *q, tmp[20];
89  int digit;
90 
91  if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X'))
92  {
93  base = 16;
94  p += 2;
95  }
96 
97  if (base == 16 && (q = strchr(p, '.')) != 0)
98  {
99  if (q - p > sizeof(tmp) - 1)
100  {
101  return (0);
102  }
103 
104  strncpy(tmp, p, q - p);
105  tmp[q - p] = '\0';
106  if (!_binAtob(&v1, tmp, 16))
107  {
108  return (0);
109  }
110 
111  q++;
112  if (strchr(q, '.'))
113  {
114  return (0);
115  }
116 
117  if (!_binAtob(&v2, q, 16))
118  {
119  return (0);
120  }
121  *vp = (v1 << 16) + v2;
122  return (1);
123  }
124 
125  value = *vp = 0;
126  for (; *p; p++)
127  {
128  if (*p >= '0' && *p <= '9')
129  {
130  digit = *p - '0';
131  }
132  else if (*p >= 'a' && *p <= 'f')
133  {
134  digit = *p - 'a' + 10;
135  }
136  else if (*p >= 'A' && *p <= 'F')
137  {
138  digit = *p - 'A' + 10;
139  }
140  else
141  {
142  return (0);
143  }
144 
145  if (digit >= base)
146  {
147  return (0);
148  }
149  value *= base;
150  value += digit;
151  }
152  *vp = value;
153  return (1);
154 }
155 
156 /*
157 * atob(vp,p,base)
158 * converts p to binary result in vp, rtn 1 on success
159 */
160 int binAtob(unsigned long *vp, char *p, int base)
161 {
162 
163  unsigned long v;
164 
165  if (base == 0)
166  {
167  p = _binGetbase(p, &base);
168  }
169  if (_binAtob(&v, p, base))
170  {
171  *vp = v;
172  return (1);
173  }
174  return (0);
175 }
176 
177 
178 /*
179  * scanf(fmt,va_alist)
180  */
181 int
182 binSscanf(const char *fmt, ...)
183 {
184  int count;
185  va_list ap;
186 
187  va_start(ap, fmt);
188  count = vfscanf(stdin, fmt, ap);
189  va_end(ap);
190  return (count);
191 }
192 
193 /*
194  * fscanf(fp,fmt,va_alist)
195  */
196 int
197 binFscanf(FILE *fp, const char *fmt, ...)
198 {
199  int count;
200  va_list ap;
201 
202  va_start(ap, fmt);
203  count = vfscanf(fp, fmt, ap);
204  va_end(ap);
205  return (count);
206 }
207 
208 /*
209  * sscanf(buf,fmt,va_alist)
210  */
211 int
212 binSscanf(const char *buf, const char *fmt, ...)
213 {
214  int count;
215  va_list ap;
216 
217  va_start(ap, fmt);
218  count = vsscanf(buf, fmt, ap);
219  va_end(ap);
220  return (count);
221 }
222 
223 /*
224  * vfscanf(fp,fmt,ap)
225  */
226 static int
227 binVfscanf(FILE *fp, const char *fmt, va_list ap)
228 {
229  int count;
230  char buf[MAXLN + 1];
231 
232  if (fgets(buf, MAXLN, fp) == 0)
233  {
234  return (-1);
235  }
236  count = vsscanf(buf, fmt, ap);
237  return (count);
238 }
239 
240 
251 static int
252 binVsscanf(const char *bufOrg, const char *s, va_list ap, int bufLen)
253 {
254  int count, noassign, base, lflag;
255  unsigned long width;
256  const char *tc;
257  char *t, tmp[MAXLN];
258  const char *buf;
259  const char *bufEnd;
260  buf = bufOrg;
261  bufEnd = buf + bufLen;
262 
263  count = noassign = width = lflag = base = 0;
264  // Parse Inputbuffer buf
265  while (*s && (buf < bufEnd))
266  {
267  while (binIsspace(*s)) // skipping blanks
268  s++;
269  if (*s == '%')
270  { // maybe a format identifier
271  s++;
272  for (; *s; s++)
273  {
274  if (strchr("dibouxycsefg%", *s))
275  { // check allowed format identifier
276  break;
277  }
278  if (*s == '*')
279  { // length identifier
280  noassign = 1;
281  }
282  else if (*s == 'l' || *s == 'L')
283  { // long flag
284  lflag = 1;
285  }
286  else if (*s >= '1' && *s <= '9')
287  { // length of argument
288  for (tc = s; isdigit(*s); s++);
289  strncpy(tmp, tc, s - tc);
290  tmp[s - tc] = '\0';
291  binAtob((unsigned long *) &width, tmp, 10);
292  s--;
293  }
294  }
295  if (*s == 's')
296  {
297  while (binIsspace((int) (0xFF & *buf))) // must be done to handle data >= 0x80
298  {
299  buf++;
300  }
301  if (!width)
302  {
303  width = (int) strcspn(buf, ISSPACE);
304  }
305  if (!noassign)
306  {
307  strncpy(t = va_arg(ap, char *), buf, width);
308  t[width] = '\0';
309  }
310  buf += width;
311  }
312  else if (*s == 'c')
313  {
314  if (!width)
315  {
316  width = 1;
317  }
318  if (!noassign)
319  {
320  strncpy(t = va_arg(ap, char *), buf, width);
321  t[width] = '\0';
322  }
323  buf += width;
324  }
325  else if (strchr("dobxyu", *s))
326  {
327  while (binIsspace((int) (0xFF & *buf))) // must be done to handle data >= 0x80
328  {
329  buf++;
330  }
331  if (*s == 'd' || *s == 'u')
332  {
333  base = 10;
334  }
335  else if (*s == 'x')
336  {
337  base = 16;
338  }
339  else if (*s == 'o')
340  {
341  base = 8;
342  }
343  else if (*s == 'b')
344  {
345  base = 2;
346  }
347  else if (*s == 'y')
348  {
349  base = 1;
350  } // use as marker for binary scan
351  if (!width)
352  {
353  if (binIsspace(*(s + 1)) || *(s + 1) == 0)
354  {
355  width = (int) strcspn(buf, ISSPACE);
356  }
357  else
358  {
359  width = (int) (strchr(buf, *(s + 1)) - buf);
360  }
361  }
362  if (base == 1) // binary data - plain copy without string function
363  {
364  memcpy(tmp, buf, width);
365  unsigned char *destAdr = va_arg(ap, unsigned char *);
366  unsigned long destVal = 0;
367  for (int i = 0; i < width; i++) // Big Endian - MSB first - convention for SOPAS-Binary
368  {
369  destVal <<= 8;
370  destVal |= (unsigned char) (0xFF & tmp[i]);
371  }
372  for (int i = 0; i < width; i++) // Big Endian - MSB first - convention for SOPAS-Binary
373  {
374  unsigned char val = (unsigned char) (0xFF & (destVal >> (i * 8)));
375  destAdr[i] = val;
376  }
377  }
378  else
379  {
380  strncpy(tmp, buf, width);
381  tmp[width] = '\0';
382  if (!noassign)
383  {
384  binAtob(va_arg(ap, unsigned long *), tmp, base);
385  }
386  }
387  buf += width;
388  }
389  if (!noassign)
390  {
391  count++;
392  }
393  width = noassign = lflag = 0;
394  s++;
395  }
396  else
397  {
398  while (binIsspace(*buf))
399  buf++;
400  if (*s != *buf)
401  {
402  break;
403  }
404  else
405  {
406  s++, buf++;
407  }
408  }
409  }
410  return (count);
411 }
412 
413 /*
414 * scanf(fmt,va_alist)
415 */
416 int
417 binScanfVec(const std::vector<unsigned char> *vec, const char *fmt, ...)
418 {
419  if (vec->size() == 0)
420  {
421  return (0);
422  }
423  const char *buf = (const char *) (&(*vec)[0]);
424  int count;
425  int bufLen = (int) vec->size();
426  if (0 == bufLen)
427  {
428  return (0);
429  }
430  va_list ap;
431 
432  va_start(ap, fmt);
433  count = binVsscanf(buf, fmt, ap, bufLen);
434  va_end(ap);
435  return (count);
436 }
437 
438 int binScanfGuessDataLenFromMask(const char *scanfMask)
439 {
440  int retLen = 0;
441  int noassign = 0;
442  int lflag = 0;
443  char tmp[20];
444  int width;
445  if (scanfMask == NULL)
446  {
447  }
448  else
449  {
450  const char *s = scanfMask;
451  const char *tc = NULL;
452  while (*s)
453  {
454  while (binIsspace(*s))
455  {
456  s++;
457  retLen++;
458  }
459  if (*s == '%')
460  {
461  s++;
462  for (; *s; s++)
463  {
464  if (strchr("dibouxycsefg%", *s))
465  {
466  break;
467  }
468  if (*s == '*')
469  {
470  noassign = 1;
471  }
472  else if (*s == 'l' || *s == 'L')
473  {
474  lflag = 1;
475  }
476  else if (*s >= '1' && *s <= '9')
477  {
478  for (tc = s; isdigit(*s); s++);
479  strncpy(tmp, tc, s - tc);
480  tmp[s - tc] = '\0';
481  sscanf(tmp, "%d", &width);
482  retLen += width;
483  }
484  }
485  }
486  else
487  {
488  s++;
489  retLen++;
490  }
491  }
492 
493  }
494  return (retLen);
495 }
int binScanfGuessDataLenFromMask(const char *scanfMask)
Definition: binScanf.cpp:438
int binIsspace(int val)
Definition: binScanf.cpp:47
int binSscanf(const char *fmt,...)
Definition: binScanf.cpp:182
int binScanfVec(const std::vector< unsigned char > *vec, const char *fmt,...)
Definition: binScanf.cpp:417
static int _binAtob(unsigned long *vp, char *p, int base)
Definition: binScanf.cpp:85
int binAtob(unsigned long *vp, char *p, int base)
Definition: binScanf.cpp:160
#define ISSPACE
Definition: binScanf.cpp:45
static char * _binGetbase(char *p, int *basep)
Definition: binScanf.cpp:58
int binFscanf(FILE *fp, const char *fmt,...)
Definition: binScanf.cpp:197
static sick_scan::SickScanCommonTcp * s
static int binVfscanf(FILE *fp, const char *fmt, va_list ap)
Definition: binScanf.cpp:227
#define MAXLN
Definition: binScanf.cpp:43
static int binVsscanf(const char *bufOrg, const char *s, va_list ap, int bufLen)
sscanf-like function In addition to standard sscanf a format identifier "y" is introduced to parse bi...
Definition: binScanf.cpp:252


sick_scan
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Wed May 5 2021 03:05:47