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
31 static inline size_t
cart_min_size(const SF_CART_INFO * info)32 cart_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
39 SF_CART_INFO_16K*
cart_var_alloc(void)40 cart_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
46 int
cart_var_set(SF_PRIVATE * psf,const SF_CART_INFO * info,size_t datasize)47 cart_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
88 int
cart_var_get(SF_PRIVATE * psf,SF_CART_INFO * data,size_t datasize)89 cart_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