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
sio_enctostr(struct sio_par * par,char * ostr)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
sio_strtoenc(struct sio_par * par,char * istr)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