1 /*
2 $Id: cddb_site.c,v 1.3 2005/06/15 16:12:04 airborne Exp $
3
4 Copyright (C) 2005 Kris Verbeeck <airborne@advalvas.be>
5
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
10
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
15
16 You should have received a copy of the GNU Library General Public
17 License along with this library; if not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
20 */
21
22
23 #include "config.h"
24
25 #ifdef HAVE_STRING_H
26 #include <string.h>
27 #endif
28
29 #include "cddb/cddb_ni.h"
30 #include "cddb/cddb_site.h"
31
32
33 /* --- type and structure definitions */
34
35
36 struct cddb_site_s
37 {
38 char *address; /**< host name of the CDDB server */
39 cddb_protocol_t protocol; /**< the protocol used by this site */
40 int port; /**< port of the CDDB server */
41 char *query_path; /**< query path for HTTP URL */
42 char *submit_path; /**< submit path for HTTP URL */
43 char *desc; /**< server description */
44 float latitude; /**< server latitude */
45 float longitude; /**< server longitude */
46 };
47
48
49 /* --- private functions */
50
51
cddb_site_iconv(iconv_t cd,cddb_site_t * site)52 int cddb_site_iconv(iconv_t cd, cddb_site_t *site)
53 {
54 char *result;
55
56 if (!cd) {
57 return TRUE; /* no user character set defined */
58 }
59 if (site->desc) {
60 if (cddb_str_iconv(cd, site->desc, &result)) {
61 free(site->desc);
62 site->desc = result;
63 } else {
64 return FALSE;
65 }
66 }
67 return TRUE;
68 }
69
70
71 /* --- construction / destruction */
72
73
cddb_site_new(void)74 cddb_site_t *cddb_site_new(void)
75 {
76 cddb_site_t *site;
77
78 site = (cddb_site_t*)calloc(1, sizeof(cddb_site_t));
79 return site;
80 }
81
cddb_site_destroy(cddb_site_t * site)82 cddb_error_t cddb_site_destroy(cddb_site_t *site)
83 {
84 ASSERT_NOT_NULL(site);
85 FREE_NOT_NULL(site->address);
86 FREE_NOT_NULL(site->query_path);
87 FREE_NOT_NULL(site->submit_path);
88 FREE_NOT_NULL(site->desc);
89 free(site);
90 return CDDB_ERR_OK;
91 }
92
cddb_site_clone(cddb_site_t * site)93 cddb_site_t *cddb_site_clone(cddb_site_t *site)
94 {
95 cddb_site_t *clone;
96
97 cddb_log_debug("cddb_site_clone()");
98 clone = cddb_site_new();
99 clone->address = (site->address ? strdup(site->address) : NULL);
100 clone->protocol = site->protocol;
101 clone->port = site->port;
102 clone->query_path = (site->query_path ? strdup(site->query_path) : NULL);
103 clone->submit_path = (site->submit_path ? strdup(site->submit_path) : NULL);
104 clone->desc = (site->desc ? strdup(site->desc) : NULL);
105 clone->latitude = site->latitude;
106 clone->longitude = site->longitude;
107 return clone;
108 }
109
110
111 /* --- setters / getters --- */
112
113
cddb_site_get_address(const cddb_site_t * site,const char ** address,unsigned int * port)114 cddb_error_t cddb_site_get_address(const cddb_site_t *site,
115 const char **address, unsigned int *port)
116 {
117 ASSERT_NOT_NULL(site);
118 ASSERT_NOT_NULL(address);
119 ASSERT_NOT_NULL(port);
120 *address = site->address;
121 *port = site->port;
122 return CDDB_ERR_OK;
123 }
124
cddb_site_set_address(cddb_site_t * site,const char * address,unsigned int port)125 cddb_error_t cddb_site_set_address(cddb_site_t *site,
126 const char *address, unsigned int port)
127 {
128 ASSERT_NOT_NULL(site);
129 ASSERT_NOT_NULL(address);
130 FREE_NOT_NULL(site->address);
131 site->address = strdup(address);
132 if (!site->address) {
133 return CDDB_ERR_OUT_OF_MEMORY;
134 }
135 site->port = port;
136 return CDDB_ERR_OK;
137 }
138
cddb_site_get_location(const cddb_site_t * site,float * latitude,float * longitude)139 cddb_error_t cddb_site_get_location(const cddb_site_t *site,
140 float *latitude, float *longitude)
141 {
142 ASSERT_NOT_NULL(site);
143 ASSERT_NOT_NULL(latitude);
144 ASSERT_NOT_NULL(longitude);
145 *latitude = site->latitude;
146 *longitude = site->longitude;
147 return CDDB_ERR_OK;
148 }
149
cddb_site_set_location(cddb_site_t * site,float latitude,float longitude)150 cddb_error_t cddb_site_set_location(cddb_site_t *site,
151 float latitude, float longitude)
152 {
153 ASSERT_NOT_NULL(site);
154 ASSERT_RANGE(latitude, -90.0, 90.0);
155 ASSERT_RANGE(longitude, -180.0, 180.0);
156 site->latitude = latitude;
157 site->longitude = longitude;
158 return CDDB_ERR_OK;
159 }
160
cddb_site_get_protocol(const cddb_site_t * site)161 cddb_protocol_t cddb_site_get_protocol(const cddb_site_t *site)
162 {
163 if (site) {
164 return site->protocol;
165 }
166 return PROTO_UNKNOWN;
167 }
168
cddb_site_set_protocol(cddb_site_t * site,cddb_protocol_t proto)169 cddb_error_t cddb_site_set_protocol(cddb_site_t *site, cddb_protocol_t proto)
170 {
171 ASSERT_NOT_NULL(site);
172 site->protocol = proto;
173 return CDDB_ERR_OK;
174 }
175
cddb_site_get_query_path(const cddb_site_t * site,const char ** path)176 cddb_error_t cddb_site_get_query_path(const cddb_site_t *site,
177 const char **path)
178 {
179 ASSERT_NOT_NULL(site);
180 ASSERT_NOT_NULL(path);
181 *path = site->query_path;
182 return CDDB_ERR_OK;
183 }
184
cddb_site_set_query_path(cddb_site_t * site,const char * path)185 cddb_error_t cddb_site_set_query_path(cddb_site_t *site, const char *path)
186 {
187 ASSERT_NOT_NULL(site);
188 FREE_NOT_NULL(site->query_path);
189 if (path) {
190 site->query_path = strdup(path);
191 if (!site->query_path) {
192 return CDDB_ERR_OUT_OF_MEMORY;
193 }
194 }
195 return CDDB_ERR_OK;
196 }
197
cddb_site_get_submit_path(const cddb_site_t * site,const char ** path)198 cddb_error_t cddb_site_get_submit_path(const cddb_site_t *site,
199 const char **path)
200 {
201 ASSERT_NOT_NULL(site);
202 ASSERT_NOT_NULL(path);
203 *path = site->submit_path;
204 return CDDB_ERR_OK;
205 }
206
cddb_site_set_submit_path(cddb_site_t * site,const char * path)207 cddb_error_t cddb_site_set_submit_path(cddb_site_t *site, const char *path)
208 {
209 ASSERT_NOT_NULL(site);
210 FREE_NOT_NULL(site->submit_path);
211 if (path) {
212 site->submit_path = strdup(path);
213 if (!site->submit_path) {
214 return CDDB_ERR_OUT_OF_MEMORY;
215 }
216 }
217 return CDDB_ERR_OK;
218 }
219
cddb_site_get_description(const cddb_site_t * site,const char ** desc)220 cddb_error_t cddb_site_get_description(const cddb_site_t *site,
221 const char **desc)
222 {
223 ASSERT_NOT_NULL(site);
224 ASSERT_NOT_NULL(desc);
225 *desc = site->desc;
226 return CDDB_ERR_OK;
227 }
228
cddb_site_set_description(cddb_site_t * site,const char * desc)229 cddb_error_t cddb_site_set_description(cddb_site_t *site, const char *desc)
230 {
231 ASSERT_NOT_NULL(site);
232 FREE_NOT_NULL(site->desc);
233 if (desc) {
234 site->desc = strdup(desc);
235 if (!site->desc) {
236 return CDDB_ERR_OUT_OF_MEMORY;
237 }
238 }
239 return CDDB_ERR_OK;
240 }
241
242
243 /* --- miscellaneous */
244
245
cddb_site_parse(cddb_site_t * site,const char * line)246 int cddb_site_parse(cddb_site_t *site, const char *line)
247 {
248 regmatch_t matches[10];
249 char *s;
250 float f;
251
252 if (regexec(REGEX_SITE, line, 10, matches, 0) == REG_NOMATCH) {
253 /* invalid repsponse */
254 return FALSE;
255 }
256 site->address = cddb_regex_get_string(line, matches, 1);
257 s = cddb_regex_get_string(line, matches, 2);
258 if (strcmp(s, "cddbp") == 0) {
259 site->protocol = PROTO_CDDBP;
260 } else if (strcmp(s, "http") == 0) {
261 site->protocol = PROTO_HTTP;
262 } else {
263 site->protocol = PROTO_UNKNOWN;
264 }
265 site->port = cddb_regex_get_int(line, matches, 3);
266 site->query_path = cddb_regex_get_string(line, matches, 4);
267 s = cddb_regex_get_string(line, matches, 5);
268 f = cddb_regex_get_float(line, matches, 6);
269 if (*s == 'N') {
270 site->latitude = f;
271 } else if (*s == 'S') {
272 site->latitude = -f;
273 } else {
274 site->latitude = 0.0;
275 }
276 free(s);
277 s = cddb_regex_get_string(line, matches, 7);
278 f = cddb_regex_get_float(line, matches, 8);
279 if (*s == 'E') {
280 site->longitude = f;
281 } else if (*s == 'W') {
282 site->longitude = -f;
283 } else {
284 site->longitude = 0.0;
285 }
286 free(s);
287 site->desc = cddb_regex_get_string(line, matches, 9);
288 return TRUE;
289 }
290
cddb_site_print(const cddb_site_t * site)291 cddb_error_t cddb_site_print(const cddb_site_t *site)
292 {
293 ASSERT_NOT_NULL(site);
294 printf("Address: ");
295 if (site->protocol == PROTO_CDDBP) {
296 printf("%s:%d\n", site->address, site->port);
297 } else if (site->protocol == PROTO_HTTP) {
298 printf("http://%s:%d%s\n", site->address, site->port, site->query_path);
299 }
300 printf("Description: %s\n", site->desc);
301 printf("Location: %4.2f %4.2f\n", site->latitude, site->longitude);
302 return CDDB_ERR_OK;
303 }
304