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