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