e2d2baece9
git-svn-id: https://svn.musicpd.org/mpd/trunk@196 09075e82-0dd4-0310-85a5-a0d7c8717e4f
225 lines
4.7 KiB
C
225 lines
4.7 KiB
C
/*
|
|
* libid3tag - ID3 tag manipulation library
|
|
* Copyright (C) 2000-2004 Underbit Technologies, Inc.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*
|
|
* $Id: ucs4.c,v 1.13 2004/01/23 09:41:32 rob Exp $
|
|
*/
|
|
|
|
# ifdef HAVE_CONFIG_H
|
|
# include "config.h"
|
|
# endif
|
|
|
|
# include "global.h"
|
|
|
|
# include <stdlib.h>
|
|
|
|
# include "id3tag.h"
|
|
# include "ucs4.h"
|
|
# include "latin1.h"
|
|
# include "utf16.h"
|
|
# include "utf8.h"
|
|
|
|
id3_ucs4_t const id3_ucs4_empty[] = { 0 };
|
|
|
|
/*
|
|
* NAME: ucs4->length()
|
|
* DESCRIPTION: return the number of ucs4 chars represented by a ucs4 string
|
|
*/
|
|
id3_length_t id3_ucs4_length(id3_ucs4_t const *ucs4)
|
|
{
|
|
id3_ucs4_t const *ptr = ucs4;
|
|
|
|
while (*ptr)
|
|
++ptr;
|
|
|
|
return ptr - ucs4;
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->size()
|
|
* DESCRIPTION: return the encoding size of a ucs4 string
|
|
*/
|
|
id3_length_t id3_ucs4_size(id3_ucs4_t const *ucs4)
|
|
{
|
|
return id3_ucs4_length(ucs4) + 1;
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->latin1size()
|
|
* DESCRIPTION: return the encoding size of a latin1-encoded ucs4 string
|
|
*/
|
|
id3_length_t id3_ucs4_latin1size(id3_ucs4_t const *ucs4)
|
|
{
|
|
return id3_ucs4_size(ucs4);
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->utf16size()
|
|
* DESCRIPTION: return the encoding size of a utf16-encoded ucs4 string
|
|
*/
|
|
id3_length_t id3_ucs4_utf16size(id3_ucs4_t const *ucs4)
|
|
{
|
|
id3_length_t size = 0;
|
|
|
|
while (*ucs4) {
|
|
++size;
|
|
if (*ucs4 >= 0x00010000L &&
|
|
*ucs4 <= 0x0010ffffL)
|
|
++size;
|
|
|
|
++ucs4;
|
|
}
|
|
|
|
return size + 1;
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->utf8size()
|
|
* DESCRIPTION: return the encoding size of a utf8-encoded ucs4 string
|
|
*/
|
|
id3_length_t id3_ucs4_utf8size(id3_ucs4_t const *ucs4)
|
|
{
|
|
id3_length_t size = 0;
|
|
|
|
while (*ucs4) {
|
|
if (*ucs4 <= 0x0000007fL)
|
|
size += 1;
|
|
else if (*ucs4 <= 0x000007ffL)
|
|
size += 2;
|
|
else if (*ucs4 <= 0x0000ffffL)
|
|
size += 3;
|
|
else if (*ucs4 <= 0x001fffffL)
|
|
size += 4;
|
|
else if (*ucs4 <= 0x03ffffffL)
|
|
size += 5;
|
|
else if (*ucs4 <= 0x7fffffffL)
|
|
size += 6;
|
|
else
|
|
size += 2; /* based on U+00B7 replacement char */
|
|
|
|
++ucs4;
|
|
}
|
|
|
|
return size + 1;
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->latin1duplicate()
|
|
* DESCRIPTION: duplicate and encode a ucs4 string into latin1
|
|
*/
|
|
id3_latin1_t *id3_ucs4_latin1duplicate(id3_ucs4_t const *ucs4)
|
|
{
|
|
id3_latin1_t *latin1;
|
|
|
|
latin1 = malloc(id3_ucs4_latin1size(ucs4) * sizeof(*latin1));
|
|
if (latin1)
|
|
id3_latin1_encode(latin1, ucs4);
|
|
|
|
return release(latin1);
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->utf16duplicate()
|
|
* DESCRIPTION: duplicate and encode a ucs4 string into utf16
|
|
*/
|
|
id3_utf16_t *id3_ucs4_utf16duplicate(id3_ucs4_t const *ucs4)
|
|
{
|
|
id3_utf16_t *utf16;
|
|
|
|
utf16 = malloc(id3_ucs4_utf16size(ucs4) * sizeof(*utf16));
|
|
if (utf16)
|
|
id3_utf16_encode(utf16, ucs4);
|
|
|
|
return release(utf16);
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->utf8duplicate()
|
|
* DESCRIPTION: duplicate and encode a ucs4 string into utf8
|
|
*/
|
|
id3_utf8_t *id3_ucs4_utf8duplicate(id3_ucs4_t const *ucs4)
|
|
{
|
|
id3_utf8_t *utf8;
|
|
|
|
utf8 = malloc(id3_ucs4_utf8size(ucs4) * sizeof(*utf8));
|
|
if (utf8)
|
|
id3_utf8_encode(utf8, ucs4);
|
|
|
|
return release(utf8);
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->copy()
|
|
* DESCRIPTION: copy a ucs4 string
|
|
*/
|
|
void id3_ucs4_copy(id3_ucs4_t *dest, id3_ucs4_t const *src)
|
|
{
|
|
while ((*dest++ = *src++))
|
|
;
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->duplicate()
|
|
* DESCRIPTION: duplicate a ucs4 string
|
|
*/
|
|
id3_ucs4_t *id3_ucs4_duplicate(id3_ucs4_t const *src)
|
|
{
|
|
id3_ucs4_t *ucs4;
|
|
|
|
ucs4 = malloc(id3_ucs4_size(src) * sizeof(*ucs4));
|
|
if (ucs4)
|
|
id3_ucs4_copy(ucs4, src);
|
|
|
|
return ucs4;
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->putnumber()
|
|
* DESCRIPTION: write a ucs4 string containing a (positive) decimal number
|
|
*/
|
|
void id3_ucs4_putnumber(id3_ucs4_t *ucs4, unsigned long number)
|
|
{
|
|
int digits[10], *digit;
|
|
|
|
digit = digits;
|
|
|
|
do {
|
|
*digit++ = number % 10;
|
|
number /= 10;
|
|
}
|
|
while (number);
|
|
|
|
while (digit != digits)
|
|
*ucs4++ = '0' + *--digit;
|
|
|
|
*ucs4 = 0;
|
|
}
|
|
|
|
/*
|
|
* NAME: ucs4->getnumber()
|
|
* DESCRIPTION: read a ucs4 string containing a (positive) decimal number
|
|
*/
|
|
unsigned long id3_ucs4_getnumber(id3_ucs4_t const *ucs4)
|
|
{
|
|
unsigned long number = 0;
|
|
|
|
while (*ucs4 >= '0' && *ucs4 <= '9')
|
|
number = 10 * number + (*ucs4++ - '0');
|
|
|
|
return number;
|
|
}
|