1/* 2 * libid3tag - ID3 tag manipulation library 3 * Copyright (C) 2000-2004 Underbit Technologies, Inc. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * 19 * $Id: latin1.c,v 1.10 2004/01/23 09:41:32 rob Exp $ 20 */ 21 22# ifdef HAVE_CONFIG_H 23# include "config.h" 24# endif 25 26# include "global.h" 27 28# include <stdlib.h> 29 30# include "id3tag.h" 31# include "latin1.h" 32# include "ucs4.h" 33 34/* 35 * NAME: latin1->length() 36 * DESCRIPTION: return the number of ucs4 chars represented by a latin1 string 37 */ 38id3_length_t id3_latin1_length(id3_latin1_t const *latin1) 39{ 40 id3_latin1_t const *ptr = latin1; 41 42 while (*ptr) 43 ++ptr; 44 45 return ptr - latin1; 46} 47 48/* 49 * NAME: latin1->size() 50 * DESCRIPTION: return the encoding size of a latin1 string 51 */ 52id3_length_t id3_latin1_size(id3_latin1_t const *latin1) 53{ 54 return id3_latin1_length(latin1) + 1; 55} 56 57/* 58 * NAME: latin1->copy() 59 * DESCRIPTION: copy a latin1 string 60 */ 61void id3_latin1_copy(id3_latin1_t *dest, id3_latin1_t const *src) 62{ 63 while ((*dest++ = *src++)) 64 ; 65} 66 67/* 68 * NAME: latin1->duplicate() 69 * DESCRIPTION: duplicate a latin1 string 70 */ 71id3_latin1_t *id3_latin1_duplicate(id3_latin1_t const *src) 72{ 73 id3_latin1_t *latin1; 74 75 latin1 = malloc(id3_latin1_size(src) * sizeof(*latin1)); 76 if (latin1) 77 id3_latin1_copy(latin1, src); 78 79 return latin1; 80} 81 82/* 83 * NAME: latin1->ucs4duplicate() 84 * DESCRIPTION: duplicate and decode a latin1 string into ucs4 85 */ 86id3_ucs4_t *id3_latin1_ucs4duplicate(id3_latin1_t const *latin1) 87{ 88 id3_ucs4_t *ucs4; 89 90 ucs4 = malloc((id3_latin1_length(latin1) + 1) * sizeof(*ucs4)); 91 if (ucs4) 92 id3_latin1_decode(latin1, ucs4); 93 94 return release(ucs4); 95} 96 97/* 98 * NAME: latin1->decodechar() 99 * DESCRIPTION: decode a (single) latin1 char into a single ucs4 char 100 */ 101id3_length_t id3_latin1_decodechar(id3_latin1_t const *latin1, 102 id3_ucs4_t *ucs4) 103{ 104 *ucs4 = *latin1; 105 106 return 1; 107} 108 109/* 110 * NAME: latin1->encodechar() 111 * DESCRIPTION: encode a single ucs4 char into a (single) latin1 char 112 */ 113id3_length_t id3_latin1_encodechar(id3_latin1_t *latin1, id3_ucs4_t ucs4) 114{ 115 *latin1 = ucs4; 116 if (ucs4 > 0x000000ffL) 117 *latin1 = ID3_UCS4_REPLACEMENTCHAR; 118 119 return 1; 120} 121 122/* 123 * NAME: latin1->decode() 124 * DESCRIPTION: decode a complete latin1 string into a ucs4 string 125 */ 126void id3_latin1_decode(id3_latin1_t const *latin1, id3_ucs4_t *ucs4) 127{ 128 do 129 latin1 += id3_latin1_decodechar(latin1, ucs4); 130 while (*ucs4++); 131} 132 133/* 134 * NAME: latin1->encode() 135 * DESCRIPTION: encode a complete ucs4 string into a latin1 string 136 */ 137void id3_latin1_encode(id3_latin1_t *latin1, id3_ucs4_t const *ucs4) 138{ 139 do 140 latin1 += id3_latin1_encodechar(latin1, *ucs4); 141 while (*ucs4++); 142} 143 144/* 145 * NAME: latin1->put() 146 * DESCRIPTION: serialize a single latin1 character 147 */ 148id3_length_t id3_latin1_put(id3_byte_t **ptr, id3_latin1_t latin1) 149{ 150 if (ptr) 151 *(*ptr)++ = latin1; 152 153 return 1; 154} 155 156/* 157 * NAME: latin1->get() 158 * DESCRIPTION: deserialize a single latin1 character 159 */ 160id3_latin1_t id3_latin1_get(id3_byte_t const **ptr) 161{ 162 return *(*ptr)++; 163} 164 165/* 166 * NAME: latin1->serialize() 167 * DESCRIPTION: serialize a ucs4 string using latin1 encoding 168 */ 169id3_length_t id3_latin1_serialize(id3_byte_t **ptr, id3_ucs4_t const *ucs4, 170 int terminate) 171{ 172 id3_length_t size = 0; 173 id3_latin1_t latin1[1], *out; 174 175 while (*ucs4) { 176 switch (id3_latin1_encodechar(out = latin1, *ucs4++)) { 177 case 1: size += id3_latin1_put(ptr, *out++); 178 case 0: break; 179 } 180 } 181 182 if (terminate) 183 size += id3_latin1_put(ptr, 0); 184 185 return size; 186} 187 188/* 189 * NAME: latin1->deserialize() 190 * DESCRIPTION: deserialize a ucs4 string using latin1 encoding 191 */ 192id3_ucs4_t *id3_latin1_deserialize(id3_byte_t const **ptr, id3_length_t length) 193{ 194 id3_byte_t const *end; 195 id3_latin1_t *latin1ptr, *latin1; 196 id3_ucs4_t *ucs4; 197 198 end = *ptr + length; 199 200 latin1 = malloc((length + 1) * sizeof(*latin1)); 201 if (latin1 == 0) 202 return 0; 203 204 latin1ptr = latin1; 205 while (end - *ptr > 0 && (*latin1ptr = id3_latin1_get(ptr))) 206 ++latin1ptr; 207 208 *latin1ptr = 0; 209 210 ucs4 = malloc((id3_latin1_length(latin1) + 1) * sizeof(*ucs4)); 211 if (ucs4) 212 id3_latin1_decode(latin1, ucs4); 213 214 free(latin1); 215 216 return ucs4; 217} 218