taglib-ruby 0.4.0-x86-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. data/.yardopts +9 -0
  2. data/CHANGES.md +53 -0
  3. data/Gemfile +4 -0
  4. data/Guardfile +8 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +87 -0
  7. data/Rakefile +29 -0
  8. data/docs/default/fulldoc/html/css/common.css +1 -0
  9. data/docs/taglib/base.rb +202 -0
  10. data/docs/taglib/id3v1.rb +5 -0
  11. data/docs/taglib/id3v2.rb +444 -0
  12. data/docs/taglib/mpeg.rb +120 -0
  13. data/docs/taglib/ogg.rb +77 -0
  14. data/docs/taglib/vorbis.rb +62 -0
  15. data/ext/extconf_common.rb +29 -0
  16. data/ext/taglib_base/extconf.rb +4 -0
  17. data/ext/taglib_base/includes.i +115 -0
  18. data/ext/taglib_base/taglib_base.i +139 -0
  19. data/ext/taglib_base/taglib_base_wrap.cxx +5153 -0
  20. data/ext/taglib_id3v1/extconf.rb +4 -0
  21. data/ext/taglib_id3v1/taglib_id3v1.i +11 -0
  22. data/ext/taglib_id3v1/taglib_id3v1_wrap.cxx +3110 -0
  23. data/ext/taglib_id3v2/extconf.rb +4 -0
  24. data/ext/taglib_id3v2/relativevolumeframe.i +35 -0
  25. data/ext/taglib_id3v2/taglib_id3v2.i +112 -0
  26. data/ext/taglib_id3v2/taglib_id3v2_wrap.cxx +9033 -0
  27. data/ext/taglib_mpeg/extconf.rb +4 -0
  28. data/ext/taglib_mpeg/taglib_mpeg.i +75 -0
  29. data/ext/taglib_mpeg/taglib_mpeg_wrap.cxx +4726 -0
  30. data/ext/taglib_ogg/extconf.rb +4 -0
  31. data/ext/taglib_ogg/taglib_ogg.i +36 -0
  32. data/ext/taglib_ogg/taglib_ogg_wrap.cxx +3631 -0
  33. data/ext/taglib_vorbis/extconf.rb +4 -0
  34. data/ext/taglib_vorbis/taglib_vorbis.i +48 -0
  35. data/ext/taglib_vorbis/taglib_vorbis_wrap.cxx +3083 -0
  36. data/ext/valgrind-suppressions.txt +170 -0
  37. data/ext/win.cmake +5 -0
  38. data/lib/libtag.dll +0 -0
  39. data/lib/taglib.rb +14 -0
  40. data/lib/taglib/base.rb +19 -0
  41. data/lib/taglib/id3v1.rb +1 -0
  42. data/lib/taglib/id3v2.rb +20 -0
  43. data/lib/taglib/mpeg.rb +7 -0
  44. data/lib/taglib/ogg.rb +1 -0
  45. data/lib/taglib/version.rb +10 -0
  46. data/lib/taglib/vorbis.rb +7 -0
  47. data/lib/taglib_base.so +0 -0
  48. data/lib/taglib_id3v1.so +0 -0
  49. data/lib/taglib_id3v2.so +0 -0
  50. data/lib/taglib_mpeg.so +0 -0
  51. data/lib/taglib_ogg.so +0 -0
  52. data/lib/taglib_vorbis.so +0 -0
  53. data/taglib-ruby.gemspec +122 -0
  54. data/tasks/docs_coverage.rake +26 -0
  55. data/tasks/ext.rake +81 -0
  56. data/tasks/gemspec_check.rake +19 -0
  57. data/tasks/swig.rake +43 -0
  58. data/test/data/Makefile +15 -0
  59. data/test/data/add-relative-volume.cpp +40 -0
  60. data/test/data/crash.mp3 +0 -0
  61. data/test/data/globe_east_540.jpg +0 -0
  62. data/test/data/id3v1-create.cpp +31 -0
  63. data/test/data/id3v1.mp3 +0 -0
  64. data/test/data/relative-volume.mp3 +0 -0
  65. data/test/data/sample.mp3 +0 -0
  66. data/test/data/unicode.mp3 +0 -0
  67. data/test/data/vorbis-create.cpp +42 -0
  68. data/test/data/vorbis.oga +0 -0
  69. data/test/fileref_open_test.rb +32 -0
  70. data/test/fileref_properties_test.rb +21 -0
  71. data/test/fileref_write_test.rb +62 -0
  72. data/test/helper.rb +10 -0
  73. data/test/id3v1_tag_test.rb +36 -0
  74. data/test/id3v2_frames_test.rb +115 -0
  75. data/test/id3v2_memory_test.rb +87 -0
  76. data/test/id3v2_relative_volume_test.rb +62 -0
  77. data/test/id3v2_tag_test.rb +59 -0
  78. data/test/id3v2_unicode_test.rb +47 -0
  79. data/test/id3v2_write_test.rb +100 -0
  80. data/test/mpeg_file_test.rb +76 -0
  81. data/test/tag_test.rb +21 -0
  82. data/test/unicode_filename_test.rb +29 -0
  83. data/test/vorbis_file_test.rb +54 -0
  84. data/test/vorbis_tag_test.rb +79 -0
  85. metadata +191 -0
