Do not crash to assertion failure on unknown audio codec
[deb_shairplay.git] / src / lib / utils.c
1 /**
2 * Copyright (C) 2011-2012 Juho Vähä-Herttua
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 */
14
15 #include <stdlib.h>
16 #include <stdio.h>
17 #include <string.h>
18
19 char *
20 utils_strsep(char **stringp, const char *delim)
21 {
22 char *original;
23 char *strptr;
24
25 if (*stringp == NULL) {
26 return NULL;
27 }
28
29 original = *stringp;
30 strptr = strstr(*stringp, delim);
31 if (strptr == NULL) {
32 *stringp = NULL;
33 return original;
34 }
35 *strptr = '\0';
36 *stringp = strptr+strlen(delim);
37 return original;
38 }
39
40 int
41 utils_read_file(char **dst, const char *filename)
42 {
43 FILE *stream;
44 int filesize;
45 char *buffer;
46 int read_bytes;
47
48 /* Open stream for reading */
49 stream = fopen(filename, "rb");
50 if (!stream) {
51 return -1;
52 }
53
54 /* Find out file size */
55 fseek(stream, 0, SEEK_END);
56 filesize = ftell(stream);
57 fseek(stream, 0, SEEK_SET);
58
59 /* Allocate one extra byte for zero */
60 buffer = malloc(filesize+1);
61 if (!buffer) {
62 fclose(stream);
63 return -2;
64 }
65
66 /* Read data in a loop to buffer */
67 read_bytes = 0;
68 do {
69 int ret = fread(buffer+read_bytes, 1,
70 filesize-read_bytes, stream);
71 if (ret == 0) {
72 break;
73 }
74 read_bytes += ret;
75 } while (read_bytes < filesize);
76
77 /* Add final null byte and close stream */
78 buffer[read_bytes] = '\0';
79 fclose(stream);
80
81 /* If read didn't finish, return error */
82 if (read_bytes != filesize) {
83 free(buffer);
84 return -3;
85 }
86
87 /* Return buffer */
88 *dst = buffer;
89 return filesize;
90 }
91
92 int
93 utils_hwaddr_raop(char *str, int strlen, const char *hwaddr, int hwaddrlen)
94 {
95 int i,j;
96
97 /* Check that our string is long enough */
98 if (strlen == 0 || strlen < 2*hwaddrlen+1)
99 return -1;
100
101 /* Convert hardware address to hex string */
102 for (i=0,j=0; i<hwaddrlen; i++) {
103 int hi = (hwaddr[i]>>4) & 0x0f;
104 int lo = hwaddr[i] & 0x0f;
105
106 if (hi < 10) str[j++] = '0' + hi;
107 else str[j++] = 'A' + hi-10;
108 if (lo < 10) str[j++] = '0' + lo;
109 else str[j++] = 'A' + lo-10;
110 }
111
112 /* Add string terminator */
113 str[j++] = '\0';
114 return j;
115 }
116
117 int
118 utils_hwaddr_airplay(char *str, int strlen, const char *hwaddr, int hwaddrlen)
119 {
120 int i,j;
121
122 /* Check that our string is long enough */
123 if (strlen == 0 || strlen < 2*hwaddrlen+hwaddrlen)
124 return -1;
125
126 /* Convert hardware address to hex string */
127 for (i=0,j=0; i<hwaddrlen; i++) {
128 int hi = (hwaddr[i]>>4) & 0x0f;
129 int lo = hwaddr[i] & 0x0f;
130
131 if (hi < 10) str[j++] = '0' + hi;
132 else str[j++] = 'a' + hi-10;
133 if (lo < 10) str[j++] = '0' + lo;
134 else str[j++] = 'a' + lo-10;
135
136 str[j++] = ':';
137 }
138
139 /* Add string terminator */
140 if (j != 0) j--;
141 str[j++] = '\0';
142 return j;
143 }
144