Recfmt_t recfmt(const void* buf, size_t size, off_t total) { register unsigned char* s; register unsigned char* t; register Sample_t* q; register unsigned int* h; register unsigned int i; unsigned int j; unsigned int k; unsigned int n; unsigned int m; unsigned int x; unsigned long f; unsigned long g; static unsigned char terminators[] = { '\n', 0x15, 0x25 }; /* * check for V format */ s = (unsigned char*)buf; t = s + size; while ((k = (t - s)) >= 4 && !s[2] && !s[3]) { if ((i = (s[0]<<8)|s[1]) > k) break; s += i; } if (!k || size > 2 * k) return REC_V_TYPE(4, 0, 2, 0, 1); s = (unsigned char*)buf; /* * check for terminated records */ for (i = 0; i < elementsof(terminators); i++) if ((t = (unsigned char*)memchr((void*)s, k = terminators[i], size / 2)) && (n = t - s + 1) > 1 && (total <= 0 || !(total % n))) { for (j = n - 1; j < size; j += n) if (s[j] != k) { n = 0; break; } if (n) return REC_D_TYPE(terminators[i]); } /* * check fixed length record frequencies */ if (!(q = newof(0, Sample_t, 1, 0))) return REC_N_TYPE(); x = 0; for (i = 0; i < size; i++) { h = q->hit + s[i]; m = i - *h; *h = i; if (m < elementsof(q->rep)) { if (m > x) x = m; q->rep[m]++; } } n = 0; m = 0; f = ~0; for (i = x; i > 1; i--) { if ((total <= 0 || !(total % i)) && q->rep[i] > q->rep[n]) { m++; g = 0; for (j = i; j < size - i; j += i) for (k = 0; k < i; k++) if (s[j + k] != s[j + k - i]) g++; g = (((g * 100) / i) * 100) / q->rep[i]; if (g <= f) { f = g; n = i; } } } if (m <= 1 && n <= 2 && total > 1 && total < 256) { n = 0; for (i = 0; i < size; i++) for (j = 0; j < elementsof(terminators); j++) if (s[i] == terminators[j]) n++; n = n ? 0 : total; } free(q); return n ? REC_F_TYPE(n) : REC_N_TYPE(); }
Recfmt_t recstr(register const char* s, char** e) { char* t; int n; long v; int a[6]; while (*s == ' ' || *s == '\t' || *s == ',') s++; switch (*s) { case 'd': case 'D': if (!*s) n = '\n'; else { if (*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X')) n = (int)strtol(s, &t, 0); else n = chresc(s, &t); s = (const char*)t; } if (e) *e = (char*)s; return REC_D_TYPE(n); case 'f': case 'F': while (*++s == ' ' || *s == '\t' || *s == ','); /*FALLTHROUGH*/ case '+': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = strton(s, &t, NiL, 0); if (n > 0 && t > (char*)s) { if (e) *e = t; return REC_F_TYPE(n); } break; case 'm': case 'M': while (*++s == ' ' || *s == '\t' || *s == ','); for (t = (char*)s; *t && *t != ' ' && *t != '\t' && *t != ','; t++); if ((t - s) == 4) { if (strneq(s, "data", 4)) { if (e) *e = t; return REC_M_TYPE(REC_M_data); } else if (strneq(s, "path", 4)) { if (e) *e = t; return REC_M_TYPE(REC_M_path); } } /* * TBD: look up name in method libraries * and assign an integer index */ break; case 'u': case 'U': while (*++s == ' ' || *s == '\t' || *s == ','); n = strtol(s, &t, 0); if (n < 0 || n > 15 || *t++ != '.') break; v = strtol(t, &t, 0); if (*t) break; if (e) *e = t; return REC_U_TYPE(n, v); case 'v': case 'V': a[0] = 0; a[1] = 4; a[2] = 0; a[3] = 2; a[4] = 0; a[5] = 1; n = 0; for (;;) { switch (*++s) { case 0: break; case 'm': case 'M': n = 0; continue; case 'h': case 'H': n = 1; continue; case 'o': case 'O': n = 2; continue; case 'z': case 'Z': n = 3; continue; case 'b': case 'B': n = 4; a[n++] = 0; continue; case 'l': case 'L': n = 4; a[n++] = 1; continue; case 'n': case 'N': n = 0; a[5] = 0; continue; case 'i': case 'I': n = 0; a[5] = 1; continue; case ' ': case '\t': case ',': case '-': case '+': continue; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': v = 0; a[n++] = strtol(s, &t, 0); s = (const char*)t - 1; continue; } break; } if (e) *e = (char*)s; if (a[3] > (a[1] - a[2])) a[3] = a[1] - a[2]; return REC_V_RECORD(REC_V_TYPE(a[1], a[2], a[3], a[4], a[5]), a[0]); case '%': if (e) *e = (char*)s + 1; return REC_M_TYPE(REC_M_path); case '-': case '?': if (e) *e = (char*)s + 1; return REC_M_TYPE(REC_M_data); } if (e) *e = (char*)s; return REC_N_TYPE(); }