Chris@0: /* Chris@0: * libid3tag - ID3 tag manipulation library Chris@0: * Copyright (C) 2000-2004 Underbit Technologies, Inc. Chris@0: * Chris@0: * This program is free software; you can redistribute it and/or modify Chris@0: * it under the terms of the GNU General Public License as published by Chris@0: * the Free Software Foundation; either version 2 of the License, or Chris@0: * (at your option) any later version. Chris@0: * Chris@0: * This program is distributed in the hope that it will be useful, Chris@0: * but WITHOUT ANY WARRANTY; without even the implied warranty of Chris@0: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Chris@0: * GNU General Public License for more details. Chris@0: * Chris@0: * You should have received a copy of the GNU General Public License Chris@0: * along with this program; if not, write to the Free Software Chris@0: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Chris@0: * Chris@0: * $Id: latin1.c,v 1.10 2004/01/23 09:41:32 rob Exp $ Chris@0: */ Chris@0: Chris@0: # ifdef HAVE_CONFIG_H Chris@0: # include "config.h" Chris@0: # endif Chris@0: Chris@0: # include "global.h" Chris@0: Chris@0: # include Chris@0: Chris@0: # include "id3tag.h" Chris@0: # include "latin1.h" Chris@0: # include "ucs4.h" Chris@0: Chris@0: /* Chris@0: * NAME: latin1->length() Chris@0: * DESCRIPTION: return the number of ucs4 chars represented by a latin1 string Chris@0: */ Chris@0: id3_length_t id3_latin1_length(id3_latin1_t const *latin1) Chris@0: { Chris@0: id3_latin1_t const *ptr = latin1; Chris@0: Chris@0: while (*ptr) Chris@0: ++ptr; Chris@0: Chris@0: return ptr - latin1; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->size() Chris@0: * DESCRIPTION: return the encoding size of a latin1 string Chris@0: */ Chris@0: id3_length_t id3_latin1_size(id3_latin1_t const *latin1) Chris@0: { Chris@0: return id3_latin1_length(latin1) + 1; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->copy() Chris@0: * DESCRIPTION: copy a latin1 string Chris@0: */ Chris@0: void id3_latin1_copy(id3_latin1_t *dest, id3_latin1_t const *src) Chris@0: { Chris@0: while ((*dest++ = *src++)) Chris@0: ; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->duplicate() Chris@0: * DESCRIPTION: duplicate a latin1 string Chris@0: */ Chris@0: id3_latin1_t *id3_latin1_duplicate(id3_latin1_t const *src) Chris@0: { Chris@0: id3_latin1_t *latin1; Chris@0: Chris@0: latin1 = malloc(id3_latin1_size(src) * sizeof(*latin1)); Chris@0: if (latin1) Chris@0: id3_latin1_copy(latin1, src); Chris@0: Chris@0: return latin1; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->ucs4duplicate() Chris@0: * DESCRIPTION: duplicate and decode a latin1 string into ucs4 Chris@0: */ Chris@0: id3_ucs4_t *id3_latin1_ucs4duplicate(id3_latin1_t const *latin1) Chris@0: { Chris@0: id3_ucs4_t *ucs4; Chris@0: Chris@0: ucs4 = malloc((id3_latin1_length(latin1) + 1) * sizeof(*ucs4)); Chris@0: if (ucs4) Chris@0: id3_latin1_decode(latin1, ucs4); Chris@0: Chris@0: return release(ucs4); Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->decodechar() Chris@0: * DESCRIPTION: decode a (single) latin1 char into a single ucs4 char Chris@0: */ Chris@0: id3_length_t id3_latin1_decodechar(id3_latin1_t const *latin1, Chris@0: id3_ucs4_t *ucs4) Chris@0: { Chris@0: *ucs4 = *latin1; Chris@0: Chris@0: return 1; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->encodechar() Chris@0: * DESCRIPTION: encode a single ucs4 char into a (single) latin1 char Chris@0: */ Chris@0: id3_length_t id3_latin1_encodechar(id3_latin1_t *latin1, id3_ucs4_t ucs4) Chris@0: { Chris@0: *latin1 = ucs4; Chris@0: if (ucs4 > 0x000000ffL) Chris@0: *latin1 = ID3_UCS4_REPLACEMENTCHAR; Chris@0: Chris@0: return 1; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->decode() Chris@0: * DESCRIPTION: decode a complete latin1 string into a ucs4 string Chris@0: */ Chris@0: void id3_latin1_decode(id3_latin1_t const *latin1, id3_ucs4_t *ucs4) Chris@0: { Chris@0: do Chris@0: latin1 += id3_latin1_decodechar(latin1, ucs4); Chris@0: while (*ucs4++); Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->encode() Chris@0: * DESCRIPTION: encode a complete ucs4 string into a latin1 string Chris@0: */ Chris@0: void id3_latin1_encode(id3_latin1_t *latin1, id3_ucs4_t const *ucs4) Chris@0: { Chris@0: do Chris@0: latin1 += id3_latin1_encodechar(latin1, *ucs4); Chris@0: while (*ucs4++); Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->put() Chris@0: * DESCRIPTION: serialize a single latin1 character Chris@0: */ Chris@0: id3_length_t id3_latin1_put(id3_byte_t **ptr, id3_latin1_t latin1) Chris@0: { Chris@0: if (ptr) Chris@0: *(*ptr)++ = latin1; Chris@0: Chris@0: return 1; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->get() Chris@0: * DESCRIPTION: deserialize a single latin1 character Chris@0: */ Chris@0: id3_latin1_t id3_latin1_get(id3_byte_t const **ptr) Chris@0: { Chris@0: return *(*ptr)++; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->serialize() Chris@0: * DESCRIPTION: serialize a ucs4 string using latin1 encoding Chris@0: */ Chris@0: id3_length_t id3_latin1_serialize(id3_byte_t **ptr, id3_ucs4_t const *ucs4, Chris@0: int terminate) Chris@0: { Chris@0: id3_length_t size = 0; Chris@0: id3_latin1_t latin1[1], *out; Chris@0: Chris@0: while (*ucs4) { Chris@0: switch (id3_latin1_encodechar(out = latin1, *ucs4++)) { Chris@0: case 1: size += id3_latin1_put(ptr, *out++); Chris@0: case 0: break; Chris@0: } Chris@0: } Chris@0: Chris@0: if (terminate) Chris@0: size += id3_latin1_put(ptr, 0); Chris@0: Chris@0: return size; Chris@0: } Chris@0: Chris@0: /* Chris@0: * NAME: latin1->deserialize() Chris@0: * DESCRIPTION: deserialize a ucs4 string using latin1 encoding Chris@0: */ Chris@0: id3_ucs4_t *id3_latin1_deserialize(id3_byte_t const **ptr, id3_length_t length) Chris@0: { Chris@0: id3_byte_t const *end; Chris@0: id3_latin1_t *latin1ptr, *latin1; Chris@0: id3_ucs4_t *ucs4; Chris@0: Chris@0: end = *ptr + length; Chris@0: Chris@0: latin1 = malloc((length + 1) * sizeof(*latin1)); Chris@0: if (latin1 == 0) Chris@0: return 0; Chris@0: Chris@0: latin1ptr = latin1; Chris@0: while (end - *ptr > 0 && (*latin1ptr = id3_latin1_get(ptr))) Chris@0: ++latin1ptr; Chris@0: Chris@0: *latin1ptr = 0; Chris@0: Chris@0: ucs4 = malloc((id3_latin1_length(latin1) + 1) * sizeof(*ucs4)); Chris@0: if (ucs4) Chris@0: id3_latin1_decode(latin1, ucs4); Chris@0: Chris@0: free(latin1); Chris@0: Chris@0: return ucs4; Chris@0: }