id3lib-ruby 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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