id3lib-ruby 0.3.1 → 0.4.0

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.
data/CHANGES CHANGED
@@ -1,5 +1,11 @@
1
1
  = id3lib-ruby changes
2
2
 
3
+ === 0.4.0 (r41)
4
+
5
+ * Fixed Unicode problems (bug 4768).
6
+ * Renamed ID3Lib::API methods to be more like the id3lib method names.
7
+ For example, the GetType() method is now named get_type instead of type.
8
+
3
9
  === 0.3.1 (r32)
4
10
 
5
11
  * Added check and messages for -lstdc++ and -lz to extconf.rb.
data/Rakefile CHANGED
@@ -10,15 +10,22 @@ require 'rake/testtask'
10
10
  require 'rake/rdoctask'
11
11
 
12
12
 
13
- PKG_VERSION = '0.3.1'
13
+ PKG_VERSION = '0.4.0'
14
14
 
15
- PKG_COMMON = FileList[
15
+ FILES_COMMON = FileList[
16
16
  'lib/**/*.rb',
17
17
  'test/test_*.rb',
18
18
  'test/data/*.mp3',
19
19
  'test/data/cover.jpg',
20
20
  'Rakefile',
21
- 'setup.rb'
21
+ '*.rb'
22
+ ]
23
+
24
+ FILES_EXT = FileList[
25
+ 'ext/*.rb',
26
+ 'ext/*.cxx',
27
+ 'ext/*.i',
28
+ 'ext/Rakefile'
22
29
  ]
23
30
 
24
31
 
@@ -42,7 +49,7 @@ Rake::TestTask.new do |t|
42
49
  end
43
50
 
44
51
 
45
- RDOC_OPTS = ['--line-numbers', '--main', 'README']
52
+ RDOC_OPTS = ['--inline-source', '--line-numbers', '--main', 'README']
46
53
 
47
54
  desc "Generate RDOC documentation."
48
55
  Rake::RDocTask.new :rdoc do |rdoc|
@@ -63,7 +70,7 @@ if defined? Gem
63
70
  'id3lib-ruby provides a Ruby interface to the id3lib C++ library for ' +
64
71
  'easily editing ID3 tags (v1 and v2) like with pyid3lib.'
65
72
  s.requirements << 'id3lib C++ library'
66
- s.files = PKG_COMMON + FileList['ext/extconf.rb', 'ext/*.cxx']
73
+ s.files = FILES_COMMON + FILES_EXT
67
74
  s.extensions = ['ext/extconf.rb']
68
75
  s.test_files = FileList['test/test_*.rb']
69
76
  s.has_rdoc = true
@@ -81,7 +88,7 @@ if defined? Gem
81
88
  end
82
89
 
83
90
  spec_mswin32 = spec.clone
84
- spec_mswin32.files = PKG_COMMON + FileList['ext/mswin32/id3lib_api.so']
91
+ spec_mswin32.files = FILES_COMMON + FileList['ext/mswin32/id3lib_api.so']
85
92
  spec_mswin32.extensions = []
86
93
  spec_mswin32.require_paths = ['lib', 'ext/mswin32']
87
94
  spec_mswin32.platform = Gem::Platform::WIN32
@@ -99,14 +106,15 @@ end # defined? Gem
99
106
  task :web => [:web_doc] do
100
107
  puts "# Now execute the following:"
101
108
  puts "scp web/* robinstocker@rubyforge.org:/var/www/gforge-projects/id3lib-ruby/"
102
- puts "scp -r web/doc robinstocker@rubyforge.org:/var/www/gforge-projects/id3lib-ruby/doc"
109
+ puts "scp -r web/doc robinstocker@rubyforge.org:/var/www/gforge-projects/id3lib-ruby/"
103
110
  end
104
111
 
105
112
  desc "Generate RDOC documentation on web."
106
113
  Rake::RDocTask.new :web_doc do |rdoc|
107
114
  rdoc.rdoc_dir = 'web/doc'
108
115
  rdoc.title = 'id3lib-ruby'
109
- rdoc.options << '--line-numbers' << '--main' << 'ID3Lib::Tag'
116
+ rdoc.options = RDOC_OPTS.clone
117
+ rdoc.options << '--main' << 'ID3Lib::Tag'
110
118
  rdoc.rdoc_files.include('README', 'TODO', 'CHANGES')
111
119
  rdoc.rdoc_files.include('lib/**/*.rb')
112
120
  end
@@ -0,0 +1,21 @@
1
+
2
+ require 'rake/clean'
3
+
4
+
5
+ CLEAN.include '*.o', 'Makefile', 'mkmf.log'
6
+ CLOBBER.include 'id3lib_api.so', 'id3lib_api.bundle'
7
+
8
+ task :default => ['id3lib_api.bundle']
9
+ task :swig => ['id3lib_api_wrap.cxx']
10
+
11
+ file 'id3lib_api.bundle' => ['id3lib_api_wrap.cxx', 'Makefile'] do
12
+ sh "make"
13
+ end
14
+
15
+ file 'id3lib_api_wrap.cxx' => ['id3lib_api.i'] do
16
+ sh "swig -c++ -ruby -feature id3lib_api id3lib_api.i"
17
+ end
18
+
19
+ file 'Makefile' do
20
+ ruby "extconf.rb"
21
+ end
@@ -0,0 +1,114 @@
1
+ require 'enumerator'
2
+
3
+ file = ARGV.first || '/usr/local/include/id3/globals.h'
4
+
5
+ data = IO.read(file)
6
+
7
+ fields = []
8
+ frames = []
9
+ genres = []
10
+
11
+ data.scan(/ID3_ENUM\((\w+)\)\s+\{\s+(.+?)\s+\}/m) do |name, enum|
12
+ case name
13
+ when 'ID3_FieldID'
14
+ id = 0
15
+ enum.scan(/([^\s,]+)(?: = (\d+),|,)\s*\/\*\*< ([^*]+)\s+\*\//m) do |field, newid, description|
16
+ id = newid.to_i if newid
17
+ field.sub!('ID3FN_', '')
18
+ field.downcase!
19
+ fields << [id, field.to_sym, description]
20
+ id += 1
21
+ end
22
+ when 'ID3_FrameID'
23
+ id = 0
24
+ enum.scan(/\/\* (\S+) \*\/ [^\s,]+(?: = (\d+),|,)\s*\/\*\*< ([^*]+)\s+\*\//m) do |frame, newid, description|
25
+ id = newid.to_i if newid
26
+ if frame == '????'
27
+ frame = :____
28
+ else
29
+ frame = frame.to_sym
30
+ end
31
+ possible_fields =
32
+ case frame
33
+ when :____ : []
34
+ when :AENC : [:owner, :data]
35
+ when :APIC : [:textenc, :mimetype, :picturetype, :description, :data]
36
+ when :ASPI, :COMR, :EQUA, :ETCO, :LINK,
37
+ :MCDI, :MLLT, :OWNE, :POSS, :RBUF,
38
+ :RVA2, :RVAD, :RVRB, :SEEK
39
+ [:data]
40
+ when :COMM : [:textenc, :language, :description, :text]
41
+ when :ENCR : [:owner, :id, :data]
42
+ when :EQU2 : [:id, :text]
43
+ when :GEOB : [:textenc, :mimetype, :filename, :description, :data]
44
+ when :GRID : [:owner, :id, :data]
45
+ when :IPLS : [:textenc, :text]
46
+ when :PRIV : [:owner, :data]
47
+ when :PCNT : [:counter]
48
+ when :POPM : [:email, :rating, :counter]
49
+ when :SIGN : [:id, :data]
50
+ when :SYLT : [:textenc, :language, :timestampformat, :contenttype, :description, :data]
51
+ when :SYTC : [:timestampformat, :data]
52
+ when :UFID : [:owner, :data]
53
+ when :USER : [:textenc, :language, :text]
54
+ when :USLT : [:textenc, :language, :description, :text]
55
+ when :WCOM, :WCOP, :WOAF, :WOAR, :WOAS, :WORS, :WPAY, :WPUB : [:text]
56
+ when :WXXX : [:textenc, :description, :url]
57
+ else [:textenc, :text]
58
+ end
59
+ frames << [id, frame, description, possible_fields]
60
+ id += 1
61
+ end
62
+ end
63
+ end
64
+
65
+ data.scan(/(ID3_v1_genre_description).+?\{(.+?)\}/m) do |name, list|
66
+ id = 0
67
+ list.scan(/"(.+?)"/) do |genre|
68
+ genres << genre.first
69
+ id += 1
70
+ end
71
+ end
72
+
73
+
74
+ def indent level, text
75
+ puts ' ' * level + text
76
+ end
77
+
78
+ indent 4, "Frames = ["
79
+ frames.each do |f|
80
+ comment = case f[1]
81
+ when :____ : "# Special frames"
82
+ when :TALB : "# Text information frames"
83
+ when :UFID : "# Special frames again"
84
+ when :WCOM : "# URL link frames"
85
+ end
86
+ indent 6, comment if comment
87
+ indent 6, f.inspect + ","
88
+ end
89
+ indent 4, "]"
90
+
91
+ indent 4, "FramesByID = {"
92
+ frames.each do |f|
93
+ indent 6, f[1].inspect + " => Frames[" + f[0].to_s + "],"
94
+ end
95
+ indent 4, "}"
96
+
97
+ indent 4, "Fields = ["
98
+ fields.each do |f|
99
+ indent 6, f.inspect + ","
100
+ end
101
+ indent 4, "]"
102
+
103
+ indent 4, "FieldsByID = {"
104
+ fields.each do |f|
105
+ indent 6, f[1].inspect.ljust(16) + " => Fields[" + f[0].to_s + "],"
106
+ end
107
+ indent 4, "}"
108
+
109
+ indent 4, "Genres = ["
110
+ genres.each_slice(4) do |gs|
111
+ indent 6, "# Winamp extensions" if gs.first == "Folk"
112
+ indent 6, gs.map{ |g| g.inspect }.join(", ") + ","
113
+ end
114
+ indent 4, "]"
@@ -0,0 +1,179 @@
1
+ %module "ID3Lib::API"
2
+ %{
3
+ #include <id3/tag.h>
4
+ %}
5
+
6
+
7
+ enum ID3_FrameID;
8
+ enum ID3_FieldID;
9
+ enum ID3_FieldType;
10
+ enum ID3_TextEnc;
11
+ enum ID3_TagType;
12
+
13
+ typedef unsigned int flags_t;
14
+
15
+
16
+ %rename (Tag) ID3_Tag;
17
+ class ID3_Tag
18
+ {
19
+ public:
20
+
21
+ ID3_Tag(const char *name = NULL);
22
+ ~ID3_Tag();
23
+
24
+ %rename (has_tag_type) HasTagType;
25
+ bool HasTagType(ID3_TagType type) const;
26
+
27
+ %rename (link) Link;
28
+ size_t Link(const char *filename, flags_t flags = ID3TT_ALL);
29
+
30
+ %rename (update) Update;
31
+ flags_t Update(flags_t flags = ID3TT_ALL);
32
+
33
+ %rename (strip) Strip;
34
+ flags_t Strip(flags_t flags = ID3TT_ALL);
35
+
36
+ %rename (clear) Clear;
37
+ void Clear();
38
+
39
+ %rename (remove_frame) RemoveFrame;
40
+ ID3_Frame * RemoveFrame(const ID3_Frame *frame);
41
+
42
+ %rename (add_frame) AddFrame;
43
+ void AddFrame(const ID3_Frame *frame);
44
+
45
+ %rename (get_filename) GetFileName;
46
+ const char * GetFileName() const;
47
+
48
+ %rename (set_padding) SetPadding;
49
+ bool SetPadding(bool padding);
50
+
51
+ %rename (size) Size;
52
+ size_t Size() const;
53
+
54
+ %rename (find) Find;
55
+ ID3_Frame * Find(ID3_FrameID name) const;
56
+
57
+ %rename (iterator_new) CreateIterator;
58
+ ID3_Tag::Iterator * CreateIterator();
59
+
60
+ // Needed because SWIG does not support nested classes yet.
61
+ %extend
62
+ {
63
+ ID3_Frame * iterator_next_frame(ID3_Tag::Iterator *iterator)
64
+ {
65
+ return iterator->GetNext();
66
+ }
67
+ }
68
+ };
69
+
70
+
71
+ %rename (Frame) ID3_Frame;
72
+ class ID3_Frame
73
+ {
74
+ public:
75
+
76
+ ID3_Frame(ID3_FrameID id = ID3FID_NOFRAME);
77
+ ~ID3_Frame();
78
+
79
+ %rename (get_field) GetField;
80
+ ID3_Field * GetField(ID3_FieldID name) const;
81
+
82
+ %rename (get_id) GetID;
83
+ ID3_FrameID GetID() const;
84
+ };
85
+
86
+
87
+ %rename (Field) ID3_Field;
88
+ class ID3_Field
89
+ {
90
+ public:
91
+
92
+ // Getters
93
+
94
+ %rename (get_type) GetType;
95
+ ID3_FieldType GetType() const;
96
+
97
+ %rename (get_encoding) GetEncoding;
98
+ ID3_TextEnc GetEncoding() const;
99
+
100
+ %rename (get_integer) Get;
101
+ unsigned long Get() const;
102
+
103
+ %rename (get_ascii) GetRawText;
104
+ const char * GetRawText() const;
105
+
106
+ %extend
107
+ {
108
+ VALUE get_binary()
109
+ {
110
+ return rb_str_new((const char *)self->GetRawBinary(), self->Size());
111
+ }
112
+
113
+ VALUE get_unicode()
114
+ {
115
+ const char *string = (const char *)self->GetRawUnicodeText();
116
+ if (string == NULL) return rb_str_new("", 0);
117
+ long size = self->Size();
118
+ if (size >= 2 && string[size-2] == '\0' && string[size-1] == '\0') {
119
+ // id3lib seems to be inconsistent: the Unicode strings
120
+ // don't always end in 0x0000. If they do, we don't want these
121
+ // trailing bytes.
122
+ size -= 2;
123
+ }
124
+ return rb_str_new(string, size);
125
+ }
126
+ }
127
+
128
+ // Setters
129
+
130
+ %rename (set_encoding) SetEncoding(ID3_TextEnc);
131
+ bool SetEncoding(ID3_TextEnc enc);
132
+
133
+ %rename (set_integer) Set(unsigned long);
134
+ void Set(unsigned long i);
135
+
136
+ %rename (set_ascii) Set(const char *);
137
+ size_t Set(const char *string);
138
+
139
+ %extend
140
+ {
141
+ size_t set_binary(VALUE data)
142
+ {
143
+ StringValue(data);
144
+ return self->Set((const unsigned char *)RSTRING(data)->ptr,
145
+ RSTRING(data)->len);
146
+ }
147
+
148
+ size_t set_unicode(VALUE data)
149
+ {
150
+ StringValue(data);
151
+
152
+ long len;
153
+ unicode_t *unicode;
154
+
155
+ len = RSTRING(data)->len / sizeof(unicode_t);
156
+ unicode = (unicode_t *)malloc(sizeof(unicode_t) * (len+1));
157
+
158
+ if (unicode == NULL) {
159
+ rb_raise(rb_eNoMemError, "Couldn't allocate memory for Unicode data.");
160
+ }
161
+
162
+ memcpy(unicode, RSTRING(data)->ptr, sizeof(unicode_t) * len);
163
+ // Unicode strings need 0x0000 at the end.
164
+ unicode[len] = 0;
165
+ size_t retval = self->Set(unicode);
166
+
167
+ // Free Unicode! ;)
168
+ free(unicode);
169
+ return retval;
170
+ }
171
+ }
172
+
173
+ protected:
174
+
175
+ ID3_Field();
176
+ ~ID3_Field();
177
+ };
178
+
179
+ // vim: set filetype=cpp sw=4 ts=4 noexpandtab:
@@ -1795,8 +1795,8 @@ SWIG_AsVal_bool (VALUE obj, bool *val)
1795
1795
  }
1796
1796
 
1797
1797
  SWIGINTERN ID3_Frame *ID3_Tag_iterator_next_frame(ID3_Tag *self,ID3_Tag::Iterator *iterator){
1798
- return iterator->GetNext();
1799
- }
1798
+ return iterator->GetNext();
1799
+ }
1800
1800
 
1801
1801
  SWIGINTERNINLINE VALUE
1802
1802
  SWIG_From_int (int value)
@@ -1804,49 +1804,48 @@ SWIG_From_int (int value)
1804
1804
  return SWIG_From_long (value);
1805
1805
  }
