xref: /openbsd-src/regress/lib/libsndio/tools.c (revision 4c68e8819720272b4665ae45efac0b163c034f47)
1*4c68e881Sratchov /*	$OpenBSD: tools.c,v 1.1 2010/11/06 20:25:42 ratchov Exp $	*/
2*4c68e881Sratchov /*
3*4c68e881Sratchov  * Copyright (c) 2008 Alexandre Ratchov <alex@caoua.org>
4*4c68e881Sratchov  *
5*4c68e881Sratchov  * Permission to use, copy, modify, and distribute this software for any
6*4c68e881Sratchov  * purpose with or without fee is hereby granted, provided that the above
7*4c68e881Sratchov  * copyright notice and this permission notice appear in all copies.
8*4c68e881Sratchov  *
9*4c68e881Sratchov  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10*4c68e881Sratchov  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11*4c68e881Sratchov  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12*4c68e881Sratchov  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13*4c68e881Sratchov  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14*4c68e881Sratchov  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15*4c68e881Sratchov  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16*4c68e881Sratchov  */
17*4c68e881Sratchov #include <sndio.h>
18*4c68e881Sratchov #include "tools.h"
19*4c68e881Sratchov 
20*4c68e881Sratchov /*
21*4c68e881Sratchov  * Generate a string corresponding to the encoding in par,
22*4c68e881Sratchov  * return the length of the resulting string
23*4c68e881Sratchov  */
24*4c68e881Sratchov int
sio_enctostr(struct sio_par * par,char * ostr)25*4c68e881Sratchov sio_enctostr(struct sio_par *par, char *ostr)
26*4c68e881Sratchov {
27*4c68e881Sratchov 	char *p = ostr;
28*4c68e881Sratchov 
29*4c68e881Sratchov 	*p++ = par->sig ? 's' : 'u';
30*4c68e881Sratchov 	if (par->bits > 9)
31*4c68e881Sratchov 		*p++ = '0' + par->bits / 10;
32*4c68e881Sratchov 	*p++ = '0' + par->bits % 10;
33*4c68e881Sratchov 	if (par->bps > 1) {
34*4c68e881Sratchov 		*p++ = par->le ? 'l' : 'b';
35*4c68e881Sratchov 		*p++ = 'e';
36*4c68e881Sratchov 		if (par->bps != SIO_BPS(par->bits) ||
37*4c68e881Sratchov 		    par->bits < par->bps * 8) {
38*4c68e881Sratchov 			*p++ = par->bps + '0';
39*4c68e881Sratchov 			if (par->bits < par->bps * 8) {
40*4c68e881Sratchov 				*p++ = par->msb ? 'm' : 'l';
41*4c68e881Sratchov 				*p++ = 's';
42*4c68e881Sratchov 				*p++ = 'b';
43*4c68e881Sratchov 			}
44*4c68e881Sratchov 		}
45*4c68e881Sratchov 	}
46*4c68e881Sratchov 	*p++ = '\0';
47*4c68e881Sratchov 	return p - ostr - 1;
48*4c68e881Sratchov }
49*4c68e881Sratchov 
50*4c68e881Sratchov /*
51*4c68e881Sratchov  * Parse an encoding string, examples: s8, u8, s16, s16le, s24be ...
52*4c68e881Sratchov  * Return the number of bytes consumed
53*4c68e881Sratchov  */
54*4c68e881Sratchov int
sio_strtoenc(struct sio_par * par,char * istr)55*4c68e881Sratchov sio_strtoenc(struct sio_par *par, char *istr)
56*4c68e881Sratchov {
57*4c68e881Sratchov 	char *p = istr;
58*4c68e881Sratchov 	int i, sig, bits, le, bps, msb;
59*4c68e881Sratchov 
60*4c68e881Sratchov #define IS_SEP(c)			\
61*4c68e881Sratchov 	(((c) < 'a' || (c) > 'z') &&	\
62*4c68e881Sratchov 	 ((c) < 'A' || (c) > 'Z') &&	\
63*4c68e881Sratchov 	 ((c) < '0' || (c) > '9'))
64*4c68e881Sratchov 
65*4c68e881Sratchov 	/*
66*4c68e881Sratchov 	 * get signedness
67*4c68e881Sratchov 	 */
68*4c68e881Sratchov 	if (*p == 's') {
69*4c68e881Sratchov 		sig = 1;
70*4c68e881Sratchov 	} else if (*p == 'u') {
71*4c68e881Sratchov 		sig = 0;
72*4c68e881Sratchov 	} else
73*4c68e881Sratchov 		return 0;
74*4c68e881Sratchov 	p++;
75*4c68e881Sratchov 
76*4c68e881Sratchov 	/*
77*4c68e881Sratchov 	 * get number of bits per sample
78*4c68e881Sratchov 	 */
79*4c68e881Sratchov 	bits = 0;
80*4c68e881Sratchov 	for (i = 0; i < 2; i++) {
81*4c68e881Sratchov 		if (*p < '0' || *p > '9')
82*4c68e881Sratchov 			break;
83*4c68e881Sratchov 		bits = (bits * 10) + *p - '0';
84*4c68e881Sratchov 		p++;
85*4c68e881Sratchov 	}
86*4c68e881Sratchov 	if (bits < 1 || bits > 32)
87*4c68e881Sratchov 		return 0;
88*4c68e881Sratchov 	bps = SIO_BPS(bits);
89*4c68e881Sratchov 	le = SIO_LE_NATIVE;
90*4c68e881Sratchov 	msb = 1;
91*4c68e881Sratchov 
92*4c68e881Sratchov 	/*
93*4c68e881Sratchov 	 * get (optional) endianness
94*4c68e881Sratchov 	 */
95*4c68e881Sratchov 	if (p[0] == 'l' && p[1] == 'e') {
96*4c68e881Sratchov 		le = 1;
97*4c68e881Sratchov 		p += 2;
98*4c68e881Sratchov 	} else if (p[0] == 'b' && p[1] == 'e') {
99*4c68e881Sratchov 		le = 0;
100*4c68e881Sratchov 		p += 2;
101*4c68e881Sratchov 	} else if (IS_SEP(*p)) {
102*4c68e881Sratchov 		goto done;
103*4c68e881Sratchov 	} else
104*4c68e881Sratchov 		return 0;
105*4c68e881Sratchov 
106*4c68e881Sratchov 	/*
107*4c68e881Sratchov 	 * get (optional) number of bytes
108*4c68e881Sratchov 	 */
109*4c68e881Sratchov 	if (*p >= '1' && *p <= '4') {
110*4c68e881Sratchov 		bps = *p - '0';
111*4c68e881Sratchov 		if (bps * 8  < bits)
112*4c68e881Sratchov 			return 0;
113*4c68e881Sratchov 		p++;
114*4c68e881Sratchov 
115*4c68e881Sratchov 		/*
116*4c68e881Sratchov 		 * get (optional) alignment
117*4c68e881Sratchov 		 */
118*4c68e881Sratchov 		if (p[0] == 'm' && p[1] == 's' && p[2] == 'b') {
119*4c68e881Sratchov 			msb = 1;
120*4c68e881Sratchov 			p += 3;
121*4c68e881Sratchov 		} else if (p[0] == 'l' && p[1] == 's' && p[2] == 'b') {
122*4c68e881Sratchov 			msb = 0;
123*4c68e881Sratchov 			p += 3;
124*4c68e881Sratchov 		} else if (IS_SEP(*p)) {
125*4c68e881Sratchov 			goto done;
126*4c68e881Sratchov 		} else
127*4c68e881Sratchov 			return 0;
128*4c68e881Sratchov 	} else if (!IS_SEP(*p))
129*4c68e881Sratchov 		return 0;
130*4c68e881Sratchov 
131*4c68e881Sratchov done:
132*4c68e881Sratchov 	par->msb = msb;
133*4c68e881Sratchov 	par->sig = sig;
134*4c68e881Sratchov 	par->bits = bits;
135*4c68e881Sratchov 	par->bps = bps;
136*4c68e881Sratchov 	par->le = le;
137*4c68e881Sratchov 	return p - istr;
138*4c68e881Sratchov }
139