diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-03-15 23:10:01 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2009-03-15 23:10:01 +0200 |
commit | 3a27428194f866050472b0f7c7b9e55b19cec230 (patch) | |
tree | 0207e9f21036bcb1b2a7fe3edf11b9ad761e2768 /src/idop.c | |
parent | f6c2e714cc84ad327cf661967cdb024f835dd1c1 (diff) | |
download | idest-3a27428194f866050472b0f7c7b9e55b19cec230.tar.gz idest-3a27428194f866050472b0f7c7b9e55b19cec230.tar.bz2 |
Remove old v1 code. Add an option for converting tags to v1.
* libid3tag/file.c (SIZE_T_MAX): Rename to MALLOC_MAX. Use (size_t_max-1),
due to a bug in glibc's malloc.
(make_temp_file): Fix size calculation (memory overrun).
(v2_write): data and/or length can be 0.
(id3_file_update): Drop v2 header, if ID3_TAG_OPTION_NO_ID3V2 is set.
* libid3tag/id3tag.h (ID3_TAG_OPTION_NO_ID3V2): New constant.
* src/id3v1.c, src/id3v1.h: Remove.
* src/id3v2.c: Rename to...
* src/idop.c: ... this.
(set_tags): Handle convert_version and version_option.
* src/Makefile.am: Reflect the above.
* src/cmdline.opt (--convert, -C): New option.
* src/idest.h: Kick off id3v1.h.
(convert_version, version_option): new externs.
(set_id3v1, query_id3v1, del_id3v1)
(set_id3v2, query_id3v2, del_id3v2): Remove.
(set_tags, query_tags, del_tags): New prototypes.
* src/main.c (convert_version): New variable.
(query_id3): use all_frames to determine ed_list.
(set_id3): Remove old v1 code.
(main): Remove old v1 code.
Diffstat (limited to 'src/idop.c')
-rw-r--r-- | src/idop.c | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/src/idop.c b/src/idop.c new file mode 100644 index 0000000..76a5b0d --- /dev/null +++ b/src/idop.c @@ -0,0 +1,233 @@ +/* This file is part of Idest. + Copyright (C) 2009 Sergey Poznyakoff + + Idest 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 3, or (at your option) + any later version. + + Idest 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 Idest. If not, see <http://www.gnu.org/licenses/>. */ + +#include "idest.h" + +void +set_frame_value(struct id3_frame *frame, const char *value) +{ + union id3_field *field; + enum id3_field_textencoding encoding = + (latin1_option ? ID3_FIELD_TEXTENCODING_ISO_8859_1 + : ID3_FIELD_TEXTENCODING_UTF_8); + id3_ucs4_t *ucs4; + + switch (frame_id(frame->id)) { + case item_title: + case item_artist: + case item_album: + case item_year: + case item_track: + case item_genre: + field = id3_frame_field(frame, 0); + id3_field_settextencoding(field, encoding); + + if (latin1_option) + ucs4 = id3_latin1_ucs4duplicate( + (const id3_latin1_t *) value); + else + ucs4 = id3_utf8_ucs4duplicate( + (const id3_utf8_t *)value); + + field = id3_frame_field(frame, 1); + id3_field_setstrings(field, 1, &ucs4); + free(ucs4); + break; + + case item_comment: + /* Field 0: Encoding */ + field = id3_frame_field(frame, 0); + id3_field_settextencoding(field, encoding); + /* FIXME: Field 1: Language */ + /* FIXME: Field 2: String */ + /* Field 3: Comment */ + field = id3_frame_field(frame, 3); + if (latin1_option) + ucs4 = id3_latin1_ucs4duplicate( + (const id3_latin1_t *) value); + else + ucs4 = id3_utf8_ucs4duplicate( + (const id3_utf8_t *)value); + id3_field_setfullstring(field, ucs4); + free(ucs4); + break; + + default: + error(1, 0, "don't know how to set field %s", frame->id); + } +} + +void +set_tags(const char *name) +{ + struct id3_file *file; + struct id3_tag *tag; + + file = id3_file_open(name, ID3_FILE_MODE_READWRITE); + if (!file) + error(1, errno, "cannot open file %s", name); + tag = id3_file_tag(file); + if (!tag) + abort(); /* FIXME */ + + if (ed_list) { + gl_list_iterator_t itr; + const void *p; + + itr = gl_list_iterator(ed_list); + while (gl_list_iterator_next(&itr, &p, NULL)) { + const struct ed_item *item = p; + struct id3_frame *frame + = id3_tag_findframe(tag, item->id, 0); + if (!frame) { + frame = id3_frame_new(item->id); + if (id3_tag_attachframe(tag, frame)) + error(1, 0, "cannot attach new frame"); + } + set_frame_value(frame, item->v.value); + } + gl_list_iterator_free(&itr); + } + + if (convert_version == 1) { + id3_tag_options(tag, + ID3_TAG_OPTION_NO_ID3V2, + ID3_TAG_OPTION_NO_ID3V2); + version_option = 1; + } + + if (version_option == 1) + id3_tag_options(tag, ID3_TAG_OPTION_ID3V1, ID3_TAG_OPTION_ID3V1); + + id3_file_update(file); + id3_file_close(file); +} + + +char * +ucs4_cvt(id3_ucs4_t const *ucs4) +{ + if (latin1_option) + return (char*)id3_ucs4_latin1duplicate(ucs4); + else + return (char*)id3_ucs4_utf8duplicate(ucs4); +} + +void +add_stringlist(gl_list_t list, struct id3_frame *frame, + union id3_field *field) +{ + unsigned i, nstrings = id3_field_getnstrings(field); + for (i = 0; i < nstrings; i++) { + id3_ucs4_t const *ucs4; + char *str; + + ucs4 = id3_field_getstrings(field, i); + if (!ucs4) + continue; + if (strcmp(frame->id, ID3_FRAME_GENRE) == 0) + ucs4 = id3_genre_name(ucs4); + str = ucs4_cvt(ucs4); + gl_list_add_last(list, str); + } +} + +void +add_field(gl_list_t list, struct id3_frame *frame, union id3_field *field) +{ + id3_ucs4_t const *ucs4; + char *str; + + switch (id3_field_type(field)) { + case ID3_FIELD_TYPE_TEXTENCODING: + break; + case ID3_FIELD_TYPE_LATIN1: + case ID3_FIELD_TYPE_LATIN1FULL: + case ID3_FIELD_TYPE_LATIN1LIST: + break; + case ID3_FIELD_TYPE_STRING: + break; + case ID3_FIELD_TYPE_STRINGFULL: + ucs4 = id3_field_getfullstring(field); + str = ucs4_cvt(ucs4); + gl_list_add_last(list, str); + break; + case ID3_FIELD_TYPE_STRINGLIST: + add_stringlist(list, frame, field); + break; + case ID3_FIELD_TYPE_LANGUAGE: + case ID3_FIELD_TYPE_FRAMEID: + case ID3_FIELD_TYPE_DATE: + case ID3_FIELD_TYPE_INT8: + case ID3_FIELD_TYPE_INT16: + case ID3_FIELD_TYPE_INT24: + case ID3_FIELD_TYPE_INT32: + case ID3_FIELD_TYPE_INT32PLUS: + case ID3_FIELD_TYPE_BINARYDATA:; + } +} + +gl_list_t +frame_to_list(struct id3_frame *frame) +{ + gl_list_t list; + unsigned i, j, nstrings; + union id3_field *field; + + list = new_string_list(true); + for (i = 0; field = id3_frame_field(frame, i); i++) + add_field(list, frame, field); + return list; +} + +static void +show_tags(struct id3_tag *tag) +{ + struct id3_frame *frame; + unsigned i; + + for (i = 0; frame = id3_tag_findframe(tag, NULL, i); i++) { + gl_list_t list = frame_to_list(frame); + if (gl_list_size(list) > 0) + ed_list_add_item(frame->id, list); + else + gl_list_free(list); + } + ed_list_print(); + ed_list_clear(); +} + +void +query_tags(const char *name) +{ + struct id3_file *file; + struct id3_tag *tag; + + file = id3_file_open(name, ID3_FILE_MODE_READONLY); + if (!file) + error(1, errno, "cannot open file %s", name); + + tag = id3_file_tag(file); + if (tag) + show_tags(tag); + + id3_file_close(file); +} + +void +del_id3v2(const char *name) +{ +} |