1806
1806
 
1807
- SWIGINTERN VALUE ID3_Field_binary(ID3_Field *self){
1808
- return rb_str_new((const char *)self->GetRawBinary(), self->Size());
1809
- }
1810
- SWIGINTERN VALUE ID3_Field_unicode(ID3_Field *self){
1811
- const char *string = (const char *)self->GetRawUnicodeText();
1812
- long size = self->Size();
1813
- if (size < 2) {
1814
- size = 0;
1815
- } else if (string[size-2] == '\0' && string[size-1] == '\0') {
1816
- // id3lib seems to be inconsistent: the unicode strings
1817
- // don't always end in 0x0000. If they do, we don't want these
1818
- // trailing bytes.
1819
- size -= 2;
1820
- }
1821
- return rb_str_new(string, size);
1822
- }
1807
+ SWIGINTERN VALUE ID3_Field_get_binary(ID3_Field *self){
1808
+ return rb_str_new((const char *)self->GetRawBinary(), self->Size());
1809
+ }
1810
+ SWIGINTERN VALUE ID3_Field_get_unicode(ID3_Field *self){
1811
+ const char *string = (const char *)self->GetRawUnicodeText();
1812
+ if (string == NULL) return rb_str_new("", 0);
1813
+ long size = self->Size();
1814
+ if (size >= 2 && string[size-2] == '\0' && string[size-1] == '\0') {
1815
+ // id3lib seems to be inconsistent: the Unicode strings
1816
+ // don't always end in 0x0000. If they do, we don't want these
1817
+ // trailing bytes.
1818
+ size -= 2;
1819
+ }
1820
+ return rb_str_new(string, size);
1821
+ }
1823
1822
  SWIGINTERN size_t ID3_Field_set_binary(ID3_Field *self,VALUE data){
1824
- StringValue(data);
1825
- return self->Set( (const unsigned char *)RSTRING(data)->ptr,
1826
- RSTRING(data)->len );
1827
- }
1823
+ StringValue(data);
1824
+ return self->Set((const unsigned char *)RSTRING(data)->ptr,
1825
+ RSTRING(data)->len);
1826
+ }
1828
1827
  SWIGINTERN size_t ID3_Field_set_unicode(ID3_Field *self,VALUE data){
1829
- StringValue(data);
1828
+ StringValue(data);
1830
1829
 
1831
- long len;
1832
- unicode_t *unicode;
1830
+ long len;
1831
+ unicode_t *unicode;
1833
1832
 
1834
- len = RSTRING(data)->len / sizeof(unicode_t);
1835
- unicode = (unicode_t *)malloc(sizeof(unicode_t) * (len+1));
1833
+ len = RSTRING(data)->len / sizeof(unicode_t);
1834
+ unicode = (unicode_t *)malloc(sizeof(unicode_t) * (len+1));
1836
1835
 
1837
- if (unicode == NULL) {
1838
- rb_raise(rb_eNoMemError, "Couldn't allocate memory for unicode data.");
1839
- }
1840
-
1841
- memcpy(unicode, RSTRING(data)->ptr, sizeof(unicode_t) * len);
1842
- // Unicode strings need 0x0000 at the end.
1843
- unicode[len] = 0;
1844
- size_t retval = self->Set(unicode);
1845
-
1846
- // Free Unicode! ;)
1847
- free(unicode);
1848
- return retval;
1849
- }
1836
+ if (unicode == NULL) {
1837
+ rb_raise(rb_eNoMemError, "Couldn't allocate memory for Unicode data.");
1838
+ }
1839
+
1840
+ memcpy(unicode, RSTRING(data)->ptr, sizeof(unicode_t) * len);
1841
+ // Unicode strings need 0x0000 at the end.
1842
+ unicode[len] = 0;
1843
+ size_t retval = self->Set(unicode);
1844
+
1845
+ // Free Unicode! ;)
1846
+ free(unicode);
1847
+ return retval;
1848
+ }
1850
1849
  swig_class cTag;
