00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #define _CRT_SECURE_NO_WARNINGS
00035 #include <stdio.h>
00036 #include <stdarg.h>
00037 #include <string.h>
00038 #include <ctype.h>
00039 #include <vector>
00040 #include "sick_scan/binScanf.hpp"
00041
00042 #define MAXLN (10 * 1024)
00043
00044 #define ISSPACE " \t\n\r\f\v"
00045
00046 int binIsspace(int val)
00047 {
00048 if (val < 0)
00049 {
00050 val = (int)(val & 0xFF);
00051 }
00052 int ret = isspace(val);
00053 return(ret);
00054 }
00055 static char *
00056 _binGetbase(char *p, int *basep)
00057 {
00058 if (p[0] == '0') {
00059 switch (p[1]) {
00060 case 'x':
00061 *basep = 16;
00062 break;
00063 case 't': case 'n':
00064 *basep = 10;
00065 break;
00066 case 'o':
00067 *basep = 8;
00068 break;
00069 default:
00070 *basep = 10;
00071 return (p);
00072 }
00073 return (p + 2);
00074 }
00075 *basep = 10;
00076 return (p);
00077 }
00078 static int
00079 _binAtob(unsigned long *vp, char *p, int base)
00080 {
00081 unsigned long value, v1, v2;
00082 char *q, tmp[20];
00083 int digit;
00084
00085 if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
00086 base = 16;
00087 p += 2;
00088 }
00089
00090 if (base == 16 && (q = strchr(p, '.')) != 0) {
00091 if (q - p > sizeof(tmp) - 1)
00092 return (0);
00093
00094 strncpy(tmp, p, q - p);
00095 tmp[q - p] = '\0';
00096 if (!_binAtob(&v1, tmp, 16))
00097 return (0);
00098
00099 q++;
00100 if (strchr(q, '.'))
00101 return (0);
00102
00103 if (!_binAtob(&v2, q, 16))
00104 return (0);
00105 *vp = (v1 << 16) + v2;
00106 return (1);
00107 }
00108
00109 value = *vp = 0;
00110 for (; *p; p++) {
00111 if (*p >= '0' && *p <= '9')
00112 digit = *p - '0';
00113 else if (*p >= 'a' && *p <= 'f')
00114 digit = *p - 'a' + 10;
00115 else if (*p >= 'A' && *p <= 'F')
00116 digit = *p - 'A' + 10;
00117 else
00118 return (0);
00119
00120 if (digit >= base)
00121 return (0);
00122 value *= base;
00123 value += digit;
00124 }
00125 *vp = value;
00126 return (1);
00127 }
00128
00129
00130
00131
00132
00133 int binAtob(unsigned long*vp, char *p, int base)
00134 {
00135
00136 unsigned long v;
00137
00138 if (base == 0)
00139 p = _binGetbase(p, &base);
00140 if (_binAtob(&v, p, base)) {
00141 *vp = v;
00142 return (1);
00143 }
00144 return (0);
00145 }
00146
00147
00148
00149
00150
00151
00152 int
00153 binSscanf(const char *fmt, ...)
00154 {
00155 int count;
00156 va_list ap;
00157
00158 va_start(ap, fmt);
00159 count = vfscanf(stdin, fmt, ap);
00160 va_end(ap);
00161 return (count);
00162 }
00163
00164
00165
00166
00167 int
00168 binFscanf(FILE *fp, const char *fmt, ...)
00169 {
00170 int count;
00171 va_list ap;
00172
00173 va_start(ap, fmt);
00174 count = vfscanf(fp, fmt, ap);
00175 va_end(ap);
00176 return (count);
00177 }
00178
00179
00180
00181
00182 int
00183 binSscanf(const char *buf, const char *fmt, ...)
00184 {
00185 int count;
00186 va_list ap;
00187
00188 va_start(ap, fmt);
00189 count = vsscanf(buf, fmt, ap);
00190 va_end(ap);
00191 return (count);
00192 }
00193
00194
00195
00196
00197 static int
00198 binVfscanf(FILE *fp, const char *fmt, va_list ap)
00199 {
00200 int count;
00201 char buf[MAXLN + 1];
00202
00203 if (fgets(buf, MAXLN, fp) == 0)
00204 return (-1);
00205 count = vsscanf(buf, fmt, ap);
00206 return (count);
00207 }
00208
00209
00220 static int
00221 binVsscanf(const char *bufOrg, const char *s, va_list ap, int bufLen)
00222 {
00223 int count, noassign, base, lflag;
00224 unsigned long width;
00225 const char *tc;
00226 char *t, tmp[MAXLN];
00227 const char *buf;
00228 const char *bufEnd;
00229 buf = bufOrg;
00230 bufEnd = buf + bufLen;
00231
00232 count = noassign = width = lflag = base = 0;
00233
00234 while (*s && (buf < bufEnd))
00235 {
00236 while (binIsspace(*s))
00237 s++;
00238 if (*s == '%') {
00239 s++;
00240 for (; *s; s++) {
00241 if (strchr("dibouxycsefg%", *s))
00242 break;
00243 if (*s == '*')
00244 noassign = 1;
00245 else if (*s == 'l' || *s == 'L')
00246 lflag = 1;
00247 else if (*s >= '1' && *s <= '9') {
00248 for (tc = s; isdigit(*s); s++);
00249 strncpy(tmp, tc, s - tc);
00250 tmp[s - tc] = '\0';
00251 binAtob((unsigned long *)&width, tmp, 10);
00252 s--;
00253 }
00254 }
00255 if (*s == 's')
00256 {
00257 while (binIsspace((int)(0xFF & *buf)))
00258 {
00259 buf++;
00260 }
00261 if (!width)
00262 width = (int)strcspn(buf, ISSPACE);
00263 if (!noassign) {
00264 strncpy(t = va_arg(ap, char *), buf, width);
00265 t[width] = '\0';
00266 }
00267 buf += width;
00268 }
00269 else if (*s == 'c') {
00270 if (!width)
00271 width = 1;
00272 if (!noassign) {
00273 strncpy(t = va_arg(ap, char *), buf, width);
00274 t[width] = '\0';
00275 }
00276 buf += width;
00277 }
00278 else if (strchr("dobxyu", *s)) {
00279 while (binIsspace((int)(0xFF & *buf)))
00280 {
00281 buf++;
00282 }
00283 if (*s == 'd' || *s == 'u')
00284 base = 10;
00285 else if (*s == 'x')
00286 base = 16;
00287 else if (*s == 'o')
00288 base = 8;
00289 else if (*s == 'b')
00290 base = 2;
00291 else if (*s == 'y')
00292 base = 1;
00293 if (!width) {
00294 if (binIsspace(*(s + 1)) || *(s + 1) == 0)
00295 width = (int)strcspn(buf, ISSPACE);
00296 else
00297 width = (int)(strchr(buf, *(s + 1)) - buf);
00298 }
00299 if (base == 1)
00300 {
00301 memcpy(tmp, buf, width);
00302 unsigned char *destAdr = va_arg(ap, unsigned char *);
00303 unsigned long destVal = 0;
00304 for (int i = 0; i < width; i++)
00305 {
00306 destVal <<= 8;
00307 destVal |= (unsigned char)(0xFF & tmp[i]);
00308 }
00309 for (int i = 0; i < width; i++)
00310 {
00311 unsigned char val = (unsigned char)(0xFF & (destVal >> (i * 8)));
00312 destAdr[i] = val;
00313 }
00314 }
00315 else
00316 {
00317 strncpy(tmp, buf, width);
00318 tmp[width] = '\0';
00319 if (!noassign)
00320 binAtob(va_arg(ap, unsigned long *), tmp, base);
00321 }
00322 buf += width;
00323 }
00324 if (!noassign)
00325 count++;
00326 width = noassign = lflag = 0;
00327 s++;
00328 }
00329 else {
00330 while (binIsspace(*buf))
00331 buf++;
00332 if (*s != *buf)
00333 break;
00334 else
00335 s++, buf++;
00336 }
00337 }
00338 return (count);
00339 }
00340
00341
00342
00343
00344 int
00345 binScanfVec(const std::vector<unsigned char> *vec, const char *fmt, ...)
00346 {
00347 if (vec->size() == 0)
00348 {
00349 return(0);
00350 }
00351 const char *buf = (const char *)(&(*vec)[0]);
00352 int count;
00353 int bufLen = (int)vec->size();
00354 if (0 == bufLen)
00355 {
00356 return(0);
00357 }
00358 va_list ap;
00359
00360 va_start(ap, fmt);
00361 count = binVsscanf(buf, fmt, ap, bufLen);
00362 va_end(ap);
00363 return (count);
00364 }
00365
00366 int binScanfGuessDataLenFromMask(const char *scanfMask)
00367 {
00368 int retLen = 0;
00369 int noassign = 0;
00370 int lflag = 0;
00371 char tmp[20];
00372 int width;
00373 if (scanfMask == NULL)
00374 {
00375 }
00376 else
00377 {
00378 const char *s = scanfMask;
00379 const char *tc = NULL;
00380 while (*s)
00381 {
00382 while (binIsspace(*s))
00383 {
00384 s++;
00385 retLen++;
00386 }
00387 if (*s == '%') {
00388 s++;
00389 for (; *s; s++) {
00390 if (strchr("dibouxycsefg%", *s))
00391 break;
00392 if (*s == '*')
00393 noassign = 1;
00394 else if (*s == 'l' || *s == 'L')
00395 lflag = 1;
00396 else if (*s >= '1' && *s <= '9') {
00397 for (tc = s; isdigit(*s); s++);
00398 strncpy(tmp, tc, s - tc);
00399 tmp[s - tc] = '\0';
00400 sscanf(tmp,"%d", &width);
00401 retLen += width;
00402 }
00403 }
00404 }
00405 else
00406 {
00407 s++;
00408 retLen++;
00409 }
00410 }
00411
00412 }
00413 return(retLen);
00414 }