xref: /titanic_41/usr/src/lib/libast/common/misc/reclen.c (revision 7c500f1b365962a44422512b5c00083faa05a79e)
1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 1985-2009 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 
33 ssize_t
34 reclen(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