xref: /third_party/libsnd/src/cart.c (revision b815c7f3)
1/*
2** Copyright (C) 2012 Chris Roberts <c.roberts@csrfm.com>
3** Copyright (C) 2006-2013 Erik de Castro Lopo <erikd@mega-nerd.com>
4** Copyright (C) 2006 Paul Davis <paul@linuxaudiosystems.com>
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU Lesser General Public License as published by
8** the Free Software Foundation; either version 2.1 of the License, or
9** (at your option) any later version.
10**
11** This program 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
14** GNU Lesser General Public License for more details.
15**
16** You should have received a copy of the GNU Lesser General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19*/
20
21#include "sfconfig.h"
22
23#include <stdio.h>
24#include <stddef.h>
25#include <string.h>
26#include <stdlib.h>
27#include "common.h"
28
29
30
31static inline size_t
32cart_min_size (const SF_CART_INFO* info)
33{	if (info == NULL)
34		return 0 ;
35
36	return offsetof (SF_CART_INFO, tag_text) + info->tag_text_size ;
37} /* cart_min_size */
38
39SF_CART_INFO_16K*
40cart_var_alloc (void)
41{	SF_CART_INFO_16K* thing ;
42	thing = malloc (sizeof (SF_CART_INFO_16K)) ;
43	return thing ;
44} /* cart_var_alloc */
45
46int
47cart_var_set (SF_PRIVATE *psf, const SF_CART_INFO * info, size_t datasize)
48{	size_t len ;
49
50	if (info == NULL)
51		return SF_FALSE ;
52
53	if (cart_min_size (info) > datasize)
54	{	psf->error = SFE_BAD_CART_INFO_SIZE ;
55		return SF_FALSE ;
56		} ;
57
58	if (datasize >= sizeof (SF_CART_INFO_16K))
59	{	psf->error = SFE_BAD_CART_INFO_TOO_BIG ;
60		return SF_FALSE ;
61		} ;
62
63	if (psf->cart_16k == NULL)
64	{	if ((psf->cart_16k = cart_var_alloc ()) == NULL)
65		{	psf->error = SFE_MALLOC_FAILED ;
66			return SF_FALSE ;
67			} ;
68		} ;
69
70	memcpy (psf->cart_16k, info, offsetof (SF_CART_INFO, tag_text)) ;
71	psf_strlcpy_crlf (psf->cart_16k->tag_text, info->tag_text, sizeof (psf->cart_16k->tag_text), datasize - offsetof (SF_CART_INFO, tag_text)) ;
72
73	len = strlen (psf->cart_16k->tag_text) ;
74
75	if (len > 0 && psf->cart_16k->tag_text [len - 1] != '\n')
76		psf_strlcat (psf->cart_16k->tag_text, sizeof (psf->cart_16k->tag_text), "\r\n") ;
77
78	/* Force tag_text_size to be even. */
79	len = strlen (psf->cart_16k->tag_text) ;
80	len += (len & 1) ? 1 : 2 ;
81
82	psf->cart_16k->tag_text_size = (uint32_t) len ;
83
84	return SF_TRUE ;
85} /* cart_var_set */
86
87
88int
89cart_var_get (SF_PRIVATE *psf, SF_CART_INFO * data, size_t datasize)
90{	size_t size ;
91	if (psf->cart_16k == NULL)
92		return SF_FALSE ;
93
94	size = SF_MIN (datasize, cart_min_size ((const SF_CART_INFO *) psf->cart_16k)) ;
95
96	memcpy (data, psf->cart_16k, size) ;
97
98	return SF_TRUE ;
99} /* cart_var_get */
100
101
102