⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 field.c

📁 OggPlay for Symbian 是symbian上的一个媒体播放程序的源码。它支持ogg,wav等等多媒体格式。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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: field.c,v 1.1 2004/05/17 19:25:37 lcanis Exp $
 */

#pragma warning( disable : 4146 )

# ifdef HAVE_CONFIG_H
#  include "config.h"
# endif

# include "global.h"

# include <stdlib.h>
# include <string.h>

# ifdef HAVE_ASSERT_H
#  include <assert.h>
# endif

# include "id3tag.h"
# include "field.h"
# include "frame.h"
# include "render.h"
# include "ucs4.h"
# include "latin1.h"
# include "parse.h"

/*
 * NAME:	field->init()
 * DESCRIPTION:	initialize a field to a default value for the given type
 */
void id3_field_init(union id3_field *field, enum id3_field_type type)
{
  assert(field);

  switch (field->type = type) {
  case ID3_FIELD_TYPE_TEXTENCODING:
  case ID3_FIELD_TYPE_INT8:
  case ID3_FIELD_TYPE_INT16:
  case ID3_FIELD_TYPE_INT24:
  case ID3_FIELD_TYPE_INT32:
    field->number.value = 0;
    break;

  case ID3_FIELD_TYPE_LATIN1:
  case ID3_FIELD_TYPE_LATIN1FULL:
    field->latin1.ptr = 0;
    break;

  case ID3_FIELD_TYPE_LATIN1LIST:
    field->latin1list.nstrings = 0;
    field->latin1list.strings  = 0;

  case ID3_FIELD_TYPE_STRING:
  case ID3_FIELD_TYPE_STRINGFULL:
    field->string.ptr = 0;
    break;

  case ID3_FIELD_TYPE_STRINGLIST:
    field->stringlist.nstrings = 0;
    field->stringlist.strings  = 0;
    break;

  case ID3_FIELD_TYPE_LANGUAGE:
    strcpy(field->immediate.value, "XXX");
    break;

  case ID3_FIELD_TYPE_FRAMEID:
    strcpy(field->immediate.value, "XXXX");
    break;

  case ID3_FIELD_TYPE_DATE:
    memset(field->immediate.value, 0, sizeof(field->immediate.value));
    break;

  case ID3_FIELD_TYPE_INT32PLUS:
  case ID3_FIELD_TYPE_BINARYDATA:
    field->binary.data   = 0;
    field->binary.length = 0;
    break;
  }
}

/*
 * NAME:	field->finish()
 * DESCRIPTION:	reset a field, deallocating memory if necessary
 */
void id3_field_finish(union id3_field *field)
{
  unsigned int i;

  assert(field);

  switch (field->type) {
  case ID3_FIELD_TYPE_TEXTENCODING:
  case ID3_FIELD_TYPE_INT8:
  case ID3_FIELD_TYPE_INT16:
  case ID3_FIELD_TYPE_INT24:
  case ID3_FIELD_TYPE_INT32:
  case ID3_FIELD_TYPE_LANGUAGE:
  case ID3_FIELD_TYPE_FRAMEID:
  case ID3_FIELD_TYPE_DATE:
    break;

  case ID3_FIELD_TYPE_LATIN1:
  case ID3_FIELD_TYPE_LATIN1FULL:
    if (field->latin1.ptr)
      free(field->latin1.ptr);
    break;

  case ID3_FIELD_TYPE_LATIN1LIST:
    for (i = 0; i < field->latin1list.nstrings; ++i)
      free(field->latin1list.strings[i]);

    if (field->latin1list.strings)
      free(field->latin1list.strings);
    break;

  case ID3_FIELD_TYPE_STRING:
  case ID3_FIELD_TYPE_STRINGFULL:
    if (field->string.ptr)
      free(field->string.ptr);
    break;

  case ID3_FIELD_TYPE_STRINGLIST:
    for (i = 0; i < field->stringlist.nstrings; ++i)
      free(field->stringlist.strings[i]);

    if (field->stringlist.strings)
      free(field->stringlist.strings);
    break;

  case ID3_FIELD_TYPE_INT32PLUS:
  case ID3_FIELD_TYPE_BINARYDATA:
    if (field->binary.data)
      free(field->binary.data);
    break;
  }

  id3_field_init(field, field->type);
}