@@ -0,0 +1,120 @@
1
+ module TagLib::MPEG
2
+ # The file class for `.mp3` and other MPEG files.
3
+ #
4
+ # @example Reading a title
5
+ # title = TagLib::MPEG::File.open("file.mp3") do |file|
6
+ # tag = file.tag
7
+ # tag.title
8
+ # end
9
+ #
10
+ class File < TagLib::File
11
+ # {include:TagLib::FileRef.open}
12
+ #
13
+ # @param (see #initialize)
14
+ # @yield [file] the {File} object, as obtained by {#initialize}
15
+ # @return the return value of the block
16
+ #
17
+ # @since 0.4.0
18
+ def self.open(filename, read_properties=true)
19
+ end
20
+
21
+ # Load an MPEG file.
22
+ #
23
+ # @param [String] filename
24
+ # @param [Boolean] read_properties if audio properties should be
25
+ # read
26
+ def initialize(filename, read_properties=true)
27
+ end
28
+
29
+ # Returns a tag that contains attributes from both the ID3v2 and
30
+ # ID3v1 tag, with ID3v2 attributes having precendence.
31
+ #
32
+ # @return [TagLib::Tag]
33
+ # @return [nil] if not present
34
+ def tag
35
+ end
36
+
37
+ # Returns the ID3v1 tag.
38
+ #
39
+ # @param create if a new tag should be created when none exists
40
+ # @return [TagLib::ID3v1::Tag]
41
+ # @return [nil] if not present
42
+ def id3v1_tag(create=false)
43
+ end
44
+
45
+ # Returns the ID3v2 tag.
46
+ #
47
+ # @param create if a new tag should be created when none exists
48
+ # @return [TagLib::ID3v2::Tag]
49
+ # @return [nil] if not present
50
+ def id3v2_tag(create=false)
51
+ end
52
+
53
+ # Returns audio properties.
54
+ #
55
+ # @return [TagLib::MPEG::Properties]
56
+ def audio_properties
57
+ end
58
+ end
59
+
60
+ # Audio properties for MPEG files.
61
+ class Properties < TagLib::AudioProperties
62
+ # @return [TagLib::MPEG::XingHeader] Xing header
63
+ # @return [nil] if not present
64
+ def xing_header
65
+ end
66
+
67
+ # @return [TagLib::MPEG::Header constant] MPEG version,
68
+ # e.g. {TagLib::MPEG::Header::Version1}
69
+ def version
70
+ end
71
+
72
+ # @return [Integer] MPEG layer (1-3)
73
+ def layer
74
+ end
75
+
76
+ # @return [true] if MPEG protection bit is set
77
+ def protection_enabled
78
+ end
79
+
80
+ # @return [TagLib::MPEG::Header constant] channel mode,
81
+ # e.g. {TagLib::MPEG::Header::JointStereo}
82
+ def channel_mode
83
+ end
84
+
85
+ # @return [true] if copyrighted bit is set
86
+ def copyrighted?
87
+ end
88
+
89
+ # @return [true] if original bit is set
90
+ def original?
91
+ end
92
+ end
93
+
94
+ # MPEG header.
95
+ class Header
96
+ Version1 = 0
97
+ Version2 = 1
98
+ Version2_5 = 2
99
+
100
+ Stereo = 0
101
+ JointStereo = 1
102
+ DualChannel = 2
103
+ SingleChannel = 3
104
+ end
105
+
106
+ # Xing VBR header.
107
+ class XingHeader
108
+ # @return [true] if a valid Xing header is present
109
+ def valid?
110
+ end
111
+
112
+ # @return [Integer] total number of frames
113
+ def total_frames
114
+ end
115
+
116
+ # @return [Integer] total size of stream in bytes
117
+ def total_size
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,77 @@
1
+ module TagLib::Ogg
2
+
3
+ # @abstract Base class for Ogg files, see subclasses.
4
+ class File < TagLib::File
5
+ end
6
+
7
+ # Xiph comments (aka VorbisComment), a metadata format used for Ogg
8
+ # Vorbis and other codecs.
9
+ #
10
+ # A Xiph comment is structured as a set of fields. Each field has a
11
+ # name and a value. Multiple fields with the same name are allowed, so
12
+ # you can also view it as a map from names to a list of values.
13
+ class XiphComment < TagLib::Tag
14
+
15
+ # Add a name-value pair to the comment.
16
+ #
17
+ # @param [String] name field name
18
+ # @param [String] value field value
19
+ # @param [Boolean] replace if true, all existing fields with the
20
+ # given name will be replaced
21
+ # @return [void]
22
+ def add_field(name, value, replace=true)
23
+ end
24
+
25
+ # Check if the comment contains a field.
26
+ #
27
+ # @param [String] name field name
28
+ # @return [Boolean]
29
+ def contains?(name)
30
+ end
31
+
32
+ # Count the number of fields.
33
+ #
34
+ # @return [Integer] the number of fields in the comment (name-value
35
+ # pairs)
36
+ def field_count
37
+ end
38
+
39
+ # Get the contents of the comment as a hash, with the key being a
40
+ # field name String and the value a list of field values for that
41
+ # key. Example result:
42
+ #
43
+ # { 'TITLE' => ["Title"],
44
+ # 'GENRE' => ["Rock", "Pop"] }
45
+ #
46
+ # Note that the returned hash is read-only. Changing it will have no
47
+ # effect on the comment; use {#add_field} and {#remove_field} for
48
+ # that.
49
+ #
50
+ # @return [Hash<String, Array<String>>] a hash from field names to
51
+ # value lists
52
+ def field_list_map
53
+ end
54
+
55
+ # Remove one or more fields.
56
+ #
57
+ # @overload remove_field(name)
58
+ # Removes all fields with the given name.
59
+ #
60
+ # @param [String] name field name
61
+ #
62
+ # @overload remove_field(name, value)
63
+ # Removes the field with the given name and value.
64
+ #
65
+ # @param [String] name field name
66
+ # @param [String] value field value
67
+ #
68
+ # @return [void]
69
+ def remove_field
70
+ end
71
+
72
+ # @return [String] vendor ID of the encoder used
73
+ attr_reader :vendor_id
74
+
75
+ end
76
+
77
+ end
@@ -0,0 +1,62 @@
1
+ module TagLib::Ogg::Vorbis
2
+
3
+ # The file class for `.ogg` and other `.oga` files.
4
+ #
5
+ # @example Reading Vorbis comments
6
+ # TagLib::Ogg::Vorbis::File.open("file.oga") do |file|
7
+ # tag = file.tag
8
+ # puts tag.title
9
+ # fields = tag.field_list_map
10
+ # puts fields['DATE']
11
+ # end
12
+ #
13
+ class File < TagLib::Ogg::File
14
+ # {include:TagLib::FileRef.open}
15
+ #
16
+ # @param (see #initialize)
17
+ # @yield [file] the {File} object, as obtained by {#initialize}
18
+ # @return the return value of the block
19
+ #
20
+ # @since 0.4.0
21
+ def self.open(filename, read_properties=true)
22
+ end
23
+
24
+ # Load an Ogg Vorbis file.
25
+ #
26
+ # @param [String] filename
27
+ # @param [Boolean] read_properties if audio properties should be
28
+ # read
29
+ def initialize(filename, read_properties=true)
30
+ end
31
+
32
+ # Returns the VorbisComment tag.
33
+ #
34
+ # @return [TagLib::Ogg::XiphComment]
35
+ def tag
36
+ end
37
+
38
+ # Returns audio properties.
39
+ #
40
+ # @return [TagLib::Ogg::Vorbis::Properties]
41
+ def audio_properties
42
+ end
43
+ end
44
+
45
+ # Ogg Vorbis audio properties.
46
+ class Properties < TagLib::AudioProperties
47
+ # @return [Integer] Vorbis version
48
+ attr_reader :vorbis_version
49
+
50
+ # @return [Integer] maximum bitrate from Vorbis identification
51
+ # header
52
+ attr_reader :bitrate_maximum
53
+
54
+ # @return [Integer] nominal bitrate from Vorbis identification
55
+ # header
56
+ attr_reader :bitrate_nominal
57
+
58
+ # @return [Integer] minimum bitrate from Vorbis identification
59
+ # header
60
+ attr_reader :bitrate_minimum
61
+ end
62
+ end
@@ -0,0 +1,29 @@
1
+ # Default opt dirs to help mkmf find taglib
2
+ configure_args = "--with-opt-dir=/usr/local:/opt/local:/sw "
3
+ ENV['CONFIGURE_ARGS'] = configure_args + ENV.fetch('CONFIGURE_ARGS', "")
4
+
5
+ require 'mkmf'
6
+
7
+ def error msg
8
+ message msg + "\n"
9
+ abort
10
+ end
11
+
12
+ dir_config('tag')
13
+
14
+ if not have_library('stdc++')
15
+ error "You must have libstdc++ installed."
16
+ end
17
+
18
+ if not have_library('tag')
19
+ error <<-DESC
20
+ You must have taglib installed in order to use taglib-ruby.
21
+
22
+ Debian/Ubuntu: sudo apt-get install libtag1-dev
23
+ Fedora/RHEL: sudo yum install taglib-devel
24
+ Brew: brew install taglib
25
+ MacPorts: sudo port install taglib
26
+ DESC
27
+ end
28
+
29
+ $CFLAGS << " -DSWIG_TYPE_TABLE=taglib"
@@ -0,0 +1,4 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..'))
2
+ require 'extconf_common'
3
+
4
+ create_makefile('taglib_base')
@@ -0,0 +1,115 @@
1
+ %trackobjects;
2
+
3
+ // Undefine macros we don't need for wrapping
4
+ #define TAGLIB_EXPORT
5
+ #define TAGLIB_IGNORE_MISSING_DESTRUCTOR
6
+
7
+ // Replaces the typemap from swigtype.swg and just adds the line
8
+ // SWIG_RubyUnlinkObjects. This is done to be safe in the case when a
9
+ // disowned object is deleted by C++ (e.g. with remove_frame).
10
+ %typemap(in, noblock=1) SWIGTYPE *DISOWN (int res = 0) {
11
+ res = SWIG_ConvertPtr($input, %as_voidptrptr(&$1), $descriptor, SWIG_POINTER_DISOWN | %convertptr_flags);
12
+ if (!SWIG_IsOK(res)) {
13
+ %argument_fail(res,"$type", $symname, $argnum);
14
+ }
15
+ SWIG_RubyUnlinkObjects(%as_voidptr($1));
16
+ }
17
+
18
+ %{
19
+ #include <taglib/tstring.h>
20
+ #include <taglib/tstringlist.h>
21
+ #include <taglib/tfile.h>
22
+
23
+ #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
24
+ # include <ruby/encoding.h>
25
+ # define ASSOCIATE_UTF8_ENCODING(value) rb_enc_associate(value, rb_utf8_encoding());
26
+ # define CONVERT_TO_UTF8(value) rb_str_export_to_enc(value, rb_utf8_encoding())
27
+ #else
28
+ # define ASSOCIATE_UTF8_ENCODING(value) /* nothing */
29
+ # define CONVERT_TO_UTF8(value) value
30
+ #endif
31
+
32
+ VALUE taglib_bytevector_to_ruby_string(const TagLib::ByteVector &byteVector) {
33
+ if (byteVector.isNull()) {
34
+ return Qnil;
35
+ } else {
36
+ return rb_tainted_str_new(byteVector.data(), byteVector.size());
37
+ }
38
+ }
39
+
40
+ TagLib::ByteVector ruby_string_to_taglib_bytevector(VALUE s) {
41
+ return TagLib::ByteVector(RSTRING_PTR(s), RSTRING_LEN(s));
42
+ }
43
+
44
+ VALUE taglib_string_to_ruby_string(const TagLib::String & string) {
45
+ if (string.isNull()) {
46
+ return Qnil;
47
+ } else {
48
+ VALUE result = rb_tainted_str_new2(string.toCString(true));
49
+ ASSOCIATE_UTF8_ENCODING(result);
50
+ return result;
51
+ }
52
+ }
53
+
54
+ TagLib::String ruby_string_to_taglib_string(VALUE s) {
55
+ return TagLib::String(RSTRING_PTR(CONVERT_TO_UTF8(s)), TagLib::String::UTF8);
56
+ }
57
+
58
+ VALUE taglib_string_list_to_ruby_array(const TagLib::StringList & list) {
59
+ VALUE ary = rb_ary_new2(list.size());
60
+ for (TagLib::StringList::ConstIterator it = list.begin(); it != list.end(); it++) {
61
+ VALUE s = taglib_string_to_ruby_string(*it);
62
+ rb_ary_push(ary, s);
63
+ }
64
+ return ary;
65
+ }
66
+
67
+ TagLib::StringList ruby_array_to_taglib_string_list(VALUE ary) {
68
+ TagLib::StringList result = TagLib::StringList();
69
+ for (long i = 0; i < RARRAY_LEN(ary); i++) {
70
+ VALUE e = RARRAY_PTR(ary)[i];
71
+ TagLib::String s = ruby_string_to_taglib_string(e);
72
+ result.append(s);
73
+ }
74
+ return result;
75
+ }
76
+
77
+ VALUE taglib_filename_to_ruby_string(TagLib::FileName filename) {
78
+ #ifdef _WIN32
79
+ const char *s = (const char *) filename;
80
+ return rb_tainted_str_new2(s);
81
+ #else
82
+ return rb_tainted_str_new2(filename);
83
+ #endif
84
+ }
85
+
86
+ TagLib::FileName ruby_string_to_taglib_filename(VALUE s) {
87
+ #ifdef _WIN32
88
+ #if defined(HAVE_RUBY_ENCODING_H) && HAVE_RUBY_ENCODING_H
89
+ VALUE ospath;
90
+ const char *utf8;
91
+ int len;
92
+ wchar_t *wide;
93
+
94
+ ospath = rb_str_encode_ospath(s);
95
+ utf8 = StringValuePtr(ospath);
96
+ len = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0);
97
+ if (!(wide = (wchar_t *) xmalloc(sizeof(wchar_t) * len))) {
98
+ return TagLib::FileName((const char *) NULL);
99
+ }
100
+ MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wide, len);
101
+ TagLib::FileName filename(wide);
102
+ xfree(wide);
103
+ return filename;
104
+ #else
105
+ const char *filename = StringValuePtr(s);
106
+ return TagLib::FileName(filename);
107
+ #endif
108
+ #else
109
+ return StringValuePtr(s);
110
+ #endif
111
+ }
112
+
113
+ %}
114
+
115
+ // vim: set filetype=cpp sw=2 ts=2 expandtab:
@@ -0,0 +1,139 @@
1
+ %module "TagLib"
2
+ %{
3
+ #include <taglib/taglib.h>
4
+ #include <taglib/tbytevector.h>
5
+ #include <taglib/tlist.h>
6
+ #include <taglib/fileref.h>
7
+ #include <taglib/tag.h>
8
+ %}
9
+
10
+ %include "includes.i"
11
+
12
+ namespace TagLib {
13
+ class StringList;
14
+ class ByteVector;
15
+
16
+ class String {
17
+ public:
18
+ enum Type { Latin1 = 0, UTF16 = 1, UTF16BE = 2, UTF8 = 3, UTF16LE = 4 };
19
+ };
20
+
21
+ class FileName;
22
+
23
+ typedef wchar_t wchar;
24
+ typedef unsigned char uchar;
25
+ typedef unsigned int uint;
26
+ typedef unsigned long ulong;
27
+ }
28
+
29
+
30
+ // Rename setters to Ruby convention (combining SWIG rename functions
31
+ // does not seem to be possible, thus resort to some magic)
32
+ %rename("%(command: ruby -e 'print(ARGV[0][3..-1].split(/(?=[A-Z])/).join(\"_\").downcase + \"=\")' )s",
33
+ regexmatch$name="^set[A-Z]") "";
34
+
35
+ // isFoo -> foo?
36
+ %rename("%(command: ruby -e 'print(ARGV[0][2..-1].split(/(?=[A-Z])/).join(\"_\").downcase + \"?\")' )s",
37
+ regexmatch$name="^is[A-Z]") "";
38
+
39
+ // ByteVector
40
+ %typemap(out) TagLib::ByteVector {
41
+ $result = taglib_bytevector_to_ruby_string($1);
42
+ }
43
+ %typemap(out) TagLib::ByteVector * {
44
+ $result = taglib_bytevector_to_ruby_string(*($1));
45
+ }
46
+ %typemap(in) TagLib::ByteVector & (TagLib::ByteVector tmp) {
47
+ tmp = ruby_string_to_taglib_bytevector($input);
48
+ $1 = &tmp;
49
+ }
50
+ %typemap(in) TagLib::ByteVector * (TagLib::ByteVector tmp) {
51
+ tmp = ruby_string_to_taglib_bytevector($input);
52
+ $1 = &tmp;
53
+ }
54
+ %typemap(typecheck) const TagLib::ByteVector & = char *;
55
+
56
+ // String
57
+ %typemap(out) TagLib::String {
58
+ $result = taglib_string_to_ruby_string($1);
59
+ }
60
+ // tmp is used for having a local variable that is destroyed at the end
61
+ // of the function. Doing "new TagLib::String" would be a big no-no.
62
+ %typemap(in) TagLib::String (TagLib::String tmp) {
63
+ tmp = ruby_string_to_taglib_string($input);
64
+ $1 = &tmp;
65
+ }
66
+ %typemap(typecheck) TagLib::String = char *;
67
+ %apply TagLib::String { TagLib::String &, const TagLib::String & };
68
+
69
+ // StringList
70
+ %typemap(out) TagLib::StringList {
71
+ $result = taglib_string_list_to_ruby_array($1);
72
+ }
73
+ %typemap(in) TagLib::StringList (TagLib::StringList tmp) {
74
+ tmp = ruby_array_to_taglib_string_list($input);
75
+ $1 = &tmp;
76
+ }
77
+ %apply TagLib::StringList { TagLib::StringList &, const TagLib::StringList & };
78
+
79
+ %typemap(out) TagLib::FileName {
80
+ $result = taglib_filename_to_ruby_string($1);
81
+ }
82
+ %typemap(in) TagLib::FileName {
83
+ $1 = ruby_string_to_taglib_filename($input);
84
+ if ((const char *)(TagLib::FileName)($1) == NULL) {
85
+ SWIG_exception_fail(SWIG_MemoryError, "Failed to allocate memory for file name.");
86
+ }
87
+ }
88
+ %typemap(typecheck) TagLib::FileName = char *;
89
+ %feature("valuewrapper") TagLib::FileName;
90
+
91
+ %ignore TagLib::List::operator[];
92
+ %ignore TagLib::List::operator=;
93
+ %include <taglib/tlist.h>
94
+
95
+ %include <taglib/tag.h>
96
+
97
+ %include <taglib/audioproperties.h>
98
+
99
+ %ignore TagLib::FileName;
100
+ %include <taglib/tfile.h>
101
+
102
+ %ignore TagLib::FileRef::operator=;
103
+ %ignore TagLib::FileRef::operator!=;
104
+ %warnfilter(SWIGWARN_PARSE_NAMED_NESTED_CLASS) TagLib::FileRef::FileTypeResolver;
105
+ %include <taglib/fileref.h>
106
+
107
+ %begin %{
108
+ static void free_taglib_fileref(void *ptr);
109
+ %}
110
+ %header %{
111
+ static void free_taglib_fileref(void *ptr) {
112
+ TagLib::FileRef *fileref = (TagLib::FileRef *) ptr;
113
+
114
+ TagLib::Tag *tag = fileref->tag();
115
+ if (tag) {
116
+ SWIG_RubyUnlinkObjects(tag);
117
+ SWIG_RubyRemoveTracking(tag);
118
+ }
119
+
120
+ TagLib::AudioProperties *properties = fileref->audioProperties();
121
+ if (properties) {
122
+ SWIG_RubyUnlinkObjects(properties);
123
+ SWIG_RubyRemoveTracking(properties);
124
+ }
125
+
126
+ SWIG_RubyUnlinkObjects(ptr);
127
+ SWIG_RubyRemoveTracking(ptr);
128
+
129
+ delete fileref;
130
+ }
131
+ %}
132
+
133
+ %extend TagLib::FileRef {
134
+ void close() {
135
+ free_taglib_fileref($self);
136
+ }
137
+ }
138
+
139
+ // vim: set filetype=cpp sw=2 ts=2 expandtab: