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