Example #1
0
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();
}
Example #2
0
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();
}