1/***********************************************************************
2*                                                                      *
3*               This software is part of the ast package               *
4*          Copyright (c) 1985-2010 AT&T Intellectual Property          *
5*                      and is licensed under the                       *
6*                  Common Public License, Version 1.0                  *
7*                    by AT&T Intellectual Property                     *
8*                                                                      *
9*                A copy of the License is available at                 *
10*            http://www.opensource.org/licenses/cpl1.0.txt             *
11*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12*                                                                      *
13*              Information and Software Systems Research               *
14*                            AT&T Research                             *
15*                           Florham Park NJ                            *
16*                                                                      *
17*                 Glenn Fowler <gsf@research.att.com>                  *
18*                  David Korn <dgk@research.att.com>                   *
19*                   Phong Vo <kpv@research.att.com>                    *
20*                                                                      *
21***********************************************************************/
22#pragma prototyped
23
24/*
25 * return the length of the current record at b, size n, according to f
26 * -1 returned on error
27 *  0 returned if more data is required
28 */
29
30#include <recfmt.h>
31#include <ctype.h>
32
33ssize_t
34reclen(Recfmt_t f, const void* b, size_t n)
35{
36	register unsigned char*	s = (unsigned char*)b;
37	register unsigned char*	e;
38	size_t			h;
39	size_t			z;
40
41	switch (RECTYPE(f))
42	{
43	case REC_delimited:
44		if (e = (unsigned char*)memchr(s, REC_D_DELIMITER(f), n))
45			return e - s + 1;
46		return 0;
47	case REC_fixed:
48		return REC_F_SIZE(f);
49	case REC_variable:
50		h = REC_V_HEADER(f);
51		if (n < h)
52			return 0;
53		z = 0;
54		s += REC_V_OFFSET(f);
55		e = s + REC_V_LENGTH(f);
56		if (REC_V_LITTLE(f))
57			while (e > s)
58				z = (z<<8)|*--e;
59		else
60			while (s < e)
61				z = (z<<8)|*s++;
62		if (!REC_V_INCLUSIVE(f))
63			z += h;
64		else if (z < h)
65			z = h;
66		return z;
67	case REC_method:
68		return -1;
69	}
70	return -1;
71}
72