/*
 * NAME:	field->type()
 * DESCRIPTION:	return the value type of a field
 */
enum id3_field_type id3_field_type(union id3_field const *field)
{
  assert(field);

  return field->type;
}

/*
 * NAME:	field->parse()
 * DESCRIPTION:	parse a field value
 */
int id3_field_parse(union id3_field *field, id3_byte_t const **ptr,
		    id3_length_t length, enum id3_field_textencoding *encoding)
{
  assert(field);

  id3_field_finish(field);

  switch (field->type) {
  case ID3_FIELD_TYPE_INT32:
    if (length < 4)
      goto fail;

    field->number.value = id3_parse_uint(ptr, 4);
    break;

  case ID3_FIELD_TYPE_INT24:
    if (length < 3)
      goto fail;

    field->number.value = id3_parse_uint(ptr, 3);
    break;

  case ID3_FIELD_TYPE_INT16:
    if (length < 2)
      goto fail;

    field->number.value = id3_parse_uint(ptr, 2);
    break;

  case ID3_FIELD_TYPE_INT8:
  case ID3_FIELD_TYPE_TEXTENCODING:
    if (length < 1)
      goto fail;

    field->number.value = id3_parse_uint(ptr, 1);

    if (field->type == ID3_FIELD_TYPE_TEXTENCODING)
      *encoding = field->number.value;
    break;

  case ID3_FIELD_TYPE_LANGUAGE:
    if (length < 3)
      goto fail;

    id3_parse_immediate(ptr, 3, field->immediate.value);
    break;

  case ID3_FIELD_TYPE_FRAMEID:
    if (length < 4)
      goto fail;

    id3_parse_immediate(ptr, 4, field->immediate.value);
    break;

  case ID3_FIELD_TYPE_DATE:
    if (length < 8)
      goto fail;

    id3_parse_immediate(ptr, 8, field->immediate.value);
    break;

  case ID3_FIELD_TYPE_LATIN1:
  case ID3_FIELD_TYPE_LATIN1FULL:
    {
      id3_latin1_t *latin1;

      latin1 = id3_parse_latin1(ptr, length,
				field->type == ID3_FIELD_TYPE_LATIN1FULL);
      if (latin1 == 0)
	goto fail;

      field->latin1.ptr = latin1;
    }
    break;

  case ID3_FIELD_TYPE_LATIN1LIST:
    {
      id3_byte_t const *end;
      id3_latin1_t *latin1, **strings;

      end = *ptr + length;

      while (end - *ptr > 0) {
	latin1 = id3_parse_latin1(ptr, end - *ptr, 0);
	if (latin1 == 0)
	  goto fail;

	strings = realloc(field->latin1list.strings,
			  (field->latin1list.nstrings + 1) * sizeof(*strings));
	if (strings == 0) {
	  free(latin1);
	  goto fail;
	}

	field->latin1list.strings = strings;
	field->latin1list.strings[field->latin1list.nstrings++] = latin1;
      }
    }
    break;

  case ID3_FIELD_TYPE_STRING:
  case ID3_FIELD_TYPE_STRINGFULL:
    {
      id3_ucs4_t *ucs4;

      ucs4 = id3_parse_string(ptr, length, *encoding,
			      field->type == ID3_FIELD_TYPE_STRINGFULL);
      if (ucs4 == 0)
	goto fail;

      field->string.ptr = ucs4;
    }
    break;

  case ID3_FIELD_TYPE_STRINGLIST:
    {
      id3_byte_t const *end;
      id3_ucs4_t *ucs4, **strings;

      end = *ptr + length;

      while (end - *ptr > 0) {
	ucs4 = id3_parse_string(ptr, end - *ptr, *encoding, 0);
	if (ucs4 == 0)
	  goto fail;

	strings = realloc(field->stringlist.strings,
			  (field->stringlist.nstrings + 1) * sizeof(*strings));
	if (strings == 0) {
	  free(ucs4);
	  goto fail;
	}

	field->stringlist.strings = strings;
	field->stringlist.strings[field->stringlist.nstrings++] = ucs4;
      }
    }
    break;

  case ID3_FIELD_TYPE_INT32PLUS:
  case ID3_FIELD_TYPE_BINARYDATA:
    {
      id3_byte_t *data;

      data = id3_parse_binary(ptr, length);
      if (data == 0)
	goto fail;

      field->binary.data   = data;
      field->binary.length = length;
    }
    break;
  }

  return 0;

 fail:
  return -1;
}

