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