1851
1850
 
1852
1851
  SWIGINTERN VALUE
@@ -2379,7 +2378,7 @@ fail:
2379
2378
 
2380
2379
 
2381
2380
  SWIGINTERN VALUE
2382
- _wrap_Tag_filename(int argc, VALUE *argv, VALUE self) {
2381
+ _wrap_Tag_get_filename(int argc, VALUE *argv, VALUE self) {
2383
2382
  ID3_Tag *arg1 = (ID3_Tag *) 0 ;
2384
2383
  char *result = 0 ;
2385
2384
  void *argp1 = 0 ;
@@ -2639,7 +2638,7 @@ free_ID3_Frame(ID3_Frame *arg1) {
2639
2638
  }
2640
2639
 
2641
2640
  SWIGINTERN VALUE
2642
- _wrap_Frame_field(int argc, VALUE *argv, VALUE self) {
2641
+ _wrap_Frame_get_field(int argc, VALUE *argv, VALUE self) {
2643
2642
  ID3_Frame *arg1 = (ID3_Frame *) 0 ;
2644
2643
  ID3_FieldID arg2 ;
2645
2644
  ID3_Field *result = 0 ;
@@ -2671,7 +2670,7 @@ fail:
2671
2670
 
2672
2671
 
2673
2672
  SWIGINTERN VALUE
2674
- _wrap_Frame_num(int argc, VALUE *argv, VALUE self) {
2673
+ _wrap_Frame_get_id(int argc, VALUE *argv, VALUE self) {
2675
2674
  ID3_Frame *arg1 = (ID3_Frame *) 0 ;
2676
2675
  ID3_FrameID result;
2677
2676
  void *argp1 = 0 ;
@@ -2697,7 +2696,7 @@ fail:
2697
2696
  swig_class cField;
2698
2697
 
2699
2698
  SWIGINTERN VALUE
2700
- _wrap_Field_type(int argc, VALUE *argv, VALUE self) {
2699
+ _wrap_Field_get_type(int argc, VALUE *argv, VALUE self) {
2701
2700
  ID3_Field *arg1 = (ID3_Field *) 0 ;
2702
2701
  ID3_FieldType result;
2703
2702
  void *argp1 = 0 ;
@@ -2721,9 +2720,9 @@ fail:
2721
2720
 
2722
2721
 
2723
2722
  SWIGINTERN VALUE
2724
- _wrap_Field_integer(int argc, VALUE *argv, VALUE self) {
2723
+ _wrap_Field_get_encoding(int argc, VALUE *argv, VALUE self) {
2725
2724
  ID3_Field *arg1 = (ID3_Field *) 0 ;
2726
- unsigned long result;
2725
+ ID3_TextEnc result;
2727
2726
  void *argp1 = 0 ;
2728
2727
  int res1 = 0 ;
2729
2728
  VALUE vresult = Qnil;
@@ -2733,11 +2732,11 @@ _wrap_Field_integer(int argc, VALUE *argv, VALUE self) {
2733
2732
  }
2734
2733
  res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
2735
2734
  if (!SWIG_IsOK(res1)) {
2736
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Get" "', argument " "1"" of type '" "ID3_Field const *""'");
2735
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "GetEncoding" "', argument " "1"" of type '" "ID3_Field const *""'");
2737
2736
  }
2738
2737
  arg1 = reinterpret_cast< ID3_Field * >(argp1);
2739
- result = (unsigned long)((ID3_Field const *)arg1)->Get();
2740
- vresult = SWIG_From_unsigned_SS_long(static_cast< unsigned long >(result));
2738
+ result = (ID3_TextEnc)((ID3_Field const *)arg1)->GetEncoding();
2739
+ vresult = SWIG_From_int(static_cast< int >(result));
2741
2740
  return vresult;
2742
2741
  fail:
2743
2742
  return Qnil;
@@ -2745,9 +2744,9 @@ fail:
2745
2744
 
2746
2745
 
2747
2746
  SWIGINTERN VALUE
2748
- _wrap_Field_binary(int argc, VALUE *argv, VALUE self) {
2747
+ _wrap_Field_get_integer(int argc, VALUE *argv, VALUE self) {
2749
2748
  ID3_Field *arg1 = (ID3_Field *) 0 ;
2750
- VALUE result;
2749
+ unsigned long result;
2751
2750
  void *argp1 = 0 ;
2752
2751
  int res1 = 0 ;
2753
2752
  VALUE vresult = Qnil;
@@ -2757,11 +2756,11 @@ _wrap_Field_binary(int argc, VALUE *argv, VALUE self) {
2757
2756
  }
2758
2757
  res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
2759
2758
  if (!SWIG_IsOK(res1)) {
2760
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "binary" "', argument " "1"" of type '" "ID3_Field *""'");
2759
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Get" "', argument " "1"" of type '" "ID3_Field const *""'");
2761
2760
  }
2762
2761
  arg1 = reinterpret_cast< ID3_Field * >(argp1);
2763
- result = (VALUE)ID3_Field_binary(arg1);
2764
- vresult = result;
2762
+ result = (unsigned long)((ID3_Field const *)arg1)->Get();
2763
+ vresult = SWIG_From_unsigned_SS_long(static_cast< unsigned long >(result));
2765
2764
  return vresult;
2766
2765
  fail:
2767
2766
  return Qnil;
@@ -2769,7 +2768,7 @@ fail:
2769
2768
 
2770
2769
 
2771
2770
  SWIGINTERN VALUE
2772
- _wrap_Field_ascii(int argc, VALUE *argv, VALUE self) {
2771
+ _wrap_Field_get_ascii(int argc, VALUE *argv, VALUE self) {
2773
2772
  ID3_Field *arg1 = (ID3_Field *) 0 ;
2774
2773
  char *result = 0 ;
2775
2774
  void *argp1 = 0 ;
@@ -2793,7 +2792,7 @@ fail:
2793
2792
 
2794
2793
 
2795
2794
  SWIGINTERN VALUE
2796
- _wrap_Field_unicode(int argc, VALUE *argv, VALUE self) {
2795
+ _wrap_Field_get_binary(int argc, VALUE *argv, VALUE self) {
2797
2796
  ID3_Field *arg1 = (ID3_Field *) 0 ;
2798
2797
  VALUE result;
2799
2798
  void *argp1 = 0 ;
@@ -2805,10 +2804,10 @@ _wrap_Field_unicode(int argc, VALUE *argv, VALUE self) {
2805
2804
  }
2806
2805
  res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
2807
2806
  if (!SWIG_IsOK(res1)) {
2808
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "unicode" "', argument " "1"" of type '" "ID3_Field *""'");
2807
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "get_binary" "', argument " "1"" of type '" "ID3_Field *""'");
2809
2808
  }
2810
2809
  arg1 = reinterpret_cast< ID3_Field * >(argp1);
2811
- result = (VALUE)ID3_Field_unicode(arg1);
2810
+ result = (VALUE)ID3_Field_get_binary(arg1);
2812
2811
  vresult = result;
2813
2812
  return vresult;
2814
2813
  fail:
@@ -2817,55 +2816,85 @@ fail:
2817
2816
 
2818
2817
 
2819
2818
  SWIGINTERN VALUE
2820
- _wrap_Field_set_integer(int argc, VALUE *argv, VALUE self) {
2819
+ _wrap_Field_get_unicode(int argc, VALUE *argv, VALUE self) {
2821
2820
  ID3_Field *arg1 = (ID3_Field *) 0 ;
2822
- unsigned long arg2 ;
2821
+ VALUE result;
2823
2822
  void *argp1 = 0 ;
2824
2823
  int res1 = 0 ;
2825
- unsigned long val2 ;
2824
+ VALUE vresult = Qnil;
2825
+
2826
+ if ((argc < 0) || (argc > 0)) {
2827
+ rb_raise(rb_eArgError, "wrong # of arguments(%d for 0)",argc); SWIG_fail;
2828
+ }
2829
+ res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
2830
+ if (!SWIG_IsOK(res1)) {
2831
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "get_unicode" "', argument " "1"" of type '" "ID3_Field *""'");
2832
+ }
2833
+ arg1 = reinterpret_cast< ID3_Field * >(argp1);
2834
+ result = (VALUE)ID3_Field_get_unicode(arg1);
2835
+ vresult = result;
2836
+ return vresult;
2837
+ fail:
2838
+ return Qnil;
2839
+ }
2840
+
2841
+
2842
+ SWIGINTERN VALUE
2843
+ _wrap_Field_set_encoding(int argc, VALUE *argv, VALUE self) {
2844
+ ID3_Field *arg1 = (ID3_Field *) 0 ;
2845
+ ID3_TextEnc arg2 ;
2846
+ bool result;
2847
+ void *argp1 = 0 ;
2848
+ int res1 = 0 ;
2849
+ int val2 ;
2826
2850
  int ecode2 = 0 ;
2851
+ VALUE vresult = Qnil;
2827
2852
 
2828
2853
  if ((argc < 1) || (argc > 1)) {
2829
2854
  rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
2830
2855
  }
2831
2856
  res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
2832
2857
  if (!SWIG_IsOK(res1)) {
2833
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Set" "', argument " "1"" of type '" "ID3_Field *""'");
2858
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SetEncoding" "', argument " "1"" of type '" "ID3_Field *""'");
2834
2859
  }
2835
2860
  arg1 = reinterpret_cast< ID3_Field * >(argp1);
2836
- ecode2 = SWIG_AsVal_unsigned_SS_long(argv[0], &val2);
2861
+ ecode2 = SWIG_AsVal_int(argv[0], &val2);
2837
2862
  if (!SWIG_IsOK(ecode2)) {
2838
- SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Set" "', argument " "2"" of type '" "unsigned long""'");
2863
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SetEncoding" "', argument " "2"" of type '" "ID3_TextEnc""'");
2839
2864
  }
2840
- arg2 = static_cast< unsigned long >(val2);
2841
- (arg1)->Set(arg2);
2842
- return Qnil;
2865
+ arg2 = static_cast< ID3_TextEnc >(val2);
2866
+ result = (bool)(arg1)->SetEncoding(arg2);
2867
+ vresult = SWIG_From_bool(static_cast< bool >(result));
2868
+ return vresult;
2843
2869
  fail:
2844
2870
  return Qnil;
2845
2871
  }
2846
2872
 
2847
2873
 
2848
2874
  SWIGINTERN VALUE
2849
- _wrap_Field_set_binary(int argc, VALUE *argv, VALUE self) {
2875
+ _wrap_Field_set_integer(int argc, VALUE *argv, VALUE self) {
2850
2876
  ID3_Field *arg1 = (ID3_Field *) 0 ;
2851
- VALUE arg2 = (VALUE) 0 ;
2852
- size_t result;
2877
+ unsigned long arg2 ;
2853
2878
  void *argp1 = 0 ;
2854
2879
  int res1 = 0 ;
2855
- VALUE vresult = Qnil;
2880
+ unsigned long val2 ;
2881
+ int ecode2 = 0 ;
2856
2882
 
2857
2883
  if ((argc < 1) || (argc > 1)) {
2858
2884
  rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)",argc); SWIG_fail;
2859
2885
  }
2860
2886
  res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
2861
2887
  if (!SWIG_IsOK(res1)) {
2862
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "set_binary" "', argument " "1"" of type '" "ID3_Field *""'");
2888
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Set" "', argument " "1"" of type '" "ID3_Field *""'");
2863
2889
  }
2864
2890
  arg1 = reinterpret_cast< ID3_Field * >(argp1);
2865
- arg2 = argv[0];
2866
- result = ID3_Field_set_binary(arg1,arg2);
2867
- vresult = SWIG_From_size_t(static_cast< size_t >(result));
2868
- return vresult;
2891
+ ecode2 = SWIG_AsVal_unsigned_SS_long(argv[0], &val2);
2892
+ if (!SWIG_IsOK(ecode2)) {
2893
+ SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "Set" "', argument " "2"" of type '" "unsigned long""'");
2894
+ }
2895
+ arg2 = static_cast< unsigned long >(val2);
2896
+ (arg1)->Set(arg2);
2897
+ return Qnil;
2869
2898
  fail:
2870
2899
  return Qnil;
2871
2900
  }
@@ -2907,14 +2936,12 @@ fail:
2907
2936
 
2908
2937
 
2909
2938
  SWIGINTERN VALUE
2910
- _wrap_Field_set_encoding(int argc, VALUE *argv, VALUE self) {
2939
+ _wrap_Field_set_binary(int argc, VALUE *argv, VALUE self) {
2911
2940
  ID3_Field *arg1 = (ID3_Field *) 0 ;
2912
- ID3_TextEnc arg2 ;
2913
- bool result;
2941
+ VALUE arg2 = (VALUE) 0 ;
2942
+ size_t result;
2914
2943
  void *argp1 = 0 ;
2915
2944
  int res1 = 0 ;
2916
- int val2 ;
2917
- int ecode2 = 0 ;
2918
2945
  VALUE vresult = Qnil;
2919
2946
 
2920
2947
  if ((argc < 1) || (argc > 1)) {
@@ -2922,16 +2949,12 @@ _wrap_Field_set_encoding(int argc, VALUE *argv, VALUE self) {
2922
2949
  }
2923
2950
  res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_ID3_Field, 0 | 0 );
2924
2951
  if (!SWIG_IsOK(res1)) {
2925
- SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "SetEncoding" "', argument " "1"" of type '" "ID3_Field *""'");
2952
+ SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "set_binary" "', argument " "1"" of type '" "ID3_Field *""'");
2926
2953
  }
2927
2954
  arg1 = reinterpret_cast< ID3_Field * >(argp1);
2928
- ecode2 = SWIG_AsVal_int(argv[0], &val2);
2929
- if (!SWIG_IsOK(ecode2)) {
2930
- SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "SetEncoding" "', argument " "2"" of type '" "ID3_TextEnc""'");
2931
- }
2932
- arg2 = static_cast< ID3_TextEnc >(val2);
2933
- result = (bool)(arg1)->SetEncoding(arg2);
2934
- vresult = SWIG_From_bool(static_cast< bool >(result));
2955
+ arg2 = argv[0];
2956
+ result = ID3_Field_set_binary(arg1,arg2);
2957
+ vresult = SWIG_From_size_t(static_cast< size_t >(result));
2935
2958
  return vresult;
2936
2959
  fail:
2937
2960
  return Qnil;
@@ -3242,7 +3265,7 @@ SWIGEXPORT void Init_id3lib_api(void) {
3242
3265
  rb_define_method(cTag.klass, "clear", VALUEFUNC(_wrap_Tag_clear), -1);
3243
3266
  rb_define_method(cTag.klass, "remove_frame", VALUEFUNC(_wrap_Tag_remove_frame), -1);
3244
3267
  rb_define_method(cTag.klass, "add_frame", VALUEFUNC(_wrap_Tag_add_frame), -1);
3245
- rb_define_method(cTag.klass, "filename", VALUEFUNC(_wrap_Tag_filename), -1);
3268
+ rb_define_method(cTag.klass, "get_filename", VALUEFUNC(_wrap_Tag_get_filename), -1);
3246
3269
  rb_define_method(cTag.klass, "set_padding", VALUEFUNC(_wrap_Tag_set_padding), -1);
3247
3270
  rb_define_method(cTag.klass, "size", VALUEFUNC(_wrap_Tag_size), -1);
3248
3271
  rb_define_method(cTag.klass, "find", VALUEFUNC(_wrap_Tag_find), -1);
@@ -3256,8 +3279,8 @@ SWIGEXPORT void Init_id3lib_api(void) {
3256
3279
  SWIG_TypeClientData(SWIGTYPE_p_ID3_Frame, (void *) &cFrame);
3257
3280
  rb_define_alloc_func(cFrame.klass, _wrap_Frame_allocate);
3258
3281
  rb_define_method(cFrame.klass, "initialize", VALUEFUNC(_wrap_new_Frame), -1);
3259
- rb_define_method(cFrame.klass, "field", VALUEFUNC(_wrap_Frame_field), -1);
3260
- rb_define_method(cFrame.klass, "num", VALUEFUNC(_wrap_Frame_num), -1);
3282
+ rb_define_method(cFrame.klass, "get_field", VALUEFUNC(_wrap_Frame_get_field), -1);
3283
+ rb_define_method(cFrame.klass, "get_id", VALUEFUNC(_wrap_Frame_get_id), -1);
3261
3284
  cFrame.mark = 0;
3262
3285
  cFrame.destroy = (void (*)(void *)) free_ID3_Frame;
3263
3286
  cFrame.trackObjects = 0;
@@ -3265,15 +3288,16 @@ SWIGEXPORT void Init_id3lib_api(void) {
3265
3288
  cField.klass = rb_define_class_under(mAPI, "Field", rb_cObject);
3266
3289
  SWIG_TypeClientData(SWIGTYPE_p_ID3_Field, (void *) &cField);
3267
3290
  rb_undef_alloc_func(cField.klass);
3268
- rb_define_method(cField.klass, "type", VALUEFUNC(_wrap_Field_type), -1);
3269
- rb_define_method(cField.klass, "integer", VALUEFUNC(_wrap_Field_integer), -1);
3270
- rb_define_method(cField.klass, "binary", VALUEFUNC(_wrap_Field_binary), -1);
3271
- rb_define_method(cField.klass, "ascii", VALUEFUNC(_wrap_Field_ascii), -1);
3272
- rb_define_method(cField.klass, "unicode", VALUEFUNC(_wrap_Field_unicode), -1);
3291
+ rb_define_method(cField.klass, "get_type", VALUEFUNC(_wrap_Field_get_type), -1);
3292
+ rb_define_method(cField.klass, "get_encoding", VALUEFUNC(_wrap_Field_get_encoding), -1);
3293
+ rb_define_method(cField.klass, "get_integer", VALUEFUNC(_wrap_Field_get_integer), -1);
3294
+ rb_define_method(cField.klass, "get_ascii", VALUEFUNC(_wrap_Field_get_ascii), -1);
3295
+ rb_define_method(cField.klass, "get_binary", VALUEFUNC(_wrap_Field_get_binary), -1);
3296
+ rb_define_method(cField.klass, "get_unicode", VALUEFUNC(_wrap_Field_get_unicode), -1);
3297
+ rb_define_method(cField.klass, "set_encoding", VALUEFUNC(_wrap_Field_set_encoding), -1);
3273
3298
  rb_define_method(cField.klass, "set_integer", VALUEFUNC(_wrap_Field_set_integer), -1);
3274
- rb_define_method(cField.klass, "set_binary", VALUEFUNC(_wrap_Field_set_binary), -1);
3275
3299
  rb_define_method(cField.klass, "set_ascii", VALUEFUNC(_wrap_Field_set_ascii), -1);
3276
- rb_define_method(cField.klass, "set_encoding", VALUEFUNC(_wrap_Field_set_encoding), -1);
3300
+ rb_define_method(cField.klass, "set_binary", VALUEFUNC(_wrap_Field_set_binary), -1);
3277
3301
  rb_define_method(cField.klass, "set_unicode", VALUEFUNC(_wrap_Field_set_unicode), -1);
3278
3302
  cField.mark = 0;
3279
3303
  cField.trackObjects = 0;
@@ -327,25 +327,26 @@ module ID3Lib
327
327
 
328
328
  def self.read(libframe)
329
329
  frame = {}
330
- info = Info.frame_num(libframe.num)
330
+ info = Info.frame_num(libframe.get_id)
331
331
  frame[:id] = info[ID]
332
- if info[FIELDS].include?(:textenc)
333
- textenc = field(libframe, :textenc).integer
334
- frame[:textenc] = textenc
335
- end
332
+
336
333
  info[FIELDS].each do |field_id|
337
- next if field_id == :textenc
338
334
  libfield = field(libframe, field_id)
339
- frame[field_id] = if textenc and textenc > 0
340
- libfield.unicode
341
- else
342
- case Info::FieldType[libfield.type]
343
- when :integer : libfield.integer
344
- when :binary : libfield.binary
345
- when :text : libfield.ascii
335
+ frame[field_id] =
336
+ case Info::FieldType[libfield.get_type]
337
+ when :integer
338
+ libfield.get_integer
339
+ when :binary
340
+ libfield.get_binary
341
+ when :text
342
+ if libfield.get_encoding > 0
343
+ libfield.get_unicode
344
+ else
345
+ libfield.get_ascii
346
+ end
346
347
  end
347
- end
348
348
  end
349
+
349
350
  frame
350
351
  end
351
352
 
@@ -353,29 +354,35 @@ module ID3Lib
353
354
  if textenc = frame[:textenc]
354
355
  field(libframe, :textenc).set_integer(textenc)
355
356
  end
357
+
356
358
  frame.each do |field_id, value|
357
359
  next if field_id == :textenc
358
360
  unless Info.frame(frame[:id])[FIELDS].include?(field_id)
359
361
  # Ignore invalid fields
360
362
  next
361
363
  end
364
+
362
365
  libfield = field(libframe, field_id)
363
- if textenc and textenc > 0
364
- # Special treatment for Unicode
365
- libfield.set_encoding(textenc)
366
- libfield.set_unicode(value)
367
- else
368
- case Info::FieldType[libfield.type]
369
- when :integer : libfield.set_integer(value)
370
- when :binary : libfield.set_binary(value)
371
- when :text : libfield.set_ascii(value)
366
+ case Info::FieldType[libfield.get_type]
367
+ when :integer
368
+ libfield.set_integer(value)
369
+ when :binary
370
+ libfield.set_binary(value)
371
+ when :text
372
+ if textenc and textenc > 0 and
373
+ [:text, :description, :filename].include?(field_id)
374
+ # Special treatment for Unicode
375
+ libfield.set_encoding(textenc)
376
+ libfield.set_unicode(value)
377
+ else
378
+ libfield.set_ascii(value)
372
379
  end
373
380
  end
374
381
  end
375
382
  end
376
383
 
377
384
  def self.field(libframe, id)
378
- libframe.field(Info.field(id)[NUM])
385
+ libframe.get_field(Info.field(id)[NUM])
379
386
  end
380
387
 
381
388
  end
@@ -172,12 +172,19 @@ class TestWriting < Test::Unit::TestCase
172
172
 
173
173
  def test_unicode
174
174
  nihao = "\x4f\x60\x59\x7d"
175
- @tag.reject!{ |f| f[:id] == :TIT2 }
176
- @tag << {:id => :TIT2, :text => nihao, :textenc => 1}
175
+ frame = {
176
+ :id => :COMM,
177
+ :text => nihao,
178
+ :description => nihao,
179
+ :language => "zho",
180
+ :textenc => 1
181
+ }
182
+ @tag.comment = nil
183
+ @tag << frame
177
184
  @tag.update!(ID3Lib::V2)
178
- assert_equal nihao, @tag.title
185
+ assert_equal frame, @tag.frame(:COMM)
179
186
  reload!(ID3Lib::V2)
180
- assert_equal nihao, @tag.title
187
+ assert_equal frame, @tag.frame(:COMM)
181
188
  end
182
189
 
183
190
  def test_unicode_invalid_data
@@ -0,0 +1,40 @@
1
+
2
+ require 'rubygems'
3
+ require 'id3lib'
4
+
5
+ # Load a tag from a file
6
+ tag = ID3Lib::Tag.new('talk.mp3')
7
+
8
+ # Get and set text frames with convenience methods
9
+ tag.title #=> "Talk"
10
+ tag.album = 'X&Y'
11
+ tag.track = '5/13'
12
+
13
+ # Tag is a subclass of Array and each frame is a Hash
14
+ tag[0]
15
+ #=> { :id => :TPE1, :textenc => 0, :text => "Coldplay" }
16
+
17
+ # Get the number of frames
18
+ tag.length #=> 7
19
+
20
+ # Remove all comment frames
21
+ tag.delete_if{ |frame| frame[:id] == :COMM }
22
+
23
+ # Get info about APIC frame to see which fields are allowed
24
+ ID3Lib::Info.frame(:APIC)
25
+ #=> [ 2, :APIC, "Attached picture",
26
+ #=> [:textenc, :mimetype, :picturetype, :description, :data] ]
27
+
28
+ # Add an attached picture frame
29
+ cover = {
30
+ :id => :APIC,
31
+ :mimetype => 'image/jpeg',
32
+ :picturetype => 3,
33
+ :description => 'A pretty picture',
34
+ :textenc => 0,
35
+ :data => File.read('cover.jpg')
36
+ }
37
+ tag << cover
38
+
39
+ # Last but not least, apply changes
40
+ tag.update!
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.11
2
+ rubygems_version: 0.8.99
3
3
  specification_version: 1
4
4
  name: id3lib-ruby
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.3.1
7
- date: 2006-06-05 00:00:00 +02:00
6
+ version: 0.4.0
7
+ date: 2006-06-27 00:00:00 +02:00
8
8
  summary: id3lib-ruby provides a Ruby interface to the id3lib C++ library for easily editing ID3 tags (v1 and v2) like with pyid3lib.
9
9
  require_paths:
10
10
  - lib
@@ -25,6 +25,7 @@ required_ruby_version: !ruby/object:Gem::Version::Requirement
25
25
  platform: ruby
26
26
  signing_key:
27
27
  cert_chain:
28
+ post_install_message:
28
29
  authors:
29
30
  - Robin Stocker
30
31
  files:
@@ -37,9 +38,13 @@ files:
37
38
  - test/data/unicode.mp3
38
39
  - test/data/cover.jpg
39
40
  - Rakefile
41
+ - usage.rb
40
42
  - setup.rb
41
43
  - ext/extconf.rb
44
+ - ext/generate_info.rb
42
45
  - ext/id3lib_api_wrap.cxx
46
+ - ext/id3lib_api.i
47
+ - ext/Rakefile
43
48
  - README
44
49
  - CHANGES
45
50
  - TODO
@@ -47,6 +52,7 @@ test_files:
47
52
  - test/test_writing.rb
48
53
  - test/test_reading.rb
49
54
  rdoc_options:
55
+ - --inline-source
50
56
  - --line-numbers
51
57
  - --main
52
58
  - README