/*
 * NAME:	field->render()
 * DESCRIPTION:	render a field value
 */
id3_length_t id3_field_render(union id3_field const *field, id3_byte_t **ptr,
			      enum id3_field_textencoding *encoding,
			      int terminate)
{
  id3_length_t size;
  unsigned int i;

  assert(field && encoding);

  switch (field->type) {
  case ID3_FIELD_TYPE_INT32:
    return id3_render_int(ptr, field->number.value, 4);

  case ID3_FIELD_TYPE_INT24:
    return id3_render_int(ptr, field->number.value, 3);

  case ID3_FIELD_TYPE_INT16:
    return id3_render_int(ptr, field->number.value, 2);

  case ID3_FIELD_TYPE_TEXTENCODING:
    *encoding = field->number.value;
  case ID3_FIELD_TYPE_INT8:
    return id3_render_int(ptr, field->number.value, 1);

  case ID3_FIELD_TYPE_LATIN1:
  case ID3_FIELD_TYPE_LATIN1FULL:
    return id3_render_latin1(ptr, field->latin1.ptr, terminate);

  case ID3_FIELD_TYPE_LATIN1LIST:
    size = 0;
    for (i = 0; i < field->latin1list.nstrings; ++i) {
      size += id3_render_latin1(ptr, field->latin1list.strings[i],
				(i < field->latin1list.nstrings - 1) ||
				terminate);
    }
    return size;

  case ID3_FIELD_TYPE_STRING:
  case ID3_FIELD_TYPE_STRINGFULL:
    return id3_render_string(ptr, field->string.ptr, *encoding, terminate);

  case ID3_FIELD_TYPE_STRINGLIST:
    size = 0;
    for (i = 0; i < field->stringlist.nstrings; ++i) {
      size += id3_render_string(ptr, field->stringlist.strings[i], *encoding,
				(i < field->stringlist.nstrings - 1) ||
				terminate);
    }
    return size;

  case ID3_FIELD_TYPE_LANGUAGE:
    return id3_render_immediate(ptr, field->immediate.value, 3);

  case ID3_FIELD_TYPE_FRAMEID:
    return id3_render_immediate(ptr, field->immediate.value, 4);

  case ID3_FIELD_TYPE_DATE:
    return id3_render_immediate(ptr, field->immediate.value, 8);

  case ID3_FIELD_TYPE_INT32PLUS:
  case ID3_FIELD_TYPE_BINARYDATA:
    return id3_render_binary(ptr, field->binary.data, field->binary.length);
  }

  return 0;
}

/*
 * NAME:	field->setint()
 * DESCRIPTION:	set the value of an int field
 */
int id3_field_setint(union id3_field *field, signed long number)
{
  assert(field);

  switch (field->type) {
  case ID3_FIELD_TYPE_INT8:
    if (number > 0x7f || number < -0x80)
      return -1;
    break;

  case ID3_FIELD_TYPE_INT16:
    if (number > 0x7fff || number < -0x8000)
      return -1;
    break;

  case ID3_FIELD_TYPE_INT24:
    if (number > 0x7fffffL || number < -0x800000L)
      return -1;
    break;

  case ID3_FIELD_TYPE_INT32:
    if (number > 0x7fffffffL || number < -0x80000000L)
      return -1;
    break;

  default:
    return -1;
  }

  id3_field_finish(field);

  field->number.value = number;

  return 0;
}

/*
 * NAME:	field->settextencoding()
 * DESCRIPTION:	set the value of a textencoding field

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -